From 321e75c87673730e8e086c7654bef044d074c056 Mon Sep 17 00:00:00 2001 From: "dadi.zhao" Date: Thu, 24 Aug 2023 04:16:36 +0100 Subject: [PATCH] branch 6.1 --- ...gneCoatOfArms.jpg => CologneCoatOfArms.jpg | Bin {src/Import => Import}/SON/Contents.m | 0 .../SON/MATLAB SON Library [2.0].pdf | Bin .../SON/SON32/C_Sources/GetFilterMask.c | 106 +- .../SON/SON32/C_Sources/SONAppID.c | 142 +- .../SON/SON32/C_Sources/SONDef.h | 10 +- .../SON/SON32/C_Sources/SONFActive.c | 116 +- .../SON/SON32/C_Sources/SONFControl.c | 274 +- .../SON/SON32/C_Sources/SONFEqual.c | 118 +- .../SON/SON32/C_Sources/SONFMode.c | 206 +- .../SON/SON32/C_Sources/SONFilter.c | 188 +- .../SON/SON32/C_Sources/SONGetADCData.c | 438 +- .../SON/SON32/C_Sources/SONGetEventData.c | 310 +- .../SON/SON32/C_Sources/SONGetExtMarkData.c | 494 +- .../SON/SON32/C_Sources/SONGetMarkData.c | 346 +- .../SON/SON32/C_Sources/SONGetRealData.c | 428 +- .../SON/SON32/C_Sources/SONGetVersion.c | 124 +- .../SON/SON32/C_Sources/SONLastPointsTime.c | 246 +- .../SON/SON32/C_Sources/SONLastTime.c | 298 +- .../SON/SON32/C_Sources/SONSetMarker.c | 388 +- .../SON/SON32/C_Sources/SONTimeDate.c | 174 +- .../SON/SON32/C_Sources/SONWriteExtMarkBlock | 280 +- .../SON/SON32/C_Sources/SONWriteExtMarkBlock2 | 284 +- .../SON/SON32/C_Sources/SONWriteMarkBlock.c | 262 +- .../SON/SON32/C_Sources/compile.m | 44 +- .../C_Sources/gatewaySONWriteExtMarkBlock.c | 288 +- {src/Import => Import}/SON/SON32/Contents.m | 0 {src/Import => Import}/SON/SON32/SONAppID.m | 34 +- .../SON/SON32/SONAppID.mexw32 | Bin {src/Import => Import}/SON/SON32/SONBlocks.m | 36 +- .../SON/SON32/SONBookFileSpace.m | 38 +- .../Import => Import}/SON/SON32/SONCanWrite.m | 32 +- .../SON/SON32/SONChanBytes.m | 38 +- .../SON/SON32/SONChanDelete.m | 76 +- .../SON/SON32/SONChanDivide.m | 42 +- .../SON/SON32/SONChanInterleave.m | 28 +- .../Import => Import}/SON/SON32/SONChanKind.m | 30 +- .../SON/SON32/SONChanMaxTime.m | 32 +- {src/Import => Import}/SON/SON32/SONCleanUp.m | 18 +- .../SON/SON32/SONCloseFile.m | 34 +- .../SON/SON32/SONCommitFile.m | 24 +- .../SON/SON32/SONCreateFile.m | 36 +- .../Import => Import}/SON/SON32/SONDateTime.m | 54 +- .../SON/SON32/SONDelBlocks.m | 36 +- .../SON/SON32/SONEmptyFile.m | 30 +- .../SON/SON32/SONExtMarkAlign.m | 46 +- {src/Import => Import}/SON/SON32/SONFActive.m | 20 +- .../SON/SON32/SONFActive.mexw32 | Bin .../Import => Import}/SON/SON32/SONFControl.m | 50 +- .../SON/SON32/SONFControl.mexw32 | Bin {src/Import => Import}/SON/SON32/SONFEqual.m | 22 +- .../SON/SON32/SONFEqual.mexw32 | Bin {src/Import => Import}/SON/SON32/SONFMode.m | 44 +- .../SON/SON32/SONFMode.mexw32 | Bin .../SON/SON32/SONFileBytes.m | 20 +- .../Import => Import}/SON/SON32/SONFileSize.m | 20 +- {src/Import => Import}/SON/SON32/SONFilter.m | 34 +- .../SON/SON32/SONFilter.mexw32 | Bin .../SON/SON32/SONGetADCData.m | 82 +- .../SON/SON32/SONGetADCData.mexw32 | Bin .../SON/SON32/SONGetADCInfo.m | 56 +- .../SON/SON32/SONGetChanComment.m | 34 +- .../SON/SON32/SONGetChanTitle.m | 30 +- .../SON/SON32/SONGetEventData.m | 62 +- .../SON/SON32/SONGetEventData.mexw32 | Bin .../SON/SON32/SONGetExtMarkData.m | 80 +- .../SON/SON32/SONGetExtMarkData.mexw32 | Bin .../SON/SON32/SONGetExtMarkInfo.m | 58 +- .../SON/SON32/SONGetExtraData.m | 146 +- .../SON/SON32/SONGetExtraDataSize.m | 18 +- .../SON/SON32/SONGetFileComment.m | 22 +- .../SON/SON32/SONGetFreeChan.m | 22 +- .../SON/SON32/SONGetFreeChanl.m | 22 +- .../SON/SON32/SONGetMarkData.m | 72 +- .../SON/SON32/SONGetMarkData.mexw32 | Bin .../SON/SON32/SONGetRealData.m | 82 +- .../SON/SON32/SONGetRealData.mexw32 | Bin .../SON/SON32/SONGetTimePerADC.m | 36 +- .../SON/SON32/SONGetVersion.m | 20 +- .../SON/SON32/SONGetusPerTime.m | 32 +- .../SON/SON32/SONIdealRate.m | 44 +- .../Import => Import}/SON/SON32/SONIsSaving.m | 26 +- .../Import => Import}/SON/SON32/SONItemSize.m | 22 +- .../SON/SON32/SONKillRange.m | 30 +- .../SON/SON32/SONLastPointsTime.m | 38 +- .../SON/SON32/SONLastPointsTime.mexw32 | Bin .../Import => Import}/SON/SON32/SONLastTime.m | 48 +- .../SON/SON32/SONLastTime.mexw32 | Bin .../SON/SON32/SONLatestTime.m | 30 +- {src/Import => Import}/SON/SON32/SONLoad.m | 98 +- .../Import => Import}/SON/SON32/SONMaxChans.m | 24 +- {src/Import => Import}/SON/SON32/SONMaxTime.m | 18 +- .../SON/SON32/SONOpenNewFile.m | 22 +- .../SON/SON32/SONOpenOldFile.m | 46 +- {src/Import => Import}/SON/SON32/SONPhyChan.m | 24 +- {src/Import => Import}/SON/SON32/SONPhySz.m | 16 +- .../Import => Import}/SON/SON32/SONPhysChan.m | 24 +- {src/Import => Import}/SON/SON32/SONSave.m | 38 +- .../SON/SON32/SONSaveRange.m | 38 +- .../SON/SON32/SONSetADCOffset.m | 36 +- .../SON/SON32/SONSetADCScale.m | 38 +- .../SON/SON32/SONSetADCUnits.m | 34 +- .../SON/SON32/SONSetBuffSpace.m | 16 +- .../SON/SON32/SONSetBuffering.m | 14 +- .../SON/SON32/SONSetChanComment.m | 26 +- .../SON/SON32/SONSetChanTitle.m | 24 +- .../SON/SON32/SONSetEventChan.m | 88 +- .../SON/SON32/SONSetFileClock.m | 30 +- .../SON/SON32/SONSetFileComment.m | 36 +- .../SON/SON32/SONSetInitLow.m | 38 +- .../SON/SON32/SONSetMarker.m | 76 +- .../SON/SON32/SONSetMarker.mexw32 | Bin .../SON/SON32/SONSetRealChan.m | 76 +- .../SON/SON32/SONSetRealMarkChan.m | 78 +- .../SON/SON32/SONSetTextMarkChan.m | 66 +- .../SON/SON32/SONSetWaveChan.m | 74 +- .../SON/SON32/SONSetWaveMarkChan.m | 84 +- .../Import => Import}/SON/SON32/SONTimeBase.m | 38 +- .../SON/SON32/SONTimeDate.mexw32 | Bin .../SON/SON32/SONUpdateStart.m | 24 +- {src/Import => Import}/SON/SON32/SONVersion.m | 32 +- .../SON/SON32/SONWriteADCBlock.m | 56 +- .../SON/SON32/SONWriteEventBlock.m | 50 +- .../SON/SON32/SONWriteExtMarkBlock.m | 0 .../SON/SON32/SONWriteExtMarkBlock.mexw32 | Bin .../SON/SON32/SONWriteMarkBlock.m | 52 +- .../SON/SON32/SONWriteRealBlock.m | 54 +- {src/Import => Import}/SON/SON32/SONYRange.m | 0 .../SON32/gatewaySONWriteExtMarkBlock.mexw32 | Bin {src/Import => Import}/SON/SON32/son32.m | 382 +- {src/Import => Import}/SON/SONADCToDouble.m | 110 +- {src/Import => Import}/SON/SONADCToSingle.m | 104 +- {src/Import => Import}/SON/SONChanList.m | 72 +- {src/Import => Import}/SON/SONChannelInfo.m | 198 +- {src/Import => Import}/SON/SONCreateChannel.m | 290 +- {src/Import => Import}/SON/SONFileHeader.m | 126 +- {src/Import => Import}/SON/SONGetADCChannel.m | 542 +- .../SON/SONGetADCMarkerChannel.m | 312 +- .../SON/SONGetBlockHeaders.m | 92 +- {src/Import => Import}/SON/SONGetChannel.m | 172 +- .../SON/SONGetEventChannel.m | 224 +- .../SON/SONGetMarkerChannel.m | 204 +- .../SON/SONGetRealMarkerChannel.m | 246 +- .../SON/SONGetRealWaveChannel.m | 516 +- .../SON/SONGetSampleInterval.m | 84 +- .../Import => Import}/SON/SONGetSampleTicks.m | 66 +- .../SON/SONGetTextMarkerChannel.m | 218 +- {src/Import => Import}/SON/SONRealToADC.m | 58 +- {src/Import => Import}/SON/SONTest.m | 66 +- .../Import => Import}/SON/SONTicksToSeconds.m | 92 +- .../SON/SONUpgradeToVersion6.m | 76 +- {src/Import => Import}/SON/SONVersion.m | 34 +- {src/Import => Import}/SON/progressbar.m | 480 +- {src/Import => Import}/SON/readme.txt | 30 +- {src/Import => Import}/acq/acqread.m | 654 +- {src/Import => Import}/acq/app156.pdf | Bin {src/Import => Import}/acq/license.txt | 48 +- ...7913 BioGraph Infiniti Getting Started.pdf | Bin .../eyelink/import_eyelink.m | 0 .../fieldtrip/fileio/COPYING | 0 .../Import => Import}/fieldtrip/fileio/README | 0 .../fieldtrip/fileio/ft_chantype.m | 0 .../fieldtrip/fileio/ft_chanunit.m | 0 .../fieldtrip/fileio/ft_create_buffer.m | 0 .../fieldtrip/fileio/ft_destroy_buffer.m | 0 .../fieldtrip/fileio/ft_filetype.m | 0 .../fieldtrip/fileio/ft_filter_event.m | 0 .../fieldtrip/fileio/ft_flush_data.m | 0 .../fieldtrip/fileio/ft_flush_event.m | 0 .../fieldtrip/fileio/ft_flush_header.m | 0 .../fieldtrip/fileio/ft_poll_buffer.m | 0 .../fieldtrip/fileio/ft_read_atlas.m | 0 .../fieldtrip/fileio/ft_read_cifti.m | 0 .../fieldtrip/fileio/ft_read_data.m | 0 .../fieldtrip/fileio/ft_read_event.m | 0 .../fieldtrip/fileio/ft_read_header.m | 0 .../fieldtrip/fileio/ft_read_headshape.m | 0 .../fieldtrip/fileio/ft_read_mri.m | 0 .../fieldtrip/fileio/ft_read_sens.m | 0 .../fieldtrip/fileio/ft_read_spike.m | 0 .../fieldtrip/fileio/ft_read_vol.m | 0 .../fieldtrip/fileio/ft_write_cifti.m | 0 .../fieldtrip/fileio/ft_write_data.m | 0 .../fieldtrip/fileio/ft_write_event.m | 0 .../fieldtrip/fileio/ft_write_headshape.m | 0 .../fieldtrip/fileio/ft_write_mri.m | 0 .../fieldtrip/fileio/ft_write_spike.m | 0 .../fileio/matlablt2010b/@uint64/abs.c | 0 .../fileio/matlablt2010b/@uint64/abs.m | 0 .../fileio/matlablt2010b/@uint64/abs.mexa64 | Bin .../fileio/matlablt2010b/@uint64/abs.mexglx | Bin .../fileio/matlablt2010b/@uint64/abs.mexmaci | Bin .../matlablt2010b/@uint64/abs.mexmaci64 | Bin .../fileio/matlablt2010b/@uint64/abs.mexw32 | Bin .../fileio/matlablt2010b/@uint64/abs.mexw64 | Bin .../fileio/matlablt2010b/@uint64/all.m | 0 .../fileio/matlablt2010b/@uint64/any.m | 0 .../matlablt2010b/@uint64/compile_uint64.m | 0 .../fileio/matlablt2010b/@uint64/diff.m | 0 .../fileio/matlablt2010b/@uint64/max.c | 0 .../fileio/matlablt2010b/@uint64/max.m | 0 .../fileio/matlablt2010b/@uint64/max.mexa64 | Bin .../fileio/matlablt2010b/@uint64/max.mexglx | Bin .../fileio/matlablt2010b/@uint64/max.mexmac | Bin .../fileio/matlablt2010b/@uint64/max.mexmaci | Bin .../matlablt2010b/@uint64/max.mexmaci64 | Bin .../fileio/matlablt2010b/@uint64/max.mexw32 | Bin .../fileio/matlablt2010b/@uint64/max.mexw64 | Bin .../fileio/matlablt2010b/@uint64/min.c | 0 .../fileio/matlablt2010b/@uint64/min.m | 0 .../fileio/matlablt2010b/@uint64/min.mexa64 | Bin .../fileio/matlablt2010b/@uint64/min.mexglx | Bin .../fileio/matlablt2010b/@uint64/min.mexmac | Bin .../fileio/matlablt2010b/@uint64/min.mexmaci | Bin .../matlablt2010b/@uint64/min.mexmaci64 | Bin .../fileio/matlablt2010b/@uint64/min.mexw32 | Bin .../fileio/matlablt2010b/@uint64/min.mexw64 | Bin .../fileio/matlablt2010b/@uint64/minus.c | 0 .../fileio/matlablt2010b/@uint64/minus.m | 0 .../fileio/matlablt2010b/@uint64/minus.mexa64 | Bin .../fileio/matlablt2010b/@uint64/minus.mexglx | Bin .../fileio/matlablt2010b/@uint64/minus.mexmac | Bin .../matlablt2010b/@uint64/minus.mexmaci | Bin .../matlablt2010b/@uint64/minus.mexmaci64 | Bin .../fileio/matlablt2010b/@uint64/minus.mexw32 | Bin .../fileio/matlablt2010b/@uint64/minus.mexw64 | Bin .../fileio/matlablt2010b/@uint64/plus.c | 0 .../fileio/matlablt2010b/@uint64/plus.m | 0 .../fileio/matlablt2010b/@uint64/plus.mexa64 | Bin .../fileio/matlablt2010b/@uint64/plus.mexglx | Bin .../fileio/matlablt2010b/@uint64/plus.mexmac | Bin .../fileio/matlablt2010b/@uint64/plus.mexmaci | Bin .../matlablt2010b/@uint64/plus.mexmaci64 | Bin .../fileio/matlablt2010b/@uint64/plus.mexw32 | Bin .../fileio/matlablt2010b/@uint64/plus.mexw64 | Bin .../fileio/matlablt2010b/@uint64/rdivide.c | 0 .../fileio/matlablt2010b/@uint64/rdivide.m | 0 .../matlablt2010b/@uint64/rdivide.mexa64 | Bin .../matlablt2010b/@uint64/rdivide.mexglx | Bin .../matlablt2010b/@uint64/rdivide.mexmac | Bin .../matlablt2010b/@uint64/rdivide.mexmaci | Bin .../matlablt2010b/@uint64/rdivide.mexmaci64 | Bin .../matlablt2010b/@uint64/rdivide.mexw32 | Bin .../matlablt2010b/@uint64/rdivide.mexw64 | Bin .../fileio/matlablt2010b/@uint64/test.m | 0 .../fileio/matlablt2010b/@uint64/times.c | 0 .../fileio/matlablt2010b/@uint64/times.m | 0 .../fileio/matlablt2010b/@uint64/times.mexa64 | Bin .../fileio/matlablt2010b/@uint64/times.mexglx | Bin .../fileio/matlablt2010b/@uint64/times.mexmac | Bin .../matlablt2010b/@uint64/times.mexmaci | Bin .../matlablt2010b/@uint64/times.mexmaci64 | Bin .../fileio/matlablt2010b/@uint64/times.mexw32 | Bin .../fileio/matlablt2010b/@uint64/times.mexw64 | Bin .../fieldtrip/fileio/private/ReadHeader.m | 0 .../fieldtrip/fileio/private/add_mex_source.m | 0 .../fieldtrip/fileio/private/ama2vol.m | 0 .../fieldtrip/fileio/private/appendevent.m | 0 .../fieldtrip/fileio/private/avw_hdr_read.m | 0 .../fieldtrip/fileio/private/avw_img_read.m | 0 .../fieldtrip/fileio/private/bigendian.m | 0 .../fieldtrip/fileio/private/bounding_mesh.m | 0 .../fieldtrip/fileio/private/bti2grad.m | 0 .../fieldtrip/fileio/private/buffer.mexa64 | Bin .../fieldtrip/fileio/private/buffer.mexglx | Bin .../fieldtrip/fileio/private/buffer.mexmac | Bin .../fieldtrip/fileio/private/buffer.mexmaci | Bin .../fieldtrip/fileio/private/buffer.mexmaci64 | Bin .../fieldtrip/fileio/private/buffer.mexw32 | Bin .../fieldtrip/fileio/private/buffer.mexw64 | Bin .../fileio/private/buffer_wait_dat.m | 0 .../fileio/private/channelposition.m | 0 .../fileio/private/compile_mex_list.m | 0 .../fieldtrip/fileio/private/cornerpoints.m | 0 .../fieldtrip/fileio/private/cstructdecode.m | 0 .../fieldtrip/fileio/private/ctf2grad.m | 0 .../fieldtrip/fileio/private/dataset2files.m | 0 .../fieldtrip/fileio/private/db_close.m | 0 .../fieldtrip/fileio/private/db_insert.m | 0 .../fieldtrip/fileio/private/db_insert_blob.m | 0 .../fieldtrip/fileio/private/db_open.m | 0 .../fieldtrip/fileio/private/db_select.m | 0 .../fieldtrip/fileio/private/db_select_blob.m | 0 .../fieldtrip/fileio/private/decode_fif.m | 0 .../fieldtrip/fileio/private/decode_nifti1.m | 0 .../fieldtrip/fileio/private/decode_res4.m | 0 .../fieldtrip/fileio/private/dimlength.m | 0 .../fieldtrip/fileio/private/elproj.m | 0 .../fieldtrip/fileio/private/encode_nifti1.m | 0 .../fieldtrip/fileio/private/fetch_url.m | 0 .../fieldtrip/fileio/private/fif2grad.m | 0 .../fieldtrip/fileio/private/fiff_open_le.m | 0 .../fileio/private/filetype_check_extension.m | 0 .../fileio/private/filetype_check_header.m | 0 .../fileio/private/filetype_check_uri.m | 0 .../fileio/private/find_outermost_boundary.m | 0 .../fieldtrip/fileio/private/fixdimord.m | 0 .../fieldtrip/fileio/private/fixinside.m | 0 .../fieldtrip/fileio/private/fixname.m | 0 .../fieldtrip/fileio/private/fixpos.m | 0 .../fieldtrip/fileio/private/fixsampleinfo.m | 0 .../fileio/private/ft_apply_montage.m | 0 .../fieldtrip/fileio/private/ft_checkdata.m | 0 .../fileio/private/ft_convert_units.m | 0 .../fieldtrip/fileio/private/ft_datatype.m | 0 .../fileio/private/ft_datatype_comp.m | 0 .../fileio/private/ft_datatype_dip.m | 0 .../fileio/private/ft_datatype_freq.m | 0 .../fileio/private/ft_datatype_headmodel.m | 0 .../fileio/private/ft_datatype_mvar.m | 0 .../fileio/private/ft_datatype_raw.m | 0 .../fileio/private/ft_datatype_sens.m | 0 .../fileio/private/ft_datatype_source.m | 0 .../fileio/private/ft_datatype_spike.m | 0 .../fileio/private/ft_datatype_timelock.m | 0 .../fileio/private/ft_datatype_vol.m | 0 .../fileio/private/ft_estimate_units.m | 0 .../fieldtrip/fileio/private/ft_fetch_data.m | 0 .../fileio/private/ft_fetch_header.m | 0 .../fieldtrip/fileio/private/ft_findcfg.m | 0 .../fieldtrip/fileio/private/ft_getopt.m | 0 .../fieldtrip/fileio/private/ft_getopt.mexa64 | Bin .../fieldtrip/fileio/private/ft_getopt.mexglx | Bin .../fileio/private/ft_getopt.mexmaci | Bin .../fileio/private/ft_getopt.mexmaci64 | Bin .../fieldtrip/fileio/private/ft_getopt.mexw32 | Bin .../fieldtrip/fileio/private/ft_getopt.mexw64 | Bin .../fieldtrip/fileio/private/ft_hastoolbox.m | 0 .../fileio/private/ft_headcoordinates.m | 0 .../fileio/private/ft_platform_supports.m | 0 .../fieldtrip/fileio/private/ft_progress.m | 0 .../fileio/private/ft_scalingfactor.m | 0 .../fieldtrip/fileio/private/ft_senslabel.m | 0 .../fieldtrip/fileio/private/ft_senstype.m | 0 .../fieldtrip/fileio/private/ft_voltype.m | 0 .../fieldtrip/fileio/private/ft_warning.m | 0 .../fieldtrip/fileio/private/ft_warp_apply.m | 0 .../fieldtrip/fileio/private/getdatfield.m | 0 .../fieldtrip/fileio/private/getdimord.m | 0 .../fieldtrip/fileio/private/getdimsiz.m | 0 .../fieldtrip/fileio/private/getsubfield.m | 0 .../fieldtrip/fileio/private/hasyokogawa.m | 0 .../fileio/private/in_fopen_manscan.m | 0 .../fileio/private/in_fread_manscan.m | 0 .../fieldtrip/fileio/private/inflate_file.m | 0 .../fieldtrip/fileio/private/inifile.m | 0 .../fieldtrip/fileio/private/issubfield.m | 0 .../fieldtrip/fileio/private/istrue.m | 0 .../fieldtrip/fileio/private/itab2grad.m | 0 .../fieldtrip/fileio/private/jaga16_packet.m | 0 .../fieldtrip/fileio/private/keyval.m | 0 .../fieldtrip/fileio/private/labelcmb2indx.m | 0 .../fieldtrip/fileio/private/littleendian.m | 0 .../fieldtrip/fileio/private/loadama.m | 0 .../fieldtrip/fileio/private/loadvar.m | 0 .../fieldtrip/fileio/private/match_str.m | 0 .../fieldtrip/fileio/private/mne2grad.m | 0 .../fieldtrip/fileio/private/mxDeserialize.m | 0 .../fileio/private/mxDeserialize_c.mexa64 | Bin .../fileio/private/mxDeserialize_c.mexglx | Bin .../fileio/private/mxDeserialize_c.mexmac | Bin .../fileio/private/mxDeserialize_c.mexmaci | Bin .../fileio/private/mxDeserialize_c.mexmaci64 | Bin .../fileio/private/mxDeserialize_c.mexw32 | Bin .../fileio/private/mxDeserialize_c.mexw64 | Bin .../fileio/private/mxDeserialize_cpp.mexa64 | Bin .../private/mxDeserialize_cpp.mexmaci64 | Bin .../fileio/private/mxDeserialize_cpp.mexw32 | Bin .../fieldtrip/fileio/private/mxSerialize.m | 0 .../fileio/private/mxSerialize_c.mexa64 | Bin .../fileio/private/mxSerialize_c.mexglx | Bin .../fileio/private/mxSerialize_c.mexmac | Bin .../fileio/private/mxSerialize_c.mexmaci | Bin .../fileio/private/mxSerialize_c.mexmaci64 | Bin .../fileio/private/mxSerialize_c.mexw32 | Bin .../fileio/private/mxSerialize_c.mexw64 | Bin .../fileio/private/mxSerialize_cpp.mexa64 | Bin .../fileio/private/mxSerialize_cpp.mexmaci64 | Bin .../fileio/private/mxSerialize_cpp.mexw32 | Bin .../fileio/private/mxSerialize_cpp.mexw64 | Bin .../fieldtrip/fileio/private/ndgrid.m | 0 .../fieldtrip/fileio/private/netmeg2grad.m | 0 .../fieldtrip/fileio/private/neuralynx_crc.m | 0 .../fileio/private/neuralynx_getheader.m | 0 .../fileio/private/neuralynx_timestamp.m | 0 .../private/np_read_splitted_fileinfo.m | 0 .../fieldtrip/fileio/private/np_readdata.m | 0 .../fileio/private/np_readfileinfo.m | 0 .../fieldtrip/fileio/private/np_readmarker.m | 0 .../fieldtrip/fileio/private/openbdf.m | 0 .../fileio/private/parameterselection.m | 0 .../fileio/private/plx_orig_header.m | 0 .../fieldtrip/fileio/private/pos2dim.m | 0 .../fieldtrip/fileio/private/pos2dim3d.m | 0 .../fieldtrip/fileio/private/pos2transform.m | 0 .../fileio/private/pthreadGC2-w64.dll | Bin .../fieldtrip/fileio/private/pthreadGC2.dll | Bin .../fieldtrip/fileio/private/pthreadVC2.dll | Bin .../fieldtrip/fileio/private/quaternion.m | 0 .../fileio/private/read_16bit.mexa64 | Bin .../fileio/private/read_16bit.mexglx | Bin .../fileio/private/read_16bit.mexmaci | Bin .../fileio/private/read_16bit.mexmaci64 | Bin .../fileio/private/read_16bit.mexw32 | Bin .../fileio/private/read_16bit.mexw64 | Bin .../fileio/private/read_24bit.mexa64 | Bin .../fileio/private/read_24bit.mexglx | Bin .../fileio/private/read_24bit.mexmac | Bin .../fileio/private/read_24bit.mexmaci | Bin .../fileio/private/read_24bit.mexmaci64 | Bin .../fileio/private/read_24bit.mexw32 | Bin .../fileio/private/read_24bit.mexw64 | Bin .../fieldtrip/fileio/private/read_4d_hdr.m | 0 .../fieldtrip/fileio/private/read_ah5_data.m | 0 .../fileio/private/read_ah5_markers.m | 0 .../fieldtrip/fileio/private/read_ahdf5_hdr.m | 0 .../fieldtrip/fileio/private/read_asa.m | 0 .../fieldtrip/fileio/private/read_asa_bnd.m | 0 .../fieldtrip/fileio/private/read_asa_dip.m | 0 .../fieldtrip/fileio/private/read_asa_elc.m | 0 .../fieldtrip/fileio/private/read_asa_mri.m | 0 .../fieldtrip/fileio/private/read_asa_msr.m | 0 .../fieldtrip/fileio/private/read_asa_vol.m | 0 .../fieldtrip/fileio/private/read_besa_avr.m | 0 .../fieldtrip/fileio/private/read_besa_besa.m | 0 .../fieldtrip/fileio/private/read_besa_sfp.m | 0 .../fieldtrip/fileio/private/read_besa_swf.m | 0 .../fieldtrip/fileio/private/read_bham.m | 0 .../fieldtrip/fileio/private/read_biff.m | 0 .../fileio/private/read_biosemi_bdf.m | 0 .../fileio/private/read_biosig_data.m | 0 .../fileio/private/read_biosig_header.m | 0 .../fileio/private/read_brainvision_eeg.m | 0 .../fileio/private/read_brainvision_pos.m | 0 .../fileio/private/read_brainvision_vhdr.m | 0 .../fileio/private/read_brainvision_vmrk.m | 0 .../fieldtrip/fileio/private/read_bti_ascii.m | 0 .../fieldtrip/fileio/private/read_bti_hs.m | 0 .../fieldtrip/fileio/private/read_bti_m4d.m | 0 .../fileio/private/read_bucn_nirsdata.m | 0 .../fileio/private/read_bucn_nirsevent.m | 0 .../fileio/private/read_bucn_nirshdr.m | 0 .../fileio/private/read_buffer_offline_data.m | 0 .../private/read_buffer_offline_events.m | 0 .../private/read_buffer_offline_header.m | 0 .../fieldtrip/fileio/private/read_bv_srf.m | 0 .../fileio/private/read_caret_spec.m | 0 .../fieldtrip/fileio/private/read_ced_son.m | 0 .../fileio/private/read_combined_ds.m | 0 .../fieldtrip/fileio/private/read_ctf_ascii.m | 0 .../fieldtrip/fileio/private/read_ctf_cls.m | 0 .../fieldtrip/fileio/private/read_ctf_coef.m | 0 .../fieldtrip/fileio/private/read_ctf_dat.m | 0 .../fieldtrip/fileio/private/read_ctf_hc.m | 0 .../fieldtrip/fileio/private/read_ctf_hdm.m | 0 .../fieldtrip/fileio/private/read_ctf_hist.m | 0 .../fieldtrip/fileio/private/read_ctf_meg4.m | 0 .../fieldtrip/fileio/private/read_ctf_mri.m | 0 .../fieldtrip/fileio/private/read_ctf_mri4.m | 0 .../fieldtrip/fileio/private/read_ctf_pos.m | 0 .../fieldtrip/fileio/private/read_ctf_res4.m | 0 .../fieldtrip/fileio/private/read_ctf_sens.m | 0 .../fieldtrip/fileio/private/read_ctf_shape.m | 0 .../fieldtrip/fileio/private/read_ctf_shm.m | 0 .../fileio/private/read_ctf_shm.mexglx | Bin .../fieldtrip/fileio/private/read_ctf_svl.m | 0 .../fileio/private/read_ctf_trigger.m | 0 .../fieldtrip/fileio/private/read_curry.m | 0 .../fileio/private/read_deymed_dat.m | 0 .../fileio/private/read_deymed_ini.m | 0 .../fieldtrip/fileio/private/read_edf.m | 0 .../fileio/private/read_eeglabdata.m | 0 .../fileio/private/read_eeglabevent.m | 0 .../fileio/private/read_eeglabheader.m | 0 .../fieldtrip/fileio/private/read_egis_data.m | 0 .../fileio/private/read_egis_header.m | 0 .../fieldtrip/fileio/private/read_elec.m | 0 .../fileio/private/read_erplabdata.m | 0 .../fileio/private/read_erplabevent.m | 0 .../fileio/private/read_erplabheader.m | 0 .../fileio/private/read_eyelink_asc.m | 0 .../fieldtrip/fileio/private/read_fcdc_trl.m | 0 .../fieldtrip/fileio/private/read_itab_mhd.m | 0 .../fieldtrip/fileio/private/read_mat.m | 0 .../fieldtrip/fileio/private/read_mclust_t.m | 0 .../fieldtrip/fileio/private/read_mff_bin.m | 0 .../fileio/private/read_micromed_event.m | 0 .../fileio/private/read_micromed_trc.m | 0 .../fieldtrip/fileio/private/read_mpi_dap.m | 0 .../fieldtrip/fileio/private/read_mpi_ds.m | 0 .../fileio/private/read_nervus_data.m | 0 .../fileio/private/read_nervus_header.m | 0 .../fileio/private/read_neuralynx_bin.m | 0 .../fileio/private/read_neuralynx_cds.m | 0 .../fileio/private/read_neuralynx_dma.m | 0 .../fileio/private/read_neuralynx_ds.m | 0 .../fileio/private/read_neuralynx_ncs.m | 0 .../fileio/private/read_neuralynx_nev.m | 0 .../fileio/private/read_neuralynx_nse.m | 0 .../fileio/private/read_neuralynx_nst.m | 0 .../fileio/private/read_neuralynx_nts.m | 0 .../fileio/private/read_neuralynx_ntt.m | 0 .../fileio/private/read_neuralynx_sdma.m | 0 .../fileio/private/read_neuralynx_ttl.m | 0 .../fileio/private/read_neuromag_eve.m | 0 .../fileio/private/read_neuromag_hc.m | 0 .../fileio/private/read_neuroshare.m | 0 .../fileio/private/read_neurosim_evolution.m | 0 .../fileio/private/read_neurosim_signals.m | 0 .../fileio/private/read_neurosim_spikes.m | 0 .../fieldtrip/fileio/private/read_nex_data.m | 0 .../fieldtrip/fileio/private/read_nex_event.m | 0 .../fileio/private/read_nex_header.m | 0 .../fileio/private/read_nexstim_event.m | 0 .../fileio/private/read_nexstim_nxe.m | 0 .../fileio/private/read_nifti2_hdr.m | 0 .../fileio/private/read_nihonkohden_hdr.m | 206 +- .../fileio/private/read_nihonkohden_m00.m | 136 +- .../fileio/private/read_nimh_cortex.m | 0 .../fileio/private/read_nmc_archive_k_data.m | 0 .../fileio/private/read_nmc_archive_k_event.m | 0 .../fileio/private/read_nmc_archive_k_hdr.m | 0 .../fieldtrip/fileio/private/read_ns_avg.m | 0 .../fieldtrip/fileio/private/read_ns_eeg.m | 0 .../fieldtrip/fileio/private/read_ns_hdr.m | 0 .../fieldtrip/fileio/private/read_off.m | 0 .../fileio/private/read_plexon_ddt.m | 0 .../fieldtrip/fileio/private/read_plexon_ds.m | 0 .../fileio/private/read_plexon_nex.m | 0 .../fileio/private/read_plexon_plx.m | 0 .../fieldtrip/fileio/private/read_ply.m | 0 .../fileio/private/read_polhemus_fil.m | 0 .../fieldtrip/fileio/private/read_sbin_data.m | 0 .../fileio/private/read_sbin_events.m | 0 .../fileio/private/read_sbin_header.m | 0 .../fileio/private/read_serial_event.m | 0 .../fieldtrip/fileio/private/read_shm_data.m | 0 .../fieldtrip/fileio/private/read_shm_event.m | 0 .../fileio/private/read_shm_header.m | 0 .../fieldtrip/fileio/private/read_smi_txt.m | 0 .../fileio/private/read_spike6mat_data.m | 0 .../fileio/private/read_spike6mat_header.m | 0 .../fileio/private/read_spmeeg_data.m | 0 .../fileio/private/read_spmeeg_event.m | 0 .../fileio/private/read_spmeeg_header.m | 0 .../fieldtrip/fileio/private/read_stl.m | 0 .../fieldtrip/fileio/private/read_tdt_sev.m | 0 .../fieldtrip/fileio/private/read_tdt_tbk.m | 0 .../fieldtrip/fileio/private/read_tdt_tdx.m | 0 .../fieldtrip/fileio/private/read_tdt_tev.m | 0 .../fieldtrip/fileio/private/read_tdt_tsq.m | 0 .../fileio/private/read_tmsi_poly5.m | 0 .../fieldtrip/fileio/private/read_tobii_tsv.m | 0 .../fieldtrip/fileio/private/read_trigger.m | 0 .../fileio/private/read_videomeg_aud.m | 0 .../fileio/private/read_videomeg_vid.m | 0 .../fieldtrip/fileio/private/read_vtk.m | 0 .../fieldtrip/fileio/private/read_wdq_data.m | 0 .../fileio/private/read_wdq_header.m | 0 .../fileio/private/read_yokogawa_data.m | 0 .../fileio/private/read_yokogawa_data_new.m | 0 .../fileio/private/read_yokogawa_event.m | 0 .../fileio/private/read_yokogawa_header.m | 0 .../fileio/private/read_yokogawa_header_new.m | 0 .../fieldtrip/fileio/private/read_zebris.m | 0 .../fieldtrip/fileio/private/readbdf.m | 0 .../fieldtrip/fileio/private/readmarkerfile.m | 0 .../fieldtrip/fileio/private/refine.m | 0 .../fieldtrip/fileio/private/rfbevent.mexa64 | Bin .../fieldtrip/fileio/private/rfbevent.mexglx | Bin .../fieldtrip/fileio/private/rfbevent.mexmac | Bin .../fieldtrip/fileio/private/rfbevent.mexmaci | Bin .../fileio/private/rfbevent.mexmaci64 | Bin .../fieldtrip/fileio/private/rmsubfield.m | 0 .../fieldtrip/fileio/private/rotate.m | 0 .../fileio/private/sap2matlab.mexa64 | Bin .../fileio/private/sap2matlab.mexmaci64 | Bin .../fileio/private/sap2matlab.mexw32 | Bin .../fieldtrip/fileio/private/setsubfield.m | 0 .../fieldtrip/fileio/private/solid_angle.m | 0 .../fileio/private/solid_angle.mexa64 | Bin .../fieldtrip/fileio/private/surf_to_tetgen.m | 0 .../fieldtrip/fileio/private/time2offset.m | 0 .../fileio/private/timestamp_neuralynx.m | 0 .../fileio/private/timestamp_plexon.m | 0 .../fieldtrip/fileio/private/tokenize.m | 0 .../fieldtrip/fileio/private/translate.m | 0 .../fieldtrip/fileio/private/undobalancing.m | 0 .../fileio/private/volumewrite_spm.m | 0 .../fileio/private/write_brainvision_eeg.m | 0 .../fieldtrip/fileio/private/write_ctf_shm.m | 0 .../fileio/private/write_ctf_shm.mexglx | Bin .../fieldtrip/fileio/private/write_edf.m | 0 .../fieldtrip/fileio/private/write_gdf.m | 0 .../fileio/private/write_neuralynx_ncs.m | 0 .../fileio/private/write_neuralynx_nts.m | 0 .../fileio/private/write_nifti2_hdr.m | 0 .../fieldtrip/fileio/private/write_off.m | 0 .../fileio/private/write_plexon_nex.m | 0 .../fieldtrip/fileio/private/write_ply.m | 0 .../fileio/private/write_serial_event.m | 0 .../fieldtrip/fileio/private/write_stl.m | 0 .../fieldtrip/fileio/private/write_vtk.m | 0 .../fieldtrip/fileio/private/xml2struct.m | 0 .../fieldtrip/fileio/private/yokogawa2grad.m | 0 .../fileio/private/yokogawa2grad_new.m | 0 .../fieldtrip/fileio/private/yokogawa2vol.m | 0 .../adi/+adi/+binary/channel_writer.m | 124 +- .../labchart/adi/+adi/+binary/file_writer.m | 368 +- .../+adi/+examples/conversion_speed_testing.m | 146 +- .../+examples/e001_writeFileFromScratch.m | 118 +- .../e002_addCommentsToAnExistingFile.m | 32 +- .../labchart/adi/+adi/+postp/mergeComments.m | 268 +- .../labchart/adi/+adi/+sdk/ReadMe.md | 4 +- .../+adi/+sl/+array/uniqueWithGroupIndices.m | 200 +- .../labchart/adi/+adi/+sl/+cellstr/join.m | 94 +- .../adi/+adi/+sl/+datetime/getTimeZone.m | 40 +- .../adi/+adi/+sl/+datetime/unixToMatlab.m | 58 +- .../adi/+adi/+sl/+dir/changeFileExtension.m | 64 +- .../adi/+adi/+sl/+dir/createFolderIfNoExist.m | 96 +- .../labchart/adi/+adi/+sl/+dir/filepartsx.m | 48 +- .../adi/+adi/+sl/+in/processVarargin.m | 420 +- .../+adi/+sl/+in/process_varargin_result.m | 242 +- .../+adi/+sl/+stack/calling_function_info.m | 144 +- .../adi/+adi/+sl/+stack/getMyBasePath.m | 160 +- .../adi/+adi/+sl/+stack/getPackageRoot.m | 44 +- .../labchart/adi/+adi/+sl/+str/contains.m | 154 +- .../+adi/+tests/t001_speedWritingAndWriting.m | 158 +- .../labchart/adi/+adi/@channel/channel.m | 782 +- .../adi/+adi/@channel/exportToHDF5File.m | 166 +- .../adi/+adi/@file_viewer/file_viewer.m | 150 +- .../adi/+adi/@file_viewer/private/main.fig | Bin .../labchart/adi/+adi/channel_writer.m | 204 +- .../labchart/adi/+adi/comment.m | 338 +- .../labchart/adi/+adi/comment_handle.m | 122 +- .../labchart/adi/+adi/convert.m | 282 +- .../labchart/adi/+adi/createFile.m | 68 +- .../labchart/adi/+adi/data_writer_handle.m | 50 +- .../+adi/documentation/FunctionMapping.csv | 62 +- .../+adi/documentation/com_interface_notes.m | 242 +- .../labchart/adi/+adi/editFile.m | 34 +- .../adi/+adi/extractRecordToNewFile.m | 178 +- .../labchart/adi/+adi/file.m | 506 +- .../labchart/adi/+adi/file_handle.m | 74 +- .../labchart/adi/+adi/file_read_options.m | 58 +- .../labchart/adi/+adi/file_writer.m | 646 +- .../labchart/adi/+adi/h5_conversion_options.m | 66 +- .../labchart/adi/+adi/h5_file_h.m | 216 +- .../labchart/adi/+adi/h5_file_sdk.m | 154 +- .../labchart/adi/+adi/handle_logger.m | 106 +- .../labchart/adi/+adi/handle_manager.m | 364 +- .../labchart/adi/+adi/mat_comment_handle.m | 128 +- .../adi/+adi/mat_conversion_options.m | 30 +- .../labchart/adi/+adi/mat_file_h.m | 88 +- .../labchart/adi/+adi/mat_file_sdk.m | 332 +- .../adi/+adi/private/ADIDatCAPI_mex.h | 908 +- .../adi/+adi/private/ADIDatIOWin64.dll | Bin .../adi/+adi/private/ADIDatIOWin64.lib | Bin .../labchart/adi/+adi/private/c.m | 6 +- .../labchart/adi/+adi/private/c0.m | 8 +- .../labchart/adi/+adi/private/clong.m | 14 +- .../labchart/adi/+adi/private/sdk_mex.cpp | 1614 +- .../labchart/adi/+adi/private/sdk_mex.mexw64 | Bin .../labchart/adi/+adi/readFile.m | 138 +- .../labchart/adi/+adi/record.m | 230 +- .../Import => Import}/labchart/adi/+adi/sdk.m | 1666 +- .../labchart/adi/+adi/test_SDK.m | 124 +- {src/Import => Import}/labchart/adi/LICENSE | 40 +- .../Import => Import}/labchart/adi/README.rst | 116 +- {src/Import => Import}/labchart/adi/adi.m | 238 +- .../labchart/adi/documentation/ReadMe.md | 0 .../adi/documentation/organization.md | 60 +- .../adi/documentation/updating_mex_code.txt | 30 +- .../adi/files/LabChartBinaryFormat.pdf | Bin .../adi/files/blank_labchart_8_file.adicht | Bin .../labchart/adi/files/crash_testing.m | 54 +- {src/Import => Import}/nwdq/nReadDataq.m | 624 +- .../physlog/import_physlog.m | 342 +- .../smi/GazeVisToolbox/LICENSE.md | 0 .../smi/GazeVisToolbox/README.md | 0 .../smi/GazeVisToolbox/ReadSmiEventHeader.m | 0 .../smi/GazeVisToolbox/ReadSmiEvents_custom.m | 0 {src/Import => Import}/smi/import_smi.m | 0 {src/Import => Import}/smi/read_smi_events.m | 0 .../vario/getVarioport_allChannels.m | 222 +- .../viewpoint/import_viewpoint.m | 0 {src/Import => Import}/wdq/ReadDataq.m | 156 +- {src/Import => Import}/wdq/activex.exe | Bin {src/Import => Import}/wdq/controlerror.m | 8 +- {src/Import => Import}/wdq/dataqfileerror.m | 8 +- {src/Import => Import}/wdq/endoffile.m | 8 +- {doc => Manual}/PsPM_Manual.pdf | Bin {doc => Manual}/PsPM_References.pdf | Bin .../SCR_f_amplitude_check.m | 0 .../blink_saccade_filtering.m | 0 {src/backroom => backroom}/pspm_axpos.m | 58 +- {src/backroom => backroom}/pspm_bf_Fourier.m | 160 +- .../pspm_combine_markers.m | 0 .../pspm_convert_illum2lum.m | 96 +- .../pspm_convert_lux2cdm2.m | 134 +- .../pspm_convert_mm2visdeg.m | 66 +- .../pspm_find_data_epochs.m | 252 +- .../pspm_get_transfer_function.m | 388 +- {src/backroom => backroom}/pspm_ledalab.m | 0 .../pspm_load_single_chan.m | 0 {src/backroom => backroom}/pspm_peakscore.m | 956 +- {src/backroom => backroom}/pspm_predval.m | 0 {src/backroom => backroom}/pspm_scr2ledalab.m | 246 +- .../backroom => backroom}/pspm_sf_get_theta.m | 272 +- .../backroom => backroom}/pspm_transfer_fit.m | 60 +- .../set_blinks_saccades_to_nan.m | 0 doc/Figures/2ndlvl_bars.PNG | Bin 19630 -> 0 bytes doc/Figures/2ndlvl_table.PNG | Bin 8063 -> 0 bytes doc/Figures/Batch_nonlinear.png | Bin 27347 -> 0 bytes doc/Figures/Comparison_VBA.PNG | Bin 17024 -> 0 bytes ...cle_MappingAndCorrectingTheInfluen_svg.pdf | Bin 307894 -> 0 bytes doc/Figures/Review_1stmodel1.PNG | Bin 32113 -> 0 bytes doc/Figures/YY1_import.png | Bin 50114 -> 0 bytes doc/Figures/YY2_trim.png | Bin 51795 -> 0 bytes doc/Figures/YY3_glm.png | Bin 57389 -> 0 bytes doc/Figures/YY41_review.png | Bin 66850 -> 0 bytes doc/Figures/YY42_review.png | Bin 60995 -> 0 bytes doc/Figures/YY43_review.png | Bin 98835 -> 0 bytes doc/Figures/YY44_review.png | Bin 46216 -> 0 bytes doc/Figures/icons/button_add_epoch.PNG | Bin 222 -> 0 bytes doc/Figures/icons/button_navigate_epochs.PNG | Bin 300 -> 0 bytes doc/Figures/icons/button_pan.PNG | Bin 360 -> 0 bytes doc/Figures/icons/button_remove_epoch.PNG | Bin 249 -> 0 bytes doc/Figures/icons/button_zoom.PNG | Bin 701 -> 0 bytes doc/Figures/reviewmodel.png | Bin 45060 -> 0 bytes doc/PsPM-help_text_progress.xlsx | Bin 17979 -> 0 bytes doc/PsPM.bib | 1056 - doc/PsPM_Developers_Guide.lyx | 33543 ---------------- doc/PsPM_Developers_Guide.pdf | Bin 279328 -> 0 bytes doc/PsPM_Manual.lyx | 21385 ---------- doc/PsPM_References.lyx | 14001 ------- doc/PsPM_release_checklist.md | 24 - ...on 2012 NeuroImage PredictionError SCR.pdf | Bin 207280 -> 0 bytes ...2013 Psychophysiology SCR Model Review.pdf | Bin 317780 -> 0 bytes ...Psychology Comparison SCRalzye-Ledalab.pdf | Bin 529391 -> 0 bytes ...l. 2010 Biological Psychology_DCM-aSCR.pdf | Bin 527763 -> 0 bytes ...ch et al. 2011 Psychophysiology DCM_SF.pdf | Bin 293566 -> 0 bytes .../BachFlandinFristonDolan_2009_SCR_GLM.pdf | Bin 842259 -> 0 bytes ...chFlandinFristonDolan_2010_IJP_SCR_LTI.pdf | Bin 1087514 -> 0 bytes .../BachFristonDolan_2010_IJP_SF_AUC.pdf | Bin 450975 -> 0 bytes doc/SampleDataMasterList.docx | Bin 24289 -> 0 bytes doc/Tests_Current_Status.docx | Bin 16184 -> 0 bytes doc/pspm_options_subfields.numbers | Bin 325973 -> 0 bytes doc/release_notes.pdf | Bin 96055 -> 0 bytes doc/release_notes.tex | 1102 - {src/ext => ext}/SPM/Contents.m | 108 +- {src/ext => ext}/SPM/cfg_get_defaults.m | 76 +- {src/ext => ext}/SPM/cfg_getfile.m | 2608 +- {src/ext => ext}/SPM/cfg_mlbatch_defaults.m | 210 +- {src/ext => ext}/SPM/spm.m | 2436 +- {src/ext => ext}/SPM/spm_Gpdf.m | 196 +- {src/ext => ext}/SPM/spm_Interactive.fig | Bin {src/ext => ext}/SPM/spm_Tcdf.m | 212 +- {src/ext => ext}/SPM/spm_figure.m | 1748 +- {src/ext => ext}/SPM/spm_file.m | 0 {src/ext => ext}/SPM/spm_input.m | 4728 +-- {src/ext => ext}/SPM/spm_orth.m | 122 +- {src/ext => ext}/SPM/spm_select.m | 196 +- {src/ext => ext}/VBA/LICENSE | 678 +- {src/ext => ext}/VBA/README.md | 62 +- {src/ext => ext}/VBA/VBA_BMA.m | 220 +- {src/ext => ext}/VBA/VBA_Bin2Cont.m | 94 +- {src/ext => ext}/VBA/VBA_EKF.m | 420 +- {src/ext => ext}/VBA/VBA_ElogBeta.m | 102 +- {src/ext => ext}/VBA/VBA_ExceedanceProb.m | 86 +- {src/ext => ext}/VBA/VBA_FreeEnergy.m | 282 +- {src/ext => ext}/VBA/VBA_FreeEnergy_UNL.m | 116 +- {src/ext => ext}/VBA/VBA_GN.m | 458 +- {src/ext => ext}/VBA/VBA_Hpost.m | 132 +- {src/ext => ext}/VBA/VBA_IX0.m | 126 +- {src/ext => ext}/VBA/VBA_IX_lagged.m | 408 +- {src/ext => ext}/VBA/VBA_IX_lagged_binomial.m | 454 +- {src/ext => ext}/VBA/VBA_Initialize.m | 122 +- {src/ext => ext}/VBA/VBA_Iphi.m | 254 +- {src/ext => ext}/VBA/VBA_Iphi_UNL.m | 246 +- {src/ext => ext}/VBA/VBA_Iphi_binomial.m | 244 +- {src/ext => ext}/VBA/VBA_Iphi_extended.m | 334 +- {src/ext => ext}/VBA/VBA_Iphi_split.m | 378 +- {src/ext => ext}/VBA/VBA_Itheta.m | 204 +- {src/ext => ext}/VBA/VBA_JensenShannon.m | 162 +- {src/ext => ext}/VBA/VBA_KL.m | 120 +- {src/ext => ext}/VBA/VBA_LMEH0.m | 118 +- {src/ext => ext}/VBA/VBA_MFX.m | 1014 +- {src/ext => ext}/VBA/VBA_NLStateSpaceModel.m | 696 +- {src/ext => ext}/VBA/VBA_PPM.m | 162 +- {src/ext => ext}/VBA/VBA_ReDisplay.m | 1408 +- {src/ext => ext}/VBA/VBA_SavageDickey.m | 220 +- {src/ext => ext}/VBA/VBA_Shapley.m | 512 +- {src/ext => ext}/VBA/VBA_UNL0.m | 384 +- {src/ext => ext}/VBA/VBA_UNLtemp.m | 168 +- {src/ext => ext}/VBA/VBA_VarParam.m | 254 +- {src/ext => ext}/VBA/VBA_VolterraKernels.m | 372 +- {src/ext => ext}/VBA/VBA_bDCM_lesion.m | 208 +- {src/ext => ext}/VBA/VBA_check.m | 668 +- {src/ext => ext}/VBA/VBA_check4DCM.m | 92 +- {src/ext => ext}/VBA/VBA_checkGN.m | 66 +- {src/ext => ext}/VBA/VBA_check_errors.m | 332 +- {src/ext => ext}/VBA/VBA_conv2glm.m | 48 +- {src/ext => ext}/VBA/VBA_dcmMatrices.m | 188 +- {src/ext => ext}/VBA/VBA_designEfficiency.m | 170 +- {src/ext => ext}/VBA/VBA_disp.m | 26 +- {src/ext => ext}/VBA/VBA_displayGrads.m | 122 +- {src/ext => ext}/VBA/VBA_displayGroupBMC.m | 318 +- {src/ext => ext}/VBA/VBA_displayGroupBMCbtw.m | 364 +- {src/ext => ext}/VBA/VBA_displayMFX.m | 428 +- {src/ext => ext}/VBA/VBA_evalAL.m | 330 +- {src/ext => ext}/VBA/VBA_evalAL2.m | 286 +- {src/ext => ext}/VBA/VBA_evalFun.m | 268 +- {src/ext => ext}/VBA/VBA_fit.m | 242 +- {src/ext => ext}/VBA/VBA_getDefaults.m | 84 +- {src/ext => ext}/VBA/VBA_getDiagnostics.m | 530 +- {src/ext => ext}/VBA/VBA_getISqrtMat.m | 68 +- {src/ext => ext}/VBA/VBA_getKernels.m | 164 +- {src/ext => ext}/VBA/VBA_getLaplace.m | 384 +- {src/ext => ext}/VBA/VBA_getNoise.m | 156 +- {src/ext => ext}/VBA/VBA_getNtuples.m | 102 +- {src/ext => ext}/VBA/VBA_getSuffStat.m | 70 +- {src/ext => ext}/VBA/VBA_getU.m | 68 +- {src/ext => ext}/VBA/VBA_getVar.m | 44 +- {src/ext => ext}/VBA/VBA_get_dL.m | 78 +- {src/ext => ext}/VBA/VBA_get_tracker.m | 4 +- {src/ext => ext}/VBA/VBA_groupBMC.m | 632 +- {src/ext => ext}/VBA/VBA_groupBMC_btwConds.m | 404 +- {src/ext => ext}/VBA/VBA_groupBMC_btwGroups.m | 64 +- {src/ext => ext}/VBA/VBA_groupBMCbtw.m | 4 +- {src/ext => ext}/VBA/VBA_initDisplay.m | 434 +- .../VBA/VBA_initDisplay_extended.m | 566 +- {src/ext => ext}/VBA/VBA_inv.m | 124 +- {src/ext => ext}/VBA/VBA_logDet.m | 70 +- {src/ext => ext}/VBA/VBA_main.m | 110 +- {src/ext => ext}/VBA/VBA_microTime.m | 144 +- .../ext => ext}/VBA/VBA_multisession_expand.m | 488 +- .../ext => ext}/VBA/VBA_multisession_factor.m | 116 +- {src/ext => ext}/VBA/VBA_odeLim.m | 166 +- {src/ext => ext}/VBA/VBA_odeLim2NLSS.m | 156 +- {src/ext => ext}/VBA/VBA_onlineWrapper.m | 536 +- {src/ext => ext}/VBA/VBA_optimPriors.m | 1358 +- {src/ext => ext}/VBA/VBA_orth.m | 48 +- {src/ext => ext}/VBA/VBA_pause.m | 102 +- {src/ext => ext}/VBA/VBA_priors.m | 168 +- {src/ext => ext}/VBA/VBA_psi.m | 114 +- {src/ext => ext}/VBA/VBA_sample.m | 180 +- {src/ext => ext}/VBA/VBA_setup.m | 294 +- {src/ext => ext}/VBA/VBA_summary.m | 288 +- {src/ext => ext}/VBA/VBA_summaryMFX.m | 122 +- {src/ext => ext}/VBA/VBA_susceptibility.m | 522 +- {src/ext => ext}/VBA/VBA_updateDisplay.m | 696 +- .../VBA/VBA_updateDisplay_extended.m | 828 +- {src/ext => ext}/VBA/VBA_version.m | 38 +- {src/ext => ext}/VBA/VBA_wrapup.m | 144 +- {src/ext => ext}/VBA/checkGX_binomial.m | 30 +- .../classification/BMM/MixtureOfBinomials.m | 658 +- .../VBA/classification/BMM/demo_BMM.m | 122 +- .../VBA/classification/BMM/generateBMM.m | 48 +- .../VBA/classification/CRP/VB_CRP.m | 616 +- .../VBA/classification/CRP/demo_DP.m | 86 +- .../VBA/classification/CRP/simulate_CRP.m | 44 +- .../VBA/classification/GMM/PCA_MoG.m | 246 +- .../VBA/classification/GMM/VBA_MoG.m | 1052 +- .../VBA/classification/GMM/VBA_projectMoG.m | 230 +- .../VBA/classification/GMM/VBEM_GM.m | 686 +- .../VBA/classification/GMM/demo_GMM.m | 126 +- .../ext => ext}/VBA/classification/GMM/dist.m | 16 +- .../VBA/classification/GMM/generateGMM.m | 86 +- .../VBA/classification/GMM/plotResults.m | 224 +- {src/ext => ext}/VBA/f_Id.m | 8 +- {src/ext => ext}/VBA/f_embed.m | 82 +- {src/ext => ext}/VBA/factorial_struct.m | 126 +- {src/ext => ext}/VBA/g_conv0.m | 86 +- {src/ext => ext}/VBA/g_convSig.m | 48 +- {src/ext => ext}/VBA/g_embed.m | 32 +- {src/ext => ext}/VBA/getF.m | 34 +- {src/ext => ext}/VBA/getHyperpriors.m | 96 +- {src/ext => ext}/VBA/getKernels.m | 170 +- {src/ext => ext}/VBA/getStateParamInput.m | 50 +- {src/ext => ext}/VBA/getSubplots.m | 404 +- .../VBA/get_MCMC_predictiveDensity.m | 360 +- .../VBA/get_MCMC_predictiveDensity_fb.m | 396 +- {src/ext => ext}/VBA/isbinary.m | 58 +- {src/ext => ext}/VBA/isweird.m | 62 +- {src/ext => ext}/VBA/numericDiff.m | 148 +- {src/ext => ext}/VBA/sampleFromArbitraryP.m | 56 +- {src/ext => ext}/VBA/setInput.m | 80 +- {src/ext => ext}/VBA/setPriors.m | 34 +- {src/ext => ext}/VBA/simulateNLSS.m | 430 +- {src/ext => ext}/VBA/simulateNLSS_fb.m | 456 +- .../VBA/stats&plots/Contrast_MEbins.m | 24 +- {src/ext => ext}/VBA/stats&plots/EVprodX.m | 30 +- .../VBA/stats&plots/GLM_contrast.m | 948 +- .../ext => ext}/VBA/stats&plots/GLM_covComp.m | 172 +- .../VBA/stats&plots/MoveAxisToOrigin.m | 80 +- .../VBA/stats&plots/Plot3AxisAtOrigin.m | 138 +- .../VBA/stats&plots/PlotAxisAtOrigin.m | 108 +- .../VBA/stats&plots/approxOnGrid.m | 42 +- {src/ext => ext}/VBA/stats&plots/cov2corr.m | 24 +- .../VBA/stats&plots/demo_GLM_missingData.m | 84 +- .../VBA/stats&plots/demo_generalizability.m | 152 +- .../VBA/stats&plots/demo_mediation.m | 26 +- .../VBA/stats&plots/displayUncertainSigmoid.m | 158 +- {src/ext => ext}/VBA/stats&plots/doROC.m | 174 +- .../VBA/stats&plots/empiricalHist.m | 82 +- .../VBA/stats&plots}/findCI.m | 228 +- {src/ext => ext}/VBA/stats&plots/fisher.m | 14 +- .../VBA/stats&plots/g_GLM_missingData.m | 26 +- {src/ext => ext}/VBA/stats&plots/getColors.m | 12 +- {src/ext => ext}/VBA/stats&plots/getPanel.m | 26 +- {src/ext => ext}/VBA/stats&plots/hatch.m | 570 +- {src/ext => ext}/VBA/stats&plots/hist2.m | 126 +- .../VBA/stats&plots/invnormalcdf.m | 52 +- {src/ext => ext}/VBA/stats&plots/lev_GLM.m | 44 +- {src/ext => ext}/VBA/stats&plots/maxMat.m | 14 +- .../VBA/stats&plots/medianfilter0.m | 66 +- .../VBA/stats&plots/mediationAnalysis0.m | 366 +- {src/ext => ext}/VBA/stats&plots/mnan.m | 20 +- .../VBA/stats&plots}/nanzscore.m | 92 +- {src/ext => ext}/VBA/stats&plots/normalize.m | 18 +- {src/ext => ext}/VBA/stats&plots/normalpdf.m | 36 +- .../ext => ext}/VBA/stats&plots/pinvComplex.m | 30 +- .../ext => ext}/VBA/stats&plots/plotDensity.m | 496 +- {src/ext => ext}/VBA/stats&plots/plotElipse.m | 44 +- .../ext => ext}/VBA/stats&plots/plotGraph3D.m | 162 +- .../VBA/stats&plots/plotUncertainTimeSeries.m | 224 +- .../VBA/stats&plots/plotVolterra.m | 164 +- {src/ext => ext}/VBA/stats&plots/prodX.m | 88 +- {src/ext => ext}/VBA/stats&plots/smooth2.m | 48 +- {src/ext => ext}/VBA/stats&plots/snan.m | 18 +- {src/ext => ext}/VBA/stats&plots/spear.m | 248 +- .../VBA/stats&plots/spm_autocorr.m | 78 +- .../VBA/stats&plots/spm_code/spm_Fcdf.m | 238 +- .../VBA/stats&plots/spm_code/spm_Gpdf.m | 202 +- .../VBA/stats&plots/spm_code/spm_Tcdf.m | 218 +- .../VBA/stats&plots/spm_code/spm_Xadjust.m | 156 +- .../VBA/stats&plots/spm_code/spm_dcm_build.m | 1618 +- .../stats&plots/spm_code/spm_dcm_explore.m | 2288 +- .../stats&plots/spm_code/spm_dcm_fmri_check.m | 254 +- .../VBA/stats&plots/spm_code/spm_dcm_graph.m | 260 +- .../VBA/stats&plots/spm_code/spm_gamrnd.c | 246 +- .../VBA/stats&plots/spm_code/spm_gamrnd.m | 50 +- .../stats&plots/spm_code/spm_gamrnd.mexa64 | Bin .../stats&plots/spm_code/spm_gamrnd.mexglx | Bin .../stats&plots/spm_code/spm_gamrnd.mexmaci | Bin .../stats&plots/spm_code/spm_gamrnd.mexmaci64 | Bin .../stats&plots/spm_code/spm_gamrnd.mexw32 | Bin .../stats&plots/spm_code/spm_gamrnd.mexw64 | Bin .../VBA/stats&plots/spm_code/spm_hrf.m | 94 +- .../VBA/stats&plots/spm_code/spm_inv.m | 60 +- .../stats&plots/spm_code/spm_log_evidence.m | 224 +- .../VBA/stats&plots/spm_code/spm_logdet.m | 98 +- .../VBA/stats&plots/spm_code/spm_unvec.m | 156 +- .../VBA/stats&plots/spm_code/spm_vec.m | 100 +- .../VBA/stats&plots/spm_dcm_batch.m | 266 +- .../VBA/stats&plots/spm_dcm_clone.m | 384 +- .../VBA/stats&plots/spm_dcm_test.m | 254 +- {src/ext => ext}/VBA/stats&plots/spm_deconv.m | 78 +- {src/ext => ext}/VBA/stats&plots/spm_getSNR.m | 54 +- .../VBA/stats&plots/spm_resample.m | 66 +- .../VBA/stats&plots/spm_split_dcm.m | 138 +- {src/ext => ext}/VBA/stats&plots/spm_uitab.m | 498 +- {src/ext => ext}/VBA/subfunctions/Av.m | 8 +- .../VBA/subfunctions/BOLD_parameters.m | 20 +- .../VBA/subfunctions/Contrast_MEbins.m | 24 +- {src/ext => ext}/VBA/subfunctions/ERP_dcm.m | 190 +- .../VBA/subfunctions/GaussNewton.m | 220 +- .../ext => ext}/VBA/subfunctions/GetGitPath.m | 150 +- {src/ext => ext}/VBA/subfunctions/ObsRecGen.m | 88 +- .../VBA/subfunctions/RecToMfunction.m | 274 +- {src/ext => ext}/VBA/subfunctions/U_dummy.m | 14 +- .../VBA/subfunctions/VarVolatility.m | 42 +- .../VBA/subfunctions/addConfounds2dcm.m | 74 +- .../VBA/subfunctions/balanced_accuracy.m | 40 +- {src/ext => ext}/VBA/subfunctions/bernoulli.m | 20 +- {src/ext => ext}/VBA/subfunctions/checkF.m | 64 +- .../VBA/subfunctions/check_constrasts.m | 28 +- .../VBA/subfunctions/check_struct.m | 32 +- {src/ext => ext}/VBA/subfunctions/compHRFs.m | 346 +- .../VBA/subfunctions/comparePredictions.m | 132 +- .../VBA/subfunctions/compare_struct.m | 30 +- .../ext => ext}/VBA/subfunctions/create2dbf.m | 56 +- {src/ext => ext}/VBA/subfunctions/dMatdvec.m | 22 +- {src/ext => ext}/VBA/subfunctions/dcm2vba.m | 328 +- {src/ext => ext}/VBA/subfunctions/defIndlev.m | 56 +- .../VBA/subfunctions/defaultHRFparams.m | 36 +- .../VBA/subfunctions/demo_2DChoices.m | 310 +- .../ext => ext}/VBA/subfunctions/demo_2Dlin.m | 146 +- .../VBA/subfunctions/demo_2DneuralField.m | 182 +- {src/ext => ext}/VBA/subfunctions/demo_AR1.m | 226 +- .../VBA/subfunctions/demo_AVL_recog.m | 378 +- {src/ext => ext}/VBA/subfunctions/demo_CI.m | 134 +- .../VBA/subfunctions/demo_CaBBI_FHN.m | 506 +- .../VBA/subfunctions/demo_CaBBI_QGIF.m | 500 +- {src/ext => ext}/VBA/subfunctions/demo_FHN.m | 146 +- {src/ext => ext}/VBA/subfunctions/demo_GLM.m | 52 +- {src/ext => ext}/VBA/subfunctions/demo_HH.m | 172 +- {src/ext => ext}/VBA/subfunctions/demo_HRF.m | 218 +- .../VBA/subfunctions/demo_HRF_distributed.m | 184 +- .../VBA/subfunctions/demo_HRF_dummy.m | 168 +- .../ext => ext}/VBA/subfunctions/demo_Henon.m | 164 +- .../VBA/subfunctions/demo_HodgkinHuxley.m | 150 +- .../VBA/subfunctions/demo_KalmanSmoother.m | 92 +- {src/ext => ext}/VBA/subfunctions/demo_LV2D.m | 142 +- .../VBA/subfunctions/demo_Lorenz.m | 158 +- .../VBA/subfunctions/demo_MCsampling.m | 92 +- {src/ext => ext}/VBA/subfunctions/demo_MFX.m | 82 +- .../VBA/subfunctions/demo_Oscillatory.m | 154 +- {src/ext => ext}/VBA/subfunctions/demo_PSP.m | 64 +- .../VBA/subfunctions/demo_Qlearning.m | 170 +- {src/ext => ext}/VBA/subfunctions/demo_RFX.m | 216 +- .../VBA/subfunctions/demo_Rossler.m | 164 +- {src/ext => ext}/VBA/subfunctions/demo_SHC.m | 156 +- .../VBA/subfunctions/demo_VBfree.m | 162 +- .../VBA/subfunctions/demo_VanDerPol.m | 152 +- .../VBA/subfunctions/demo_asymRW.m | 420 +- .../VBA/subfunctions/demo_behaviouralDCM.m | 316 +- {src/ext => ext}/VBA/subfunctions/demo_bin.m | 224 +- .../VBA/subfunctions/demo_binomial.m | 146 +- .../subfunctions/demo_binomial_AdaptDesign.m | 226 +- .../VBA/subfunctions/demo_binomial_adapt.m | 114 +- .../VBA/subfunctions/demo_bmc4glm.m | 120 +- .../VBA/subfunctions/demo_classification.m | 48 +- .../VBA/subfunctions/demo_covComp.m | 132 +- .../VBA/subfunctions/demo_dcm4fmri.m | 316 +- .../subfunctions/demo_dcm4fmri_distributed.m | 428 +- .../VBA/subfunctions/demo_dcm_1region.m | 282 +- .../VBA/subfunctions/demo_dcm_motorPremotor.m | 326 +- .../VBA/subfunctions/demo_dcmonline.m | 398 +- .../VBA/subfunctions/demo_delays.m | 196 +- .../VBA/subfunctions/demo_discounting.m | 152 +- .../VBA/subfunctions/demo_doubleWell.m | 180 +- .../VBA/subfunctions/demo_dummyUNL.m | 70 +- .../VBA/subfunctions/demo_dynLearningRate.m | 312 +- .../VBA/subfunctions/demo_dynsys.m | 250 +- .../VBA/subfunctions/demo_fitzhugh.m | 162 +- .../VBA/subfunctions/demo_gaussian.m | 98 +- .../VBA/subfunctions/demo_getConvKernel.m | 116 +- .../VBA/subfunctions/demo_groupbtw.m | 288 +- .../VBA/subfunctions/demo_imageRegistration.m | 88 +- .../VBA/subfunctions/demo_interaction.m | 56 +- .../VBA/subfunctions/demo_irregular.m | 88 +- .../ext => ext}/VBA/subfunctions/demo_lin2D.m | 76 +- .../VBA/subfunctions/demo_linear.m | 84 +- .../VBA/subfunctions/demo_logNormal.m | 74 +- .../VBA/subfunctions/demo_logistic.m | 62 +- .../VBA/subfunctions/demo_micro2macro.m | 206 +- .../VBA/subfunctions/demo_multisession.m | 212 +- .../VBA/subfunctions/demo_multisource.m | 124 +- .../VBA/subfunctions/demo_negfeedback.m | 334 +- .../VBA/subfunctions/demo_nullSpace.m | 38 +- .../VBA/subfunctions/demo_prodsig.m | 128 +- .../ext => ext}/VBA/subfunctions/demo_recur.m | 62 +- .../VBA/subfunctions/demo_redundancy.m | 132 +- .../VBA/subfunctions/demo_sparsePriors.m | 334 +- .../VBA/subfunctions/demo_spm_hrf.m | 258 +- .../VBA/subfunctions/demo_stability_HRF.m | 406 +- .../subfunctions/demo_stochasticBinomial.m | 130 +- .../VBA/subfunctions/demo_susceptibility.m | 288 +- {src/ext => ext}/VBA/subfunctions/demo_test.m | 66 +- .../VBA/subfunctions/demo_trainTest.m | 266 +- .../VBA/subfunctions/demo_volatileVB.m | 156 +- {src/ext => ext}/VBA/subfunctions/demo_wsls.m | 234 +- .../VBA/subfunctions/displayResults.m | 314 +- .../VBA/subfunctions/displaySimulations.m | 202 +- {src/ext => ext}/VBA/subfunctions/dsdv.m | 14 +- {src/ext => ext}/VBA/subfunctions/elvis.m | 18 +- .../VBA/subfunctions/evolution0bisND.m | 42 +- {src/ext => ext}/VBA/subfunctions/expBinom.m | 34 +- .../ext => ext}/VBA/subfunctions/extend_dcm.m | 130 +- .../ext => ext}/VBA/subfunctions/extractFIR.m | 6 +- .../VBA/subfunctions/extractKernels.m | 18 +- .../VBA/subfunctions/f_2DneuralField.m | 106 +- {src/ext => ext}/VBA/subfunctions/f_2d.m | 6 +- {src/ext => ext}/VBA/subfunctions/f_2dwu.m | 4 +- {src/ext => ext}/VBA/subfunctions/f_AR.m | 8 +- {src/ext => ext}/VBA/subfunctions/f_ARn.m | 28 +- {src/ext => ext}/VBA/subfunctions/f_ARplus.m | 8 +- {src/ext => ext}/VBA/subfunctions/f_AVL.m | 510 +- .../VBA/subfunctions/f_CaBBI_FHN.m | 88 +- .../VBA/subfunctions/f_CaBBI_QGIF.m | 112 +- {src/ext => ext}/VBA/subfunctions/f_DCMwHRF.m | 42 +- .../VBA/subfunctions/f_DCMwHRFext.m | 102 +- .../VBA/subfunctions/f_FitzHughNagumo.m | 46 +- .../subfunctions/f_FitzHughNagumo_calcium.m | 76 +- {src/ext => ext}/VBA/subfunctions/f_HH.m | 98 +- {src/ext => ext}/VBA/subfunctions/f_HRF.m | 90 +- {src/ext => ext}/VBA/subfunctions/f_HRF2.m | 400 +- {src/ext => ext}/VBA/subfunctions/f_HRF3.m | 302 +- {src/ext => ext}/VBA/subfunctions/f_Henon.m | 44 +- {src/ext => ext}/VBA/subfunctions/f_L1.m | 6 +- {src/ext => ext}/VBA/subfunctions/f_LV2D.m | 28 +- {src/ext => ext}/VBA/subfunctions/f_Lorenz.m | 54 +- .../VBA/subfunctions/f_LotkaVolterra.m | 12 +- {src/ext => ext}/VBA/subfunctions/f_OpLearn.m | 46 +- {src/ext => ext}/VBA/subfunctions/f_PSP.m | 34 +- {src/ext => ext}/VBA/subfunctions/f_Qlearn.m | 58 +- {src/ext => ext}/VBA/subfunctions/f_Qlearn2.m | 58 +- .../VBA/subfunctions/f_Qlearn_dynLR.m | 66 +- .../VBA/subfunctions/f_Qlearn_gammaLR.m | 42 +- {src/ext => ext}/VBA/subfunctions/f_Rossler.m | 24 +- {src/ext => ext}/VBA/subfunctions/f_SHC.m | 196 +- {src/ext => ext}/VBA/subfunctions/f_VBfree.m | 52 +- .../VBA/subfunctions/f_VBvolatile0.m | 130 +- ext/VBA/subfunctions/f_alpha.m | 4 + {src/ext => ext}/VBA/subfunctions/f_dbw.m | 14 +- .../ext => ext}/VBA/subfunctions/f_dcm4fmri.m | 182 +- .../VBA/subfunctions/f_dcm4fmri0.m | 156 +- .../VBA/subfunctions/f_dcm_extension.m | 210 +- .../VBA/subfunctions/f_dcm_withU.m | 40 +- .../VBA/subfunctions/f_doubleWell.m | 72 +- {src/ext => ext}/VBA/subfunctions/f_embed0.m | 56 +- {src/ext => ext}/VBA/subfunctions/f_embedAR.m | 26 +- .../VBA/subfunctions/f_embed_old.m | 66 +- .../VBA/subfunctions/f_fullDCM4fmri.m | 40 +- {src/ext => ext}/VBA/subfunctions/f_gen.m | 94 +- {src/ext => ext}/VBA/subfunctions/f_lin1D.m | 50 +- {src/ext => ext}/VBA/subfunctions/f_lin2D.m | 48 +- .../VBA/subfunctions/f_replicator.m | 24 +- {src/ext => ext}/VBA/subfunctions/f_rwl.m | 8 +- {src/ext => ext}/VBA/subfunctions/f_rwl2.m | 70 +- {src/ext => ext}/VBA/subfunctions/f_try.m | 12 +- .../VBA/subfunctions/f_vanDerPol.m | 66 +- {src/ext => ext}/VBA/subfunctions/f_vgo.m | 2 +- {src/ext => ext}/VBA/subfunctions/f_wsls.m | 48 +- .../VBA/subfunctions}/findCI.m | 228 +- .../VBA/subfunctions/g_2AFC_basis.m | 82 +- {src/ext => ext}/VBA/subfunctions/g_AVL.m | 104 +- {src/ext => ext}/VBA/subfunctions/g_CaBBI.m | 36 +- .../VBA/subfunctions/g_DCMwHRFext.m | 70 +- {src/ext => ext}/VBA/subfunctions/g_DG2.m | 32 +- .../VBA/subfunctions/g_DoubleGamma.m | 48 +- {src/ext => ext}/VBA/subfunctions/g_ERP.m | 68 +- .../VBA/subfunctions/g_ERP_reduced.m | 56 +- {src/ext => ext}/VBA/subfunctions/g_ExpUtil.m | 42 +- {src/ext => ext}/VBA/subfunctions/g_Fourier.m | 52 +- {src/ext => ext}/VBA/subfunctions/g_GLM.m | 22 +- .../VBA/subfunctions/g_GLMsparse.m | 8 +- .../VBA/subfunctions/g_GammaDensity.m | 10 +- .../ext => ext}/VBA/subfunctions/g_Gaussian.m | 80 +- {src/ext => ext}/VBA/subfunctions/g_HRF3.m | 260 +- .../VBA/subfunctions/g_HRF_distributed.m | 68 +- {src/ext => ext}/VBA/subfunctions/g_Id.m | 60 +- {src/ext => ext}/VBA/subfunctions/g_Id_phi.m | 12 +- {src/ext => ext}/VBA/subfunctions/g_NI.m | 30 +- {src/ext => ext}/VBA/subfunctions/g_RFX.m | 6 +- {src/ext => ext}/VBA/subfunctions/g_Udummy.m | 6 +- .../VBA/subfunctions/g_VBvolatile0.m | 70 +- {src/ext => ext}/VBA/subfunctions/g_classif.m | 24 +- .../VBA/subfunctions/g_convSig_approx.m | 52 +- .../VBA/subfunctions/g_conv_approx.m | 62 +- .../VBA/subfunctions/g_demo_extended.m | 80 +- .../VBA/subfunctions/g_demo_susceptibility.m | 84 +- .../VBA/subfunctions/g_discounting.m | 52 +- {src/ext => ext}/VBA/subfunctions/g_dummy.m | 4 +- {src/ext => ext}/VBA/subfunctions/g_embedAR.m | 24 +- ext/VBA/subfunctions/g_exp.m | 3 + {src/ext => ext}/VBA/subfunctions/g_exp2d.m | 28 +- .../VBA/subfunctions/g_fullDCM4fmri.m | 168 +- {src/ext => ext}/VBA/subfunctions/g_goNogo.m | 22 +- {src/ext => ext}/VBA/subfunctions/g_ip.m | 14 +- .../ext => ext}/VBA/subfunctions/g_logistic.m | 26 +- {src/ext => ext}/VBA/subfunctions/g_matmap.m | 16 +- {src/ext => ext}/VBA/subfunctions/g_mixU.m | 4 +- {src/ext => ext}/VBA/subfunctions/g_nl0.m | 12 +- {src/ext => ext}/VBA/subfunctions/g_odds.m | 16 +- {src/ext => ext}/VBA/subfunctions/g_odds2.m | 14 +- ext/VBA/subfunctions/g_probit.m | 2 + {src/ext => ext}/VBA/subfunctions/g_rbf.m | 50 +- {src/ext => ext}/VBA/subfunctions/g_rigid2D.m | 92 +- {src/ext => ext}/VBA/subfunctions/g_sig_u.m | 6 +- {src/ext => ext}/VBA/subfunctions/g_sigm.m | 16 +- .../VBA/subfunctions/g_sigm_binomial.m | 36 +- {src/ext => ext}/VBA/subfunctions/g_sigmoid.m | 100 +- {src/ext => ext}/VBA/subfunctions/g_softmax.m | 32 +- .../VBA/subfunctions/g_softmax4decoding.m | 70 +- {src/ext => ext}/VBA/subfunctions/g_sqrtSig.m | 44 +- {src/ext => ext}/VBA/subfunctions/g_u2c.m | 22 +- {src/ext => ext}/VBA/subfunctions/g_u2p.m | 24 +- {src/ext => ext}/VBA/subfunctions/g_vgo.m | 2 +- {src/ext => ext}/VBA/subfunctions/getFamily.m | 30 +- .../ext => ext}/VBA/subfunctions/getGitInfo.m | 306 +- .../VBA/subfunctions/getOptions4dcm.m | 158 +- .../VBA/subfunctions/getPosteriorfromOTO.m | 56 +- {src/ext => ext}/VBA/subfunctions/getPriors.m | 270 +- {src/ext => ext}/VBA/subfunctions/get_ARcov.m | 8 +- .../VBA/subfunctions/get_HRFparams.m | 202 +- .../VBA/subfunctions/get_U_basis.m | 84 +- .../VBA/subfunctions/get_sigmoidMoments.m | 70 +- .../VBA/subfunctions/gridL_binomial.m | 100 +- {src/ext => ext}/VBA/subfunctions/h_Id.m | 2 +- {src/ext => ext}/VBA/subfunctions/h_goNogo.m | 14 +- .../VBA/subfunctions/h_randOutcome.m | 14 +- .../VBA/subfunctions/h_truefalse.m | 12 +- .../VBA/subfunctions/h_whichItem.m | 2 +- .../ext => ext}/VBA/subfunctions/invsigmoid.m | 16 +- .../VBA/subfunctions/isHrfStable.m | 118 +- {src/ext => ext}/VBA/subfunctions/iswithin.m | 56 +- .../VBA/subfunctions/kernel_sinexp.m | 48 +- {src/ext => ext}/VBA/subfunctions/logExp.m | 42 +- .../VBA/subfunctions/medianfilter0.m | 66 +- {src/ext => ext}/VBA/subfunctions/multi2num.m | 14 +- .../VBA/subfunctions/multinomial_accuracy.m | 78 +- {src/ext => ext}/VBA/subfunctions/nanfft.m | 112 +- .../VBA/subfunctions}/nanzscore.m | 92 +- {src/ext => ext}/VBA/subfunctions/num2multi.m | 18 +- {src/ext => ext}/VBA/subfunctions/optimCost.m | 142 +- {src/ext => ext}/VBA/subfunctions/parseargs.m | 194 +- .../VBA/subfunctions/prepare_dcm.m | 272 +- .../VBA/subfunctions/prepare_fullDCM.m | 290 +- .../VBA/subfunctions/priorPrettifyer.m | 14 +- .../VBA/subfunctions/priorUglyfier.m | 66 +- .../VBA/subfunctions/script_test_rec.m | 258 +- {src/ext => ext}/VBA/subfunctions/sgm.m | 22 +- .../VBA/subfunctions/show_potential.m | 40 +- {src/ext => ext}/VBA/subfunctions/sig.m | 6 +- {src/ext => ext}/VBA/subfunctions/sigm.m | 158 +- {src/ext => ext}/VBA/subfunctions/sigmoid.m | 12 +- {src/ext => ext}/VBA/subfunctions/sizeXrec.m | 38 +- {src/ext => ext}/VBA/subfunctions/softmax.m | 4 +- .../VBA/subfunctions/sparseTransform.m | 30 +- {src/ext => ext}/VBA/subfunctions/spear.m | 248 +- .../VBA/subfunctions/spm_sdcm_estimate.m | 122 +- .../VBA/subfunctions/spm_sdcm_estimate2.m | 364 +- {src/ext => ext}/VBA/subfunctions/u_Fourier.m | 56 +- .../VBA/subfunctions/u_FourierComplete.m | 68 +- .../VBA/subfunctions/u_GaussianBumps.m | 40 +- {src/ext => ext}/VBA/subfunctions/u_RBF.m | 56 +- .../VBA/subfunctions/unwrapVBvolatileOTO.m | 230 +- {src/ext => ext}/VBA/subfunctions/util.m | 12 +- .../VBA/subfunctions/v_discounting.m | 44 +- {src/ext => ext}/VBA/subfunctions/vba2dcm.m | 600 +- {src/ext => ext}/VBA/vec.m | 24 +- .../ext => ext}/amri_eegfmri/CHANGES_MADE.txt | 0 {src/ext => ext}/amri_eegfmri/LICENSE.txt | 0 {src/ext => ext}/amri_eegfmri/README_1.txt | 0 {src/ext => ext}/amri_eegfmri/README_2.txt | 0 .../ext => ext}/amri_eegfmri/amri_eeg_rpeak.m | 0 {src/ext => ext}/amri_eegfmri/amri_sig_corr.m | 0 .../amri_eegfmri/amri_sig_filtfft.m | 0 .../amri_eegfmri/amri_sig_findpeaks.m | 0 .../ext => ext}/amri_eegfmri/amri_sig_xcorr.m | 0 .../amri_eegfmri/amri_stat_outlier.m | 0 {src/ext => ext}/bsearch/bsearch.m | 134 +- {src/ext => ext}/bsearch/license.txt | 0 .../matlabbatch/@cfg_branch}/all_leafs.m | 60 +- .../matlabbatch/@cfg_branch/all_set.m | 66 +- .../matlabbatch/@cfg_branch/all_set_item.m | 32 +- .../matlabbatch/@cfg_branch/cfg2jobsubs.m | 62 +- .../matlabbatch/@cfg_branch}/cfg2struct.m | 52 +- .../matlabbatch/@cfg_branch/cfg_branch.m | 192 +- .../matlabbatch/@cfg_branch/checksubs_job.m | 56 +- .../matlabbatch/@cfg_branch/clearval.m | 44 +- .../matlabbatch/@cfg_branch/expand.m | 146 +- .../matlabbatch/@cfg_branch/fillvals.m | 106 +- .../matlabbatch/@cfg_branch}/harvest.m | 130 +- .../matlabbatch/@cfg_branch/initialise.m | 130 +- .../matlabbatch/@cfg_branch}/list.m | 266 +- .../@cfg_branch/private/mysubs_fields.m | 36 +- .../matlabbatch/@cfg_branch/setval.m | 32 +- .../matlabbatch/@cfg_branch/showdetail.m | 44 +- .../matlabbatch/@cfg_branch}/showdoc.m | 52 +- .../matlabbatch/@cfg_branch/showmydoc.m | 48 +- .../matlabbatch/@cfg_branch/subs_fields.m | 40 +- .../matlabbatch/@cfg_branch/subsasgn.m | 214 +- .../matlabbatch/@cfg_branch/subsasgn_check.m | 46 +- .../matlabbatch/@cfg_branch}/subsasgn_job.m | 80 +- .../matlabbatch/@cfg_branch}/subsref.m | 154 +- .../matlabbatch/@cfg_branch/subsref_job.m | 88 +- .../matlabbatch/@cfg_branch/tag2cfgsubs.m | 118 +- .../matlabbatch/@cfg_branch}/tagnames.m | 52 +- .../matlabbatch/@cfg_branch/treepart.m | 34 +- .../matlabbatch/@cfg_branch}/update_deps.m | 48 +- .../matlabbatch/@cfg_branch}/val2def.m | 60 +- .../matlabbatch/@cfg_choice}/all_leafs.m | 60 +- .../matlabbatch/@cfg_choice/all_set.m | 66 +- .../matlabbatch/@cfg_choice/all_set_item.m | 34 +- .../matlabbatch/@cfg_choice/cfg2jobsubs.m | 62 +- .../matlabbatch/@cfg_choice}/cfg2struct.m | 68 +- .../matlabbatch/@cfg_choice/cfg_choice.m | 190 +- .../matlabbatch/@cfg_choice/checksubs_job.m | 56 +- .../matlabbatch/@cfg_choice}/clearval.m | 54 +- .../matlabbatch/@cfg_choice/expand.m | 146 +- .../matlabbatch/@cfg_choice}/fieldnames.m | 38 +- .../matlabbatch/@cfg_choice}/fillvals.m | 106 +- .../matlabbatch/@cfg_choice}/gencode_item.m | 170 +- .../matlabbatch/@cfg_choice}/harvest.m | 130 +- .../matlabbatch/@cfg_choice/initialise.m | 190 +- .../matlabbatch/@cfg_choice}/list.m | 266 +- .../@cfg_choice/private/mysubs_fields.m | 38 +- .../matlabbatch/@cfg_choice/setval.m | 46 +- .../matlabbatch/@cfg_choice/showdetail.m | 48 +- .../matlabbatch/@cfg_choice}/showdoc.m | 52 +- .../matlabbatch/@cfg_choice/showmydoc.m | 62 +- .../matlabbatch/@cfg_choice}/subs_fields.m | 40 +- .../matlabbatch/@cfg_choice/subsasgn.m | 214 +- .../matlabbatch/@cfg_choice/subsasgn_check.m | 50 +- .../matlabbatch/@cfg_choice}/subsasgn_job.m | 80 +- .../matlabbatch/@cfg_choice}/subsref.m | 154 +- .../matlabbatch/@cfg_choice}/subsref_job.m | 88 +- .../matlabbatch/@cfg_choice}/tag2cfgsubs.m | 118 +- .../matlabbatch/@cfg_choice}/tagnames.m | 52 +- .../matlabbatch/@cfg_choice/treepart.m | 44 +- .../matlabbatch/@cfg_choice}/update_deps.m | 48 +- .../matlabbatch/@cfg_choice}/val2def.m | 60 +- .../matlabbatch/@cfg_const}/cfg2struct.m | 52 +- .../matlabbatch/@cfg_const/cfg_const.m | 184 +- .../@cfg_const/private/mysubs_fields.m | 36 +- .../matlabbatch/@cfg_const/showdetail.m | 36 +- .../matlabbatch/@cfg_const/showdoc.m | 38 +- .../matlabbatch/@cfg_const}/subs_fields.m | 40 +- .../matlabbatch/@cfg_const/subsasgn.m | 214 +- .../matlabbatch/@cfg_const}/subsref.m | 154 +- .../matlabbatch/@cfg_dep/add_to_source.m | 130 +- .../matlabbatch/@cfg_dep/cfg_dep.m | 218 +- .../matlabbatch/@cfg_dep/del_in_source.m | 52 +- .../matlabbatch/@cfg_dep/del_in_target.m | 96 +- .../matlabbatch/@cfg_dep/dep_add.m | 48 +- {src/ext => ext}/matlabbatch/@cfg_dep/disp.m | 62 +- .../matlabbatch/@cfg_dep/display.m | 42 +- .../matlabbatch/@cfg_dep/gencode.m | 112 +- .../matlabbatch/@cfg_dep/isequalsource.m | 52 +- .../matlabbatch/@cfg_dep/isequaltarget.m | 52 +- .../@cfg_dep/private/mysubs_fields.m | 36 +- .../matlabbatch/@cfg_dep/subs_fields.m | 38 +- .../matlabbatch/@cfg_dep/subsasgn.m | 256 +- .../matlabbatch/@cfg_dep/subsref.m | 104 +- .../matlabbatch/@cfg_dep/update_deps.m | 50 +- .../matlabbatch/@cfg_entry/cfg2struct.m | 52 +- .../matlabbatch/@cfg_entry/cfg_entry.m | 304 +- .../matlabbatch/@cfg_entry}/fieldnames.m | 38 +- .../matlabbatch/@cfg_entry/gencode_item.m | 110 +- .../matlabbatch/@cfg_entry/match.m | 156 +- .../@cfg_entry/private/mysubs_fields.m | 36 +- .../matlabbatch/@cfg_entry/showdetail.m | 48 +- .../matlabbatch/@cfg_entry/showdoc.m | 140 +- .../matlabbatch/@cfg_entry}/subs_fields.m | 40 +- .../matlabbatch/@cfg_entry/subsasgn.m | 214 +- .../matlabbatch/@cfg_entry/subsasgn_check.m | 410 +- .../matlabbatch/@cfg_entry}/subsref.m | 154 +- .../matlabbatch/@cfg_exbranch/cfg2struct.m | 52 +- .../matlabbatch/@cfg_exbranch/cfg_exbranch.m | 232 +- .../matlabbatch/@cfg_exbranch/disp.m | 68 +- .../matlabbatch/@cfg_exbranch/display.m | 42 +- .../matlabbatch/@cfg_exbranch/fieldnames.m | 38 +- .../matlabbatch/@cfg_exbranch/gencode_item.m | 146 +- .../matlabbatch/@cfg_exbranch/harvest.m | 318 +- .../@cfg_exbranch/private/mysubs_fields.m | 36 +- .../matlabbatch/@cfg_exbranch/showdetail.m | 52 +- ext/matlabbatch/@cfg_exbranch/subs_fields.m | 21 + ext/matlabbatch/@cfg_exbranch/subsasgn.m | 108 + .../@cfg_exbranch/subsasgn_check.m | 74 +- ext/matlabbatch/@cfg_exbranch/subsref.m | 77 + .../matlabbatch/@cfg_exbranch/update_deps.m | 80 +- .../matlabbatch/@cfg_files}/cfg2struct.m | 52 +- .../matlabbatch/@cfg_files/cfg_files.m | 244 +- .../matlabbatch/@cfg_files}/fieldnames.m | 38 +- .../matlabbatch/@cfg_files/gencode_item.m | 108 +- .../matlabbatch/@cfg_files/match.m | 164 +- .../@cfg_files/private/mysubs_fields.m | 36 +- .../matlabbatch/@cfg_files/showdetail.m | 40 +- ext/matlabbatch/@cfg_files/subs_fields.m | 21 + ext/matlabbatch/@cfg_files/subsasgn.m | 108 + .../matlabbatch/@cfg_files/subsasgn_check.m | 156 +- ext/matlabbatch/@cfg_files/subsref.m | 77 + .../matlabbatch/@cfg_intree/cfg_intree.m | 32 +- .../matlabbatch/@cfg_intree}/disp.m | 32 +- .../matlabbatch/@cfg_intree}/display.m | 32 +- .../matlabbatch/@cfg_inv_out/cfg_inv_out.m | 42 +- .../matlabbatch/@cfg_item/all_leafs.m | 38 +- .../matlabbatch/@cfg_item/all_set.m | 52 +- .../matlabbatch/@cfg_item/all_set_item.m | 34 +- {src/ext => ext}/matlabbatch/@cfg_item/cat.m | 44 +- .../matlabbatch/@cfg_item/cfg2jobsubs.m | 52 +- .../matlabbatch/@cfg_item/cfg2struct.m | 56 +- .../matlabbatch/@cfg_item/cfg_item.m | 296 +- .../matlabbatch/@cfg_item/clearval.m | 42 +- {src/ext => ext}/matlabbatch/@cfg_item/disp.m | 88 +- .../matlabbatch/@cfg_item/display.m | 42 +- .../matlabbatch/@cfg_item/docheck.m | 74 +- .../matlabbatch/@cfg_item/expand.m | 100 +- .../matlabbatch/@cfg_item/fieldnames.m | 32 +- .../matlabbatch/@cfg_item/fillvals.m | 78 +- .../matlabbatch/@cfg_item/gencode.m | 86 +- .../matlabbatch/@cfg_item/gencode_item.m | 314 +- .../matlabbatch/@cfg_item/gettag.m | 34 +- .../matlabbatch/@cfg_item/harvest.m | 132 +- .../matlabbatch/@cfg_item/horzcat.m | 34 +- .../matlabbatch/@cfg_item/initialise.m | 96 +- {src/ext => ext}/matlabbatch/@cfg_item/list.m | 224 +- .../ext => ext}/matlabbatch/@cfg_item/match.m | 102 +- .../@cfg_item/private/mysubs_fields.m | 40 +- .../matlabbatch/@cfg_item/resolve_deps.m | 204 +- .../matlabbatch/@cfg_item/setval.m | 114 +- .../matlabbatch/@cfg_item/showdetail.m | 44 +- .../matlabbatch/@cfg_item/showdoc.m | 60 +- ext/matlabbatch/@cfg_item/subs_fields.m | 21 + ext/matlabbatch/@cfg_item/subsasgn.m | 108 + .../matlabbatch/@cfg_item/subsasgn_check.m | 132 +- .../matlabbatch/@cfg_item/subsasgn_checkstr.m | 34 +- .../matlabbatch/@cfg_item/subsasgn_job.m | 40 +- ext/matlabbatch/@cfg_item/subsref.m | 77 + .../matlabbatch/@cfg_item/subsref_job.m | 60 +- .../matlabbatch/@cfg_item/tag2cfgsubs.m | 64 +- .../matlabbatch/@cfg_item/update_deps.m | 40 +- .../matlabbatch/@cfg_item/val2def.m | 78 +- .../matlabbatch/@cfg_item/vertcat.m | 34 +- .../matlabbatch/@cfg_leaf/cfg_leaf.m | 32 +- .../matlabbatch/@cfg_leaf}/disp.m | 32 +- .../matlabbatch/@cfg_leaf}/display.m | 32 +- .../matlabbatch/@cfg_mchoice/all_leafs.m | 60 +- .../matlabbatch/@cfg_mchoice}/all_set.m | 66 +- .../matlabbatch/@cfg_mchoice/all_set_item.m | 32 +- .../matlabbatch/@cfg_mchoice/cfg2jobsubs.m | 62 +- .../matlabbatch/@cfg_mchoice}/cfg2struct.m | 68 +- .../matlabbatch/@cfg_mchoice/cfg_mchoice.m | 190 +- .../matlabbatch/@cfg_mchoice/checksubs_job.m | 56 +- .../matlabbatch/@cfg_mchoice}/clearval.m | 54 +- .../matlabbatch/@cfg_mchoice}/expand.m | 146 +- .../matlabbatch/@cfg_mchoice}/fieldnames.m | 38 +- .../matlabbatch/@cfg_mchoice}/fillvals.m | 106 +- .../matlabbatch/@cfg_mchoice}/gencode_item.m | 170 +- .../matlabbatch/@cfg_mchoice}/harvest.m | 130 +- .../matlabbatch/@cfg_mchoice/initialise.m | 192 +- .../matlabbatch/@cfg_mchoice}/list.m | 266 +- .../@cfg_mchoice/private/mysubs_fields.m | 38 +- .../matlabbatch/@cfg_mchoice/setval.m | 64 +- .../matlabbatch/@cfg_mchoice/showdetail.m | 48 +- .../matlabbatch/@cfg_mchoice/showdoc.m | 52 +- .../matlabbatch/@cfg_mchoice/showmydoc.m | 68 +- ext/matlabbatch/@cfg_mchoice/subs_fields.m | 21 + ext/matlabbatch/@cfg_mchoice/subsasgn.m | 108 + .../matlabbatch/@cfg_mchoice/subsasgn_check.m | 50 +- .../matlabbatch/@cfg_mchoice}/subsasgn_job.m | 80 +- ext/matlabbatch/@cfg_mchoice/subsref.m | 77 + .../matlabbatch/@cfg_mchoice}/subsref_job.m | 88 +- .../matlabbatch/@cfg_mchoice}/tag2cfgsubs.m | 118 +- .../matlabbatch/@cfg_mchoice}/tagnames.m | 52 +- .../matlabbatch/@cfg_mchoice/treepart.m | 44 +- .../matlabbatch/@cfg_mchoice}/update_deps.m | 48 +- .../matlabbatch/@cfg_mchoice}/val2def.m | 60 +- ext/matlabbatch/@cfg_menu/cfg2struct.m | 26 + .../matlabbatch/@cfg_menu/cfg_menu.m | 198 +- ext/matlabbatch/@cfg_menu/fieldnames.m | 20 + .../matlabbatch/@cfg_menu/gencode_item.m | 98 +- .../@cfg_menu/private/mysubs_fields.m | 36 +- .../matlabbatch/@cfg_menu/setval.m | 132 +- .../matlabbatch/@cfg_menu/showdetail.m | 46 +- .../matlabbatch/@cfg_menu/showdoc.m | 44 +- ext/matlabbatch/@cfg_menu/subs_fields.m | 21 + ext/matlabbatch/@cfg_menu/subsasgn.m | 108 + .../matlabbatch/@cfg_menu/subsasgn_check.m | 88 +- ext/matlabbatch/@cfg_menu/subsref.m | 77 + .../matlabbatch/@cfg_repeat}/all_leafs.m | 60 +- .../matlabbatch/@cfg_repeat}/all_set.m | 66 +- .../matlabbatch/@cfg_repeat/all_set_item.m | 36 +- .../matlabbatch/@cfg_repeat/cfg2jobsubs.m | 78 +- .../matlabbatch/@cfg_repeat}/cfg2struct.m | 68 +- .../matlabbatch/@cfg_repeat/cfg_repeat.m | 216 +- .../matlabbatch/@cfg_repeat/checksubs_job.m | 100 +- .../matlabbatch/@cfg_repeat/clearval.m | 54 +- .../matlabbatch/@cfg_repeat}/expand.m | 146 +- ext/matlabbatch/@cfg_repeat/fieldnames.m | 20 + .../matlabbatch/@cfg_repeat/fillvals.m | 106 +- .../matlabbatch/@cfg_repeat/gencode_item.m | 182 +- .../matlabbatch/@cfg_repeat/gettag.m | 50 +- .../matlabbatch/@cfg_repeat/harvest.m | 204 +- .../matlabbatch/@cfg_repeat/initialise.m | 266 +- .../matlabbatch/@cfg_repeat}/list.m | 266 +- .../@cfg_repeat/private/mysubs_fields.m | 36 +- .../matlabbatch/@cfg_repeat/setval.m | 110 +- .../matlabbatch/@cfg_repeat/showdetail.m | 66 +- .../matlabbatch/@cfg_repeat}/showdoc.m | 52 +- .../matlabbatch/@cfg_repeat/showmydoc.m | 80 +- ext/matlabbatch/@cfg_repeat/subs_fields.m | 21 + ext/matlabbatch/@cfg_repeat/subsasgn.m | 108 + .../matlabbatch/@cfg_repeat/subsasgn_check.m | 50 +- .../matlabbatch/@cfg_repeat/subsasgn_job.m | 288 +- ext/matlabbatch/@cfg_repeat/subsref.m | 77 + .../matlabbatch/@cfg_repeat/subsref_job.m | 110 +- .../matlabbatch/@cfg_repeat}/tag2cfgsubs.m | 118 +- .../matlabbatch/@cfg_repeat/tagnames.m | 52 +- .../matlabbatch/@cfg_repeat/treepart.m | 44 +- .../matlabbatch/@cfg_repeat/update_deps.m | 48 +- .../matlabbatch/@cfg_repeat/val2def.m | 66 +- {src/ext => ext}/matlabbatch/bin/cpcode.sh | 188 +- .../matlabbatch/bin/resave_cfg_ui.sh | 42 +- .../cfg_basicio/cfg_basicio_rewrite.m | 56 +- .../matlabbatch/cfg_basicio/cfg_cfg_basicio.m | 2684 +- .../cfg_basicio/cfg_cfg_basicio_def.m | 226 +- .../cfg_basicio/cfg_check_assignin.m | 40 +- .../matlabbatch/cfg_basicio/cfg_load_vars.m | 274 +- .../cfg_basicio/cfg_run_assignin.m | 50 +- .../cfg_basicio/cfg_run_call_matlab.m | 278 +- .../matlabbatch/cfg_basicio/cfg_run_cd.m | 36 +- .../cfg_basicio/cfg_run_file_filter.m | 32 +- .../cfg_basicio/cfg_run_file_fplist.m | 38 +- .../cfg_basicio/cfg_run_file_move.m | 188 +- .../cfg_basicio/cfg_run_file_split.m | 42 +- .../cfg_basicio/cfg_run_fileparts.m | 32 +- .../cfg_basicio/cfg_run_gunzip_files.m | 42 +- .../cfg_basicio/cfg_run_gzip_files.m | 42 +- .../matlabbatch/cfg_basicio/cfg_run_mkdir.m | 36 +- .../cfg_basicio/cfg_run_named_dir.m | 32 +- .../cfg_basicio/cfg_run_named_file.m | 42 +- .../cfg_basicio/cfg_run_named_input.m | 32 +- .../matlabbatch/cfg_basicio/cfg_run_runjobs.m | 118 +- .../cfg_basicio/cfg_run_save_vars.m | 50 +- .../cfg_basicio/cfg_run_subsrefvar.m | 328 +- .../cfg_basicio/cfg_vout_file_filter.m | 44 +- .../cfg_basicio/cfg_vout_file_fplist.m | 60 +- .../cfg_basicio/cfg_vout_file_move.m | 46 +- .../cfg_basicio/cfg_vout_file_split.m | 64 +- .../cfg_basicio/cfg_vout_fileparts.m | 64 +- .../cfg_basicio/cfg_vout_gunzip_files.m | 40 +- .../cfg_basicio/cfg_vout_gzip_files.m | 40 +- .../matlabbatch/cfg_basicio/cfg_vout_mkdir.m | 46 +- .../cfg_basicio/cfg_vout_named_dir.m | 58 +- .../cfg_basicio/cfg_vout_named_file.m | 72 +- .../cfg_basicio/cfg_vout_named_input.m | 38 +- .../cfg_basicio/cfg_vout_runjobs.m | 56 +- .../cfg_basicio/cfg_vout_save_vars.m | 50 +- .../01_dir_ops/batch_basicio_02_cd.m | 52 +- .../01_dir_ops/batch_basicio_03_mkdir.m | 82 +- .../01_dir_ops/batch_basicio_04_named_dir.m | 108 +- .../01_dir_ops/batch_basicio_toplevel.m | 26 +- .../02_file_ops/batch_basicio_01_file_move.m | 406 +- .../02_file_ops/batch_basicio_02_gzip_files.m | 120 +- .../batch_basicio_03_gunzip_files.m | 120 +- .../02_file_ops/batch_basicio_05_named_file.m | 114 +- .../batch_basicio_06_file_fplist.m | 122 +- .../batch_basicio_07_file_filter.m | 142 +- .../02_file_ops/batch_basicio_09_file_split.m | 150 +- .../02_file_ops/batch_basicio_toplevel.m | 52 +- .../batch_basicio_08_fileparts.m | 42 +- .../01_file_dir_ops/batch_basicio_toplevel.m | 26 +- .../02_var_ops/batch_basicio_10_named_input.m | 80 +- .../02_var_ops/batch_basicio_11_load_vars.m | 156 +- .../02_var_ops/batch_basicio_12_save_vars.m | 230 +- .../02_var_ops/batch_basicio_13_subsrefvar.m | 554 +- .../02_var_ops/batch_basicio_14_assignin.m | 86 +- .../src/02_var_ops/batch_basicio_toplevel.m | 30 +- .../src/03_run_ops/batch_basicio_15_runjobs.m | 464 +- .../03_run_ops/batch_basicio_16_call_matlab.m | 666 +- .../src/03_run_ops/batch_basicio_toplevel.m | 24 +- .../cfg_basicio/src/batch_basicio_codegen.m | 18 +- .../cfg_basicio/src/batch_basicio_toplevel.m | 32 +- .../cfg_basicio/src/create_cfg_cfg_basicio.m | 94 +- .../ext => ext}/matlabbatch/cfg_callbuiltin.m | 22 +- .../matlabbatch/cfg_confgui/cfg_confgui.m | 1512 +- .../cfg_confgui/cfg_run_template.m | 242 +- {src/ext => ext}/matlabbatch/cfg_conftest.m | 656 +- {src/ext => ext}/matlabbatch/cfg_dbstop.m | 50 +- {src/ext => ext}/matlabbatch/cfg_findspec.m | 92 +- .../matlabbatch/cfg_get_defaults.m | 76 +- {src/ext => ext}/matlabbatch/cfg_getfile.m | 3104 +- {src/ext => ext}/matlabbatch/cfg_job.m | 230 +- {src/ext => ext}/matlabbatch/cfg_load_jobs.m | 138 +- {src/ext => ext}/matlabbatch/cfg_message.m | 512 +- .../matlabbatch/cfg_mlbatch_appcfg.m | 62 +- {src/ext => ext}/matlabbatch/cfg_serial.m | 538 +- {src/ext => ext}/matlabbatch/cfg_struct2cfg.m | 284 +- {src/ext => ext}/matlabbatch/cfg_tropts.m | 64 +- .../ext => ext}/matlabbatch/cfg_txtdesc2cfg.m | 354 +- {src/ext => ext}/matlabbatch/cfg_ui.fig | Bin {src/ext => ext}/matlabbatch/cfg_ui.m | 2134 +- .../matlabbatch/cfg_ui_multibatch.fig | Bin .../matlabbatch/cfg_ui_multibatch.m | 842 +- {src/ext => ext}/matlabbatch/cfg_ui_util.m | 1326 +- {src/ext => ext}/matlabbatch/cfg_util.m | 3702 +- .../matlabbatch/examples/batch_example_add1.m | 52 +- .../examples/batch_example_add1_div.m | 38 +- .../examples/batch_example_add1_div_reuse_b.m | 82 +- .../batch_example_add1_div_reuse_b_outname.m | 82 +- .../matlabbatch/examples/cfg_example_add1.m | 108 +- .../matlabbatch/examples/cfg_example_add2.m | 90 +- .../examples/cfg_example_cumsum1.m | 92 +- .../examples/cfg_example_cumsum2.m | 110 +- .../matlabbatch/examples/cfg_example_div.m | 114 +- .../matlabbatch/examples/cfg_example_master.m | 74 +- .../examples/cfg_example_run_add1.m | 32 +- .../examples/cfg_example_run_add2.m | 32 +- .../examples/cfg_example_run_cumsum1.m | 32 +- .../examples/cfg_example_run_cumsum2.m | 36 +- .../examples/cfg_example_run_div.m | 32 +- .../examples/cfg_example_run_sum.m | 32 +- .../matlabbatch/examples/cfg_example_sum.m | 92 +- .../examples/cfg_mlbatch_appcfg.m.example | 44 +- .../matlabbatch/examples/toy_example.m | 68 +- {src/ext => ext}/matlabbatch/gencode.m | 446 +- {src/ext => ext}/matlabbatch/gencode_rvalue.m | 378 +- .../matlabbatch/gencode_substruct.m | 142 +- .../matlabbatch/gencode_substructcode.m | 174 +- {src/ext => ext}/matlabbatch/help2cell.m | 68 +- .../ext => ext}/matlabbatch/hgsave_pre2008a.m | 232 +- {src/ext => ext}/matlabbatch/matlabbatch.man | 194 +- .../matlabbatch/private/README.inputdlg.txt | 18 +- .../matlabbatch/private/cfg_disp_error.m | 96 +- .../matlabbatch/private/cfg_eval_valedit.m | 100 +- .../matlabbatch/private/cfg_justify.m | 330 +- .../matlabbatch/private/cfg_maxextent.m | 48 +- .../private/cfg_mlbatch_defaults.m | 284 +- .../matlabbatch/private/cfg_mlbatch_root.m | 146 +- .../matlabbatch/private/cfg_onscreen.m | 80 +- .../matlabbatch/private/cfg_run_cm.m | 60 +- .../matlabbatch/private/cfg_textfill.m | 212 +- .../matlabbatch/private/cfg_ui_disable.m | 50 +- .../private/cfg_ui_getListboxTop.m | 42 +- .../matlabbatch/private/cfg_ui_restore.m | 42 +- .../matlabbatch/private/cfg_util_persistent.m | 50 +- .../matlabbatch/private/copyright_cfg.m | 22 +- .../matlabbatch/private/copyright_spm.m | 12 +- .../private/getnicedialoglocation.m | 56 +- .../matlabbatch/private/inputdlg.m | 884 +- .../ext => ext}/matlabbatch/private/int2str.m | 180 +- .../ext => ext}/matlabbatch/private/listdlg.m | 530 +- .../ext => ext}/matlabbatch/private/num2str.m | 386 +- .../matlabbatch/private/requestJavaAdapter.m | 58 +- .../matlabbatch/private/setdefaultbutton.m | 154 +- .../matlabbatch/subsasgn_check_funhandle.m | 76 +- .../matlabbatch/subsasgn_check_num.m | 52 +- .../matlabbatch/subsasgn_check_valcfg.m | 82 +- {src/ext => ext}/pupil-size/CHANGES_MADE.md | 0 {src/ext => ext}/pupil-size/LICENSE | 0 {src/ext => ext}/pupil-size/README.md | 0 {src/ext => ext}/pupil-size/code/READ_ME.txt | 98 +- .../code/dataModels/PupilDataModel.m | 1602 +- .../code/dataModels/RawSamplesModel.m | 766 +- .../code/dataModels/ValidSamplesModel.m | 768 +- .../code/helperFunctions/LEGACY/array2table.m | 24 +- .../code/helperFunctions/LEGACY/table.m | 262 +- .../code/helperFunctions/genMeanDiaSamples.m | 178 +- .../code/helperFunctions/legacyModeCheck.m | 56 +- .../code/helperFunctions/plotSegments.m | 318 +- .../code/helperFunctions/printToConsole.m | 124 +- .../code/helperFunctions/rawDataFilter.m | 1128 +- src/f_SCR.m => f_SCR.m | 0 src/f_SF.m => f_SF.m | 0 src/g_SCR.m => g_SCR.m | 0 src/pspm.m => pspm.m | 0 ..._align_channels.m => pspm_align_channels.m | 0 ...pm_appdesigner.mat => pspm_appdesigner.mat | Bin ...ppdesigner.mlapp => pspm_appdesigner.mlapp | Bin src/pspm_bf_FIR.m => pspm_bf_FIR.m | 0 src/pspm_bf_data.m => pspm_bf_data.m | 0 src/pspm_bf_hprf.m => pspm_bf_hprf.m | 0 src/pspm_bf_hprf_e.m => pspm_bf_hprf_e.m | 0 src/pspm_bf_hprf_f.m => pspm_bf_hprf_f.m | 0 src/pspm_bf_hprf_fc.m => pspm_bf_hprf_fc.m | 0 ...pspm_bf_hprf_fc_f.m => pspm_bf_hprf_fc_f.m | 0 src/pspm_bf_lcrf_gm.m => pspm_bf_lcrf_gm.m | 0 src/pspm_bf_ldrf_gm.m => pspm_bf_ldrf_gm.m | 0 src/pspm_bf_ldrf_gu.m => pspm_bf_ldrf_gu.m | 0 src/pspm_bf_psrf_erl.m => pspm_bf_psrf_erl.m | 0 src/pspm_bf_psrf_fc.m => pspm_bf_psrf_fc.m | 0 src/pspm_bf_rarf_e.m => pspm_bf_rarf_e.m | 0 src/pspm_bf_rarf_fc.m => pspm_bf_rarf_fc.m | 0 src/pspm_bf_rfrrf_e.m => pspm_bf_rfrrf_e.m | 0 src/pspm_bf_rprf_e.m => pspm_bf_rprf_e.m | 0 src/pspm_bf_scrf.m => pspm_bf_scrf.m | 0 src/pspm_bf_scrf_f.m => pspm_bf_scrf_f.m | 0 src/pspm_bf_sebrf.m => pspm_bf_sebrf.m | 0 ...pspm_bf_spsrf_box.m => pspm_bf_spsrf_box.m | 0 ..._bf_spsrf_gamma.m => pspm_bf_spsrf_gamma.m | 0 ...accade_filt.m => pspm_blink_saccade_filt.m | 0 src/pspm_butter.m => pspm_butter.m | 0 {src/pspm_cfg => pspm_cfg}/cfg_add_module.m | 0 .../cfg_mlbatch_appcfg.m | 0 {src/pspm_cfg => pspm_cfg}/pspm_cfg.m | 0 .../pspm_cfg_artefact_rm.m | 0 .../pspm_cfg_contrast1.m | 0 .../pspm_cfg_contrast2.m | 0 .../pspm_cfg_data_convert.m | 0 .../pspm_cfg_data_editor.m | 0 .../pspm_cfg_data_preprocessing.m | 0 {src/pspm_cfg => pspm_cfg}/pspm_cfg_dcm.m | 0 {src/pspm_cfg => pspm_cfg}/pspm_cfg_display.m | 0 .../pspm_cfg_downsample.m | 0 .../pspm_cfg_ecg_editor.m | 0 {src/pspm_cfg => pspm_cfg}/pspm_cfg_export.m | 0 .../pspm_cfg_extract_segments.m | 0 .../pspm_cfg_find_sounds.m | 0 .../pspm_cfg_find_valid_fixations.m | 0 .../pspm_cfg_first_level.m | 0 .../pspm_cfg_first_level_hp.m | 0 .../pspm_cfg_first_level_ps.m | 0 .../pspm_cfg_first_level_resp.m | 0 .../pspm_cfg_first_level_scr.m | 0 .../pspm_cfg_first_level_sebr.m | 0 .../pspm_cfg_first_level_sps.m | 0 .../pspm_cfg_gaze_convert.m | 0 .../pspm_cfg_get_markerinfo.m | 0 {src/pspm_cfg => pspm_cfg}/pspm_cfg_glm.m | 0 .../pspm_cfg => pspm_cfg}/pspm_cfg_glm_hp_e.m | 0 .../pspm_cfg_glm_hp_fc.m | 0 .../pspm_cfg_glm_ps_fc.m | 0 .../pspm_cfg => pspm_cfg}/pspm_cfg_glm_ra_e.m | 0 .../pspm_cfg_glm_ra_fc.m | 0 .../pspm_cfg_glm_rfr_e.m | 0 .../pspm_cfg => pspm_cfg}/pspm_cfg_glm_rp_e.m | 0 {src/pspm_cfg => pspm_cfg}/pspm_cfg_glm_scr.m | 0 .../pspm_cfg => pspm_cfg}/pspm_cfg_glm_sebr.m | 0 {src/pspm_cfg => pspm_cfg}/pspm_cfg_glm_sps.m | 0 {src/pspm_cfg => pspm_cfg}/pspm_cfg_import.m | 0 .../pspm_cfg_interpolate.m | 0 {src/pspm_cfg => pspm_cfg}/pspm_cfg_merge.m | 0 {src/pspm_cfg => pspm_cfg}/pspm_cfg_pp_emg.m | 0 .../pspm_cfg_pp_emg_data.m | 0 .../pspm_cfg_pp_heart_data.m | 0 .../pspm_cfg_pp_heart_period.m | 0 .../pspm_cfg => pspm_cfg}/pspm_cfg_pp_pupil.m | 0 {src/pspm_cfg => pspm_cfg}/pspm_cfg_pp_scr.m | 0 .../pspm_cfg_preparation.m | 0 .../pspm_cfg_process_illuminance.m | 0 .../pspm_cfg_pupil_correct.m | 0 .../pspm_cfg_pupil_preprocess.m | 0 .../pspm_cfg_pupil_size_convert.m | 0 {src/pspm_cfg => pspm_cfg}/pspm_cfg_rename.m | 0 {src/pspm_cfg => pspm_cfg}/pspm_cfg_resp_pp.m | 0 {src/pspm_cfg => pspm_cfg}/pspm_cfg_review1.m | 0 {src/pspm_cfg => pspm_cfg}/pspm_cfg_review2.m | 0 .../pspm_cfg_run_artefact_rm.m | 0 .../pspm_cfg_run_contrast1.m | 0 .../pspm_cfg_run_contrast2.m | 0 .../pspm_cfg_run_data_convert.m | 0 .../pspm_cfg_run_data_editor.m | 0 {src/pspm_cfg => pspm_cfg}/pspm_cfg_run_dcm.m | 0 .../pspm_cfg_run_downsample.m | 0 .../pspm_cfg_run_ecg_editor.m | 0 .../pspm_cfg_run_export.m | 0 .../pspm_cfg_run_extract_segments.m | 0 .../pspm_cfg_run_find_sounds.m | 0 .../pspm_cfg_run_find_valid_fixations.m | 0 .../pspm_cfg_run_gaze_convert.m | 0 .../pspm_cfg_run_get_markerinfo.m | 0 {src/pspm_cfg => pspm_cfg}/pspm_cfg_run_glm.m | 0 .../pspm_cfg_run_glm_hp_e.m | 0 .../pspm_cfg_run_glm_hp_fc.m | 0 .../pspm_cfg_run_glm_ps_fc.m | 0 .../pspm_cfg_run_glm_ra_e.m | 0 .../pspm_cfg_run_glm_ra_fc.m | 0 .../pspm_cfg_run_glm_rfr_e.m | 0 .../pspm_cfg_run_glm_rp_e.m | 0 .../pspm_cfg_run_glm_scr.m | 0 .../pspm_cfg_run_glm_sebr.m | 0 .../pspm_cfg_run_glm_sps.m | 0 .../pspm_cfg_run_import.m | 0 .../pspm_cfg_run_interpolate.m | 0 .../pspm_cfg_run_merge.m | 0 .../pspm_cfg_run_pp_emg_data.m | 0 .../pspm_cfg_run_pp_heart_data.m | 0 .../pspm_cfg_run_proc_illuminance.m | 0 .../pspm_cfg_run_pupil_correct.m | 0 .../pspm_cfg_run_pupil_preprocess.m | 0 .../pspm_cfg_run_pupil_size_convert.m | 0 .../pspm_cfg_run_rename.m | 0 .../pspm_cfg_run_review1.m | 0 .../pspm_cfg_run_review2.m | 0 .../pspm_cfg_run_segment_mean.m | 0 {src/pspm_cfg => pspm_cfg}/pspm_cfg_run_sf.m | 0 .../pspm_cfg => pspm_cfg}/pspm_cfg_run_trim.m | 0 .../pspm_cfg_second_level.m | 0 .../pspm_cfg_segment_mean.m | 0 {src/pspm_cfg => pspm_cfg}/pspm_cfg_sf.m | 0 .../pspm_cfg_split_sessions.m | 0 {src/pspm_cfg => pspm_cfg}/pspm_cfg_tools.m | 0 {src/pspm_cfg => pspm_cfg}/pspm_cfg_trim.m | 0 ...ual_angle.m => pspm_compute_visual_angle.m | 0 ...core.m => pspm_compute_visual_angle_core.m | 0 src/pspm_con1.m => pspm_con1.m | 0 src/pspm_con2.m => pspm_con2.m | 0 src/pspm_contrast.fig => pspm_contrast.fig | Bin src/pspm_contrast.m => pspm_contrast.m | 0 ...trast_App.mlapp => pspm_contrast_App.mlapp | Bin ...diameter.m => pspm_convert_area2diameter.m | 0 ...onvert_au2unit.m => pspm_convert_au2unit.m | 0 ..._convert_ecg2hb.m => pspm_convert_ecg2hb.m | 0 ...cg2hb_amri.m => pspm_convert_ecg2hb_amri.m | 0 ...distance.m => pspm_convert_gaze_distance.m | 0 ...pm_convert_hb2hp.m => pspm_convert_hb2hp.m | 0 ..._pixel2unit.m => pspm_convert_pixel2unit.m | 0 ..._convert_ppg2hb.m => pspm_convert_ppg2hb.m | 0 ...pspm_convert_unit.m => pspm_convert_unit.m | 0 ...angle2sps.m => pspm_convert_visangle2sps.m | 0 ...core.m => pspm_convert_visangle2sps_core.m | 0 ...pm_data_editor.fig => pspm_data_editor.fig | Bin src/pspm_data_editor.m => pspm_data_editor.m | 0 ...or_App.mlapp => pspm_data_editor_App.mlapp | Bin src/pspm_dcm.m => pspm_dcm.m | 0 src/pspm_dcm_inv.m => pspm_dcm_inv.m | 0 ...pm_denoise_spike.m => pspm_denoise_spike.m | 0 src/pspm_display.fig => pspm_display.fig | Bin src/pspm_display.m => pspm_display.m | 0 ...isplay_App.mlapp => pspm_display_App.mlapp | Bin src/pspm_down.m => pspm_down.m | 0 src/pspm_downsample.m => pspm_downsample.m | 0 ...pspm_ecg_editor.fig => pspm_ecg_editor.fig | Bin src/pspm_ecg_editor.m => pspm_ecg_editor.m | 0 ...tor_App.mlapp => pspm_ecg_editor_App.mlapp | Bin src/pspm_emg_pp.m => pspm_emg_pp.m | 0 src/pspm_exp.m => pspm_exp.m | 0 ...ract_segments.m => pspm_extract_segments.m | 0 src/pspm_eye.m => pspm_eye.m | 0 src/pspm_filtfilt.m => pspm_filtfilt.m | 0 ...pspm_find_channel.m => pspm_find_channel.m | 0 src/pspm_find_sounds.m => pspm_find_sounds.m | 0 ...fixations.m => pspm_find_valid_fixations.m | 0 ..._format_history.m => pspm_format_history.m | 0 ..._file.m => pspm_format_history_from_file.m | 0 src/pspm_gaze_pp.m => pspm_gaze_pp.m | 0 src/pspm_get_acq.m => pspm_get_acq.m | 0 ...et_acq_bioread.m => pspm_get_acq_bioread.m | 0 src/pspm_get_acqmat.m => pspm_get_acqmat.m | 0 ...pspm_get_biograph.m => pspm_get_biograph.m | 0 src/pspm_get_biosemi.m => pspm_get_biosemi.m | 0 ...pspm_get_biotrace.m => pspm_get_biotrace.m | 0 src/pspm_get_blink_l.m => pspm_get_blink_l.m | 0 src/pspm_get_blink_r.m => pspm_get_blink_r.m | 0 ...pspm_get_brainvis.m => pspm_get_brainvis.m | 0 src/pspm_get_cnt.m => pspm_get_cnt.m | 0 src/pspm_get_csv.m => pspm_get_csv.m | 0 src/pspm_get_custom.m => pspm_get_custom.m | 0 src/pspm_get_ecg.m => pspm_get_ecg.m | 0 src/pspm_get_edf.m => pspm_get_edf.m | 0 src/pspm_get_emg.m => pspm_get_emg.m | 0 src/pspm_get_events.m => pspm_get_events.m | 0 src/pspm_get_eyelink.m => pspm_get_eyelink.m | 0 ...pspm_get_gaze_x_l.m => pspm_get_gaze_x_l.m | 0 ...pspm_get_gaze_x_r.m => pspm_get_gaze_x_r.m | 0 ...pspm_get_gaze_y_l.m => pspm_get_gaze_y_l.m | 0 ...pspm_get_gaze_y_r.m => pspm_get_gaze_y_r.m | 0 src/pspm_get_hb.m => pspm_get_hb.m | 0 src/pspm_get_hp.m => pspm_get_hp.m | 0 src/pspm_get_hr.m => pspm_get_hr.m | 0 ...pspm_get_labchart.m => pspm_get_labchart.m | 0 ...artmat_ext.m => pspm_get_labchartmat_ext.m | 0 ...chartmat_in.m => pspm_get_labchartmat_in.m | 0 src/pspm_get_marker.m => pspm_get_marker.m | 0 ..._get_markerinfo.m => pspm_get_markerinfo.m | 0 src/pspm_get_mat.m => pspm_get_mat.m | 0 src/pspm_get_obs.m => pspm_get_obs.m | 0 src/pspm_get_physlog.m => pspm_get_physlog.m | 0 src/pspm_get_ppg.m => pspm_get_ppg.m | 0 src/pspm_get_pupil.m => pspm_get_pupil.m | 0 src/pspm_get_pupil_l.m => pspm_get_pupil_l.m | 0 src/pspm_get_pupil_r.m => pspm_get_pupil_r.m | 0 src/pspm_get_resp.m => pspm_get_resp.m | 0 src/pspm_get_rf.m => pspm_get_rf.m | 0 ...pm_get_saccade_l.m => pspm_get_saccade_l.m | 0 ...pm_get_saccade_r.m => pspm_get_saccade_r.m | 0 src/pspm_get_scr.m => pspm_get_scr.m | 0 src/pspm_get_smi.m => pspm_get_smi.m | 0 src/pspm_get_sound.m => pspm_get_sound.m | 0 src/pspm_get_spike.m => pspm_get_spike.m | 0 src/pspm_get_sps.m => pspm_get_sps.m | 0 src/pspm_get_sps_l.m => pspm_get_sps_l.m | 0 src/pspm_get_sps_r.m => pspm_get_sps_r.m | 0 src/pspm_get_timing.m => pspm_get_timing.m | 0 src/pspm_get_txt.m => pspm_get_txt.m | 0 src/pspm_get_vario.m => pspm_get_vario.m | 0 ...pm_get_viewpoint.m => pspm_get_viewpoint.m | 0 src/pspm_get_wdq.m => pspm_get_wdq.m | 0 src/pspm_get_wdq_n.m => pspm_get_wdq_n.m | 0 src/pspm_glm.m => pspm_glm.m | 0 src/pspm_glm_recon.m => pspm_glm_recon.m | 0 src/pspm_guide.fig => pspm_guide.fig | Bin src/pspm_guide.m => pspm_guide.m | 0 src/pspm_help.m => pspm_help.m | 0 src/pspm_import.m => pspm_import.m | 0 src/pspm_init.m => pspm_init.m | 0 src/pspm_interp1.m => pspm_interp1.m | 0 src/pspm_interpolate.m => pspm_interpolate.m | 0 src/pspm_jobman.m => pspm_jobman.m | 0 src/pspm_load1.m => pspm_load1.m | 0 src/pspm_load_data.m => pspm_load_data.m | 0 src/pspm_merge.m => pspm_merge.m | 0 src/pspm_msg.txt => pspm_msg.txt | 0 src/pspm_options.m => pspm_options.m | 0 src/pspm_overwrite.m => pspm_overwrite.m | 0 src/pspm_path.m => pspm_path.m | 0 src/pspm_pfm.m => pspm_pfm.m | 0 src/pspm_pp.m => pspm_pp.m | 0 src/pspm_prepdata.m => pspm_prepdata.m | 0 ...lluminance.m => pspm_process_illuminance.m | 0 ...pm_pulse_convert.m => pspm_pulse_convert.m | 0 ...pm_pupil_correct.m => pspm_pupil_correct.m | 0 ..._eyelink.m => pspm_pupil_correct_eyelink.m | 0 src/pspm_pupil_pp.m => pspm_pupil_pp.m | 0 ...il_pp_options.m => pspm_pupil_pp_options.m | 0 src/pspm_quit.m => pspm_quit.m | 58 +- ...pm_remove_epochs.m => pspm_remove_epochs.m | 0 src/pspm_ren.m => pspm_ren.m | 0 src/pspm_resp_pp.m => pspm_resp_pp.m | 0 src/pspm_rev2.m => pspm_rev2.m | 0 src/pspm_rev_con.m => pspm_rev_con.m | 0 src/pspm_rev_dcm.m => pspm_rev_dcm.m | 0 src/pspm_rev_glm.m => pspm_rev_glm.m | 0 src/pspm_review.fig => pspm_review.fig | Bin src/pspm_review.m => pspm_review.m | 0 ..._review_App.mlapp => pspm_review_App.mlapp | Bin src/pspm_scr_pp.m => pspm_scr_pp.m | 0 ...pspm_segment_mean.m => pspm_segment_mean.m | 0 src/pspm_sf.m => pspm_sf.m | 0 src/pspm_sf_auc.m => pspm_sf_auc.m | 0 src/pspm_sf_dcm.m => pspm_sf_dcm.m | 0 src/pspm_sf_mp.m => pspm_sf_mp.m | 0 src/pspm_sf_scl.m => pspm_sf_scl.m | 0 src/pspm_sf_theta.m => pspm_sf_theta.m | 0 src/pspm_show_arms.m => pspm_show_arms.m | 0 src/pspm_show_forum.m => pspm_show_forum.m | 0 ...pm_show_help_doc.m => pspm_show_help_doc.m | 0 ..._split_sessions.m => pspm_split_sessions.m | 0 src/pspm_text.m => pspm_text.m | 0 src/pspm_time2index.m => pspm_time2index.m | 0 ...fer_function.m => pspm_transfer_function.m | 0 src/pspm_trim.m => pspm_trim.m | 0 src/pspm_ui.m => pspm_ui.m | 0 src/pspm_ui_app.m => pspm_ui_app.m | 0 ...channeltype.m => pspm_update_channeltype.m | 0 src/pspm_version.m => pspm_version.m | 0 ...pm_write_channel.m => pspm_write_channel.m | 0 src/LICENSE.txt | 622 - src/ext/VBA/subfunctions/f_alpha.m | 4 - src/ext/VBA/subfunctions/g_exp.m | 3 - src/ext/VBA/subfunctions/g_probit.m | 2 - src/ext/VBA/subfunctions/phi.mat | Bin 1108 -> 0 bytes .../matlabbatch/@cfg_exbranch/subs_fields.m | 21 - src/ext/matlabbatch/@cfg_exbranch/subsasgn.m | 108 - src/ext/matlabbatch/@cfg_exbranch/subsref.m | 77 - src/ext/matlabbatch/@cfg_files/subs_fields.m | 21 - src/ext/matlabbatch/@cfg_files/subsasgn.m | 108 - src/ext/matlabbatch/@cfg_files/subsref.m | 77 - src/ext/matlabbatch/@cfg_item/subs_fields.m | 21 - src/ext/matlabbatch/@cfg_item/subsasgn.m | 108 - src/ext/matlabbatch/@cfg_item/subsref.m | 77 - .../matlabbatch/@cfg_mchoice/subs_fields.m | 21 - src/ext/matlabbatch/@cfg_mchoice/subsasgn.m | 108 - src/ext/matlabbatch/@cfg_mchoice/subsref.m | 77 - src/ext/matlabbatch/@cfg_menu/cfg2struct.m | 26 - src/ext/matlabbatch/@cfg_menu/fieldnames.m | 20 - src/ext/matlabbatch/@cfg_menu/subs_fields.m | 21 - src/ext/matlabbatch/@cfg_menu/subsasgn.m | 108 - src/ext/matlabbatch/@cfg_menu/subsref.m | 77 - src/ext/matlabbatch/@cfg_repeat/fieldnames.m | 20 - src/ext/matlabbatch/@cfg_repeat/subs_fields.m | 21 - src/ext/matlabbatch/@cfg_repeat/subsasgn.m | 108 - src/ext/matlabbatch/@cfg_repeat/subsref.m | 77 - src/pspm_butter.mat | Bin 8964 -> 0 bytes src/pspm_convert.mat | Bin 336 -> 0 bytes test/format_test_results.m | 40 - test/import_eyelink_test.m | 171 - test/import_smi_test.m | 143 - test/import_viewpoint_test.m | 140 - test/pspm_align_channels_test.m | 114 - test/pspm_bf_data_test.m | 51 - test/pspm_bf_test.m | 70 - test/pspm_blink_saccade_filt_test.m | 62 - test/pspm_butter_test.m | 21 - test/pspm_convert_au2unit_test.m | 6 - test/pspm_convert_ecg2hb_amri_test.m | 37 - test/pspm_convert_ecg2hb_test.m | 186 - test/pspm_convert_gaze_distance_test.m | 95 - test/pspm_convert_hb2hp_test.m | 53 - test/pspm_convert_pixel2unit_test.m | 4 - test/pspm_convert_unit_test.m | 53 - test/pspm_dcm_test.m | 170 - test/pspm_down_test.m | 81 - test/pspm_exp_test.m | 161 - test/pspm_extract_segments_test.m | 418 - test/pspm_filtfilt_test.m | 14 - test/pspm_find_channel_test.m | 30 - test/pspm_find_free_fn.m | 11 - test/pspm_find_sounds_test.m | 213 - test/pspm_find_valid_fixations_test.m | 457 - test/pspm_gaze_pp_test.m | 113 - test/pspm_get_acq_bioread_test.m | 39 - test/pspm_get_acq_test.m | 82 - test/pspm_get_acqmat_test.m | 32 - test/pspm_get_biograph_test.m | 20 - test/pspm_get_biosemi_test.m | 36 - test/pspm_get_biotrace_test.m | 21 - test/pspm_get_brainvis_test.m | 29 - test/pspm_get_ecg_test.m | 19 - test/pspm_get_edf_test.m | 40 - test/pspm_get_events_test.m | 124 - test/pspm_get_eyelink_test.m | 172 - test/pspm_get_hb_test.m | 20 - test/pspm_get_hr_test.m | 20 - test/pspm_get_labchart_test.m | 29 - test/pspm_get_labchartmat_ext_test.m | 31 - test/pspm_get_labchartmat_in_test.m | 37 - test/pspm_get_marker_test.m | 40 - test/pspm_get_mat_test.m | 89 - test/pspm_get_obs_test.m | 33 - test/pspm_get_physlog_test.m | 52 - test/pspm_get_pupil_test.m | 20 - test/pspm_get_resp_test.m | 20 - test/pspm_get_scr_test.m | 69 - test/pspm_get_smi_test.m | 131 - test/pspm_get_spike_test.m | 40 - test/pspm_get_sps_test.m | 23 - test/pspm_get_superclass.m | 120 - test/pspm_get_timing_test.m | 135 - test/pspm_get_txt_test.m | 111 - test/pspm_get_vario_test.m | 29 - test/pspm_get_viewpoint_test.m | 94 - test/pspm_get_wdq_n_test.m | 33 - test/pspm_glm_test.m | 587 - test/pspm_import_test.m | 87 - test/pspm_interpolate_test.m | 396 - test/pspm_load1_test.m | 347 - test/pspm_load_data_test.m | 302 - test/pspm_load_data_ui_test.m | 55 - test/pspm_path_test.m | 27 - test/pspm_pp_test.m | 136 - test/pspm_prepdata_test.m | 139 - test/pspm_process_illuminance_test.m | 168 - test/pspm_pulse_convert_test.m | 26 - test/pspm_pupil_correct_eyelink_test.m | 101 - test/pspm_pupil_correct_test.m | 74 - test/pspm_pupil_pp_test.m | 98 - test/pspm_ren_test.m | 47 - test/pspm_resp_pp_test.m | 72 - test/pspm_scr_pp_test.m | 113 - test/pspm_sf_test.m | 90 - test/pspm_split_sessions_test.m | 147 - test/pspm_test.m | 115 - test/pspm_test_github_actions.m | 119 - test/pspm_testcase.m | 63 - test/pspm_testdata_gen.m | 185 - test/pspm_trim_test.m | 304 - test/pspm_write_channel_test.m | 316 - test/set_blinks_saccades_to_nan_test.m | 77 - 2034 files changed, 91547 insertions(+), 172175 deletions(-) rename src/CologneCoatOfArms.jpg => CologneCoatOfArms.jpg (100%) rename {src/Import => Import}/SON/Contents.m (100%) rename {src/Import => Import}/SON/MATLAB SON Library [2.0].pdf (100%) rename {src/Import => Import}/SON/SON32/C_Sources/GetFilterMask.c (95%) rename {src/Import => Import}/SON/SON32/C_Sources/SONAppID.c (95%) rename {src/Import => Import}/SON/SON32/C_Sources/SONDef.h (92%) rename {src/Import => Import}/SON/SON32/C_Sources/SONFActive.c (95%) rename {src/Import => Import}/SON/SON32/C_Sources/SONFControl.c (96%) rename {src/Import => Import}/SON/SON32/C_Sources/SONFEqual.c (95%) rename {src/Import => Import}/SON/SON32/C_Sources/SONFMode.c (95%) rename {src/Import => Import}/SON/SON32/C_Sources/SONFilter.c (95%) rename {src/Import => Import}/SON/SON32/C_Sources/SONGetADCData.c (96%) rename {src/Import => Import}/SON/SON32/C_Sources/SONGetEventData.c (96%) rename {src/Import => Import}/SON/SON32/C_Sources/SONGetExtMarkData.c (96%) rename {src/Import => Import}/SON/SON32/C_Sources/SONGetMarkData.c (96%) rename {src/Import => Import}/SON/SON32/C_Sources/SONGetRealData.c (96%) rename {src/Import => Import}/SON/SON32/C_Sources/SONGetVersion.c (94%) rename {src/Import => Import}/SON/SON32/C_Sources/SONLastPointsTime.c (96%) rename {src/Import => Import}/SON/SON32/C_Sources/SONLastTime.c (96%) rename {src/Import => Import}/SON/SON32/C_Sources/SONSetMarker.c (96%) rename {src/Import => Import}/SON/SON32/C_Sources/SONTimeDate.c (96%) rename {src/Import => Import}/SON/SON32/C_Sources/SONWriteExtMarkBlock (96%) rename {src/Import => Import}/SON/SON32/C_Sources/SONWriteExtMarkBlock2 (96%) rename {src/Import => Import}/SON/SON32/C_Sources/SONWriteMarkBlock.c (96%) rename {src/Import => Import}/SON/SON32/C_Sources/compile.m (97%) rename {src/Import => Import}/SON/SON32/C_Sources/gatewaySONWriteExtMarkBlock.c (96%) rename {src/Import => Import}/SON/SON32/Contents.m (100%) rename {src/Import => Import}/SON/SON32/SONAppID.m (88%) rename {src/Import => Import}/SON/SON32/SONAppID.mexw32 (100%) rename {src/Import => Import}/SON/SON32/SONBlocks.m (96%) rename {src/Import => Import}/SON/SON32/SONBookFileSpace.m (96%) rename {src/Import => Import}/SON/SON32/SONCanWrite.m (94%) rename {src/Import => Import}/SON/SON32/SONChanBytes.m (94%) rename {src/Import => Import}/SON/SON32/SONChanDelete.m (95%) rename {src/Import => Import}/SON/SON32/SONChanDivide.m (95%) rename {src/Import => Import}/SON/SON32/SONChanInterleave.m (96%) rename {src/Import => Import}/SON/SON32/SONChanKind.m (97%) rename {src/Import => Import}/SON/SON32/SONChanMaxTime.m (96%) rename {src/Import => Import}/SON/SON32/SONCleanUp.m (95%) rename {src/Import => Import}/SON/SON32/SONCloseFile.m (95%) rename {src/Import => Import}/SON/SON32/SONCommitFile.m (96%) rename {src/Import => Import}/SON/SON32/SONCreateFile.m (97%) rename {src/Import => Import}/SON/SON32/SONDateTime.m (96%) rename {src/Import => Import}/SON/SON32/SONDelBlocks.m (94%) rename {src/Import => Import}/SON/SON32/SONEmptyFile.m (82%) rename {src/Import => Import}/SON/SON32/SONExtMarkAlign.m (96%) rename {src/Import => Import}/SON/SON32/SONFActive.m (83%) rename {src/Import => Import}/SON/SON32/SONFActive.mexw32 (100%) rename {src/Import => Import}/SON/SON32/SONFControl.m (97%) rename {src/Import => Import}/SON/SON32/SONFControl.mexw32 (100%) rename {src/Import => Import}/SON/SON32/SONFEqual.m (84%) rename {src/Import => Import}/SON/SON32/SONFEqual.mexw32 (100%) rename {src/Import => Import}/SON/SON32/SONFMode.m (93%) rename {src/Import => Import}/SON/SON32/SONFMode.mexw32 (100%) rename {src/Import => Import}/SON/SON32/SONFileBytes.m (94%) rename {src/Import => Import}/SON/SON32/SONFileSize.m (94%) rename {src/Import => Import}/SON/SON32/SONFilter.m (90%) rename {src/Import => Import}/SON/SON32/SONFilter.mexw32 (100%) rename {src/Import => Import}/SON/SON32/SONGetADCData.m (97%) rename {src/Import => Import}/SON/SON32/SONGetADCData.mexw32 (100%) rename {src/Import => Import}/SON/SON32/SONGetADCInfo.m (97%) rename {src/Import => Import}/SON/SON32/SONGetChanComment.m (97%) rename {src/Import => Import}/SON/SON32/SONGetChanTitle.m (95%) rename {src/Import => Import}/SON/SON32/SONGetEventData.m (97%) rename {src/Import => Import}/SON/SON32/SONGetEventData.mexw32 (100%) rename {src/Import => Import}/SON/SON32/SONGetExtMarkData.m (98%) rename {src/Import => Import}/SON/SON32/SONGetExtMarkData.mexw32 (100%) rename {src/Import => Import}/SON/SON32/SONGetExtMarkInfo.m (96%) rename {src/Import => Import}/SON/SON32/SONGetExtraData.m (96%) rename {src/Import => Import}/SON/SON32/SONGetExtraDataSize.m (79%) rename {src/Import => Import}/SON/SON32/SONGetFileComment.m (97%) rename {src/Import => Import}/SON/SON32/SONGetFreeChan.m (96%) rename {src/Import => Import}/SON/SON32/SONGetFreeChanl.m (96%) rename {src/Import => Import}/SON/SON32/SONGetMarkData.m (95%) rename {src/Import => Import}/SON/SON32/SONGetMarkData.mexw32 (100%) rename {src/Import => Import}/SON/SON32/SONGetRealData.m (97%) rename {src/Import => Import}/SON/SON32/SONGetRealData.mexw32 (100%) rename {src/Import => Import}/SON/SON32/SONGetTimePerADC.m (94%) rename {src/Import => Import}/SON/SON32/SONGetVersion.m (82%) rename {src/Import => Import}/SON/SON32/SONGetusPerTime.m (94%) rename {src/Import => Import}/SON/SON32/SONIdealRate.m (89%) rename {src/Import => Import}/SON/SON32/SONIsSaving.m (97%) rename {src/Import => Import}/SON/SON32/SONItemSize.m (85%) rename {src/Import => Import}/SON/SON32/SONKillRange.m (97%) rename {src/Import => Import}/SON/SON32/SONLastPointsTime.m (92%) rename {src/Import => Import}/SON/SON32/SONLastPointsTime.mexw32 (100%) rename {src/Import => Import}/SON/SON32/SONLastTime.m (93%) rename {src/Import => Import}/SON/SON32/SONLastTime.mexw32 (100%) rename {src/Import => Import}/SON/SON32/SONLatestTime.m (96%) rename {src/Import => Import}/SON/SON32/SONLoad.m (97%) rename {src/Import => Import}/SON/SON32/SONMaxChans.m (95%) rename {src/Import => Import}/SON/SON32/SONMaxTime.m (96%) rename {src/Import => Import}/SON/SON32/SONOpenNewFile.m (83%) rename {src/Import => Import}/SON/SON32/SONOpenOldFile.m (95%) rename {src/Import => Import}/SON/SON32/SONPhyChan.m (86%) rename {src/Import => Import}/SON/SON32/SONPhySz.m (96%) rename {src/Import => Import}/SON/SON32/SONPhysChan.m (86%) rename {src/Import => Import}/SON/SON32/SONSave.m (89%) rename {src/Import => Import}/SON/SON32/SONSaveRange.m (97%) rename {src/Import => Import}/SON/SON32/SONSetADCOffset.m (96%) rename {src/Import => Import}/SON/SON32/SONSetADCScale.m (96%) rename {src/Import => Import}/SON/SON32/SONSetADCUnits.m (86%) rename {src/Import => Import}/SON/SON32/SONSetBuffSpace.m (96%) rename {src/Import => Import}/SON/SON32/SONSetBuffering.m (76%) rename {src/Import => Import}/SON/SON32/SONSetChanComment.m (96%) rename {src/Import => Import}/SON/SON32/SONSetChanTitle.m (83%) rename {src/Import => Import}/SON/SON32/SONSetEventChan.m (92%) rename {src/Import => Import}/SON/SON32/SONSetFileClock.m (97%) rename {src/Import => Import}/SON/SON32/SONSetFileComment.m (96%) rename {src/Import => Import}/SON/SON32/SONSetInitLow.m (87%) rename {src/Import => Import}/SON/SON32/SONSetMarker.m (97%) rename {src/Import => Import}/SON/SON32/SONSetMarker.mexw32 (100%) rename {src/Import => Import}/SON/SON32/SONSetRealChan.m (97%) rename {src/Import => Import}/SON/SON32/SONSetRealMarkChan.m (96%) rename {src/Import => Import}/SON/SON32/SONSetTextMarkChan.m (94%) rename {src/Import => Import}/SON/SON32/SONSetWaveChan.m (94%) rename {src/Import => Import}/SON/SON32/SONSetWaveMarkChan.m (95%) rename {src/Import => Import}/SON/SON32/SONTimeBase.m (96%) rename {src/Import => Import}/SON/SON32/SONTimeDate.mexw32 (100%) rename {src/Import => Import}/SON/SON32/SONUpdateStart.m (83%) rename {src/Import => Import}/SON/SON32/SONVersion.m (95%) rename {src/Import => Import}/SON/SON32/SONWriteADCBlock.m (97%) rename {src/Import => Import}/SON/SON32/SONWriteEventBlock.m (96%) rename {src/Import => Import}/SON/SON32/SONWriteExtMarkBlock.m (100%) rename {src/Import => Import}/SON/SON32/SONWriteExtMarkBlock.mexw32 (100%) rename {src/Import => Import}/SON/SON32/SONWriteMarkBlock.m (93%) rename {src/Import => Import}/SON/SON32/SONWriteRealBlock.m (96%) rename {src/Import => Import}/SON/SON32/SONYRange.m (100%) rename {src/Import => Import}/SON/SON32/gatewaySONWriteExtMarkBlock.mexw32 (100%) rename {src/Import => Import}/SON/SON32/son32.m (99%) rename {src/Import => Import}/SON/SONADCToDouble.m (95%) rename {src/Import => Import}/SON/SONADCToSingle.m (95%) rename {src/Import => Import}/SON/SONChanList.m (96%) rename {src/Import => Import}/SON/SONChannelInfo.m (96%) rename {src/Import => Import}/SON/SONCreateChannel.m (97%) rename {src/Import => Import}/SON/SONFileHeader.m (95%) rename {src/Import => Import}/SON/SONGetADCChannel.m (97%) rename {src/Import => Import}/SON/SONGetADCMarkerChannel.m (97%) rename {src/Import => Import}/SON/SONGetBlockHeaders.m (97%) rename {src/Import => Import}/SON/SONGetChannel.m (95%) rename {src/Import => Import}/SON/SONGetEventChannel.m (96%) rename {src/Import => Import}/SON/SONGetMarkerChannel.m (97%) rename {src/Import => Import}/SON/SONGetRealMarkerChannel.m (96%) rename {src/Import => Import}/SON/SONGetRealWaveChannel.m (97%) rename {src/Import => Import}/SON/SONGetSampleInterval.m (97%) rename {src/Import => Import}/SON/SONGetSampleTicks.m (97%) rename {src/Import => Import}/SON/SONGetTextMarkerChannel.m (97%) rename {src/Import => Import}/SON/SONRealToADC.m (97%) rename {src/Import => Import}/SON/SONTest.m (96%) rename {src/Import => Import}/SON/SONTicksToSeconds.m (96%) rename {src/Import => Import}/SON/SONUpgradeToVersion6.m (95%) rename {src/Import => Import}/SON/SONVersion.m (97%) rename {src/Import => Import}/SON/progressbar.m (97%) rename {src/Import => Import}/SON/readme.txt (96%) rename {src/Import => Import}/acq/acqread.m (97%) rename {src/Import => Import}/acq/app156.pdf (100%) rename {src/Import => Import}/acq/license.txt (98%) rename {src/Import => Import}/biograph/SA7913 BioGraph Infiniti Getting Started.pdf (100%) rename {src/Import => Import}/eyelink/import_eyelink.m (100%) rename {src/Import => Import}/fieldtrip/fileio/COPYING (100%) rename {src/Import => Import}/fieldtrip/fileio/README (100%) rename {src/Import => Import}/fieldtrip/fileio/ft_chantype.m (100%) rename {src/Import => Import}/fieldtrip/fileio/ft_chanunit.m (100%) rename {src/Import => Import}/fieldtrip/fileio/ft_create_buffer.m (100%) rename {src/Import => Import}/fieldtrip/fileio/ft_destroy_buffer.m (100%) rename {src/Import => Import}/fieldtrip/fileio/ft_filetype.m (100%) rename {src/Import => Import}/fieldtrip/fileio/ft_filter_event.m (100%) rename {src/Import => Import}/fieldtrip/fileio/ft_flush_data.m (100%) rename {src/Import => Import}/fieldtrip/fileio/ft_flush_event.m (100%) rename {src/Import => Import}/fieldtrip/fileio/ft_flush_header.m (100%) rename {src/Import => Import}/fieldtrip/fileio/ft_poll_buffer.m (100%) rename {src/Import => Import}/fieldtrip/fileio/ft_read_atlas.m (100%) rename {src/Import => Import}/fieldtrip/fileio/ft_read_cifti.m (100%) rename {src/Import => Import}/fieldtrip/fileio/ft_read_data.m (100%) rename {src/Import => Import}/fieldtrip/fileio/ft_read_event.m (100%) rename {src/Import => Import}/fieldtrip/fileio/ft_read_header.m (100%) rename {src/Import => Import}/fieldtrip/fileio/ft_read_headshape.m (100%) rename {src/Import => Import}/fieldtrip/fileio/ft_read_mri.m (100%) rename {src/Import => Import}/fieldtrip/fileio/ft_read_sens.m (100%) rename {src/Import => Import}/fieldtrip/fileio/ft_read_spike.m (100%) rename {src/Import => Import}/fieldtrip/fileio/ft_read_vol.m (100%) rename {src/Import => Import}/fieldtrip/fileio/ft_write_cifti.m (100%) rename {src/Import => Import}/fieldtrip/fileio/ft_write_data.m (100%) rename {src/Import => Import}/fieldtrip/fileio/ft_write_event.m (100%) rename {src/Import => Import}/fieldtrip/fileio/ft_write_headshape.m (100%) rename {src/Import => Import}/fieldtrip/fileio/ft_write_mri.m (100%) rename {src/Import => Import}/fieldtrip/fileio/ft_write_spike.m (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/abs.c (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/abs.m (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/abs.mexa64 (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/abs.mexglx (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/abs.mexmaci (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/abs.mexmaci64 (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/abs.mexw32 (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/abs.mexw64 (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/all.m (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/any.m (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/compile_uint64.m (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/diff.m (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/max.c (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/max.m (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/max.mexa64 (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/max.mexglx (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/max.mexmac (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/max.mexmaci (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/max.mexmaci64 (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/max.mexw32 (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/max.mexw64 (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/min.c (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/min.m (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/min.mexa64 (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/min.mexglx (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/min.mexmac (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/min.mexmaci (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/min.mexmaci64 (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/min.mexw32 (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/min.mexw64 (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/minus.c (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/minus.m (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/minus.mexa64 (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/minus.mexglx (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/minus.mexmac (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/minus.mexmaci (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/minus.mexmaci64 (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/minus.mexw32 (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/minus.mexw64 (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/plus.c (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/plus.m (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/plus.mexa64 (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/plus.mexglx (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/plus.mexmac (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/plus.mexmaci (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/plus.mexmaci64 (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/plus.mexw32 (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/plus.mexw64 (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/rdivide.c (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/rdivide.m (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/rdivide.mexa64 (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/rdivide.mexglx (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/rdivide.mexmac (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/rdivide.mexmaci (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/rdivide.mexmaci64 (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/rdivide.mexw32 (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/rdivide.mexw64 (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/test.m (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/times.c (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/times.m (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/times.mexa64 (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/times.mexglx (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/times.mexmac (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/times.mexmaci (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/times.mexmaci64 (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/times.mexw32 (100%) rename {src/Import => Import}/fieldtrip/fileio/matlablt2010b/@uint64/times.mexw64 (100%) rename {src/Import => Import}/fieldtrip/fileio/private/ReadHeader.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/add_mex_source.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/ama2vol.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/appendevent.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/avw_hdr_read.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/avw_img_read.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/bigendian.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/bounding_mesh.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/bti2grad.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/buffer.mexa64 (100%) rename {src/Import => Import}/fieldtrip/fileio/private/buffer.mexglx (100%) rename {src/Import => Import}/fieldtrip/fileio/private/buffer.mexmac (100%) rename {src/Import => Import}/fieldtrip/fileio/private/buffer.mexmaci (100%) rename {src/Import => Import}/fieldtrip/fileio/private/buffer.mexmaci64 (100%) rename {src/Import => Import}/fieldtrip/fileio/private/buffer.mexw32 (100%) rename {src/Import => Import}/fieldtrip/fileio/private/buffer.mexw64 (100%) rename {src/Import => Import}/fieldtrip/fileio/private/buffer_wait_dat.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/channelposition.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/compile_mex_list.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/cornerpoints.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/cstructdecode.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/ctf2grad.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/dataset2files.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/db_close.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/db_insert.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/db_insert_blob.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/db_open.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/db_select.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/db_select_blob.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/decode_fif.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/decode_nifti1.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/decode_res4.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/dimlength.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/elproj.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/encode_nifti1.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/fetch_url.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/fif2grad.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/fiff_open_le.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/filetype_check_extension.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/filetype_check_header.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/filetype_check_uri.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/find_outermost_boundary.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/fixdimord.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/fixinside.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/fixname.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/fixpos.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/fixsampleinfo.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/ft_apply_montage.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/ft_checkdata.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/ft_convert_units.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/ft_datatype.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/ft_datatype_comp.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/ft_datatype_dip.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/ft_datatype_freq.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/ft_datatype_headmodel.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/ft_datatype_mvar.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/ft_datatype_raw.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/ft_datatype_sens.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/ft_datatype_source.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/ft_datatype_spike.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/ft_datatype_timelock.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/ft_datatype_vol.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/ft_estimate_units.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/ft_fetch_data.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/ft_fetch_header.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/ft_findcfg.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/ft_getopt.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/ft_getopt.mexa64 (100%) rename {src/Import => Import}/fieldtrip/fileio/private/ft_getopt.mexglx (100%) rename {src/Import => Import}/fieldtrip/fileio/private/ft_getopt.mexmaci (100%) rename {src/Import => Import}/fieldtrip/fileio/private/ft_getopt.mexmaci64 (100%) rename {src/Import => Import}/fieldtrip/fileio/private/ft_getopt.mexw32 (100%) rename {src/Import => Import}/fieldtrip/fileio/private/ft_getopt.mexw64 (100%) rename {src/Import => Import}/fieldtrip/fileio/private/ft_hastoolbox.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/ft_headcoordinates.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/ft_platform_supports.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/ft_progress.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/ft_scalingfactor.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/ft_senslabel.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/ft_senstype.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/ft_voltype.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/ft_warning.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/ft_warp_apply.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/getdatfield.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/getdimord.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/getdimsiz.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/getsubfield.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/hasyokogawa.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/in_fopen_manscan.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/in_fread_manscan.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/inflate_file.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/inifile.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/issubfield.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/istrue.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/itab2grad.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/jaga16_packet.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/keyval.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/labelcmb2indx.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/littleendian.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/loadama.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/loadvar.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/match_str.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/mne2grad.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/mxDeserialize.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/mxDeserialize_c.mexa64 (100%) rename {src/Import => Import}/fieldtrip/fileio/private/mxDeserialize_c.mexglx (100%) rename {src/Import => Import}/fieldtrip/fileio/private/mxDeserialize_c.mexmac (100%) rename {src/Import => Import}/fieldtrip/fileio/private/mxDeserialize_c.mexmaci (100%) rename {src/Import => Import}/fieldtrip/fileio/private/mxDeserialize_c.mexmaci64 (100%) rename {src/Import => Import}/fieldtrip/fileio/private/mxDeserialize_c.mexw32 (100%) rename {src/Import => Import}/fieldtrip/fileio/private/mxDeserialize_c.mexw64 (100%) rename {src/Import => Import}/fieldtrip/fileio/private/mxDeserialize_cpp.mexa64 (100%) rename {src/Import => Import}/fieldtrip/fileio/private/mxDeserialize_cpp.mexmaci64 (100%) rename {src/Import => Import}/fieldtrip/fileio/private/mxDeserialize_cpp.mexw32 (100%) rename {src/Import => Import}/fieldtrip/fileio/private/mxSerialize.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/mxSerialize_c.mexa64 (100%) rename {src/Import => Import}/fieldtrip/fileio/private/mxSerialize_c.mexglx (100%) rename {src/Import => Import}/fieldtrip/fileio/private/mxSerialize_c.mexmac (100%) rename {src/Import => Import}/fieldtrip/fileio/private/mxSerialize_c.mexmaci (100%) rename {src/Import => Import}/fieldtrip/fileio/private/mxSerialize_c.mexmaci64 (100%) rename {src/Import => Import}/fieldtrip/fileio/private/mxSerialize_c.mexw32 (100%) rename {src/Import => Import}/fieldtrip/fileio/private/mxSerialize_c.mexw64 (100%) rename {src/Import => Import}/fieldtrip/fileio/private/mxSerialize_cpp.mexa64 (100%) rename {src/Import => Import}/fieldtrip/fileio/private/mxSerialize_cpp.mexmaci64 (100%) rename {src/Import => Import}/fieldtrip/fileio/private/mxSerialize_cpp.mexw32 (100%) rename {src/Import => Import}/fieldtrip/fileio/private/mxSerialize_cpp.mexw64 (100%) rename {src/Import => Import}/fieldtrip/fileio/private/ndgrid.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/netmeg2grad.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/neuralynx_crc.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/neuralynx_getheader.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/neuralynx_timestamp.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/np_read_splitted_fileinfo.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/np_readdata.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/np_readfileinfo.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/np_readmarker.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/openbdf.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/parameterselection.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/plx_orig_header.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/pos2dim.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/pos2dim3d.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/pos2transform.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/pthreadGC2-w64.dll (100%) rename {src/Import => Import}/fieldtrip/fileio/private/pthreadGC2.dll (100%) rename {src/Import => Import}/fieldtrip/fileio/private/pthreadVC2.dll (100%) rename {src/Import => Import}/fieldtrip/fileio/private/quaternion.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_16bit.mexa64 (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_16bit.mexglx (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_16bit.mexmaci (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_16bit.mexmaci64 (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_16bit.mexw32 (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_16bit.mexw64 (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_24bit.mexa64 (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_24bit.mexglx (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_24bit.mexmac (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_24bit.mexmaci (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_24bit.mexmaci64 (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_24bit.mexw32 (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_24bit.mexw64 (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_4d_hdr.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_ah5_data.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_ah5_markers.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_ahdf5_hdr.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_asa.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_asa_bnd.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_asa_dip.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_asa_elc.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_asa_mri.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_asa_msr.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_asa_vol.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_besa_avr.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_besa_besa.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_besa_sfp.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_besa_swf.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_bham.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_biff.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_biosemi_bdf.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_biosig_data.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_biosig_header.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_brainvision_eeg.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_brainvision_pos.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_brainvision_vhdr.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_brainvision_vmrk.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_bti_ascii.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_bti_hs.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_bti_m4d.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_bucn_nirsdata.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_bucn_nirsevent.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_bucn_nirshdr.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_buffer_offline_data.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_buffer_offline_events.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_buffer_offline_header.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_bv_srf.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_caret_spec.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_ced_son.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_combined_ds.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_ctf_ascii.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_ctf_cls.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_ctf_coef.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_ctf_dat.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_ctf_hc.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_ctf_hdm.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_ctf_hist.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_ctf_meg4.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_ctf_mri.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_ctf_mri4.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_ctf_pos.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_ctf_res4.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_ctf_sens.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_ctf_shape.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_ctf_shm.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_ctf_shm.mexglx (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_ctf_svl.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_ctf_trigger.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_curry.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_deymed_dat.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_deymed_ini.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_edf.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_eeglabdata.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_eeglabevent.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_eeglabheader.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_egis_data.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_egis_header.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_elec.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_erplabdata.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_erplabevent.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_erplabheader.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_eyelink_asc.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_fcdc_trl.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_itab_mhd.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_mat.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_mclust_t.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_mff_bin.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_micromed_event.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_micromed_trc.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_mpi_dap.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_mpi_ds.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_nervus_data.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_nervus_header.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_neuralynx_bin.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_neuralynx_cds.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_neuralynx_dma.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_neuralynx_ds.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_neuralynx_ncs.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_neuralynx_nev.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_neuralynx_nse.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_neuralynx_nst.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_neuralynx_nts.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_neuralynx_ntt.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_neuralynx_sdma.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_neuralynx_ttl.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_neuromag_eve.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_neuromag_hc.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_neuroshare.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_neurosim_evolution.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_neurosim_signals.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_neurosim_spikes.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_nex_data.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_nex_event.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_nex_header.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_nexstim_event.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_nexstim_nxe.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_nifti2_hdr.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_nihonkohden_hdr.m (96%) rename {src/Import => Import}/fieldtrip/fileio/private/read_nihonkohden_m00.m (97%) rename {src/Import => Import}/fieldtrip/fileio/private/read_nimh_cortex.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_nmc_archive_k_data.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_nmc_archive_k_event.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_nmc_archive_k_hdr.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_ns_avg.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_ns_eeg.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_ns_hdr.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_off.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_plexon_ddt.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_plexon_ds.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_plexon_nex.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_plexon_plx.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_ply.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_polhemus_fil.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_sbin_data.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_sbin_events.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_sbin_header.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_serial_event.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_shm_data.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_shm_event.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_shm_header.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_smi_txt.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_spike6mat_data.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_spike6mat_header.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_spmeeg_data.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_spmeeg_event.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_spmeeg_header.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_stl.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_tdt_sev.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_tdt_tbk.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_tdt_tdx.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_tdt_tev.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_tdt_tsq.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_tmsi_poly5.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_tobii_tsv.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_trigger.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_videomeg_aud.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_videomeg_vid.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_vtk.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_wdq_data.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_wdq_header.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_yokogawa_data.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_yokogawa_data_new.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_yokogawa_event.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_yokogawa_header.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_yokogawa_header_new.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/read_zebris.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/readbdf.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/readmarkerfile.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/refine.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/rfbevent.mexa64 (100%) rename {src/Import => Import}/fieldtrip/fileio/private/rfbevent.mexglx (100%) rename {src/Import => Import}/fieldtrip/fileio/private/rfbevent.mexmac (100%) rename {src/Import => Import}/fieldtrip/fileio/private/rfbevent.mexmaci (100%) rename {src/Import => Import}/fieldtrip/fileio/private/rfbevent.mexmaci64 (100%) rename {src/Import => Import}/fieldtrip/fileio/private/rmsubfield.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/rotate.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/sap2matlab.mexa64 (100%) rename {src/Import => Import}/fieldtrip/fileio/private/sap2matlab.mexmaci64 (100%) rename {src/Import => Import}/fieldtrip/fileio/private/sap2matlab.mexw32 (100%) rename {src/Import => Import}/fieldtrip/fileio/private/setsubfield.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/solid_angle.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/solid_angle.mexa64 (100%) rename {src/Import => Import}/fieldtrip/fileio/private/surf_to_tetgen.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/time2offset.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/timestamp_neuralynx.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/timestamp_plexon.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/tokenize.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/translate.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/undobalancing.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/volumewrite_spm.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/write_brainvision_eeg.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/write_ctf_shm.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/write_ctf_shm.mexglx (100%) rename {src/Import => Import}/fieldtrip/fileio/private/write_edf.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/write_gdf.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/write_neuralynx_ncs.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/write_neuralynx_nts.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/write_nifti2_hdr.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/write_off.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/write_plexon_nex.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/write_ply.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/write_serial_event.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/write_stl.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/write_vtk.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/xml2struct.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/yokogawa2grad.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/yokogawa2grad_new.m (100%) rename {src/Import => Import}/fieldtrip/fileio/private/yokogawa2vol.m (100%) rename {src/Import => Import}/labchart/adi/+adi/+binary/channel_writer.m (96%) rename {src/Import => Import}/labchart/adi/+adi/+binary/file_writer.m (97%) rename {src/Import => Import}/labchart/adi/+adi/+examples/conversion_speed_testing.m (94%) rename {src/Import => Import}/labchart/adi/+adi/+examples/e001_writeFileFromScratch.m (95%) rename {src/Import => Import}/labchart/adi/+adi/+examples/e002_addCommentsToAnExistingFile.m (94%) rename {src/Import => Import}/labchart/adi/+adi/+postp/mergeComments.m (96%) rename {src/Import => Import}/labchart/adi/+adi/+sdk/ReadMe.md (60%) rename {src/Import => Import}/labchart/adi/+adi/+sl/+array/uniqueWithGroupIndices.m (95%) rename {src/Import => Import}/labchart/adi/+adi/+sl/+cellstr/join.m (96%) rename {src/Import => Import}/labchart/adi/+adi/+sl/+datetime/getTimeZone.m (91%) rename {src/Import => Import}/labchart/adi/+adi/+sl/+datetime/unixToMatlab.m (96%) rename {src/Import => Import}/labchart/adi/+adi/+sl/+dir/changeFileExtension.m (96%) rename {src/Import => Import}/labchart/adi/+adi/+sl/+dir/createFolderIfNoExist.m (96%) rename {src/Import => Import}/labchart/adi/+adi/+sl/+dir/filepartsx.m (95%) rename {src/Import => Import}/labchart/adi/+adi/+sl/+in/processVarargin.m (96%) rename {src/Import => Import}/labchart/adi/+adi/+sl/+in/process_varargin_result.m (97%) rename {src/Import => Import}/labchart/adi/+adi/+sl/+stack/calling_function_info.m (96%) rename {src/Import => Import}/labchart/adi/+adi/+sl/+stack/getMyBasePath.m (96%) rename {src/Import => Import}/labchart/adi/+adi/+sl/+stack/getPackageRoot.m (95%) rename {src/Import => Import}/labchart/adi/+adi/+sl/+str/contains.m (96%) rename {src/Import => Import}/labchart/adi/+adi/+tests/t001_speedWritingAndWriting.m (97%) rename {src/Import => Import}/labchart/adi/+adi/@channel/channel.m (97%) rename {src/Import => Import}/labchart/adi/+adi/@channel/exportToHDF5File.m (96%) rename {src/Import => Import}/labchart/adi/+adi/@file_viewer/file_viewer.m (96%) rename {src/Import => Import}/labchart/adi/+adi/@file_viewer/private/main.fig (100%) rename {src/Import => Import}/labchart/adi/+adi/channel_writer.m (96%) rename {src/Import => Import}/labchart/adi/+adi/comment.m (97%) rename {src/Import => Import}/labchart/adi/+adi/comment_handle.m (97%) rename {src/Import => Import}/labchart/adi/+adi/convert.m (96%) rename {src/Import => Import}/labchart/adi/+adi/createFile.m (95%) rename {src/Import => Import}/labchart/adi/+adi/data_writer_handle.m (95%) rename {src/Import => Import}/labchart/adi/+adi/documentation/FunctionMapping.csv (96%) rename {src/Import => Import}/labchart/adi/+adi/documentation/com_interface_notes.m (96%) rename {src/Import => Import}/labchart/adi/+adi/editFile.m (95%) rename {src/Import => Import}/labchart/adi/+adi/extractRecordToNewFile.m (96%) rename {src/Import => Import}/labchart/adi/+adi/file.m (97%) rename {src/Import => Import}/labchart/adi/+adi/file_handle.m (96%) rename {src/Import => Import}/labchart/adi/+adi/file_read_options.m (96%) rename {src/Import => Import}/labchart/adi/+adi/file_writer.m (97%) rename {src/Import => Import}/labchart/adi/+adi/h5_conversion_options.m (96%) rename {src/Import => Import}/labchart/adi/+adi/h5_file_h.m (97%) rename {src/Import => Import}/labchart/adi/+adi/h5_file_sdk.m (97%) rename {src/Import => Import}/labchart/adi/+adi/handle_logger.m (96%) rename {src/Import => Import}/labchart/adi/+adi/handle_manager.m (97%) rename {src/Import => Import}/labchart/adi/+adi/mat_comment_handle.m (96%) rename {src/Import => Import}/labchart/adi/+adi/mat_conversion_options.m (92%) rename {src/Import => Import}/labchart/adi/+adi/mat_file_h.m (96%) rename {src/Import => Import}/labchart/adi/+adi/mat_file_sdk.m (97%) rename {src/Import => Import}/labchart/adi/+adi/private/ADIDatCAPI_mex.h (98%) rename {src/Import => Import}/labchart/adi/+adi/private/ADIDatIOWin64.dll (100%) rename {src/Import => Import}/labchart/adi/+adi/private/ADIDatIOWin64.lib (100%) rename {src/Import => Import}/labchart/adi/+adi/private/c.m (89%) rename {src/Import => Import}/labchart/adi/+adi/private/c0.m (76%) rename {src/Import => Import}/labchart/adi/+adi/private/clong.m (94%) rename {src/Import => Import}/labchart/adi/+adi/private/sdk_mex.cpp (97%) rename {src/Import => Import}/labchart/adi/+adi/private/sdk_mex.mexw64 (100%) rename {src/Import => Import}/labchart/adi/+adi/readFile.m (96%) rename {src/Import => Import}/labchart/adi/+adi/record.m (97%) rename {src/Import => Import}/labchart/adi/+adi/sdk.m (97%) rename {src/Import => Import}/labchart/adi/+adi/test_SDK.m (96%) rename {src/Import => Import}/labchart/adi/LICENSE (97%) rename {src/Import => Import}/labchart/adi/README.rst (97%) rename {src/Import => Import}/labchart/adi/adi.m (97%) rename {src/Import => Import}/labchart/adi/documentation/ReadMe.md (100%) rename {src/Import => Import}/labchart/adi/documentation/organization.md (96%) rename {src/Import => Import}/labchart/adi/documentation/updating_mex_code.txt (91%) rename {src/Import => Import}/labchart/adi/files/LabChartBinaryFormat.pdf (100%) rename {src/Import => Import}/labchart/adi/files/blank_labchart_8_file.adicht (100%) rename {src/Import => Import}/labchart/adi/files/crash_testing.m (96%) rename {src/Import => Import}/nwdq/nReadDataq.m (97%) rename {src/Import => Import}/physlog/import_physlog.m (97%) rename {src/Import => Import}/smi/GazeVisToolbox/LICENSE.md (100%) rename {src/Import => Import}/smi/GazeVisToolbox/README.md (100%) rename {src/Import => Import}/smi/GazeVisToolbox/ReadSmiEventHeader.m (100%) rename {src/Import => Import}/smi/GazeVisToolbox/ReadSmiEvents_custom.m (100%) rename {src/Import => Import}/smi/import_smi.m (100%) rename {src/Import => Import}/smi/read_smi_events.m (100%) rename {src/Import => Import}/vario/getVarioport_allChannels.m (95%) rename {src/Import => Import}/viewpoint/import_viewpoint.m (100%) rename {src/Import => Import}/wdq/ReadDataq.m (97%) rename {src/Import => Import}/wdq/activex.exe (100%) rename {src/Import => Import}/wdq/controlerror.m (83%) rename {src/Import => Import}/wdq/dataqfileerror.m (82%) rename {src/Import => Import}/wdq/endoffile.m (97%) rename {doc => Manual}/PsPM_Manual.pdf (100%) rename {doc => Manual}/PsPM_References.pdf (100%) rename {src/backroom => backroom}/SCR_f_amplitude_check.m (100%) rename {src/backroom => backroom}/blink_saccade_filtering.m (100%) rename {src/backroom => backroom}/pspm_axpos.m (95%) rename {src/backroom => backroom}/pspm_bf_Fourier.m (96%) rename {src/backroom => backroom}/pspm_combine_markers.m (100%) rename {src/backroom => backroom}/pspm_convert_illum2lum.m (97%) rename {src/backroom => backroom}/pspm_convert_lux2cdm2.m (97%) rename {src/backroom => backroom}/pspm_convert_mm2visdeg.m (95%) rename {src/backroom => backroom}/pspm_find_data_epochs.m (97%) rename {src/backroom => backroom}/pspm_get_transfer_function.m (97%) rename {src/backroom => backroom}/pspm_ledalab.m (100%) rename {src/backroom => backroom}/pspm_load_single_chan.m (100%) rename {src/backroom => backroom}/pspm_peakscore.m (97%) rename {src/backroom => backroom}/pspm_predval.m (100%) rename {src/backroom => backroom}/pspm_scr2ledalab.m (97%) rename {src/backroom => backroom}/pspm_sf_get_theta.m (96%) rename {src/backroom => backroom}/pspm_transfer_fit.m (97%) rename {src/backroom => backroom}/set_blinks_saccades_to_nan.m (100%) delete mode 100644 doc/Figures/2ndlvl_bars.PNG delete mode 100644 doc/Figures/2ndlvl_table.PNG delete mode 100644 doc/Figures/Batch_nonlinear.png delete mode 100644 doc/Figures/Comparison_VBA.PNG delete mode 100644 doc/Figures/Hayes-Petrov2016_Article_MappingAndCorrectingTheInfluen_svg.pdf delete mode 100644 doc/Figures/Review_1stmodel1.PNG delete mode 100644 doc/Figures/YY1_import.png delete mode 100644 doc/Figures/YY2_trim.png delete mode 100644 doc/Figures/YY3_glm.png delete mode 100644 doc/Figures/YY41_review.png delete mode 100644 doc/Figures/YY42_review.png delete mode 100644 doc/Figures/YY43_review.png delete mode 100644 doc/Figures/YY44_review.png delete mode 100644 doc/Figures/icons/button_add_epoch.PNG delete mode 100644 doc/Figures/icons/button_navigate_epochs.PNG delete mode 100644 doc/Figures/icons/button_pan.PNG delete mode 100644 doc/Figures/icons/button_remove_epoch.PNG delete mode 100644 doc/Figures/icons/button_zoom.PNG delete mode 100644 doc/Figures/reviewmodel.png delete mode 100644 doc/PsPM-help_text_progress.xlsx delete mode 100644 doc/PsPM.bib delete mode 100644 doc/PsPM_Developers_Guide.lyx delete mode 100644 doc/PsPM_Developers_Guide.pdf delete mode 100644 doc/PsPM_Manual.lyx delete mode 100644 doc/PsPM_References.lyx delete mode 100644 doc/PsPM_release_checklist.md delete mode 100644 doc/References/Bach & Friston 2012 NeuroImage PredictionError SCR.pdf delete mode 100644 doc/References/Bach & Friston 2013 Psychophysiology SCR Model Review.pdf delete mode 100644 doc/References/Bach 2014 BiolPsychology Comparison SCRalzye-Ledalab.pdf delete mode 100644 doc/References/Bach et al. 2010 Biological Psychology_DCM-aSCR.pdf delete mode 100644 doc/References/Bach et al. 2011 Psychophysiology DCM_SF.pdf delete mode 100644 doc/References/BachFlandinFristonDolan_2009_SCR_GLM.pdf delete mode 100644 doc/References/BachFlandinFristonDolan_2010_IJP_SCR_LTI.pdf delete mode 100644 doc/References/BachFristonDolan_2010_IJP_SF_AUC.pdf delete mode 100644 doc/SampleDataMasterList.docx delete mode 100644 doc/Tests_Current_Status.docx delete mode 100755 doc/pspm_options_subfields.numbers delete mode 100644 doc/release_notes.pdf delete mode 100644 doc/release_notes.tex rename {src/ext => ext}/SPM/Contents.m (98%) rename {src/ext => ext}/SPM/cfg_get_defaults.m (96%) rename {src/ext => ext}/SPM/cfg_getfile.m (96%) rename {src/ext => ext}/SPM/cfg_mlbatch_defaults.m (98%) rename {src/ext => ext}/SPM/spm.m (97%) rename {src/ext => ext}/SPM/spm_Gpdf.m (97%) rename {src/ext => ext}/SPM/spm_Interactive.fig (100%) rename {src/ext => ext}/SPM/spm_Tcdf.m (97%) rename {src/ext => ext}/SPM/spm_figure.m (97%) rename {src/ext => ext}/SPM/spm_file.m (100%) rename {src/ext => ext}/SPM/spm_input.m (97%) rename {src/ext => ext}/SPM/spm_orth.m (96%) rename {src/ext => ext}/SPM/spm_select.m (97%) rename {src/ext => ext}/VBA/LICENSE (98%) rename {src/ext => ext}/VBA/README.md (98%) rename {src/ext => ext}/VBA/VBA_BMA.m (95%) rename {src/ext => ext}/VBA/VBA_Bin2Cont.m (96%) rename {src/ext => ext}/VBA/VBA_EKF.m (97%) rename {src/ext => ext}/VBA/VBA_ElogBeta.m (96%) rename {src/ext => ext}/VBA/VBA_ExceedanceProb.m (96%) rename {src/ext => ext}/VBA/VBA_FreeEnergy.m (96%) rename {src/ext => ext}/VBA/VBA_FreeEnergy_UNL.m (97%) rename {src/ext => ext}/VBA/VBA_GN.m (96%) rename {src/ext => ext}/VBA/VBA_Hpost.m (97%) rename {src/ext => ext}/VBA/VBA_IX0.m (96%) rename {src/ext => ext}/VBA/VBA_IX_lagged.m (96%) rename {src/ext => ext}/VBA/VBA_IX_lagged_binomial.m (96%) rename {src/ext => ext}/VBA/VBA_Initialize.m (97%) rename {src/ext => ext}/VBA/VBA_Iphi.m (96%) rename {src/ext => ext}/VBA/VBA_Iphi_UNL.m (96%) rename {src/ext => ext}/VBA/VBA_Iphi_binomial.m (96%) rename {src/ext => ext}/VBA/VBA_Iphi_extended.m (96%) rename {src/ext => ext}/VBA/VBA_Iphi_split.m (96%) rename {src/ext => ext}/VBA/VBA_Itheta.m (96%) rename {src/ext => ext}/VBA/VBA_JensenShannon.m (96%) rename {src/ext => ext}/VBA/VBA_KL.m (96%) rename {src/ext => ext}/VBA/VBA_LMEH0.m (96%) rename {src/ext => ext}/VBA/VBA_MFX.m (97%) rename {src/ext => ext}/VBA/VBA_NLStateSpaceModel.m (97%) rename {src/ext => ext}/VBA/VBA_PPM.m (97%) rename {src/ext => ext}/VBA/VBA_ReDisplay.m (97%) rename {src/ext => ext}/VBA/VBA_SavageDickey.m (96%) rename {src/ext => ext}/VBA/VBA_Shapley.m (97%) rename {src/ext => ext}/VBA/VBA_UNL0.m (97%) rename {src/ext => ext}/VBA/VBA_UNLtemp.m (95%) rename {src/ext => ext}/VBA/VBA_VarParam.m (97%) rename {src/ext => ext}/VBA/VBA_VolterraKernels.m (96%) rename {src/ext => ext}/VBA/VBA_bDCM_lesion.m (95%) rename {src/ext => ext}/VBA/VBA_check.m (97%) rename {src/ext => ext}/VBA/VBA_check4DCM.m (95%) rename {src/ext => ext}/VBA/VBA_checkGN.m (96%) rename {src/ext => ext}/VBA/VBA_check_errors.m (96%) rename {src/ext => ext}/VBA/VBA_conv2glm.m (94%) rename {src/ext => ext}/VBA/VBA_dcmMatrices.m (93%) rename {src/ext => ext}/VBA/VBA_designEfficiency.m (97%) rename {src/ext => ext}/VBA/VBA_disp.m (93%) rename {src/ext => ext}/VBA/VBA_displayGrads.m (96%) rename {src/ext => ext}/VBA/VBA_displayGroupBMC.m (97%) rename {src/ext => ext}/VBA/VBA_displayGroupBMCbtw.m (97%) rename {src/ext => ext}/VBA/VBA_displayMFX.m (97%) rename {src/ext => ext}/VBA/VBA_evalAL.m (96%) rename {src/ext => ext}/VBA/VBA_evalAL2.m (96%) rename {src/ext => ext}/VBA/VBA_evalFun.m (96%) rename {src/ext => ext}/VBA/VBA_fit.m (96%) rename {src/ext => ext}/VBA/VBA_getDefaults.m (98%) rename {src/ext => ext}/VBA/VBA_getDiagnostics.m (96%) rename {src/ext => ext}/VBA/VBA_getISqrtMat.m (95%) rename {src/ext => ext}/VBA/VBA_getKernels.m (96%) rename {src/ext => ext}/VBA/VBA_getLaplace.m (97%) rename {src/ext => ext}/VBA/VBA_getNoise.m (96%) rename {src/ext => ext}/VBA/VBA_getNtuples.m (96%) rename {src/ext => ext}/VBA/VBA_getSuffStat.m (97%) rename {src/ext => ext}/VBA/VBA_getU.m (96%) rename {src/ext => ext}/VBA/VBA_getVar.m (96%) rename {src/ext => ext}/VBA/VBA_get_dL.m (95%) rename {src/ext => ext}/VBA/VBA_get_tracker.m (96%) rename {src/ext => ext}/VBA/VBA_groupBMC.m (96%) rename {src/ext => ext}/VBA/VBA_groupBMC_btwConds.m (97%) rename {src/ext => ext}/VBA/VBA_groupBMC_btwGroups.m (97%) rename {src/ext => ext}/VBA/VBA_groupBMCbtw.m (97%) rename {src/ext => ext}/VBA/VBA_initDisplay.m (97%) rename {src/ext => ext}/VBA/VBA_initDisplay_extended.m (97%) rename {src/ext => ext}/VBA/VBA_inv.m (96%) rename {src/ext => ext}/VBA/VBA_logDet.m (96%) rename {src/ext => ext}/VBA/VBA_main.m (97%) rename {src/ext => ext}/VBA/VBA_microTime.m (96%) rename {src/ext => ext}/VBA/VBA_multisession_expand.m (96%) rename {src/ext => ext}/VBA/VBA_multisession_factor.m (97%) rename {src/ext => ext}/VBA/VBA_odeLim.m (96%) rename {src/ext => ext}/VBA/VBA_odeLim2NLSS.m (97%) rename {src/ext => ext}/VBA/VBA_onlineWrapper.m (96%) rename {src/ext => ext}/VBA/VBA_optimPriors.m (97%) rename {src/ext => ext}/VBA/VBA_orth.m (96%) rename {src/ext => ext}/VBA/VBA_pause.m (96%) rename {src/ext => ext}/VBA/VBA_priors.m (96%) rename {src/ext => ext}/VBA/VBA_psi.m (95%) rename {src/ext => ext}/VBA/VBA_sample.m (96%) rename {src/ext => ext}/VBA/VBA_setup.m (96%) rename {src/ext => ext}/VBA/VBA_summary.m (96%) rename {src/ext => ext}/VBA/VBA_summaryMFX.m (97%) rename {src/ext => ext}/VBA/VBA_susceptibility.m (97%) rename {src/ext => ext}/VBA/VBA_updateDisplay.m (96%) rename {src/ext => ext}/VBA/VBA_updateDisplay_extended.m (97%) rename {src/ext => ext}/VBA/VBA_version.m (95%) rename {src/ext => ext}/VBA/VBA_wrapup.m (96%) rename {src/ext => ext}/VBA/checkGX_binomial.m (90%) rename {src/ext => ext}/VBA/classification/BMM/MixtureOfBinomials.m (96%) rename {src/ext => ext}/VBA/classification/BMM/demo_BMM.m (95%) rename {src/ext => ext}/VBA/classification/BMM/generateBMM.m (96%) rename {src/ext => ext}/VBA/classification/CRP/VB_CRP.m (96%) rename {src/ext => ext}/VBA/classification/CRP/demo_DP.m (96%) rename {src/ext => ext}/VBA/classification/CRP/simulate_CRP.m (95%) rename {src/ext => ext}/VBA/classification/GMM/PCA_MoG.m (95%) rename {src/ext => ext}/VBA/classification/GMM/VBA_MoG.m (96%) rename {src/ext => ext}/VBA/classification/GMM/VBA_projectMoG.m (97%) rename {src/ext => ext}/VBA/classification/GMM/VBEM_GM.m (96%) rename {src/ext => ext}/VBA/classification/GMM/demo_GMM.m (96%) rename {src/ext => ext}/VBA/classification/GMM/dist.m (94%) rename {src/ext => ext}/VBA/classification/GMM/generateGMM.m (95%) rename {src/ext => ext}/VBA/classification/GMM/plotResults.m (97%) rename {src/ext => ext}/VBA/f_Id.m (75%) rename {src/ext => ext}/VBA/f_embed.m (95%) rename {src/ext => ext}/VBA/factorial_struct.m (96%) rename {src/ext => ext}/VBA/g_conv0.m (96%) rename {src/ext => ext}/VBA/g_convSig.m (95%) rename {src/ext => ext}/VBA/g_embed.m (94%) rename {src/ext => ext}/VBA/getF.m (91%) rename {src/ext => ext}/VBA/getHyperpriors.m (96%) rename {src/ext => ext}/VBA/getKernels.m (96%) rename {src/ext => ext}/VBA/getStateParamInput.m (95%) rename {src/ext => ext}/VBA/getSubplots.m (96%) rename {src/ext => ext}/VBA/get_MCMC_predictiveDensity.m (96%) rename {src/ext => ext}/VBA/get_MCMC_predictiveDensity_fb.m (96%) rename {src/ext => ext}/VBA/isbinary.m (95%) rename {src/ext => ext}/VBA/isweird.m (96%) rename {src/ext => ext}/VBA/numericDiff.m (97%) rename {src/ext => ext}/VBA/sampleFromArbitraryP.m (95%) rename {src/ext => ext}/VBA/setInput.m (96%) rename {src/ext => ext}/VBA/setPriors.m (97%) rename {src/ext => ext}/VBA/simulateNLSS.m (96%) rename {src/ext => ext}/VBA/simulateNLSS_fb.m (96%) rename {src/ext => ext}/VBA/stats&plots/Contrast_MEbins.m (95%) rename {src/ext => ext}/VBA/stats&plots/EVprodX.m (87%) rename {src/ext => ext}/VBA/stats&plots/GLM_contrast.m (96%) rename {src/ext => ext}/VBA/stats&plots/GLM_covComp.m (96%) rename {src/ext => ext}/VBA/stats&plots/MoveAxisToOrigin.m (95%) rename {src/ext => ext}/VBA/stats&plots/Plot3AxisAtOrigin.m (95%) rename {src/ext => ext}/VBA/stats&plots/PlotAxisAtOrigin.m (94%) rename {src/ext => ext}/VBA/stats&plots/approxOnGrid.m (94%) rename {src/ext => ext}/VBA/stats&plots/cov2corr.m (94%) rename {src/ext => ext}/VBA/stats&plots/demo_GLM_missingData.m (94%) rename {src/ext => ext}/VBA/stats&plots/demo_generalizability.m (97%) rename {src/ext => ext}/VBA/stats&plots/demo_mediation.m (83%) rename {src/ext => ext}/VBA/stats&plots/displayUncertainSigmoid.m (96%) rename {src/ext => ext}/VBA/stats&plots/doROC.m (96%) rename {src/ext => ext}/VBA/stats&plots/empiricalHist.m (96%) rename {src/ext/VBA/subfunctions => ext/VBA/stats&plots}/findCI.m (97%) rename {src/ext => ext}/VBA/stats&plots/fisher.m (95%) rename {src/ext => ext}/VBA/stats&plots/g_GLM_missingData.m (89%) rename {src/ext => ext}/VBA/stats&plots/getColors.m (92%) rename {src/ext => ext}/VBA/stats&plots/getPanel.m (97%) rename {src/ext => ext}/VBA/stats&plots/hatch.m (96%) rename {src/ext => ext}/VBA/stats&plots/hist2.m (96%) rename {src/ext => ext}/VBA/stats&plots/invnormalcdf.m (95%) rename {src/ext => ext}/VBA/stats&plots/lev_GLM.m (95%) rename {src/ext => ext}/VBA/stats&plots/maxMat.m (95%) rename {src/ext => ext}/VBA/stats&plots/medianfilter0.m (96%) rename {src/ext => ext}/VBA/stats&plots/mediationAnalysis0.m (97%) rename {src/ext => ext}/VBA/stats&plots/mnan.m (95%) rename {src/ext/VBA/subfunctions => ext/VBA/stats&plots}/nanzscore.m (97%) rename {src/ext => ext}/VBA/stats&plots/normalize.m (94%) rename {src/ext => ext}/VBA/stats&plots/normalpdf.m (93%) rename {src/ext => ext}/VBA/stats&plots/pinvComplex.m (95%) rename {src/ext => ext}/VBA/stats&plots/plotDensity.m (96%) rename {src/ext => ext}/VBA/stats&plots/plotElipse.m (96%) rename {src/ext => ext}/VBA/stats&plots/plotGraph3D.m (95%) rename {src/ext => ext}/VBA/stats&plots/plotUncertainTimeSeries.m (96%) rename {src/ext => ext}/VBA/stats&plots/plotVolterra.m (96%) rename {src/ext => ext}/VBA/stats&plots/prodX.m (96%) rename {src/ext => ext}/VBA/stats&plots/smooth2.m (94%) rename {src/ext => ext}/VBA/stats&plots/snan.m (94%) rename {src/ext => ext}/VBA/stats&plots/spear.m (94%) rename {src/ext => ext}/VBA/stats&plots/spm_autocorr.m (96%) rename {src/ext => ext}/VBA/stats&plots/spm_code/spm_Fcdf.m (97%) rename {src/ext => ext}/VBA/stats&plots/spm_code/spm_Gpdf.m (97%) rename {src/ext => ext}/VBA/stats&plots/spm_code/spm_Tcdf.m (97%) rename {src/ext => ext}/VBA/stats&plots/spm_code/spm_Xadjust.m (96%) rename {src/ext => ext}/VBA/stats&plots/spm_code/spm_dcm_build.m (96%) rename {src/ext => ext}/VBA/stats&plots/spm_code/spm_dcm_explore.m (96%) rename {src/ext => ext}/VBA/stats&plots/spm_code/spm_dcm_fmri_check.m (97%) rename {src/ext => ext}/VBA/stats&plots/spm_code/spm_dcm_graph.m (96%) rename {src/ext => ext}/VBA/stats&plots/spm_code/spm_gamrnd.c (95%) rename {src/ext => ext}/VBA/stats&plots/spm_code/spm_gamrnd.m (97%) rename {src/ext => ext}/VBA/stats&plots/spm_code/spm_gamrnd.mexa64 (100%) rename {src/ext => ext}/VBA/stats&plots/spm_code/spm_gamrnd.mexglx (100%) rename {src/ext => ext}/VBA/stats&plots/spm_code/spm_gamrnd.mexmaci (100%) rename {src/ext => ext}/VBA/stats&plots/spm_code/spm_gamrnd.mexmaci64 (100%) rename {src/ext => ext}/VBA/stats&plots/spm_code/spm_gamrnd.mexw32 (100%) rename {src/ext => ext}/VBA/stats&plots/spm_code/spm_gamrnd.mexw64 (100%) rename {src/ext => ext}/VBA/stats&plots/spm_code/spm_hrf.m (97%) rename {src/ext => ext}/VBA/stats&plots/spm_code/spm_inv.m (96%) rename {src/ext => ext}/VBA/stats&plots/spm_code/spm_log_evidence.m (96%) rename {src/ext => ext}/VBA/stats&plots/spm_code/spm_logdet.m (97%) rename {src/ext => ext}/VBA/stats&plots/spm_code/spm_unvec.m (96%) rename {src/ext => ext}/VBA/stats&plots/spm_code/spm_vec.m (96%) rename {src/ext => ext}/VBA/stats&plots/spm_dcm_batch.m (97%) rename {src/ext => ext}/VBA/stats&plots/spm_dcm_clone.m (96%) rename {src/ext => ext}/VBA/stats&plots/spm_dcm_test.m (96%) rename {src/ext => ext}/VBA/stats&plots/spm_deconv.m (95%) rename {src/ext => ext}/VBA/stats&plots/spm_getSNR.m (91%) rename {src/ext => ext}/VBA/stats&plots/spm_resample.m (95%) rename {src/ext => ext}/VBA/stats&plots/spm_split_dcm.m (95%) rename {src/ext => ext}/VBA/stats&plots/spm_uitab.m (96%) rename {src/ext => ext}/VBA/subfunctions/Av.m (85%) rename {src/ext => ext}/VBA/subfunctions/BOLD_parameters.m (95%) rename {src/ext => ext}/VBA/subfunctions/Contrast_MEbins.m (95%) rename {src/ext => ext}/VBA/subfunctions/ERP_dcm.m (98%) rename {src/ext => ext}/VBA/subfunctions/GaussNewton.m (95%) rename {src/ext => ext}/VBA/subfunctions/GetGitPath.m (97%) rename {src/ext => ext}/VBA/subfunctions/ObsRecGen.m (96%) rename {src/ext => ext}/VBA/subfunctions/RecToMfunction.m (97%) rename {src/ext => ext}/VBA/subfunctions/U_dummy.m (83%) rename {src/ext => ext}/VBA/subfunctions/VarVolatility.m (95%) rename {src/ext => ext}/VBA/subfunctions/addConfounds2dcm.m (97%) rename {src/ext => ext}/VBA/subfunctions/balanced_accuracy.m (95%) rename {src/ext => ext}/VBA/subfunctions/bernoulli.m (90%) rename {src/ext => ext}/VBA/subfunctions/checkF.m (97%) rename {src/ext => ext}/VBA/subfunctions/check_constrasts.m (96%) rename {src/ext => ext}/VBA/subfunctions/check_struct.m (95%) rename {src/ext => ext}/VBA/subfunctions/compHRFs.m (96%) rename {src/ext => ext}/VBA/subfunctions/comparePredictions.m (96%) rename {src/ext => ext}/VBA/subfunctions/compare_struct.m (85%) rename {src/ext => ext}/VBA/subfunctions/create2dbf.m (95%) rename {src/ext => ext}/VBA/subfunctions/dMatdvec.m (93%) rename {src/ext => ext}/VBA/subfunctions/dcm2vba.m (96%) rename {src/ext => ext}/VBA/subfunctions/defIndlev.m (97%) rename {src/ext => ext}/VBA/subfunctions/defaultHRFparams.m (93%) rename {src/ext => ext}/VBA/subfunctions/demo_2DChoices.m (96%) rename {src/ext => ext}/VBA/subfunctions/demo_2Dlin.m (95%) rename {src/ext => ext}/VBA/subfunctions/demo_2DneuralField.m (96%) rename {src/ext => ext}/VBA/subfunctions/demo_AR1.m (96%) rename {src/ext => ext}/VBA/subfunctions/demo_AVL_recog.m (96%) rename {src/ext => ext}/VBA/subfunctions/demo_CI.m (96%) rename {src/ext => ext}/VBA/subfunctions/demo_CaBBI_FHN.m (98%) rename {src/ext => ext}/VBA/subfunctions/demo_CaBBI_QGIF.m (98%) rename {src/ext => ext}/VBA/subfunctions/demo_FHN.m (96%) rename {src/ext => ext}/VBA/subfunctions/demo_GLM.m (97%) rename {src/ext => ext}/VBA/subfunctions/demo_HH.m (96%) rename {src/ext => ext}/VBA/subfunctions/demo_HRF.m (96%) rename {src/ext => ext}/VBA/subfunctions/demo_HRF_distributed.m (96%) rename {src/ext => ext}/VBA/subfunctions/demo_HRF_dummy.m (95%) rename {src/ext => ext}/VBA/subfunctions/demo_Henon.m (95%) rename {src/ext => ext}/VBA/subfunctions/demo_HodgkinHuxley.m (96%) rename {src/ext => ext}/VBA/subfunctions/demo_KalmanSmoother.m (96%) rename {src/ext => ext}/VBA/subfunctions/demo_LV2D.m (95%) rename {src/ext => ext}/VBA/subfunctions/demo_Lorenz.m (96%) rename {src/ext => ext}/VBA/subfunctions/demo_MCsampling.m (95%) rename {src/ext => ext}/VBA/subfunctions/demo_MFX.m (96%) rename {src/ext => ext}/VBA/subfunctions/demo_Oscillatory.m (96%) rename {src/ext => ext}/VBA/subfunctions/demo_PSP.m (93%) rename {src/ext => ext}/VBA/subfunctions/demo_Qlearning.m (97%) rename {src/ext => ext}/VBA/subfunctions/demo_RFX.m (96%) rename {src/ext => ext}/VBA/subfunctions/demo_Rossler.m (95%) rename {src/ext => ext}/VBA/subfunctions/demo_SHC.m (95%) rename {src/ext => ext}/VBA/subfunctions/demo_VBfree.m (96%) rename {src/ext => ext}/VBA/subfunctions/demo_VanDerPol.m (95%) rename {src/ext => ext}/VBA/subfunctions/demo_asymRW.m (96%) rename {src/ext => ext}/VBA/subfunctions/demo_behaviouralDCM.m (95%) rename {src/ext => ext}/VBA/subfunctions/demo_bin.m (96%) rename {src/ext => ext}/VBA/subfunctions/demo_binomial.m (95%) rename {src/ext => ext}/VBA/subfunctions/demo_binomial_AdaptDesign.m (96%) rename {src/ext => ext}/VBA/subfunctions/demo_binomial_adapt.m (96%) rename {src/ext => ext}/VBA/subfunctions/demo_bmc4glm.m (96%) rename {src/ext => ext}/VBA/subfunctions/demo_classification.m (95%) rename {src/ext => ext}/VBA/subfunctions/demo_covComp.m (95%) rename {src/ext => ext}/VBA/subfunctions/demo_dcm4fmri.m (96%) rename {src/ext => ext}/VBA/subfunctions/demo_dcm4fmri_distributed.m (96%) rename {src/ext => ext}/VBA/subfunctions/demo_dcm_1region.m (96%) rename {src/ext => ext}/VBA/subfunctions/demo_dcm_motorPremotor.m (96%) rename {src/ext => ext}/VBA/subfunctions/demo_dcmonline.m (96%) rename {src/ext => ext}/VBA/subfunctions/demo_delays.m (96%) rename {src/ext => ext}/VBA/subfunctions/demo_discounting.m (96%) rename {src/ext => ext}/VBA/subfunctions/demo_doubleWell.m (95%) rename {src/ext => ext}/VBA/subfunctions/demo_dummyUNL.m (96%) rename {src/ext => ext}/VBA/subfunctions/demo_dynLearningRate.m (96%) rename {src/ext => ext}/VBA/subfunctions/demo_dynsys.m (96%) rename {src/ext => ext}/VBA/subfunctions/demo_fitzhugh.m (96%) rename {src/ext => ext}/VBA/subfunctions/demo_gaussian.m (96%) rename {src/ext => ext}/VBA/subfunctions/demo_getConvKernel.m (96%) rename {src/ext => ext}/VBA/subfunctions/demo_groupbtw.m (96%) rename {src/ext => ext}/VBA/subfunctions/demo_imageRegistration.m (92%) rename {src/ext => ext}/VBA/subfunctions/demo_interaction.m (96%) rename {src/ext => ext}/VBA/subfunctions/demo_irregular.m (91%) rename {src/ext => ext}/VBA/subfunctions/demo_lin2D.m (94%) rename {src/ext => ext}/VBA/subfunctions/demo_linear.m (95%) rename {src/ext => ext}/VBA/subfunctions/demo_logNormal.m (92%) rename {src/ext => ext}/VBA/subfunctions/demo_logistic.m (89%) rename {src/ext => ext}/VBA/subfunctions/demo_micro2macro.m (96%) rename {src/ext => ext}/VBA/subfunctions/demo_multisession.m (96%) rename {src/ext => ext}/VBA/subfunctions/demo_multisource.m (97%) rename {src/ext => ext}/VBA/subfunctions/demo_negfeedback.m (96%) rename {src/ext => ext}/VBA/subfunctions/demo_nullSpace.m (95%) rename {src/ext => ext}/VBA/subfunctions/demo_prodsig.m (95%) rename {src/ext => ext}/VBA/subfunctions/demo_recur.m (95%) rename {src/ext => ext}/VBA/subfunctions/demo_redundancy.m (96%) rename {src/ext => ext}/VBA/subfunctions/demo_sparsePriors.m (96%) rename {src/ext => ext}/VBA/subfunctions/demo_spm_hrf.m (95%) rename {src/ext => ext}/VBA/subfunctions/demo_stability_HRF.m (96%) rename {src/ext => ext}/VBA/subfunctions/demo_stochasticBinomial.m (96%) rename {src/ext => ext}/VBA/subfunctions/demo_susceptibility.m (96%) rename {src/ext => ext}/VBA/subfunctions/demo_test.m (87%) rename {src/ext => ext}/VBA/subfunctions/demo_trainTest.m (96%) rename {src/ext => ext}/VBA/subfunctions/demo_volatileVB.m (96%) rename {src/ext => ext}/VBA/subfunctions/demo_wsls.m (95%) rename {src/ext => ext}/VBA/subfunctions/displayResults.m (96%) rename {src/ext => ext}/VBA/subfunctions/displaySimulations.m (95%) rename {src/ext => ext}/VBA/subfunctions/dsdv.m (85%) rename {src/ext => ext}/VBA/subfunctions/elvis.m (92%) rename {src/ext => ext}/VBA/subfunctions/evolution0bisND.m (96%) rename {src/ext => ext}/VBA/subfunctions/expBinom.m (95%) rename {src/ext => ext}/VBA/subfunctions/extend_dcm.m (94%) rename {src/ext => ext}/VBA/subfunctions/extractFIR.m (96%) rename {src/ext => ext}/VBA/subfunctions/extractKernels.m (97%) rename {src/ext => ext}/VBA/subfunctions/f_2DneuralField.m (94%) rename {src/ext => ext}/VBA/subfunctions/f_2d.m (95%) rename {src/ext => ext}/VBA/subfunctions/f_2dwu.m (73%) rename {src/ext => ext}/VBA/subfunctions/f_AR.m (88%) rename {src/ext => ext}/VBA/subfunctions/f_ARn.m (87%) rename {src/ext => ext}/VBA/subfunctions/f_ARplus.m (83%) rename {src/ext => ext}/VBA/subfunctions/f_AVL.m (97%) rename {src/ext => ext}/VBA/subfunctions/f_CaBBI_FHN.m (97%) rename {src/ext => ext}/VBA/subfunctions/f_CaBBI_QGIF.m (97%) rename {src/ext => ext}/VBA/subfunctions/f_DCMwHRF.m (96%) rename {src/ext => ext}/VBA/subfunctions/f_DCMwHRFext.m (95%) rename {src/ext => ext}/VBA/subfunctions/f_FitzHughNagumo.m (96%) rename {src/ext => ext}/VBA/subfunctions/f_FitzHughNagumo_calcium.m (91%) rename {src/ext => ext}/VBA/subfunctions/f_HH.m (96%) rename {src/ext => ext}/VBA/subfunctions/f_HRF.m (96%) rename {src/ext => ext}/VBA/subfunctions/f_HRF2.m (96%) rename {src/ext => ext}/VBA/subfunctions/f_HRF3.m (96%) rename {src/ext => ext}/VBA/subfunctions/f_Henon.m (90%) rename {src/ext => ext}/VBA/subfunctions/f_L1.m (81%) rename {src/ext => ext}/VBA/subfunctions/f_LV2D.m (95%) rename {src/ext => ext}/VBA/subfunctions/f_Lorenz.m (93%) rename {src/ext => ext}/VBA/subfunctions/f_LotkaVolterra.m (95%) rename {src/ext => ext}/VBA/subfunctions/f_OpLearn.m (96%) rename {src/ext => ext}/VBA/subfunctions/f_PSP.m (95%) rename {src/ext => ext}/VBA/subfunctions/f_Qlearn.m (92%) rename {src/ext => ext}/VBA/subfunctions/f_Qlearn2.m (96%) rename {src/ext => ext}/VBA/subfunctions/f_Qlearn_dynLR.m (95%) rename {src/ext => ext}/VBA/subfunctions/f_Qlearn_gammaLR.m (97%) rename {src/ext => ext}/VBA/subfunctions/f_Rossler.m (78%) rename {src/ext => ext}/VBA/subfunctions/f_SHC.m (95%) rename {src/ext => ext}/VBA/subfunctions/f_VBfree.m (90%) rename {src/ext => ext}/VBA/subfunctions/f_VBvolatile0.m (96%) create mode 100644 ext/VBA/subfunctions/f_alpha.m rename {src/ext => ext}/VBA/subfunctions/f_dbw.m (89%) rename {src/ext => ext}/VBA/subfunctions/f_dcm4fmri.m (95%) rename {src/ext => ext}/VBA/subfunctions/f_dcm4fmri0.m (95%) rename {src/ext => ext}/VBA/subfunctions/f_dcm_extension.m (95%) rename {src/ext => ext}/VBA/subfunctions/f_dcm_withU.m (91%) rename {src/ext => ext}/VBA/subfunctions/f_doubleWell.m (96%) rename {src/ext => ext}/VBA/subfunctions/f_embed0.m (93%) rename {src/ext => ext}/VBA/subfunctions/f_embedAR.m (96%) rename {src/ext => ext}/VBA/subfunctions/f_embed_old.m (94%) rename {src/ext => ext}/VBA/subfunctions/f_fullDCM4fmri.m (97%) rename {src/ext => ext}/VBA/subfunctions/f_gen.m (95%) rename {src/ext => ext}/VBA/subfunctions/f_lin1D.m (95%) rename {src/ext => ext}/VBA/subfunctions/f_lin2D.m (85%) rename {src/ext => ext}/VBA/subfunctions/f_replicator.m (93%) rename {src/ext => ext}/VBA/subfunctions/f_rwl.m (92%) rename {src/ext => ext}/VBA/subfunctions/f_rwl2.m (97%) rename {src/ext => ext}/VBA/subfunctions/f_try.m (83%) rename {src/ext => ext}/VBA/subfunctions/f_vanDerPol.m (94%) rename {src/ext => ext}/VBA/subfunctions/f_vgo.m (58%) rename {src/ext => ext}/VBA/subfunctions/f_wsls.m (96%) rename {src/ext/VBA/stats&plots => ext/VBA/subfunctions}/findCI.m (97%) rename {src/ext => ext}/VBA/subfunctions/g_2AFC_basis.m (97%) rename {src/ext => ext}/VBA/subfunctions/g_AVL.m (97%) rename {src/ext => ext}/VBA/subfunctions/g_CaBBI.m (97%) rename {src/ext => ext}/VBA/subfunctions/g_DCMwHRFext.m (95%) rename {src/ext => ext}/VBA/subfunctions/g_DG2.m (93%) rename {src/ext => ext}/VBA/subfunctions/g_DoubleGamma.m (94%) rename {src/ext => ext}/VBA/subfunctions/g_ERP.m (95%) rename {src/ext => ext}/VBA/subfunctions/g_ERP_reduced.m (94%) rename {src/ext => ext}/VBA/subfunctions/g_ExpUtil.m (90%) rename {src/ext => ext}/VBA/subfunctions/g_Fourier.m (95%) rename {src/ext => ext}/VBA/subfunctions/g_GLM.m (94%) rename {src/ext => ext}/VBA/subfunctions/g_GLMsparse.m (98%) rename {src/ext => ext}/VBA/subfunctions/g_GammaDensity.m (96%) rename {src/ext => ext}/VBA/subfunctions/g_Gaussian.m (95%) rename {src/ext => ext}/VBA/subfunctions/g_HRF3.m (96%) rename {src/ext => ext}/VBA/subfunctions/g_HRF_distributed.m (96%) rename {src/ext => ext}/VBA/subfunctions/g_Id.m (93%) rename {src/ext => ext}/VBA/subfunctions/g_Id_phi.m (95%) rename {src/ext => ext}/VBA/subfunctions/g_NI.m (93%) rename {src/ext => ext}/VBA/subfunctions/g_RFX.m (76%) rename {src/ext => ext}/VBA/subfunctions/g_Udummy.m (79%) rename {src/ext => ext}/VBA/subfunctions/g_VBvolatile0.m (93%) rename {src/ext => ext}/VBA/subfunctions/g_classif.m (95%) rename {src/ext => ext}/VBA/subfunctions/g_convSig_approx.m (94%) rename {src/ext => ext}/VBA/subfunctions/g_conv_approx.m (95%) rename {src/ext => ext}/VBA/subfunctions/g_demo_extended.m (95%) rename {src/ext => ext}/VBA/subfunctions/g_demo_susceptibility.m (94%) rename {src/ext => ext}/VBA/subfunctions/g_discounting.m (96%) rename {src/ext => ext}/VBA/subfunctions/g_dummy.m (96%) rename {src/ext => ext}/VBA/subfunctions/g_embedAR.m (94%) create mode 100644 ext/VBA/subfunctions/g_exp.m rename {src/ext => ext}/VBA/subfunctions/g_exp2d.m (89%) rename {src/ext => ext}/VBA/subfunctions/g_fullDCM4fmri.m (96%) rename {src/ext => ext}/VBA/subfunctions/g_goNogo.m (90%) rename {src/ext => ext}/VBA/subfunctions/g_ip.m (93%) rename {src/ext => ext}/VBA/subfunctions/g_logistic.m (95%) rename {src/ext => ext}/VBA/subfunctions/g_matmap.m (96%) rename {src/ext => ext}/VBA/subfunctions/g_mixU.m (92%) rename {src/ext => ext}/VBA/subfunctions/g_nl0.m (91%) rename {src/ext => ext}/VBA/subfunctions/g_odds.m (94%) rename {src/ext => ext}/VBA/subfunctions/g_odds2.m (74%) create mode 100644 ext/VBA/subfunctions/g_probit.m rename {src/ext => ext}/VBA/subfunctions/g_rbf.m (94%) rename {src/ext => ext}/VBA/subfunctions/g_rigid2D.m (96%) rename {src/ext => ext}/VBA/subfunctions/g_sig_u.m (97%) rename {src/ext => ext}/VBA/subfunctions/g_sigm.m (95%) rename {src/ext => ext}/VBA/subfunctions/g_sigm_binomial.m (95%) rename {src/ext => ext}/VBA/subfunctions/g_sigmoid.m (94%) rename {src/ext => ext}/VBA/subfunctions/g_softmax.m (95%) rename {src/ext => ext}/VBA/subfunctions/g_softmax4decoding.m (94%) rename {src/ext => ext}/VBA/subfunctions/g_sqrtSig.m (94%) rename {src/ext => ext}/VBA/subfunctions/g_u2c.m (91%) rename {src/ext => ext}/VBA/subfunctions/g_u2p.m (92%) rename {src/ext => ext}/VBA/subfunctions/g_vgo.m (61%) rename {src/ext => ext}/VBA/subfunctions/getFamily.m (94%) rename {src/ext => ext}/VBA/subfunctions/getGitInfo.m (96%) rename {src/ext => ext}/VBA/subfunctions/getOptions4dcm.m (97%) rename {src/ext => ext}/VBA/subfunctions/getPosteriorfromOTO.m (97%) rename {src/ext => ext}/VBA/subfunctions/getPriors.m (96%) rename {src/ext => ext}/VBA/subfunctions/get_ARcov.m (82%) rename {src/ext => ext}/VBA/subfunctions/get_HRFparams.m (96%) rename {src/ext => ext}/VBA/subfunctions/get_U_basis.m (96%) rename {src/ext => ext}/VBA/subfunctions/get_sigmoidMoments.m (95%) rename {src/ext => ext}/VBA/subfunctions/gridL_binomial.m (96%) rename {src/ext => ext}/VBA/subfunctions/h_Id.m (67%) rename {src/ext => ext}/VBA/subfunctions/h_goNogo.m (95%) rename {src/ext => ext}/VBA/subfunctions/h_randOutcome.m (82%) rename {src/ext => ext}/VBA/subfunctions/h_truefalse.m (94%) rename {src/ext => ext}/VBA/subfunctions/h_whichItem.m (66%) rename {src/ext => ext}/VBA/subfunctions/invsigmoid.m (94%) rename {src/ext => ext}/VBA/subfunctions/isHrfStable.m (94%) rename {src/ext => ext}/VBA/subfunctions/iswithin.m (95%) rename {src/ext => ext}/VBA/subfunctions/kernel_sinexp.m (97%) rename {src/ext => ext}/VBA/subfunctions/logExp.m (90%) rename {src/ext => ext}/VBA/subfunctions/medianfilter0.m (96%) rename {src/ext => ext}/VBA/subfunctions/multi2num.m (92%) rename {src/ext => ext}/VBA/subfunctions/multinomial_accuracy.m (95%) rename {src/ext => ext}/VBA/subfunctions/nanfft.m (97%) rename {src/ext/VBA/stats&plots => ext/VBA/subfunctions}/nanzscore.m (97%) rename {src/ext => ext}/VBA/subfunctions/num2multi.m (93%) rename {src/ext => ext}/VBA/subfunctions/optimCost.m (96%) rename {src/ext => ext}/VBA/subfunctions/parseargs.m (97%) rename {src/ext => ext}/VBA/subfunctions/prepare_dcm.m (95%) rename {src/ext => ext}/VBA/subfunctions/prepare_fullDCM.m (95%) rename {src/ext => ext}/VBA/subfunctions/priorPrettifyer.m (94%) rename {src/ext => ext}/VBA/subfunctions/priorUglyfier.m (93%) rename {src/ext => ext}/VBA/subfunctions/script_test_rec.m (95%) rename {src/ext => ext}/VBA/subfunctions/sgm.m (94%) rename {src/ext => ext}/VBA/subfunctions/show_potential.m (94%) rename {src/ext => ext}/VBA/subfunctions/sig.m (71%) rename {src/ext => ext}/VBA/subfunctions/sigm.m (96%) rename {src/ext => ext}/VBA/subfunctions/sigmoid.m (93%) rename {src/ext => ext}/VBA/subfunctions/sizeXrec.m (96%) rename {src/ext => ext}/VBA/subfunctions/softmax.m (57%) rename {src/ext => ext}/VBA/subfunctions/sparseTransform.m (96%) rename {src/ext => ext}/VBA/subfunctions/spear.m (94%) rename {src/ext => ext}/VBA/subfunctions/spm_sdcm_estimate.m (96%) rename {src/ext => ext}/VBA/subfunctions/spm_sdcm_estimate2.m (95%) rename {src/ext => ext}/VBA/subfunctions/u_Fourier.m (93%) rename {src/ext => ext}/VBA/subfunctions/u_FourierComplete.m (94%) rename {src/ext => ext}/VBA/subfunctions/u_GaussianBumps.m (96%) rename {src/ext => ext}/VBA/subfunctions/u_RBF.m (93%) rename {src/ext => ext}/VBA/subfunctions/unwrapVBvolatileOTO.m (97%) rename {src/ext => ext}/VBA/subfunctions/util.m (84%) rename {src/ext => ext}/VBA/subfunctions/v_discounting.m (95%) rename {src/ext => ext}/VBA/subfunctions/vba2dcm.m (96%) rename {src/ext => ext}/VBA/vec.m (92%) rename {src/ext => ext}/amri_eegfmri/CHANGES_MADE.txt (100%) rename {src/ext => ext}/amri_eegfmri/LICENSE.txt (100%) rename {src/ext => ext}/amri_eegfmri/README_1.txt (100%) rename {src/ext => ext}/amri_eegfmri/README_2.txt (100%) rename {src/ext => ext}/amri_eegfmri/amri_eeg_rpeak.m (100%) rename {src/ext => ext}/amri_eegfmri/amri_sig_corr.m (100%) rename {src/ext => ext}/amri_eegfmri/amri_sig_filtfft.m (100%) rename {src/ext => ext}/amri_eegfmri/amri_sig_findpeaks.m (100%) rename {src/ext => ext}/amri_eegfmri/amri_sig_xcorr.m (100%) rename {src/ext => ext}/amri_eegfmri/amri_stat_outlier.m (100%) rename {src/ext => ext}/bsearch/bsearch.m (95%) rename {src/ext => ext}/bsearch/license.txt (100%) rename {src/ext/matlabbatch/@cfg_choice => ext/matlabbatch/@cfg_branch}/all_leafs.m (96%) rename {src/ext => ext}/matlabbatch/@cfg_branch/all_set.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_branch/all_set_item.m (96%) rename {src/ext => ext}/matlabbatch/@cfg_branch/cfg2jobsubs.m (97%) rename {src/ext/matlabbatch/@cfg_const => ext/matlabbatch/@cfg_branch}/cfg2struct.m (96%) rename {src/ext => ext}/matlabbatch/@cfg_branch/cfg_branch.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_branch/checksubs_job.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_branch/clearval.m (96%) rename {src/ext => ext}/matlabbatch/@cfg_branch/expand.m (96%) rename {src/ext => ext}/matlabbatch/@cfg_branch/fillvals.m (97%) rename {src/ext/matlabbatch/@cfg_choice => ext/matlabbatch/@cfg_branch}/harvest.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_branch/initialise.m (97%) rename {src/ext/matlabbatch/@cfg_choice => ext/matlabbatch/@cfg_branch}/list.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_branch/private/mysubs_fields.m (94%) rename {src/ext => ext}/matlabbatch/@cfg_branch/setval.m (92%) rename {src/ext => ext}/matlabbatch/@cfg_branch/showdetail.m (96%) rename {src/ext/matlabbatch/@cfg_repeat => ext/matlabbatch/@cfg_branch}/showdoc.m (96%) rename {src/ext => ext}/matlabbatch/@cfg_branch/showmydoc.m (93%) rename {src/ext => ext}/matlabbatch/@cfg_branch/subs_fields.m (94%) rename {src/ext => ext}/matlabbatch/@cfg_branch/subsasgn.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_branch/subsasgn_check.m (96%) rename {src/ext/matlabbatch/@cfg_choice => ext/matlabbatch/@cfg_branch}/subsasgn_job.m (97%) rename {src/ext/matlabbatch/@cfg_const => ext/matlabbatch/@cfg_branch}/subsref.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_branch/subsref_job.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_branch/tag2cfgsubs.m (97%) rename {src/ext/matlabbatch/@cfg_mchoice => ext/matlabbatch/@cfg_branch}/tagnames.m (96%) rename {src/ext => ext}/matlabbatch/@cfg_branch/treepart.m (96%) rename {src/ext/matlabbatch/@cfg_choice => ext/matlabbatch/@cfg_branch}/update_deps.m (91%) rename {src/ext/matlabbatch/@cfg_mchoice => ext/matlabbatch/@cfg_branch}/val2def.m (97%) rename {src/ext/matlabbatch/@cfg_repeat => ext/matlabbatch/@cfg_choice}/all_leafs.m (96%) rename {src/ext => ext}/matlabbatch/@cfg_choice/all_set.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_choice/all_set_item.m (96%) rename {src/ext => ext}/matlabbatch/@cfg_choice/cfg2jobsubs.m (97%) rename {src/ext/matlabbatch/@cfg_mchoice => ext/matlabbatch/@cfg_choice}/cfg2struct.m (96%) rename {src/ext => ext}/matlabbatch/@cfg_choice/cfg_choice.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_choice/checksubs_job.m (97%) rename {src/ext/matlabbatch/@cfg_mchoice => ext/matlabbatch/@cfg_choice}/clearval.m (96%) rename {src/ext => ext}/matlabbatch/@cfg_choice/expand.m (96%) rename {src/ext/matlabbatch/@cfg_mchoice => ext/matlabbatch/@cfg_choice}/fieldnames.m (92%) rename {src/ext/matlabbatch/@cfg_mchoice => ext/matlabbatch/@cfg_choice}/fillvals.m (97%) rename {src/ext/matlabbatch/@cfg_mchoice => ext/matlabbatch/@cfg_choice}/gencode_item.m (97%) rename {src/ext/matlabbatch/@cfg_mchoice => ext/matlabbatch/@cfg_choice}/harvest.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_choice/initialise.m (97%) rename {src/ext/matlabbatch/@cfg_repeat => ext/matlabbatch/@cfg_choice}/list.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_choice/private/mysubs_fields.m (96%) rename {src/ext => ext}/matlabbatch/@cfg_choice/setval.m (96%) rename {src/ext => ext}/matlabbatch/@cfg_choice/showdetail.m (96%) rename {src/ext/matlabbatch/@cfg_branch => ext/matlabbatch/@cfg_choice}/showdoc.m (96%) rename {src/ext => ext}/matlabbatch/@cfg_choice/showmydoc.m (93%) rename {src/ext/matlabbatch/@cfg_const => ext/matlabbatch/@cfg_choice}/subs_fields.m (94%) rename {src/ext => ext}/matlabbatch/@cfg_choice/subsasgn.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_choice/subsasgn_check.m (97%) rename {src/ext/matlabbatch/@cfg_mchoice => ext/matlabbatch/@cfg_choice}/subsasgn_job.m (97%) rename {src/ext/matlabbatch/@cfg_entry => ext/matlabbatch/@cfg_choice}/subsref.m (97%) rename {src/ext/matlabbatch/@cfg_mchoice => ext/matlabbatch/@cfg_choice}/subsref_job.m (97%) rename {src/ext/matlabbatch/@cfg_repeat => ext/matlabbatch/@cfg_choice}/tag2cfgsubs.m (97%) rename {src/ext/matlabbatch/@cfg_branch => ext/matlabbatch/@cfg_choice}/tagnames.m (96%) rename {src/ext => ext}/matlabbatch/@cfg_choice/treepart.m (96%) rename {src/ext/matlabbatch/@cfg_mchoice => ext/matlabbatch/@cfg_choice}/update_deps.m (91%) rename {src/ext/matlabbatch/@cfg_branch => ext/matlabbatch/@cfg_choice}/val2def.m (97%) rename {src/ext/matlabbatch/@cfg_files => ext/matlabbatch/@cfg_const}/cfg2struct.m (96%) rename {src/ext => ext}/matlabbatch/@cfg_const/cfg_const.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_const/private/mysubs_fields.m (94%) rename {src/ext => ext}/matlabbatch/@cfg_const/showdetail.m (96%) rename {src/ext => ext}/matlabbatch/@cfg_const/showdoc.m (96%) rename {src/ext/matlabbatch/@cfg_entry => ext/matlabbatch/@cfg_const}/subs_fields.m (94%) rename {src/ext => ext}/matlabbatch/@cfg_const/subsasgn.m (97%) rename {src/ext/matlabbatch/@cfg_choice => ext/matlabbatch/@cfg_const}/subsref.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_dep/add_to_source.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_dep/cfg_dep.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_dep/del_in_source.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_dep/del_in_target.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_dep/dep_add.m (96%) rename {src/ext => ext}/matlabbatch/@cfg_dep/disp.m (95%) rename {src/ext => ext}/matlabbatch/@cfg_dep/display.m (95%) rename {src/ext => ext}/matlabbatch/@cfg_dep/gencode.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_dep/isequalsource.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_dep/isequaltarget.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_dep/private/mysubs_fields.m (92%) rename {src/ext => ext}/matlabbatch/@cfg_dep/subs_fields.m (94%) rename {src/ext => ext}/matlabbatch/@cfg_dep/subsasgn.m (96%) rename {src/ext => ext}/matlabbatch/@cfg_dep/subsref.m (96%) rename {src/ext => ext}/matlabbatch/@cfg_dep/update_deps.m (96%) rename {src/ext => ext}/matlabbatch/@cfg_entry/cfg2struct.m (96%) rename {src/ext => ext}/matlabbatch/@cfg_entry/cfg_entry.m (97%) rename {src/ext/matlabbatch/@cfg_choice => ext/matlabbatch/@cfg_entry}/fieldnames.m (92%) rename {src/ext => ext}/matlabbatch/@cfg_entry/gencode_item.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_entry/match.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_entry/private/mysubs_fields.m (93%) rename {src/ext => ext}/matlabbatch/@cfg_entry/showdetail.m (96%) rename {src/ext => ext}/matlabbatch/@cfg_entry/showdoc.m (97%) rename {src/ext/matlabbatch/@cfg_choice => ext/matlabbatch/@cfg_entry}/subs_fields.m (94%) rename {src/ext => ext}/matlabbatch/@cfg_entry/subsasgn.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_entry/subsasgn_check.m (97%) rename {src/ext/matlabbatch/@cfg_branch => ext/matlabbatch/@cfg_entry}/subsref.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_exbranch/cfg2struct.m (96%) rename {src/ext => ext}/matlabbatch/@cfg_exbranch/cfg_exbranch.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_exbranch/disp.m (95%) rename {src/ext => ext}/matlabbatch/@cfg_exbranch/display.m (95%) rename {src/ext => ext}/matlabbatch/@cfg_exbranch/fieldnames.m (92%) rename {src/ext => ext}/matlabbatch/@cfg_exbranch/gencode_item.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_exbranch/harvest.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_exbranch/private/mysubs_fields.m (95%) rename {src/ext => ext}/matlabbatch/@cfg_exbranch/showdetail.m (97%) create mode 100644 ext/matlabbatch/@cfg_exbranch/subs_fields.m create mode 100644 ext/matlabbatch/@cfg_exbranch/subsasgn.m rename {src/ext => ext}/matlabbatch/@cfg_exbranch/subsasgn_check.m (97%) create mode 100644 ext/matlabbatch/@cfg_exbranch/subsref.m rename {src/ext => ext}/matlabbatch/@cfg_exbranch/update_deps.m (93%) rename {src/ext/matlabbatch/@cfg_branch => ext/matlabbatch/@cfg_files}/cfg2struct.m (96%) rename {src/ext => ext}/matlabbatch/@cfg_files/cfg_files.m (97%) rename {src/ext/matlabbatch/@cfg_entry => ext/matlabbatch/@cfg_files}/fieldnames.m (92%) rename {src/ext => ext}/matlabbatch/@cfg_files/gencode_item.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_files/match.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_files/private/mysubs_fields.m (91%) rename {src/ext => ext}/matlabbatch/@cfg_files/showdetail.m (90%) create mode 100644 ext/matlabbatch/@cfg_files/subs_fields.m create mode 100644 ext/matlabbatch/@cfg_files/subsasgn.m rename {src/ext => ext}/matlabbatch/@cfg_files/subsasgn_check.m (97%) create mode 100644 ext/matlabbatch/@cfg_files/subsref.m rename {src/ext => ext}/matlabbatch/@cfg_intree/cfg_intree.m (89%) rename {src/ext/matlabbatch/@cfg_leaf => ext/matlabbatch/@cfg_intree}/disp.m (91%) rename {src/ext/matlabbatch/@cfg_leaf => ext/matlabbatch/@cfg_intree}/display.m (92%) rename {src/ext => ext}/matlabbatch/@cfg_inv_out/cfg_inv_out.m (93%) rename {src/ext => ext}/matlabbatch/@cfg_item/all_leafs.m (96%) rename {src/ext => ext}/matlabbatch/@cfg_item/all_set.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_item/all_set_item.m (96%) rename {src/ext => ext}/matlabbatch/@cfg_item/cat.m (96%) rename {src/ext => ext}/matlabbatch/@cfg_item/cfg2jobsubs.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_item/cfg2struct.m (96%) rename {src/ext => ext}/matlabbatch/@cfg_item/cfg_item.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_item/clearval.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_item/disp.m (96%) rename {src/ext => ext}/matlabbatch/@cfg_item/display.m (95%) rename {src/ext => ext}/matlabbatch/@cfg_item/docheck.m (96%) rename {src/ext => ext}/matlabbatch/@cfg_item/expand.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_item/fieldnames.m (93%) rename {src/ext => ext}/matlabbatch/@cfg_item/fillvals.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_item/gencode.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_item/gencode_item.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_item/gettag.m (96%) rename {src/ext => ext}/matlabbatch/@cfg_item/harvest.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_item/horzcat.m (91%) rename {src/ext => ext}/matlabbatch/@cfg_item/initialise.m (96%) rename {src/ext => ext}/matlabbatch/@cfg_item/list.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_item/match.m (96%) rename {src/ext => ext}/matlabbatch/@cfg_item/private/mysubs_fields.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_item/resolve_deps.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_item/setval.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_item/showdetail.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_item/showdoc.m (96%) create mode 100644 ext/matlabbatch/@cfg_item/subs_fields.m create mode 100644 ext/matlabbatch/@cfg_item/subsasgn.m rename {src/ext => ext}/matlabbatch/@cfg_item/subsasgn_check.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_item/subsasgn_checkstr.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_item/subsasgn_job.m (97%) create mode 100644 ext/matlabbatch/@cfg_item/subsref.m rename {src/ext => ext}/matlabbatch/@cfg_item/subsref_job.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_item/tag2cfgsubs.m (95%) rename {src/ext => ext}/matlabbatch/@cfg_item/update_deps.m (96%) rename {src/ext => ext}/matlabbatch/@cfg_item/val2def.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_item/vertcat.m (91%) rename {src/ext => ext}/matlabbatch/@cfg_leaf/cfg_leaf.m (89%) rename {src/ext/matlabbatch/@cfg_intree => ext/matlabbatch/@cfg_leaf}/disp.m (91%) rename {src/ext/matlabbatch/@cfg_intree => ext/matlabbatch/@cfg_leaf}/display.m (92%) rename {src/ext => ext}/matlabbatch/@cfg_mchoice/all_leafs.m (96%) rename {src/ext/matlabbatch/@cfg_repeat => ext/matlabbatch/@cfg_mchoice}/all_set.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_mchoice/all_set_item.m (96%) rename {src/ext => ext}/matlabbatch/@cfg_mchoice/cfg2jobsubs.m (97%) rename {src/ext/matlabbatch/@cfg_repeat => ext/matlabbatch/@cfg_mchoice}/cfg2struct.m (96%) rename {src/ext => ext}/matlabbatch/@cfg_mchoice/cfg_mchoice.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_mchoice/checksubs_job.m (97%) rename {src/ext/matlabbatch/@cfg_choice => ext/matlabbatch/@cfg_mchoice}/clearval.m (96%) rename {src/ext/matlabbatch/@cfg_repeat => ext/matlabbatch/@cfg_mchoice}/expand.m (96%) rename {src/ext/matlabbatch/@cfg_files => ext/matlabbatch/@cfg_mchoice}/fieldnames.m (92%) rename {src/ext/matlabbatch/@cfg_choice => ext/matlabbatch/@cfg_mchoice}/fillvals.m (97%) rename {src/ext/matlabbatch/@cfg_choice => ext/matlabbatch/@cfg_mchoice}/gencode_item.m (97%) rename {src/ext/matlabbatch/@cfg_branch => ext/matlabbatch/@cfg_mchoice}/harvest.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_mchoice/initialise.m (97%) rename {src/ext/matlabbatch/@cfg_branch => ext/matlabbatch/@cfg_mchoice}/list.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_mchoice/private/mysubs_fields.m (96%) rename {src/ext => ext}/matlabbatch/@cfg_mchoice/setval.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_mchoice/showdetail.m (96%) rename {src/ext => ext}/matlabbatch/@cfg_mchoice/showdoc.m (96%) rename {src/ext => ext}/matlabbatch/@cfg_mchoice/showmydoc.m (93%) create mode 100644 ext/matlabbatch/@cfg_mchoice/subs_fields.m create mode 100644 ext/matlabbatch/@cfg_mchoice/subsasgn.m rename {src/ext => ext}/matlabbatch/@cfg_mchoice/subsasgn_check.m (97%) rename {src/ext/matlabbatch/@cfg_branch => ext/matlabbatch/@cfg_mchoice}/subsasgn_job.m (97%) create mode 100644 ext/matlabbatch/@cfg_mchoice/subsref.m rename {src/ext/matlabbatch/@cfg_choice => ext/matlabbatch/@cfg_mchoice}/subsref_job.m (97%) rename {src/ext/matlabbatch/@cfg_choice => ext/matlabbatch/@cfg_mchoice}/tag2cfgsubs.m (97%) rename {src/ext/matlabbatch/@cfg_choice => ext/matlabbatch/@cfg_mchoice}/tagnames.m (96%) rename {src/ext => ext}/matlabbatch/@cfg_mchoice/treepart.m (96%) rename {src/ext/matlabbatch/@cfg_branch => ext/matlabbatch/@cfg_mchoice}/update_deps.m (91%) rename {src/ext/matlabbatch/@cfg_choice => ext/matlabbatch/@cfg_mchoice}/val2def.m (97%) create mode 100644 ext/matlabbatch/@cfg_menu/cfg2struct.m rename {src/ext => ext}/matlabbatch/@cfg_menu/cfg_menu.m (97%) create mode 100644 ext/matlabbatch/@cfg_menu/fieldnames.m rename {src/ext => ext}/matlabbatch/@cfg_menu/gencode_item.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_menu/private/mysubs_fields.m (94%) rename {src/ext => ext}/matlabbatch/@cfg_menu/setval.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_menu/showdetail.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_menu/showdoc.m (96%) create mode 100644 ext/matlabbatch/@cfg_menu/subs_fields.m create mode 100644 ext/matlabbatch/@cfg_menu/subsasgn.m rename {src/ext => ext}/matlabbatch/@cfg_menu/subsasgn_check.m (97%) create mode 100644 ext/matlabbatch/@cfg_menu/subsref.m rename {src/ext/matlabbatch/@cfg_branch => ext/matlabbatch/@cfg_repeat}/all_leafs.m (96%) rename {src/ext/matlabbatch/@cfg_mchoice => ext/matlabbatch/@cfg_repeat}/all_set.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_repeat/all_set_item.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_repeat/cfg2jobsubs.m (97%) rename {src/ext/matlabbatch/@cfg_choice => ext/matlabbatch/@cfg_repeat}/cfg2struct.m (96%) rename {src/ext => ext}/matlabbatch/@cfg_repeat/cfg_repeat.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_repeat/checksubs_job.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_repeat/clearval.m (96%) rename {src/ext/matlabbatch/@cfg_mchoice => ext/matlabbatch/@cfg_repeat}/expand.m (96%) create mode 100644 ext/matlabbatch/@cfg_repeat/fieldnames.m rename {src/ext => ext}/matlabbatch/@cfg_repeat/fillvals.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_repeat/gencode_item.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_repeat/gettag.m (96%) rename {src/ext => ext}/matlabbatch/@cfg_repeat/harvest.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_repeat/initialise.m (97%) rename {src/ext/matlabbatch/@cfg_mchoice => ext/matlabbatch/@cfg_repeat}/list.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_repeat/private/mysubs_fields.m (92%) rename {src/ext => ext}/matlabbatch/@cfg_repeat/setval.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_repeat/showdetail.m (96%) rename {src/ext/matlabbatch/@cfg_choice => ext/matlabbatch/@cfg_repeat}/showdoc.m (96%) rename {src/ext => ext}/matlabbatch/@cfg_repeat/showmydoc.m (93%) create mode 100644 ext/matlabbatch/@cfg_repeat/subs_fields.m create mode 100644 ext/matlabbatch/@cfg_repeat/subsasgn.m rename {src/ext => ext}/matlabbatch/@cfg_repeat/subsasgn_check.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_repeat/subsasgn_job.m (98%) create mode 100644 ext/matlabbatch/@cfg_repeat/subsref.m rename {src/ext => ext}/matlabbatch/@cfg_repeat/subsref_job.m (97%) rename {src/ext/matlabbatch/@cfg_mchoice => ext/matlabbatch/@cfg_repeat}/tag2cfgsubs.m (97%) rename {src/ext => ext}/matlabbatch/@cfg_repeat/tagnames.m (96%) rename {src/ext => ext}/matlabbatch/@cfg_repeat/treepart.m (96%) rename {src/ext => ext}/matlabbatch/@cfg_repeat/update_deps.m (91%) rename {src/ext => ext}/matlabbatch/@cfg_repeat/val2def.m (97%) rename {src/ext => ext}/matlabbatch/bin/cpcode.sh (97%) rename {src/ext => ext}/matlabbatch/bin/resave_cfg_ui.sh (97%) rename {src/ext => ext}/matlabbatch/cfg_basicio/cfg_basicio_rewrite.m (97%) rename {src/ext => ext}/matlabbatch/cfg_basicio/cfg_cfg_basicio.m (97%) rename {src/ext => ext}/matlabbatch/cfg_basicio/cfg_cfg_basicio_def.m (98%) rename {src/ext => ext}/matlabbatch/cfg_basicio/cfg_check_assignin.m (96%) rename {src/ext => ext}/matlabbatch/cfg_basicio/cfg_load_vars.m (97%) rename {src/ext => ext}/matlabbatch/cfg_basicio/cfg_run_assignin.m (97%) rename {src/ext => ext}/matlabbatch/cfg_basicio/cfg_run_call_matlab.m (97%) rename {src/ext => ext}/matlabbatch/cfg_basicio/cfg_run_cd.m (96%) rename {src/ext => ext}/matlabbatch/cfg_basicio/cfg_run_file_filter.m (96%) rename {src/ext => ext}/matlabbatch/cfg_basicio/cfg_run_file_fplist.m (96%) rename {src/ext => ext}/matlabbatch/cfg_basicio/cfg_run_file_move.m (96%) rename {src/ext => ext}/matlabbatch/cfg_basicio/cfg_run_file_split.m (92%) rename {src/ext => ext}/matlabbatch/cfg_basicio/cfg_run_fileparts.m (92%) rename {src/ext => ext}/matlabbatch/cfg_basicio/cfg_run_gunzip_files.m (96%) rename {src/ext => ext}/matlabbatch/cfg_basicio/cfg_run_gzip_files.m (96%) rename {src/ext => ext}/matlabbatch/cfg_basicio/cfg_run_mkdir.m (96%) rename {src/ext => ext}/matlabbatch/cfg_basicio/cfg_run_named_dir.m (96%) rename {src/ext => ext}/matlabbatch/cfg_basicio/cfg_run_named_file.m (96%) rename {src/ext => ext}/matlabbatch/cfg_basicio/cfg_run_named_input.m (96%) rename {src/ext => ext}/matlabbatch/cfg_basicio/cfg_run_runjobs.m (96%) rename {src/ext => ext}/matlabbatch/cfg_basicio/cfg_run_save_vars.m (96%) rename {src/ext => ext}/matlabbatch/cfg_basicio/cfg_run_subsrefvar.m (97%) rename {src/ext => ext}/matlabbatch/cfg_basicio/cfg_vout_file_filter.m (97%) rename {src/ext => ext}/matlabbatch/cfg_basicio/cfg_vout_file_fplist.m (97%) rename {src/ext => ext}/matlabbatch/cfg_basicio/cfg_vout_file_move.m (96%) rename {src/ext => ext}/matlabbatch/cfg_basicio/cfg_vout_file_split.m (97%) rename {src/ext => ext}/matlabbatch/cfg_basicio/cfg_vout_fileparts.m (97%) rename {src/ext => ext}/matlabbatch/cfg_basicio/cfg_vout_gunzip_files.m (97%) rename {src/ext => ext}/matlabbatch/cfg_basicio/cfg_vout_gzip_files.m (97%) rename {src/ext => ext}/matlabbatch/cfg_basicio/cfg_vout_mkdir.m (97%) rename {src/ext => ext}/matlabbatch/cfg_basicio/cfg_vout_named_dir.m (97%) rename {src/ext => ext}/matlabbatch/cfg_basicio/cfg_vout_named_file.m (97%) rename {src/ext => ext}/matlabbatch/cfg_basicio/cfg_vout_named_input.m (88%) rename {src/ext => ext}/matlabbatch/cfg_basicio/cfg_vout_runjobs.m (97%) rename {src/ext => ext}/matlabbatch/cfg_basicio/cfg_vout_save_vars.m (96%) rename {src/ext => ext}/matlabbatch/cfg_basicio/src/01_file_dir_ops/01_dir_ops/batch_basicio_02_cd.m (98%) rename {src/ext => ext}/matlabbatch/cfg_basicio/src/01_file_dir_ops/01_dir_ops/batch_basicio_03_mkdir.m (98%) rename {src/ext => ext}/matlabbatch/cfg_basicio/src/01_file_dir_ops/01_dir_ops/batch_basicio_04_named_dir.m (98%) rename {src/ext => ext}/matlabbatch/cfg_basicio/src/01_file_dir_ops/01_dir_ops/batch_basicio_toplevel.m (98%) rename {src/ext => ext}/matlabbatch/cfg_basicio/src/01_file_dir_ops/02_file_ops/batch_basicio_01_file_move.m (98%) rename {src/ext => ext}/matlabbatch/cfg_basicio/src/01_file_dir_ops/02_file_ops/batch_basicio_02_gzip_files.m (98%) rename {src/ext => ext}/matlabbatch/cfg_basicio/src/01_file_dir_ops/02_file_ops/batch_basicio_03_gunzip_files.m (98%) rename {src/ext => ext}/matlabbatch/cfg_basicio/src/01_file_dir_ops/02_file_ops/batch_basicio_05_named_file.m (98%) rename {src/ext => ext}/matlabbatch/cfg_basicio/src/01_file_dir_ops/02_file_ops/batch_basicio_06_file_fplist.m (98%) rename {src/ext => ext}/matlabbatch/cfg_basicio/src/01_file_dir_ops/02_file_ops/batch_basicio_07_file_filter.m (98%) rename {src/ext => ext}/matlabbatch/cfg_basicio/src/01_file_dir_ops/02_file_ops/batch_basicio_09_file_split.m (98%) rename {src/ext => ext}/matlabbatch/cfg_basicio/src/01_file_dir_ops/02_file_ops/batch_basicio_toplevel.m (98%) rename {src/ext => ext}/matlabbatch/cfg_basicio/src/01_file_dir_ops/batch_basicio_08_fileparts.m (98%) rename {src/ext => ext}/matlabbatch/cfg_basicio/src/01_file_dir_ops/batch_basicio_toplevel.m (98%) rename {src/ext => ext}/matlabbatch/cfg_basicio/src/02_var_ops/batch_basicio_10_named_input.m (98%) rename {src/ext => ext}/matlabbatch/cfg_basicio/src/02_var_ops/batch_basicio_11_load_vars.m (98%) rename {src/ext => ext}/matlabbatch/cfg_basicio/src/02_var_ops/batch_basicio_12_save_vars.m (98%) rename {src/ext => ext}/matlabbatch/cfg_basicio/src/02_var_ops/batch_basicio_13_subsrefvar.m (98%) rename {src/ext => ext}/matlabbatch/cfg_basicio/src/02_var_ops/batch_basicio_14_assignin.m (98%) rename {src/ext => ext}/matlabbatch/cfg_basicio/src/02_var_ops/batch_basicio_toplevel.m (98%) rename {src/ext => ext}/matlabbatch/cfg_basicio/src/03_run_ops/batch_basicio_15_runjobs.m (98%) rename {src/ext => ext}/matlabbatch/cfg_basicio/src/03_run_ops/batch_basicio_16_call_matlab.m (98%) rename {src/ext => ext}/matlabbatch/cfg_basicio/src/03_run_ops/batch_basicio_toplevel.m (98%) rename {src/ext => ext}/matlabbatch/cfg_basicio/src/batch_basicio_codegen.m (98%) rename {src/ext => ext}/matlabbatch/cfg_basicio/src/batch_basicio_toplevel.m (98%) rename {src/ext => ext}/matlabbatch/cfg_basicio/src/create_cfg_cfg_basicio.m (96%) rename {src/ext => ext}/matlabbatch/cfg_callbuiltin.m (95%) rename {src/ext => ext}/matlabbatch/cfg_confgui/cfg_confgui.m (97%) rename {src/ext => ext}/matlabbatch/cfg_confgui/cfg_run_template.m (97%) rename {src/ext => ext}/matlabbatch/cfg_conftest.m (97%) rename {src/ext => ext}/matlabbatch/cfg_dbstop.m (97%) rename {src/ext => ext}/matlabbatch/cfg_findspec.m (96%) rename {src/ext => ext}/matlabbatch/cfg_get_defaults.m (96%) rename {src/ext => ext}/matlabbatch/cfg_getfile.m (97%) rename {src/ext => ext}/matlabbatch/cfg_job.m (97%) rename {src/ext => ext}/matlabbatch/cfg_load_jobs.m (96%) rename {src/ext => ext}/matlabbatch/cfg_message.m (97%) rename {src/ext => ext}/matlabbatch/cfg_mlbatch_appcfg.m (97%) rename {src/ext => ext}/matlabbatch/cfg_serial.m (97%) rename {src/ext => ext}/matlabbatch/cfg_struct2cfg.m (96%) rename {src/ext => ext}/matlabbatch/cfg_tropts.m (95%) rename {src/ext => ext}/matlabbatch/cfg_txtdesc2cfg.m (97%) rename {src/ext => ext}/matlabbatch/cfg_ui.fig (100%) rename {src/ext => ext}/matlabbatch/cfg_ui.m (97%) rename {src/ext => ext}/matlabbatch/cfg_ui_multibatch.fig (100%) rename {src/ext => ext}/matlabbatch/cfg_ui_multibatch.m (97%) rename {src/ext => ext}/matlabbatch/cfg_ui_util.m (97%) rename {src/ext => ext}/matlabbatch/cfg_util.m (97%) rename {src/ext => ext}/matlabbatch/examples/batch_example_add1.m (98%) rename {src/ext => ext}/matlabbatch/examples/batch_example_add1_div.m (98%) rename {src/ext => ext}/matlabbatch/examples/batch_example_add1_div_reuse_b.m (98%) rename {src/ext => ext}/matlabbatch/examples/batch_example_add1_div_reuse_b_outname.m (98%) rename {src/ext => ext}/matlabbatch/examples/cfg_example_add1.m (98%) rename {src/ext => ext}/matlabbatch/examples/cfg_example_add2.m (98%) rename {src/ext => ext}/matlabbatch/examples/cfg_example_cumsum1.m (98%) rename {src/ext => ext}/matlabbatch/examples/cfg_example_cumsum2.m (98%) rename {src/ext => ext}/matlabbatch/examples/cfg_example_div.m (98%) rename {src/ext => ext}/matlabbatch/examples/cfg_example_master.m (95%) rename {src/ext => ext}/matlabbatch/examples/cfg_example_run_add1.m (94%) rename {src/ext => ext}/matlabbatch/examples/cfg_example_run_add2.m (94%) rename {src/ext => ext}/matlabbatch/examples/cfg_example_run_cumsum1.m (93%) rename {src/ext => ext}/matlabbatch/examples/cfg_example_run_cumsum2.m (93%) rename {src/ext => ext}/matlabbatch/examples/cfg_example_run_div.m (92%) rename {src/ext => ext}/matlabbatch/examples/cfg_example_run_sum.m (94%) rename {src/ext => ext}/matlabbatch/examples/cfg_example_sum.m (98%) rename {src/ext => ext}/matlabbatch/examples/cfg_mlbatch_appcfg.m.example (96%) rename {src/ext => ext}/matlabbatch/examples/toy_example.m (97%) rename {src/ext => ext}/matlabbatch/gencode.m (97%) rename {src/ext => ext}/matlabbatch/gencode_rvalue.m (97%) rename {src/ext => ext}/matlabbatch/gencode_substruct.m (97%) rename {src/ext => ext}/matlabbatch/gencode_substructcode.m (97%) rename {src/ext => ext}/matlabbatch/help2cell.m (97%) rename {src/ext => ext}/matlabbatch/hgsave_pre2008a.m (97%) rename {src/ext => ext}/matlabbatch/matlabbatch.man (97%) rename {src/ext => ext}/matlabbatch/private/README.inputdlg.txt (96%) rename {src/ext => ext}/matlabbatch/private/cfg_disp_error.m (97%) rename {src/ext => ext}/matlabbatch/private/cfg_eval_valedit.m (97%) rename {src/ext => ext}/matlabbatch/private/cfg_justify.m (96%) rename {src/ext => ext}/matlabbatch/private/cfg_maxextent.m (97%) rename {src/ext => ext}/matlabbatch/private/cfg_mlbatch_defaults.m (98%) rename {src/ext => ext}/matlabbatch/private/cfg_mlbatch_root.m (98%) rename {src/ext => ext}/matlabbatch/private/cfg_onscreen.m (97%) rename {src/ext => ext}/matlabbatch/private/cfg_run_cm.m (96%) rename {src/ext => ext}/matlabbatch/private/cfg_textfill.m (96%) rename {src/ext => ext}/matlabbatch/private/cfg_ui_disable.m (97%) rename {src/ext => ext}/matlabbatch/private/cfg_ui_getListboxTop.m (97%) rename {src/ext => ext}/matlabbatch/private/cfg_ui_restore.m (96%) rename {src/ext => ext}/matlabbatch/private/cfg_util_persistent.m (96%) rename {src/ext => ext}/matlabbatch/private/copyright_cfg.m (96%) rename {src/ext => ext}/matlabbatch/private/copyright_spm.m (98%) rename {src/ext => ext}/matlabbatch/private/getnicedialoglocation.m (96%) rename {src/ext => ext}/matlabbatch/private/inputdlg.m (96%) rename {src/ext => ext}/matlabbatch/private/int2str.m (96%) rename {src/ext => ext}/matlabbatch/private/listdlg.m (96%) rename {src/ext => ext}/matlabbatch/private/num2str.m (96%) rename {src/ext => ext}/matlabbatch/private/requestJavaAdapter.m (97%) rename {src/ext => ext}/matlabbatch/private/setdefaultbutton.m (97%) rename {src/ext => ext}/matlabbatch/subsasgn_check_funhandle.m (96%) rename {src/ext => ext}/matlabbatch/subsasgn_check_num.m (97%) rename {src/ext => ext}/matlabbatch/subsasgn_check_valcfg.m (96%) rename {src/ext => ext}/pupil-size/CHANGES_MADE.md (100%) rename {src/ext => ext}/pupil-size/LICENSE (100%) rename {src/ext => ext}/pupil-size/README.md (100%) rename {src/ext => ext}/pupil-size/code/READ_ME.txt (97%) rename {src/ext => ext}/pupil-size/code/dataModels/PupilDataModel.m (97%) rename {src/ext => ext}/pupil-size/code/dataModels/RawSamplesModel.m (97%) rename {src/ext => ext}/pupil-size/code/dataModels/ValidSamplesModel.m (97%) rename {src/ext => ext}/pupil-size/code/helperFunctions/LEGACY/array2table.m (96%) rename {src/ext => ext}/pupil-size/code/helperFunctions/LEGACY/table.m (97%) rename {src/ext => ext}/pupil-size/code/helperFunctions/genMeanDiaSamples.m (96%) rename {src/ext => ext}/pupil-size/code/helperFunctions/legacyModeCheck.m (97%) rename {src/ext => ext}/pupil-size/code/helperFunctions/plotSegments.m (97%) rename {src/ext => ext}/pupil-size/code/helperFunctions/printToConsole.m (96%) rename {src/ext => ext}/pupil-size/code/helperFunctions/rawDataFilter.m (97%) rename src/f_SCR.m => f_SCR.m (100%) rename src/f_SF.m => f_SF.m (100%) rename src/g_SCR.m => g_SCR.m (100%) rename src/pspm.m => pspm.m (100%) rename src/pspm_align_channels.m => pspm_align_channels.m (100%) rename src/pspm_appdesigner.mat => pspm_appdesigner.mat (100%) rename src/pspm_appdesigner.mlapp => pspm_appdesigner.mlapp (100%) rename src/pspm_bf_FIR.m => pspm_bf_FIR.m (100%) rename src/pspm_bf_data.m => pspm_bf_data.m (100%) rename src/pspm_bf_hprf.m => pspm_bf_hprf.m (100%) rename src/pspm_bf_hprf_e.m => pspm_bf_hprf_e.m (100%) rename src/pspm_bf_hprf_f.m => pspm_bf_hprf_f.m (100%) rename src/pspm_bf_hprf_fc.m => pspm_bf_hprf_fc.m (100%) rename src/pspm_bf_hprf_fc_f.m => pspm_bf_hprf_fc_f.m (100%) rename src/pspm_bf_lcrf_gm.m => pspm_bf_lcrf_gm.m (100%) rename src/pspm_bf_ldrf_gm.m => pspm_bf_ldrf_gm.m (100%) rename src/pspm_bf_ldrf_gu.m => pspm_bf_ldrf_gu.m (100%) rename src/pspm_bf_psrf_erl.m => pspm_bf_psrf_erl.m (100%) rename src/pspm_bf_psrf_fc.m => pspm_bf_psrf_fc.m (100%) rename src/pspm_bf_rarf_e.m => pspm_bf_rarf_e.m (100%) rename src/pspm_bf_rarf_fc.m => pspm_bf_rarf_fc.m (100%) rename src/pspm_bf_rfrrf_e.m => pspm_bf_rfrrf_e.m (100%) rename src/pspm_bf_rprf_e.m => pspm_bf_rprf_e.m (100%) rename src/pspm_bf_scrf.m => pspm_bf_scrf.m (100%) rename src/pspm_bf_scrf_f.m => pspm_bf_scrf_f.m (100%) rename src/pspm_bf_sebrf.m => pspm_bf_sebrf.m (100%) rename src/pspm_bf_spsrf_box.m => pspm_bf_spsrf_box.m (100%) rename src/pspm_bf_spsrf_gamma.m => pspm_bf_spsrf_gamma.m (100%) rename src/pspm_blink_saccade_filt.m => pspm_blink_saccade_filt.m (100%) rename src/pspm_butter.m => pspm_butter.m (100%) rename {src/pspm_cfg => pspm_cfg}/cfg_add_module.m (100%) rename {src/pspm_cfg => pspm_cfg}/cfg_mlbatch_appcfg.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_artefact_rm.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_contrast1.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_contrast2.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_data_convert.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_data_editor.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_data_preprocessing.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_dcm.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_display.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_downsample.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_ecg_editor.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_export.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_extract_segments.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_find_sounds.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_find_valid_fixations.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_first_level.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_first_level_hp.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_first_level_ps.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_first_level_resp.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_first_level_scr.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_first_level_sebr.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_first_level_sps.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_gaze_convert.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_get_markerinfo.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_glm.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_glm_hp_e.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_glm_hp_fc.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_glm_ps_fc.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_glm_ra_e.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_glm_ra_fc.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_glm_rfr_e.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_glm_rp_e.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_glm_scr.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_glm_sebr.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_glm_sps.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_import.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_interpolate.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_merge.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_pp_emg.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_pp_emg_data.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_pp_heart_data.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_pp_heart_period.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_pp_pupil.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_pp_scr.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_preparation.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_process_illuminance.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_pupil_correct.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_pupil_preprocess.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_pupil_size_convert.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_rename.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_resp_pp.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_review1.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_review2.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_run_artefact_rm.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_run_contrast1.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_run_contrast2.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_run_data_convert.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_run_data_editor.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_run_dcm.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_run_downsample.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_run_ecg_editor.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_run_export.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_run_extract_segments.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_run_find_sounds.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_run_find_valid_fixations.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_run_gaze_convert.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_run_get_markerinfo.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_run_glm.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_run_glm_hp_e.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_run_glm_hp_fc.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_run_glm_ps_fc.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_run_glm_ra_e.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_run_glm_ra_fc.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_run_glm_rfr_e.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_run_glm_rp_e.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_run_glm_scr.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_run_glm_sebr.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_run_glm_sps.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_run_import.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_run_interpolate.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_run_merge.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_run_pp_emg_data.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_run_pp_heart_data.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_run_proc_illuminance.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_run_pupil_correct.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_run_pupil_preprocess.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_run_pupil_size_convert.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_run_rename.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_run_review1.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_run_review2.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_run_segment_mean.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_run_sf.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_run_trim.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_second_level.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_segment_mean.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_sf.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_split_sessions.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_tools.m (100%) rename {src/pspm_cfg => pspm_cfg}/pspm_cfg_trim.m (100%) rename src/pspm_compute_visual_angle.m => pspm_compute_visual_angle.m (100%) rename src/pspm_compute_visual_angle_core.m => pspm_compute_visual_angle_core.m (100%) rename src/pspm_con1.m => pspm_con1.m (100%) rename src/pspm_con2.m => pspm_con2.m (100%) rename src/pspm_contrast.fig => pspm_contrast.fig (100%) rename src/pspm_contrast.m => pspm_contrast.m (100%) rename src/pspm_contrast_App.mlapp => pspm_contrast_App.mlapp (100%) rename src/pspm_convert_area2diameter.m => pspm_convert_area2diameter.m (100%) rename src/pspm_convert_au2unit.m => pspm_convert_au2unit.m (100%) rename src/pspm_convert_ecg2hb.m => pspm_convert_ecg2hb.m (100%) rename src/pspm_convert_ecg2hb_amri.m => pspm_convert_ecg2hb_amri.m (100%) rename src/pspm_convert_gaze_distance.m => pspm_convert_gaze_distance.m (100%) rename src/pspm_convert_hb2hp.m => pspm_convert_hb2hp.m (100%) rename src/pspm_convert_pixel2unit.m => pspm_convert_pixel2unit.m (100%) rename src/pspm_convert_ppg2hb.m => pspm_convert_ppg2hb.m (100%) rename src/pspm_convert_unit.m => pspm_convert_unit.m (100%) rename src/pspm_convert_visangle2sps.m => pspm_convert_visangle2sps.m (100%) rename src/pspm_convert_visangle2sps_core.m => pspm_convert_visangle2sps_core.m (100%) rename src/pspm_data_editor.fig => pspm_data_editor.fig (100%) rename src/pspm_data_editor.m => pspm_data_editor.m (100%) rename src/pspm_data_editor_App.mlapp => pspm_data_editor_App.mlapp (100%) rename src/pspm_dcm.m => pspm_dcm.m (100%) rename src/pspm_dcm_inv.m => pspm_dcm_inv.m (100%) rename src/pspm_denoise_spike.m => pspm_denoise_spike.m (100%) rename src/pspm_display.fig => pspm_display.fig (100%) rename src/pspm_display.m => pspm_display.m (100%) rename src/pspm_display_App.mlapp => pspm_display_App.mlapp (100%) rename src/pspm_down.m => pspm_down.m (100%) rename src/pspm_downsample.m => pspm_downsample.m (100%) rename src/pspm_ecg_editor.fig => pspm_ecg_editor.fig (100%) rename src/pspm_ecg_editor.m => pspm_ecg_editor.m (100%) rename src/pspm_ecg_editor_App.mlapp => pspm_ecg_editor_App.mlapp (100%) rename src/pspm_emg_pp.m => pspm_emg_pp.m (100%) rename src/pspm_exp.m => pspm_exp.m (100%) rename src/pspm_extract_segments.m => pspm_extract_segments.m (100%) rename src/pspm_eye.m => pspm_eye.m (100%) rename src/pspm_filtfilt.m => pspm_filtfilt.m (100%) rename src/pspm_find_channel.m => pspm_find_channel.m (100%) rename src/pspm_find_sounds.m => pspm_find_sounds.m (100%) rename src/pspm_find_valid_fixations.m => pspm_find_valid_fixations.m (100%) rename src/pspm_format_history.m => pspm_format_history.m (100%) rename src/pspm_format_history_from_file.m => pspm_format_history_from_file.m (100%) rename src/pspm_gaze_pp.m => pspm_gaze_pp.m (100%) rename src/pspm_get_acq.m => pspm_get_acq.m (100%) rename src/pspm_get_acq_bioread.m => pspm_get_acq_bioread.m (100%) rename src/pspm_get_acqmat.m => pspm_get_acqmat.m (100%) rename src/pspm_get_biograph.m => pspm_get_biograph.m (100%) rename src/pspm_get_biosemi.m => pspm_get_biosemi.m (100%) rename src/pspm_get_biotrace.m => pspm_get_biotrace.m (100%) rename src/pspm_get_blink_l.m => pspm_get_blink_l.m (100%) rename src/pspm_get_blink_r.m => pspm_get_blink_r.m (100%) rename src/pspm_get_brainvis.m => pspm_get_brainvis.m (100%) rename src/pspm_get_cnt.m => pspm_get_cnt.m (100%) rename src/pspm_get_csv.m => pspm_get_csv.m (100%) rename src/pspm_get_custom.m => pspm_get_custom.m (100%) rename src/pspm_get_ecg.m => pspm_get_ecg.m (100%) rename src/pspm_get_edf.m => pspm_get_edf.m (100%) rename src/pspm_get_emg.m => pspm_get_emg.m (100%) rename src/pspm_get_events.m => pspm_get_events.m (100%) rename src/pspm_get_eyelink.m => pspm_get_eyelink.m (100%) rename src/pspm_get_gaze_x_l.m => pspm_get_gaze_x_l.m (100%) rename src/pspm_get_gaze_x_r.m => pspm_get_gaze_x_r.m (100%) rename src/pspm_get_gaze_y_l.m => pspm_get_gaze_y_l.m (100%) rename src/pspm_get_gaze_y_r.m => pspm_get_gaze_y_r.m (100%) rename src/pspm_get_hb.m => pspm_get_hb.m (100%) rename src/pspm_get_hp.m => pspm_get_hp.m (100%) rename src/pspm_get_hr.m => pspm_get_hr.m (100%) rename src/pspm_get_labchart.m => pspm_get_labchart.m (100%) rename src/pspm_get_labchartmat_ext.m => pspm_get_labchartmat_ext.m (100%) rename src/pspm_get_labchartmat_in.m => pspm_get_labchartmat_in.m (100%) rename src/pspm_get_marker.m => pspm_get_marker.m (100%) rename src/pspm_get_markerinfo.m => pspm_get_markerinfo.m (100%) rename src/pspm_get_mat.m => pspm_get_mat.m (100%) rename src/pspm_get_obs.m => pspm_get_obs.m (100%) rename src/pspm_get_physlog.m => pspm_get_physlog.m (100%) rename src/pspm_get_ppg.m => pspm_get_ppg.m (100%) rename src/pspm_get_pupil.m => pspm_get_pupil.m (100%) rename src/pspm_get_pupil_l.m => pspm_get_pupil_l.m (100%) rename src/pspm_get_pupil_r.m => pspm_get_pupil_r.m (100%) rename src/pspm_get_resp.m => pspm_get_resp.m (100%) rename src/pspm_get_rf.m => pspm_get_rf.m (100%) rename src/pspm_get_saccade_l.m => pspm_get_saccade_l.m (100%) rename src/pspm_get_saccade_r.m => pspm_get_saccade_r.m (100%) rename src/pspm_get_scr.m => pspm_get_scr.m (100%) rename src/pspm_get_smi.m => pspm_get_smi.m (100%) rename src/pspm_get_sound.m => pspm_get_sound.m (100%) rename src/pspm_get_spike.m => pspm_get_spike.m (100%) rename src/pspm_get_sps.m => pspm_get_sps.m (100%) rename src/pspm_get_sps_l.m => pspm_get_sps_l.m (100%) rename src/pspm_get_sps_r.m => pspm_get_sps_r.m (100%) rename src/pspm_get_timing.m => pspm_get_timing.m (100%) rename src/pspm_get_txt.m => pspm_get_txt.m (100%) rename src/pspm_get_vario.m => pspm_get_vario.m (100%) rename src/pspm_get_viewpoint.m => pspm_get_viewpoint.m (100%) rename src/pspm_get_wdq.m => pspm_get_wdq.m (100%) rename src/pspm_get_wdq_n.m => pspm_get_wdq_n.m (100%) rename src/pspm_glm.m => pspm_glm.m (100%) rename src/pspm_glm_recon.m => pspm_glm_recon.m (100%) rename src/pspm_guide.fig => pspm_guide.fig (100%) rename src/pspm_guide.m => pspm_guide.m (100%) rename src/pspm_help.m => pspm_help.m (100%) rename src/pspm_import.m => pspm_import.m (100%) rename src/pspm_init.m => pspm_init.m (100%) rename src/pspm_interp1.m => pspm_interp1.m (100%) rename src/pspm_interpolate.m => pspm_interpolate.m (100%) rename src/pspm_jobman.m => pspm_jobman.m (100%) rename src/pspm_load1.m => pspm_load1.m (100%) rename src/pspm_load_data.m => pspm_load_data.m (100%) rename src/pspm_merge.m => pspm_merge.m (100%) rename src/pspm_msg.txt => pspm_msg.txt (100%) rename src/pspm_options.m => pspm_options.m (100%) rename src/pspm_overwrite.m => pspm_overwrite.m (100%) rename src/pspm_path.m => pspm_path.m (100%) rename src/pspm_pfm.m => pspm_pfm.m (100%) rename src/pspm_pp.m => pspm_pp.m (100%) rename src/pspm_prepdata.m => pspm_prepdata.m (100%) rename src/pspm_process_illuminance.m => pspm_process_illuminance.m (100%) rename src/pspm_pulse_convert.m => pspm_pulse_convert.m (100%) rename src/pspm_pupil_correct.m => pspm_pupil_correct.m (100%) rename src/pspm_pupil_correct_eyelink.m => pspm_pupil_correct_eyelink.m (100%) rename src/pspm_pupil_pp.m => pspm_pupil_pp.m (100%) rename src/pspm_pupil_pp_options.m => pspm_pupil_pp_options.m (100%) rename src/pspm_quit.m => pspm_quit.m (96%) rename src/pspm_remove_epochs.m => pspm_remove_epochs.m (100%) rename src/pspm_ren.m => pspm_ren.m (100%) rename src/pspm_resp_pp.m => pspm_resp_pp.m (100%) rename src/pspm_rev2.m => pspm_rev2.m (100%) rename src/pspm_rev_con.m => pspm_rev_con.m (100%) rename src/pspm_rev_dcm.m => pspm_rev_dcm.m (100%) rename src/pspm_rev_glm.m => pspm_rev_glm.m (100%) rename src/pspm_review.fig => pspm_review.fig (100%) rename src/pspm_review.m => pspm_review.m (100%) rename src/pspm_review_App.mlapp => pspm_review_App.mlapp (100%) rename src/pspm_scr_pp.m => pspm_scr_pp.m (100%) rename src/pspm_segment_mean.m => pspm_segment_mean.m (100%) rename src/pspm_sf.m => pspm_sf.m (100%) rename src/pspm_sf_auc.m => pspm_sf_auc.m (100%) rename src/pspm_sf_dcm.m => pspm_sf_dcm.m (100%) rename src/pspm_sf_mp.m => pspm_sf_mp.m (100%) rename src/pspm_sf_scl.m => pspm_sf_scl.m (100%) rename src/pspm_sf_theta.m => pspm_sf_theta.m (100%) rename src/pspm_show_arms.m => pspm_show_arms.m (100%) rename src/pspm_show_forum.m => pspm_show_forum.m (100%) rename src/pspm_show_help_doc.m => pspm_show_help_doc.m (100%) rename src/pspm_split_sessions.m => pspm_split_sessions.m (100%) rename src/pspm_text.m => pspm_text.m (100%) rename src/pspm_time2index.m => pspm_time2index.m (100%) rename src/pspm_transfer_function.m => pspm_transfer_function.m (100%) rename src/pspm_trim.m => pspm_trim.m (100%) rename src/pspm_ui.m => pspm_ui.m (100%) rename src/pspm_ui_app.m => pspm_ui_app.m (100%) rename src/pspm_update_channeltype.m => pspm_update_channeltype.m (100%) rename src/pspm_version.m => pspm_version.m (100%) rename src/pspm_write_channel.m => pspm_write_channel.m (100%) delete mode 100644 src/LICENSE.txt delete mode 100644 src/ext/VBA/subfunctions/f_alpha.m delete mode 100644 src/ext/VBA/subfunctions/g_exp.m delete mode 100644 src/ext/VBA/subfunctions/g_probit.m delete mode 100644 src/ext/VBA/subfunctions/phi.mat delete mode 100644 src/ext/matlabbatch/@cfg_exbranch/subs_fields.m delete mode 100644 src/ext/matlabbatch/@cfg_exbranch/subsasgn.m delete mode 100644 src/ext/matlabbatch/@cfg_exbranch/subsref.m delete mode 100644 src/ext/matlabbatch/@cfg_files/subs_fields.m delete mode 100644 src/ext/matlabbatch/@cfg_files/subsasgn.m delete mode 100644 src/ext/matlabbatch/@cfg_files/subsref.m delete mode 100644 src/ext/matlabbatch/@cfg_item/subs_fields.m delete mode 100644 src/ext/matlabbatch/@cfg_item/subsasgn.m delete mode 100644 src/ext/matlabbatch/@cfg_item/subsref.m delete mode 100644 src/ext/matlabbatch/@cfg_mchoice/subs_fields.m delete mode 100644 src/ext/matlabbatch/@cfg_mchoice/subsasgn.m delete mode 100644 src/ext/matlabbatch/@cfg_mchoice/subsref.m delete mode 100644 src/ext/matlabbatch/@cfg_menu/cfg2struct.m delete mode 100644 src/ext/matlabbatch/@cfg_menu/fieldnames.m delete mode 100644 src/ext/matlabbatch/@cfg_menu/subs_fields.m delete mode 100644 src/ext/matlabbatch/@cfg_menu/subsasgn.m delete mode 100644 src/ext/matlabbatch/@cfg_menu/subsref.m delete mode 100644 src/ext/matlabbatch/@cfg_repeat/fieldnames.m delete mode 100644 src/ext/matlabbatch/@cfg_repeat/subs_fields.m delete mode 100644 src/ext/matlabbatch/@cfg_repeat/subsasgn.m delete mode 100644 src/ext/matlabbatch/@cfg_repeat/subsref.m delete mode 100644 src/pspm_butter.mat delete mode 100644 src/pspm_convert.mat delete mode 100644 test/format_test_results.m delete mode 100644 test/import_eyelink_test.m delete mode 100644 test/import_smi_test.m delete mode 100644 test/import_viewpoint_test.m delete mode 100644 test/pspm_align_channels_test.m delete mode 100644 test/pspm_bf_data_test.m delete mode 100644 test/pspm_bf_test.m delete mode 100644 test/pspm_blink_saccade_filt_test.m delete mode 100644 test/pspm_butter_test.m delete mode 100644 test/pspm_convert_au2unit_test.m delete mode 100644 test/pspm_convert_ecg2hb_amri_test.m delete mode 100644 test/pspm_convert_ecg2hb_test.m delete mode 100644 test/pspm_convert_gaze_distance_test.m delete mode 100644 test/pspm_convert_hb2hp_test.m delete mode 100644 test/pspm_convert_pixel2unit_test.m delete mode 100644 test/pspm_convert_unit_test.m delete mode 100644 test/pspm_dcm_test.m delete mode 100644 test/pspm_down_test.m delete mode 100644 test/pspm_exp_test.m delete mode 100644 test/pspm_extract_segments_test.m delete mode 100644 test/pspm_filtfilt_test.m delete mode 100644 test/pspm_find_channel_test.m delete mode 100644 test/pspm_find_free_fn.m delete mode 100644 test/pspm_find_sounds_test.m delete mode 100644 test/pspm_find_valid_fixations_test.m delete mode 100644 test/pspm_gaze_pp_test.m delete mode 100644 test/pspm_get_acq_bioread_test.m delete mode 100644 test/pspm_get_acq_test.m delete mode 100644 test/pspm_get_acqmat_test.m delete mode 100644 test/pspm_get_biograph_test.m delete mode 100644 test/pspm_get_biosemi_test.m delete mode 100644 test/pspm_get_biotrace_test.m delete mode 100644 test/pspm_get_brainvis_test.m delete mode 100644 test/pspm_get_ecg_test.m delete mode 100644 test/pspm_get_edf_test.m delete mode 100644 test/pspm_get_events_test.m delete mode 100644 test/pspm_get_eyelink_test.m delete mode 100644 test/pspm_get_hb_test.m delete mode 100644 test/pspm_get_hr_test.m delete mode 100644 test/pspm_get_labchart_test.m delete mode 100644 test/pspm_get_labchartmat_ext_test.m delete mode 100644 test/pspm_get_labchartmat_in_test.m delete mode 100644 test/pspm_get_marker_test.m delete mode 100644 test/pspm_get_mat_test.m delete mode 100644 test/pspm_get_obs_test.m delete mode 100644 test/pspm_get_physlog_test.m delete mode 100644 test/pspm_get_pupil_test.m delete mode 100644 test/pspm_get_resp_test.m delete mode 100644 test/pspm_get_scr_test.m delete mode 100644 test/pspm_get_smi_test.m delete mode 100644 test/pspm_get_spike_test.m delete mode 100644 test/pspm_get_sps_test.m delete mode 100644 test/pspm_get_superclass.m delete mode 100644 test/pspm_get_timing_test.m delete mode 100644 test/pspm_get_txt_test.m delete mode 100644 test/pspm_get_vario_test.m delete mode 100644 test/pspm_get_viewpoint_test.m delete mode 100644 test/pspm_get_wdq_n_test.m delete mode 100644 test/pspm_glm_test.m delete mode 100644 test/pspm_import_test.m delete mode 100644 test/pspm_interpolate_test.m delete mode 100644 test/pspm_load1_test.m delete mode 100755 test/pspm_load_data_test.m delete mode 100644 test/pspm_load_data_ui_test.m delete mode 100644 test/pspm_path_test.m delete mode 100644 test/pspm_pp_test.m delete mode 100644 test/pspm_prepdata_test.m delete mode 100644 test/pspm_process_illuminance_test.m delete mode 100644 test/pspm_pulse_convert_test.m delete mode 100644 test/pspm_pupil_correct_eyelink_test.m delete mode 100644 test/pspm_pupil_correct_test.m delete mode 100644 test/pspm_pupil_pp_test.m delete mode 100644 test/pspm_ren_test.m delete mode 100644 test/pspm_resp_pp_test.m delete mode 100644 test/pspm_scr_pp_test.m delete mode 100644 test/pspm_sf_test.m delete mode 100644 test/pspm_split_sessions_test.m delete mode 100644 test/pspm_test.m delete mode 100644 test/pspm_test_github_actions.m delete mode 100644 test/pspm_testcase.m delete mode 100755 test/pspm_testdata_gen.m delete mode 100755 test/pspm_trim_test.m delete mode 100644 test/pspm_write_channel_test.m delete mode 100644 test/set_blinks_saccades_to_nan_test.m diff --git a/src/CologneCoatOfArms.jpg b/CologneCoatOfArms.jpg similarity index 100% rename from src/CologneCoatOfArms.jpg rename to CologneCoatOfArms.jpg diff --git a/src/Import/SON/Contents.m b/Import/SON/Contents.m similarity index 100% rename from src/Import/SON/Contents.m rename to Import/SON/Contents.m diff --git a/src/Import/SON/MATLAB SON Library [2.0].pdf b/Import/SON/MATLAB SON Library [2.0].pdf similarity index 100% rename from src/Import/SON/MATLAB SON Library [2.0].pdf rename to Import/SON/MATLAB SON Library [2.0].pdf diff --git a/src/Import/SON/SON32/C_Sources/GetFilterMask.c b/Import/SON/SON32/C_Sources/GetFilterMask.c similarity index 95% rename from src/Import/SON/SON32/C_Sources/GetFilterMask.c rename to Import/SON/SON32/C_Sources/GetFilterMask.c index e7403a39..fd8bd7a1 100644 --- a/src/Import/SON/SON32/C_Sources/GetFilterMask.c +++ b/Import/SON/SON32/C_Sources/GetFilterMask.c @@ -1,53 +1,53 @@ -#include -#include -#include -#include -#include "mex.h" -#include "son.h" -#include "machine.h" - -int GetFilterMask(mxArray *rhsptr, TpFilterMask pMask) - -{ - mxArray *tmpPtr; - int error; - unsigned char *ptr; - const int *empty[2]={0,0}; - - - tmpPtr=mxGetField(rhsptr,0,"lFlags"); - - if ((tmpPtr==NULL) || mxGetClassID(tmpPtr) != mxINT32_CLASS){ - mexPrintf("Bad Filter: lFlags missing or not int32 class\n"); - error=1; - } - else { - (*pMask).lFlags=mxGetScalar(tmpPtr); - } - - tmpPtr=mxGetField(rhsptr,0,"aMask"); - if (tmpPtr ==NULL){ - mexPrintf("SONGetRealData Bad Filter: aMask missing\n"); - error=1; - } - else { - if ((mxGetM(tmpPtr)!=32) ||( mxGetN(tmpPtr)!=4)){ - mexPrintf("SONGetRealData Bad Filter:" - "aMask has wrong dimensions\n"); - error=1; - } - if (mxGetClassID(tmpPtr) != mxUINT8_CLASS){ - mexPrintf("SONGetRealData Bad Filter:" - "aMask must be uint8 class\n"); - error=1; - } - } - if (error==1) - return SON_BAD_PARAM; - - ptr=mxGetData(tmpPtr);// Mask - - memcpy((*pMask).aMask,ptr,sizeof((*pMask).aMask)); - - return 1; -} +#include +#include +#include +#include +#include "mex.h" +#include "son.h" +#include "machine.h" + +int GetFilterMask(mxArray *rhsptr, TpFilterMask pMask) + +{ + mxArray *tmpPtr; + int error; + unsigned char *ptr; + const int *empty[2]={0,0}; + + + tmpPtr=mxGetField(rhsptr,0,"lFlags"); + + if ((tmpPtr==NULL) || mxGetClassID(tmpPtr) != mxINT32_CLASS){ + mexPrintf("Bad Filter: lFlags missing or not int32 class\n"); + error=1; + } + else { + (*pMask).lFlags=mxGetScalar(tmpPtr); + } + + tmpPtr=mxGetField(rhsptr,0,"aMask"); + if (tmpPtr ==NULL){ + mexPrintf("SONGetRealData Bad Filter: aMask missing\n"); + error=1; + } + else { + if ((mxGetM(tmpPtr)!=32) ||( mxGetN(tmpPtr)!=4)){ + mexPrintf("SONGetRealData Bad Filter:" + "aMask has wrong dimensions\n"); + error=1; + } + if (mxGetClassID(tmpPtr) != mxUINT8_CLASS){ + mexPrintf("SONGetRealData Bad Filter:" + "aMask must be uint8 class\n"); + error=1; + } + } + if (error==1) + return SON_BAD_PARAM; + + ptr=mxGetData(tmpPtr);// Mask + + memcpy((*pMask).aMask,ptr,sizeof((*pMask).aMask)); + + return 1; +} diff --git a/src/Import/SON/SON32/C_Sources/SONAppID.c b/Import/SON/SON32/C_Sources/SONAppID.c similarity index 95% rename from src/Import/SON/SON32/C_Sources/SONAppID.c rename to Import/SON/SON32/C_Sources/SONAppID.c index 33fb6d65..81da31fe 100644 --- a/src/Import/SON/SON32/C_Sources/SONAppID.c +++ b/Import/SON/SON32/C_Sources/SONAppID.c @@ -1,71 +1,71 @@ -#include -#include -#include -#include -#include "mex.h" - -#include "son.h" -#include "machine.h" -#include "SONDef.h" - -HINSTANCE hinstLib; -BOOL fFreeResult; - -int _SONAppID(short fh, TSONCreator *p1, TSONCreator *p2) -{ - FARPROC SONAppID; - int i; - SONAppID=GetProcAddress(hinstLib,"SONAppID"); - if (SONAppID != NULL){ - i=(*SONAppID)(fh, p1, p2); - return i; - } - mexErrMsgTxt("SONAppID not found in library\n"); -} - - -void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[]) -{ - short fh, i; - TSONCreator creator={""}; - char buf [9]; - double *p; - const int dim[2]={1,8}; - - if (nrhs>=1) - fh=mxGetScalar(prhs[0]); - - if (nrhs==2){ - if (mxGetClassID(prhs[1])==mxCHAR_CLASS) { - mxGetString(prhs[1], &buf, 9); - memcpy(creator.acID, buf, 8); - } - else - mexErrMsgTxt("SONAppID: String required on input (arg 2)"); - } - - -//Load and get pointer to the library SON32.DLL// -hinstLib = LoadLibrary(SON32); -if (hinstLib == NULL){ - mexPrintf("%s not found",SON32); - plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); - p=mxGetPr(plhs[0]); - p[0]=SON_BAD_PARAM; - return; -} - -if (nrhs==1) - i=_SONAppID(fh, &creator, NULL); //read -else { - i=_SONAppID(fh, NULL, &creator); //write - _SONAppID(fh, &creator, NULL); //and read back -} - -fFreeResult = FreeLibrary(hinstLib); - -memcpy(&buf, creator.acID, 8); -buf[8]=0; -plhs[0]=mxCreateString(&buf); -return; -} +#include +#include +#include +#include +#include "mex.h" + +#include "son.h" +#include "machine.h" +#include "SONDef.h" + +HINSTANCE hinstLib; +BOOL fFreeResult; + +int _SONAppID(short fh, TSONCreator *p1, TSONCreator *p2) +{ + FARPROC SONAppID; + int i; + SONAppID=GetProcAddress(hinstLib,"SONAppID"); + if (SONAppID != NULL){ + i=(*SONAppID)(fh, p1, p2); + return i; + } + mexErrMsgTxt("SONAppID not found in library\n"); +} + + +void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[]) +{ + short fh, i; + TSONCreator creator={""}; + char buf [9]; + double *p; + const int dim[2]={1,8}; + + if (nrhs>=1) + fh=mxGetScalar(prhs[0]); + + if (nrhs==2){ + if (mxGetClassID(prhs[1])==mxCHAR_CLASS) { + mxGetString(prhs[1], &buf, 9); + memcpy(creator.acID, buf, 8); + } + else + mexErrMsgTxt("SONAppID: String required on input (arg 2)"); + } + + +//Load and get pointer to the library SON32.DLL// +hinstLib = LoadLibrary(SON32); +if (hinstLib == NULL){ + mexPrintf("%s not found",SON32); + plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); + p=mxGetPr(plhs[0]); + p[0]=SON_BAD_PARAM; + return; +} + +if (nrhs==1) + i=_SONAppID(fh, &creator, NULL); //read +else { + i=_SONAppID(fh, NULL, &creator); //write + _SONAppID(fh, &creator, NULL); //and read back +} + +fFreeResult = FreeLibrary(hinstLib); + +memcpy(&buf, creator.acID, 8); +buf[8]=0; +plhs[0]=mxCreateString(&buf); +return; +} diff --git a/src/Import/SON/SON32/C_Sources/SONDef.h b/Import/SON/SON32/C_Sources/SONDef.h similarity index 92% rename from src/Import/SON/SON32/C_Sources/SONDef.h rename to Import/SON/SON32/C_Sources/SONDef.h index f14bd096..139f685a 100644 --- a/src/Import/SON/SON32/C_Sources/SONDef.h +++ b/Import/SON/SON32/C_Sources/SONDef.h @@ -1,5 +1,5 @@ -#define SON32 "c:\\Spike5\\son32.dll" -int GetFilterMask(); - - - +#define SON32 "c:\\Spike5\\son32.dll" +int GetFilterMask(); + + + diff --git a/src/Import/SON/SON32/C_Sources/SONFActive.c b/Import/SON/SON32/C_Sources/SONFActive.c similarity index 95% rename from src/Import/SON/SON32/C_Sources/SONFActive.c rename to Import/SON/SON32/C_Sources/SONFActive.c index af020fff..92b6bbad 100644 --- a/src/Import/SON/SON32/C_Sources/SONFActive.c +++ b/Import/SON/SON32/C_Sources/SONFActive.c @@ -1,58 +1,58 @@ -#include -#include -#include -#include -#include "mex.h" - -#include "son.h" -#include "machine.h" -#include "SONDef.h" - -HINSTANCE hinstLib; -BOOL fFreeResult; - -int _SONFActive(TpFilterMask Mask) -{ - FARPROC SONFActive; - int i; - SONFActive=GetProcAddress(hinstLib,"SONFActive"); - if (SONFActive != NULL){ - i=(*SONFActive)(Mask); - return i; - } - mexErrMsgTxt("SONFActive not found in library\n"); -} - - -void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[]) -{ - TFilterMask FilterMask; - int i, *ret; - int dim[2]={1,1}; - double *p; - - - if (nrhs<1) - mexErrMsgTxt("SONFEqual: Too few input arguments\n"); - - if (mxIsStruct(prhs[0])==1) - GetFilterMask(prhs[0], &FilterMask); - -//Load and get pointer to the library SON32.DLL// - hinstLib = LoadLibrary(SON32); - if (hinstLib == NULL){ - mexPrintf("%s not found",SON32); - plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); - p=mxGetPr(plhs[0]); - p[0]=SON_BAD_PARAM; - return; - } - - - i=_SONFActive(&FilterMask); - plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); - ret=mxGetData(plhs[0]); - *ret=i; - fFreeResult = FreeLibrary(hinstLib); - return; -} +#include +#include +#include +#include +#include "mex.h" + +#include "son.h" +#include "machine.h" +#include "SONDef.h" + +HINSTANCE hinstLib; +BOOL fFreeResult; + +int _SONFActive(TpFilterMask Mask) +{ + FARPROC SONFActive; + int i; + SONFActive=GetProcAddress(hinstLib,"SONFActive"); + if (SONFActive != NULL){ + i=(*SONFActive)(Mask); + return i; + } + mexErrMsgTxt("SONFActive not found in library\n"); +} + + +void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[]) +{ + TFilterMask FilterMask; + int i, *ret; + int dim[2]={1,1}; + double *p; + + + if (nrhs<1) + mexErrMsgTxt("SONFEqual: Too few input arguments\n"); + + if (mxIsStruct(prhs[0])==1) + GetFilterMask(prhs[0], &FilterMask); + +//Load and get pointer to the library SON32.DLL// + hinstLib = LoadLibrary(SON32); + if (hinstLib == NULL){ + mexPrintf("%s not found",SON32); + plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); + p=mxGetPr(plhs[0]); + p[0]=SON_BAD_PARAM; + return; + } + + + i=_SONFActive(&FilterMask); + plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); + ret=mxGetData(plhs[0]); + *ret=i; + fFreeResult = FreeLibrary(hinstLib); + return; +} diff --git a/src/Import/SON/SON32/C_Sources/SONFControl.c b/Import/SON/SON32/C_Sources/SONFControl.c similarity index 96% rename from src/Import/SON/SON32/C_Sources/SONFControl.c rename to Import/SON/SON32/C_Sources/SONFControl.c index 632b521a..bbca88d7 100644 --- a/src/Import/SON/SON32/C_Sources/SONFControl.c +++ b/Import/SON/SON32/C_Sources/SONFControl.c @@ -1,137 +1,137 @@ -#include -#include -#include -#include -#include "mex.h" - -#include "son.h" -#include "machine.h" -#include "SONDef.h" - -HINSTANCE hinstLib; -BOOL fFreeResult; - -int _SONFControl(TpFilterMask pMask, int layer, int item, int set) -{ - FARPROC SONFControl; - int i; - SONFControl=GetProcAddress(hinstLib,"SONFControl"); - if (SONFControl != NULL){ - i=(*SONFControl)(pMask, layer, item, set); - return i; - } - mexErrMsgTxt("SONFControl not found in library\n"); -} - - -void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[]) -{ - TFilterMask FilterMask={0,0}; - int layer, item, set; - int i, *ret; - int dim[2]={1,1}; - double *p; - char fieldnames[2][7]={"lFlags","aMask"}; - const char *f[2]; - const char **fnames=&f[0]; - long *tmpPtr; - int len; - char *ptr; - char mode[8]; - - f[0]=&fieldnames[0][0]; - f[1]=&fieldnames[1][1]; - - if (nrhs<4) { - mexPrintf("SONFControl:Too few LHS arguments \n"); - plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); - ret=mxGetData(plhs[0]); - *ret=SON_BAD_PARAM; - return; - } - - if (mxIsStruct(prhs[0])==1) - GetFilterMask(prhs[0], &FilterMask); - else { - mexPrintf("SONFControl:No valid filter mask on input \n"); - plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); - ret=mxGetData(plhs[0]); - *ret=SON_BAD_PARAM; - return; - - } - - - - if (mxIsNumeric(prhs[1])) - layer=mxGetScalar(prhs[1]); - else - layer=SON_FALLLAYERS; - - if (mxIsNumeric(prhs[2])) - item=mxGetScalar(prhs[2]); - else - item=SON_FALLITEMS; - - len=mxGetN(prhs[3])*mxGetM(prhs[3])+1; - if(len>7) - len=7; - mxGetString(prhs[3], mode, len); - -switch (mode[0]) { - case 'C': - case 'c': - set=SON_FCLEAR; - break; - case 'S': - case 's': - set=SON_FSET; - break; - case 'I': - case 'i': - set=SON_FINVERT; - break; - case 'R': - case 'r': - default: - set=SON_FREAD; - break; -} - - - //Load and get pointer to the library SON32.DLL// - hinstLib = LoadLibrary(SON32); - if (hinstLib == NULL){ - mexPrintf("%s not found",SON32); - plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); - p=mxGetPr(plhs[0]); - p[0]=SON_BAD_PARAM; - return; - } - - - i=_SONFControl(&FilterMask, layer, item, set); - fFreeResult = FreeLibrary(hinstLib); - - plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); - ret=mxGetData(plhs[0]); - *ret=i; - - if (nrhs==2) { - - plhs[1]=mxCreateStructMatrix(1, 1, 2, fnames); - if (plhs[1] != NULL) { - mxSetField(plhs[1], 0, "lFlags", - mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL)); - tmpPtr=mxGetData(mxGetField(plhs[1], 0, "lFlags")); - *tmpPtr=FilterMask.lFlags; - dim[0]=32; - dim[1]=4; - mxSetField(plhs[1], 0, "aMask", - mxCreateNumericArray(2, dim, mxUINT8_CLASS, mxREAL)); - ptr=mxGetData(mxGetField(plhs[1], 0, "aMask")); - memcpy(ptr, &FilterMask.aMask, sizeof(FilterMask.aMask)); - } - } - -} +#include +#include +#include +#include +#include "mex.h" + +#include "son.h" +#include "machine.h" +#include "SONDef.h" + +HINSTANCE hinstLib; +BOOL fFreeResult; + +int _SONFControl(TpFilterMask pMask, int layer, int item, int set) +{ + FARPROC SONFControl; + int i; + SONFControl=GetProcAddress(hinstLib,"SONFControl"); + if (SONFControl != NULL){ + i=(*SONFControl)(pMask, layer, item, set); + return i; + } + mexErrMsgTxt("SONFControl not found in library\n"); +} + + +void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[]) +{ + TFilterMask FilterMask={0,0}; + int layer, item, set; + int i, *ret; + int dim[2]={1,1}; + double *p; + char fieldnames[2][7]={"lFlags","aMask"}; + const char *f[2]; + const char **fnames=&f[0]; + long *tmpPtr; + int len; + char *ptr; + char mode[8]; + + f[0]=&fieldnames[0][0]; + f[1]=&fieldnames[1][1]; + + if (nrhs<4) { + mexPrintf("SONFControl:Too few LHS arguments \n"); + plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); + ret=mxGetData(plhs[0]); + *ret=SON_BAD_PARAM; + return; + } + + if (mxIsStruct(prhs[0])==1) + GetFilterMask(prhs[0], &FilterMask); + else { + mexPrintf("SONFControl:No valid filter mask on input \n"); + plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); + ret=mxGetData(plhs[0]); + *ret=SON_BAD_PARAM; + return; + + } + + + + if (mxIsNumeric(prhs[1])) + layer=mxGetScalar(prhs[1]); + else + layer=SON_FALLLAYERS; + + if (mxIsNumeric(prhs[2])) + item=mxGetScalar(prhs[2]); + else + item=SON_FALLITEMS; + + len=mxGetN(prhs[3])*mxGetM(prhs[3])+1; + if(len>7) + len=7; + mxGetString(prhs[3], mode, len); + +switch (mode[0]) { + case 'C': + case 'c': + set=SON_FCLEAR; + break; + case 'S': + case 's': + set=SON_FSET; + break; + case 'I': + case 'i': + set=SON_FINVERT; + break; + case 'R': + case 'r': + default: + set=SON_FREAD; + break; +} + + + //Load and get pointer to the library SON32.DLL// + hinstLib = LoadLibrary(SON32); + if (hinstLib == NULL){ + mexPrintf("%s not found",SON32); + plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); + p=mxGetPr(plhs[0]); + p[0]=SON_BAD_PARAM; + return; + } + + + i=_SONFControl(&FilterMask, layer, item, set); + fFreeResult = FreeLibrary(hinstLib); + + plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); + ret=mxGetData(plhs[0]); + *ret=i; + + if (nrhs==2) { + + plhs[1]=mxCreateStructMatrix(1, 1, 2, fnames); + if (plhs[1] != NULL) { + mxSetField(plhs[1], 0, "lFlags", + mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL)); + tmpPtr=mxGetData(mxGetField(plhs[1], 0, "lFlags")); + *tmpPtr=FilterMask.lFlags; + dim[0]=32; + dim[1]=4; + mxSetField(plhs[1], 0, "aMask", + mxCreateNumericArray(2, dim, mxUINT8_CLASS, mxREAL)); + ptr=mxGetData(mxGetField(plhs[1], 0, "aMask")); + memcpy(ptr, &FilterMask.aMask, sizeof(FilterMask.aMask)); + } + } + +} diff --git a/src/Import/SON/SON32/C_Sources/SONFEqual.c b/Import/SON/SON32/C_Sources/SONFEqual.c similarity index 95% rename from src/Import/SON/SON32/C_Sources/SONFEqual.c rename to Import/SON/SON32/C_Sources/SONFEqual.c index 5d7bf0c5..63d1164a 100644 --- a/src/Import/SON/SON32/C_Sources/SONFEqual.c +++ b/Import/SON/SON32/C_Sources/SONFEqual.c @@ -1,59 +1,59 @@ -#include -#include -#include -#include -#include "mex.h" - -#include "son.h" -#include "machine.h" -#include "SONDef.h" - -HINSTANCE hinstLib; -BOOL fFreeResult; - -BOOLEAN _SONFEqual(TpFilterMask Mask1, TpFilterMask Mask2) -{ - FARPROC SONFEqual; - int i; - SONFEqual=GetProcAddress(hinstLib,"SONFEqual"); - if (SONFEqual != NULL){ - i=(*SONFEqual)(Mask1, Mask2); - return i; - } - mexErrMsgTxt("SONFEqual not found in library\n"); -} - - -void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[]) -{ - TFilterMask FilterMask1, FilterMask2; - int i, *ret; - int dim[2]={1,1}; - double *p; - - - if (nrhs<2)return; - - if (mxIsStruct(prhs[0])==1 && mxIsStruct(prhs[1])==1 ) - GetFilterMask(prhs[0], &FilterMask1); - GetFilterMask(prhs[1], &FilterMask2); - - //Load and get pointer to the library SON32.DLL// - hinstLib = LoadLibrary(SON32); - if (hinstLib == NULL){ - mexPrintf("%s not found",SON32); - plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); - p=mxGetPr(plhs[0]); - p[0]=SON_BAD_PARAM; - return; - } - - - i=_SONFEqual(&FilterMask1, &FilterMask2); - mexPrintf("%d \n",i); - fFreeResult = FreeLibrary(hinstLib); - plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); - ret=mxGetData(plhs[0]); - *ret=i; - return; -} +#include +#include +#include +#include +#include "mex.h" + +#include "son.h" +#include "machine.h" +#include "SONDef.h" + +HINSTANCE hinstLib; +BOOL fFreeResult; + +BOOLEAN _SONFEqual(TpFilterMask Mask1, TpFilterMask Mask2) +{ + FARPROC SONFEqual; + int i; + SONFEqual=GetProcAddress(hinstLib,"SONFEqual"); + if (SONFEqual != NULL){ + i=(*SONFEqual)(Mask1, Mask2); + return i; + } + mexErrMsgTxt("SONFEqual not found in library\n"); +} + + +void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[]) +{ + TFilterMask FilterMask1, FilterMask2; + int i, *ret; + int dim[2]={1,1}; + double *p; + + + if (nrhs<2)return; + + if (mxIsStruct(prhs[0])==1 && mxIsStruct(prhs[1])==1 ) + GetFilterMask(prhs[0], &FilterMask1); + GetFilterMask(prhs[1], &FilterMask2); + + //Load and get pointer to the library SON32.DLL// + hinstLib = LoadLibrary(SON32); + if (hinstLib == NULL){ + mexPrintf("%s not found",SON32); + plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); + p=mxGetPr(plhs[0]); + p[0]=SON_BAD_PARAM; + return; + } + + + i=_SONFEqual(&FilterMask1, &FilterMask2); + mexPrintf("%d \n",i); + fFreeResult = FreeLibrary(hinstLib); + plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); + ret=mxGetData(plhs[0]); + *ret=i; + return; +} diff --git a/src/Import/SON/SON32/C_Sources/SONFMode.c b/Import/SON/SON32/C_Sources/SONFMode.c similarity index 95% rename from src/Import/SON/SON32/C_Sources/SONFMode.c rename to Import/SON/SON32/C_Sources/SONFMode.c index 09dc6aa7..5161ad7c 100644 --- a/src/Import/SON/SON32/C_Sources/SONFMode.c +++ b/Import/SON/SON32/C_Sources/SONFMode.c @@ -1,103 +1,103 @@ -#include -#include -#include -#include -#include "mex.h" - -#include "son.h" -#include "machine.h" -#include "SONDef.h" - -HINSTANCE hinstLib; -BOOL fFreeResult; - -long _SONFMode(TpFilterMask pMask, int mode) -{ - FARPROC SONFMode; - long i; - SONFMode=GetProcAddress(hinstLib,"SONFMode"); - if (SONFMode != NULL){ - i=(*SONFMode)(pMask, mode); - return i; - } - mexErrMsgTxt("SONFMode not found in library\n"); -} - - -void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[]) -{ - TFilterMask FilterMask={0,0}; - int index, lmode, len; - int dim[2]={1,1}; - double *p; - long retmode; - char mode[4]; - const char fieldnames[2][7]={"lFlags","aMask"}; - const char *f[2]; - const char **fnames=&f[0]; - long *tmpPtr; - char *ptr; - - f[0]=&fieldnames[0][0]; - f[1]=&fieldnames[1][0]; - - if (nrhs<1) - mode[0]='a'; - else { - index=0; - if (mxIsStruct(prhs[0])==1){ - GetFilterMask(prhs[0], &FilterMask); - index=1; - } - - len=mxGetN(prhs[index])*mxGetM(prhs[index])+1; - if(len>7) - len=7; - mxGetString(prhs[index], mode, len); - } - - - //Load and get pointer to the library SON32.DLL// - hinstLib = LoadLibrary(SON32); - if (hinstLib == NULL){ - mexPrintf("%s not found",SON32); - plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); - p=mxGetPr(plhs[0]); - p[0]=SON_BAD_PARAM; - return; - } - - switch (mode[0]) { - case 'o': - case 'O': lmode=SON_FMASK_ORMODE; - break; - case 'a': - case 'A': lmode=SON_FMASK_ANDMODE; - break; - case 'n': - case 'N': - default: lmode=-1; - } - - retmode=_SONFMode(&FilterMask, lmode); - fFreeResult = FreeLibrary(hinstLib); - - - plhs[0]=mxCreateStructMatrix(1, 1, 2, fnames); - if (plhs[0] != NULL) { - mxSetField(plhs[0], 0, "lFlags", - mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL)); - tmpPtr=mxGetData(mxGetField(plhs[0], 0, "lFlags")); - *tmpPtr=FilterMask.lFlags; - dim[0]=32; - dim[1]=4; - mxSetField(plhs[0], 0, "aMask", - mxCreateNumericArray(2, dim, mxUINT8_CLASS, mxREAL)); - ptr=mxGetData(mxGetField(plhs[0], 0, "aMask")); - memcpy(ptr, &FilterMask.aMask, sizeof(FilterMask.aMask)); - } - - - - -} +#include +#include +#include +#include +#include "mex.h" + +#include "son.h" +#include "machine.h" +#include "SONDef.h" + +HINSTANCE hinstLib; +BOOL fFreeResult; + +long _SONFMode(TpFilterMask pMask, int mode) +{ + FARPROC SONFMode; + long i; + SONFMode=GetProcAddress(hinstLib,"SONFMode"); + if (SONFMode != NULL){ + i=(*SONFMode)(pMask, mode); + return i; + } + mexErrMsgTxt("SONFMode not found in library\n"); +} + + +void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[]) +{ + TFilterMask FilterMask={0,0}; + int index, lmode, len; + int dim[2]={1,1}; + double *p; + long retmode; + char mode[4]; + const char fieldnames[2][7]={"lFlags","aMask"}; + const char *f[2]; + const char **fnames=&f[0]; + long *tmpPtr; + char *ptr; + + f[0]=&fieldnames[0][0]; + f[1]=&fieldnames[1][0]; + + if (nrhs<1) + mode[0]='a'; + else { + index=0; + if (mxIsStruct(prhs[0])==1){ + GetFilterMask(prhs[0], &FilterMask); + index=1; + } + + len=mxGetN(prhs[index])*mxGetM(prhs[index])+1; + if(len>7) + len=7; + mxGetString(prhs[index], mode, len); + } + + + //Load and get pointer to the library SON32.DLL// + hinstLib = LoadLibrary(SON32); + if (hinstLib == NULL){ + mexPrintf("%s not found",SON32); + plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); + p=mxGetPr(plhs[0]); + p[0]=SON_BAD_PARAM; + return; + } + + switch (mode[0]) { + case 'o': + case 'O': lmode=SON_FMASK_ORMODE; + break; + case 'a': + case 'A': lmode=SON_FMASK_ANDMODE; + break; + case 'n': + case 'N': + default: lmode=-1; + } + + retmode=_SONFMode(&FilterMask, lmode); + fFreeResult = FreeLibrary(hinstLib); + + + plhs[0]=mxCreateStructMatrix(1, 1, 2, fnames); + if (plhs[0] != NULL) { + mxSetField(plhs[0], 0, "lFlags", + mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL)); + tmpPtr=mxGetData(mxGetField(plhs[0], 0, "lFlags")); + *tmpPtr=FilterMask.lFlags; + dim[0]=32; + dim[1]=4; + mxSetField(plhs[0], 0, "aMask", + mxCreateNumericArray(2, dim, mxUINT8_CLASS, mxREAL)); + ptr=mxGetData(mxGetField(plhs[0], 0, "aMask")); + memcpy(ptr, &FilterMask.aMask, sizeof(FilterMask.aMask)); + } + + + + +} diff --git a/src/Import/SON/SON32/C_Sources/SONFilter.c b/Import/SON/SON32/C_Sources/SONFilter.c similarity index 95% rename from src/Import/SON/SON32/C_Sources/SONFilter.c rename to Import/SON/SON32/C_Sources/SONFilter.c index 43f0301b..4a35b313 100644 --- a/src/Import/SON/SON32/C_Sources/SONFilter.c +++ b/Import/SON/SON32/C_Sources/SONFilter.c @@ -1,94 +1,94 @@ -#include -#include -#include -#include -#include "mex.h" - -#include "son.h" -#include "machine.h" -#include "SONDef.h" - -HINSTANCE hinstLib; -BOOL fFreeResult; - -int _SONFilter(TpMarker pMarks, TpFilterMask pMask) -{ - FARPROC SONFilter; - long i; - SONFilter=GetProcAddress(hinstLib,"SONFilter"); - if (SONFilter != NULL){ - i=(*SONFilter)(pMarks, pMask); - return i; - } - mexErrMsgTxt("SONFilter not found in library\n"); -} - - -void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[]) -{ - TFilterMask FilterMask; - int i, *ret; - int dim[2]={1,1}; - double *p; - TMarker Mark; - unsigned char *ptr; - mxArray *ptr2; - - if (nrhs<2) { - mexPrintf("SONFilter:Too few LHS arguments \n"); - plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); - ret=mxGetData(plhs[0]); - *ret=SON_BAD_PARAM; - return; - } - - ptr=NULL; - if (mxIsStruct(prhs[0])){ - ptr2=mxGetField(prhs[0],0,"mvals"); - if (ptr2 != NULL) - ptr=mxGetData(ptr2); - } - else - ptr=mxGetData(prhs[0]); - - if (ptr==NULL) { - mexPrintf("SONFilter:Invalid markers: 4-btye uint8 vector\n" - " or TMarker structure expected\n"); - plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); - ret=mxGetData(plhs[0]); - *ret=SON_BAD_PARAM; - return; - } - - memcpy(&Mark.mvals, ptr, 4); - - - if (mxIsStruct(prhs[1])==1) - GetFilterMask(prhs[1], &FilterMask); - - - - - //Load and get pointer to the library SON32.DLL// - hinstLib = LoadLibrary(SON32); - if (hinstLib == NULL){ - mexPrintf("%s not found",SON32); - plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); - p=mxGetPr(plhs[0]); - p[0]=SON_BAD_PARAM; - return; - } - - - i=_SONFilter(&Mark, &FilterMask); - fFreeResult = FreeLibrary(hinstLib); - - - plhs[0]=mxCreateNumericArray(2,dim,mxINT32_CLASS, mxREAL); - ptr=mxGetData(plhs[0]); - *ptr=i; - - - - -} +#include +#include +#include +#include +#include "mex.h" + +#include "son.h" +#include "machine.h" +#include "SONDef.h" + +HINSTANCE hinstLib; +BOOL fFreeResult; + +int _SONFilter(TpMarker pMarks, TpFilterMask pMask) +{ + FARPROC SONFilter; + long i; + SONFilter=GetProcAddress(hinstLib,"SONFilter"); + if (SONFilter != NULL){ + i=(*SONFilter)(pMarks, pMask); + return i; + } + mexErrMsgTxt("SONFilter not found in library\n"); +} + + +void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[]) +{ + TFilterMask FilterMask; + int i, *ret; + int dim[2]={1,1}; + double *p; + TMarker Mark; + unsigned char *ptr; + mxArray *ptr2; + + if (nrhs<2) { + mexPrintf("SONFilter:Too few LHS arguments \n"); + plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); + ret=mxGetData(plhs[0]); + *ret=SON_BAD_PARAM; + return; + } + + ptr=NULL; + if (mxIsStruct(prhs[0])){ + ptr2=mxGetField(prhs[0],0,"mvals"); + if (ptr2 != NULL) + ptr=mxGetData(ptr2); + } + else + ptr=mxGetData(prhs[0]); + + if (ptr==NULL) { + mexPrintf("SONFilter:Invalid markers: 4-btye uint8 vector\n" + " or TMarker structure expected\n"); + plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); + ret=mxGetData(plhs[0]); + *ret=SON_BAD_PARAM; + return; + } + + memcpy(&Mark.mvals, ptr, 4); + + + if (mxIsStruct(prhs[1])==1) + GetFilterMask(prhs[1], &FilterMask); + + + + + //Load and get pointer to the library SON32.DLL// + hinstLib = LoadLibrary(SON32); + if (hinstLib == NULL){ + mexPrintf("%s not found",SON32); + plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); + p=mxGetPr(plhs[0]); + p[0]=SON_BAD_PARAM; + return; + } + + + i=_SONFilter(&Mark, &FilterMask); + fFreeResult = FreeLibrary(hinstLib); + + + plhs[0]=mxCreateNumericArray(2,dim,mxINT32_CLASS, mxREAL); + ptr=mxGetData(plhs[0]); + *ptr=i; + + + + +} diff --git a/src/Import/SON/SON32/C_Sources/SONGetADCData.c b/Import/SON/SON32/C_Sources/SONGetADCData.c similarity index 96% rename from src/Import/SON/SON32/C_Sources/SONGetADCData.c rename to Import/SON/SON32/C_Sources/SONGetADCData.c index c020b758..72d71e92 100644 --- a/src/Import/SON/SON32/C_Sources/SONGetADCData.c +++ b/Import/SON/SON32/C_Sources/SONGetADCData.c @@ -1,219 +1,219 @@ -/*% SONGETADCDATA returns data for Adc, AdcMark, RealWave ( and RealMark?) -% data channels -% -% Implemented through SONGetADCData.dll -% -% [npoints, bTime, data]=SONGETADCDATA(fh, chan,... -% maxpoints, sTime, eTime{, FilterMask}) -% -% INPUTS: FH = file handle -% CHAN = channel number 0 to SONMAXCHANS-1 -% MAXPOINTS = Maximum number of data points to return -% The routine will calculate MAXPOINTS -% if this is passed as zero or less. -% STIME = the start time for the data search -% (in clock ticks) -% ETIME = the end time for the search -% (in clock ticks) -% FILTERMASK if present is a filter mask structure -% There will be no filtering if this is -% absent. -% OUTPUTS: NPOINTS= number of data points returned -% or a negative error -% BTIME = the time for the first sample returned in -% data (in clock ticks) -% DATA = the output data array -% -% Alternative call: -% [npoints, bTime]=SONGETADCDATA(fh, chan,... -% data, sTime, eTime{, FilterMask}) -% Here, DATA must be a pre-allocated int16 column vector. SON32.DLL will -% place data directly into this array in the matlab workspace. For repeated -% calls, this can be faster but it breaks normal matlab conventions. -% -% For error codes returned in NPOINTS see the CED documentation -% -% ML 03/05*/ - - - -#include -#include -#include -#include -#include - -#include "son.h" -#include "machine.h" -#include "SONDef.h" - -HINSTANCE hinstLib=NULL; -BOOL fFreeResult; - - -// Calls the SON32.DLL read routine -long _SONGetADCData(short fh, -WORD chan, -TpAdc psData, -long maxpoints, -TSTime sTime, -TSTime eTime, -TpSTime pbTime, -TpFilterMask pFltMask) -{ - long i; - FARPROC SONGetADCData; - SONGetADCData =GetProcAddress(hinstLib,"SONGetADCData"); - if (SONGetADCData != NULL){ - i=(*SONGetADCData)(fh, chan, psData, maxpoints, sTime, eTime, - pbTime, pFltMask); - return i; - } - return -1000; -} - -// Returns the number of clock ticks per sampling interval for channel -// chan -int ChanInterval(short fh, WORD chan) -{ - FARPROC SONGetTimePerADC,SONChanDivide; - WORD a; - TSTime b; - - SONGetTimePerADC=GetProcAddress(hinstLib,"SONGetTimePerADC"); - SONChanDivide=GetProcAddress(hinstLib,"SONChanDivide"); - if ((SONGetTimePerADC==NULL) || (SONChanDivide==NULL)) { - mexErrMsgTxt("Required routines not found in SON32.DLL"); - } - a=(*SONGetTimePerADC)(fh, 0); - b=(*SONChanDivide)(fh, chan); - return a*b ; -} - - -void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[]) -{ - - short fh; - WORD chan; - TpAdc psData; - long maxpoints; - TSTime sTime; - TSTime eTime; - TSTime StartTime; - TpSTime pbTime=&StartTime; - TpFilterMask pFltMask=NULL; - TFilterMask FilterMask; - double *p; - long npoints; - int dim[2]={1,1}; - long * ret; - - //Used for filter - int mode; - int m,n; - const int empty[2]={0,0}; - - - if (nrhs<5) - mexErrMsgTxt("SONGetADCData: Too few input arguments\n"); - - //Get input arguments - fh=mxGetScalar(prhs[0]); //File handle - chan=mxGetScalar(prhs[1]); //Channel number - //maxpoints - see below - sTime=mxGetScalar(prhs[3]); //Start time for data search - eTime=mxGetScalar(prhs[4]); //End Time for data search - - //prhs[2] can be maxpoints (a scalar; =mode 1)or a pointer to a - //pre-allocated array in the matlab calling space (mode 2). - if (mxGetM(prhs[2])==1 && mxGetN(prhs[2])==1) {// scalar so mode 1 - if (nlhs<3) { - mexPrintf("SONGetRealData:Too few LHS arguments \n"); - plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); - ret=mxGetData(plhs[0]); - *ret=SON_BAD_PARAM; - for (m=1; m1)||(mxGetClassID(prhs[2])!= mxINT16_CLASS)) { - mexPrintf("SONGetADCData:" - "Data array must be an int16 column vector\n"); - plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); - ret=mxGetData(plhs[0]); - *ret=SON_BAD_PARAM; - for (m=1; m=3) { - dim[1]=maxpoints; - plhs[2]=mxCreateNumericArray(2, dim, mxINT16_CLASS, mxREAL); - psData=mxGetData(plhs[2]); - } - - if(psData != NULL){ - - //Call DLL - npoints=_SONGetADCData(fh, chan, psData, maxpoints, sTime, eTime, - pbTime, pFltMask); - fFreeResult = FreeLibrary(hinstLib); - - //return results. This one goes in ans if no arguments - dim[1]=1; - plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); - ret=mxGetData(plhs[0]); - *ret=npoints; - - if (nlhs>=2){ - plhs[1]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); - ret=mxGetData(plhs[1]); - *ret=*pbTime; - } - - - } - -} - - +/*% SONGETADCDATA returns data for Adc, AdcMark, RealWave ( and RealMark?) +% data channels +% +% Implemented through SONGetADCData.dll +% +% [npoints, bTime, data]=SONGETADCDATA(fh, chan,... +% maxpoints, sTime, eTime{, FilterMask}) +% +% INPUTS: FH = file handle +% CHAN = channel number 0 to SONMAXCHANS-1 +% MAXPOINTS = Maximum number of data points to return +% The routine will calculate MAXPOINTS +% if this is passed as zero or less. +% STIME = the start time for the data search +% (in clock ticks) +% ETIME = the end time for the search +% (in clock ticks) +% FILTERMASK if present is a filter mask structure +% There will be no filtering if this is +% absent. +% OUTPUTS: NPOINTS= number of data points returned +% or a negative error +% BTIME = the time for the first sample returned in +% data (in clock ticks) +% DATA = the output data array +% +% Alternative call: +% [npoints, bTime]=SONGETADCDATA(fh, chan,... +% data, sTime, eTime{, FilterMask}) +% Here, DATA must be a pre-allocated int16 column vector. SON32.DLL will +% place data directly into this array in the matlab workspace. For repeated +% calls, this can be faster but it breaks normal matlab conventions. +% +% For error codes returned in NPOINTS see the CED documentation +% +% ML 03/05*/ + + + +#include +#include +#include +#include +#include + +#include "son.h" +#include "machine.h" +#include "SONDef.h" + +HINSTANCE hinstLib=NULL; +BOOL fFreeResult; + + +// Calls the SON32.DLL read routine +long _SONGetADCData(short fh, +WORD chan, +TpAdc psData, +long maxpoints, +TSTime sTime, +TSTime eTime, +TpSTime pbTime, +TpFilterMask pFltMask) +{ + long i; + FARPROC SONGetADCData; + SONGetADCData =GetProcAddress(hinstLib,"SONGetADCData"); + if (SONGetADCData != NULL){ + i=(*SONGetADCData)(fh, chan, psData, maxpoints, sTime, eTime, + pbTime, pFltMask); + return i; + } + return -1000; +} + +// Returns the number of clock ticks per sampling interval for channel +// chan +int ChanInterval(short fh, WORD chan) +{ + FARPROC SONGetTimePerADC,SONChanDivide; + WORD a; + TSTime b; + + SONGetTimePerADC=GetProcAddress(hinstLib,"SONGetTimePerADC"); + SONChanDivide=GetProcAddress(hinstLib,"SONChanDivide"); + if ((SONGetTimePerADC==NULL) || (SONChanDivide==NULL)) { + mexErrMsgTxt("Required routines not found in SON32.DLL"); + } + a=(*SONGetTimePerADC)(fh, 0); + b=(*SONChanDivide)(fh, chan); + return a*b ; +} + + +void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[]) +{ + + short fh; + WORD chan; + TpAdc psData; + long maxpoints; + TSTime sTime; + TSTime eTime; + TSTime StartTime; + TpSTime pbTime=&StartTime; + TpFilterMask pFltMask=NULL; + TFilterMask FilterMask; + double *p; + long npoints; + int dim[2]={1,1}; + long * ret; + + //Used for filter + int mode; + int m,n; + const int empty[2]={0,0}; + + + if (nrhs<5) + mexErrMsgTxt("SONGetADCData: Too few input arguments\n"); + + //Get input arguments + fh=mxGetScalar(prhs[0]); //File handle + chan=mxGetScalar(prhs[1]); //Channel number + //maxpoints - see below + sTime=mxGetScalar(prhs[3]); //Start time for data search + eTime=mxGetScalar(prhs[4]); //End Time for data search + + //prhs[2] can be maxpoints (a scalar; =mode 1)or a pointer to a + //pre-allocated array in the matlab calling space (mode 2). + if (mxGetM(prhs[2])==1 && mxGetN(prhs[2])==1) {// scalar so mode 1 + if (nlhs<3) { + mexPrintf("SONGetRealData:Too few LHS arguments \n"); + plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); + ret=mxGetData(plhs[0]); + *ret=SON_BAD_PARAM; + for (m=1; m1)||(mxGetClassID(prhs[2])!= mxINT16_CLASS)) { + mexPrintf("SONGetADCData:" + "Data array must be an int16 column vector\n"); + plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); + ret=mxGetData(plhs[0]); + *ret=SON_BAD_PARAM; + for (m=1; m=3) { + dim[1]=maxpoints; + plhs[2]=mxCreateNumericArray(2, dim, mxINT16_CLASS, mxREAL); + psData=mxGetData(plhs[2]); + } + + if(psData != NULL){ + + //Call DLL + npoints=_SONGetADCData(fh, chan, psData, maxpoints, sTime, eTime, + pbTime, pFltMask); + fFreeResult = FreeLibrary(hinstLib); + + //return results. This one goes in ans if no arguments + dim[1]=1; + plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); + ret=mxGetData(plhs[0]); + *ret=npoints; + + if (nlhs>=2){ + plhs[1]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); + ret=mxGetData(plhs[1]); + *ret=*pbTime; + } + + + } + +} + + diff --git a/src/Import/SON/SON32/C_Sources/SONGetEventData.c b/Import/SON/SON32/C_Sources/SONGetEventData.c similarity index 96% rename from src/Import/SON/SON32/C_Sources/SONGetEventData.c rename to Import/SON/SON32/C_Sources/SONGetEventData.c index 041ba911..83be8ccc 100644 --- a/src/Import/SON/SON32/C_Sources/SONGetEventData.c +++ b/Import/SON/SON32/C_Sources/SONGetEventData.c @@ -1,155 +1,155 @@ -/*% SONGETEVENTDATA returns the timings for an Event or marker channel -% -% Implemented through SONGetEventData.dll -% -% [npoints, times, levlow]= -% SONGETEVENTDATA(fh, chan, maxpoints, stime, etime{, filtermask}) -% -% INPUTS: FH = file handle -% CHAN = channel number 0 to SONMAXCHANS-1 -% MAXPOINTS = Maximum number of data values to return -% STIME = the start time for the data search -% (in clock ticks) -% ETIME = the end time for teh search -% (in clock ticks) -% FILTERMASK if present is a filter mask structure -% There will be no filtering if this is -% absent. -% OUTPUTS: NPOINTS= number of data points returned -% or a negative error -% TIMES = an NPOINT column vector containing the -% timestamps (in clock ticks) -% LEVLOW = For a EventBoth (level) channel, -% this is set to 1 if the first event -% is a high to low transition, 0 otherwise -% -% -% For error codes, see the CED documentation -% -%ML 05/05 -*/ - - - -#include -#include -#include -#include -#include - -#include "son.h" -#include "machine.h" -#include "SONDef.h" - -HINSTANCE hinstLib; -BOOL fFreeResult; - - -// Calls the SON32.DLL read routine -long _SONGetEventData(short fh, - WORD chan, - TpSTime plTimes, - long maxpoints, - TSTime sTime, - TSTime eTime, - TpBOOL plevLow, - TpFilterMask pFltMask) -{ - long i; - FARPROC SONGetEventData; - SONGetEventData = GetProcAddress(hinstLib,"SONGetEventData"); - if (SONGetEventData != NULL){ - i=(*SONGetEventData)(fh, chan, plTimes, maxpoints, sTime, eTime, plevLow, pFltMask); - return i; - } - mexErrMsgTxt("SONGetMarkData not found in SON32.DLL\n"); -} - - -void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[]) -{ - - short fh; - WORD chan; - long maxpoints; - TSTime sTime; - TSTime eTime; - TpFilterMask pFltMask=NULL; - TFilterMask FilterMask; - long npoints=0, *ret; - TpSTime plTimes; - int levLow=0; - int *ptr; - int dim[2]={1,1}; - double *p; - - - - - //Used for filter - int m,n; - const int *empty[2]={0,0}; - - - if (nrhs<5) - mexErrMsgTxt("SONGetEventData: Too few arguments\n"); - - //Get input arguments - fh=mxGetScalar(prhs[0]); //File handle - chan=mxGetScalar(prhs[1]); //Channel number - maxpoints=mxGetScalar(prhs[2]); //maxpoints - sTime=mxGetScalar(prhs[3]); //Start time for data search - eTime=mxGetScalar(prhs[4]); //End Time for data search - -mexPrintf("%d\n",eTime); - - //Get and set up the filter mask - if (nrhs==5 && mxIsStruct(prhs[5])==1){ - GetFilterMask(prhs[5], &FilterMask); - pFltMask=&FilterMask; - } - else - pFltMask=NULL; - - - //Load and get pointer to the library SON32.DLL// - hinstLib = LoadLibrary(SON32); - if (hinstLib == NULL){ - mexPrintf("%s not found",SON32); - plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); - p=mxGetData(plhs[0]); - p[0]=SON_BAD_PARAM; - return; - } - -// allocate array for return of event data - if (nlhs>=2){ - dim[0]=1; - dim[1]=maxpoints; - plhs[1]= mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); - plTimes=mxGetData(plhs[1]); - } - - //Call DLL - npoints=_SONGetEventData(fh, chan, plTimes, maxpoints, sTime, eTime, &levLow, pFltMask); - fFreeResult = FreeLibrary(hinstLib); - - - //return results. This one goes in ans if no arguments - dim[0]=1; - dim[1]=1; - plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); - ret=mxGetData(plhs[0]); - *ret=npoints; - - - if (nlhs==3) { - plhs[2]=mxCreateNumericArray(2, dim, mxINT16_CLASS, mxREAL); - ptr=mxGetData(plhs[2]); - *ptr=levLow; - - } -} - - - +/*% SONGETEVENTDATA returns the timings for an Event or marker channel +% +% Implemented through SONGetEventData.dll +% +% [npoints, times, levlow]= +% SONGETEVENTDATA(fh, chan, maxpoints, stime, etime{, filtermask}) +% +% INPUTS: FH = file handle +% CHAN = channel number 0 to SONMAXCHANS-1 +% MAXPOINTS = Maximum number of data values to return +% STIME = the start time for the data search +% (in clock ticks) +% ETIME = the end time for teh search +% (in clock ticks) +% FILTERMASK if present is a filter mask structure +% There will be no filtering if this is +% absent. +% OUTPUTS: NPOINTS= number of data points returned +% or a negative error +% TIMES = an NPOINT column vector containing the +% timestamps (in clock ticks) +% LEVLOW = For a EventBoth (level) channel, +% this is set to 1 if the first event +% is a high to low transition, 0 otherwise +% +% +% For error codes, see the CED documentation +% +%ML 05/05 +*/ + + + +#include +#include +#include +#include +#include + +#include "son.h" +#include "machine.h" +#include "SONDef.h" + +HINSTANCE hinstLib; +BOOL fFreeResult; + + +// Calls the SON32.DLL read routine +long _SONGetEventData(short fh, + WORD chan, + TpSTime plTimes, + long maxpoints, + TSTime sTime, + TSTime eTime, + TpBOOL plevLow, + TpFilterMask pFltMask) +{ + long i; + FARPROC SONGetEventData; + SONGetEventData = GetProcAddress(hinstLib,"SONGetEventData"); + if (SONGetEventData != NULL){ + i=(*SONGetEventData)(fh, chan, plTimes, maxpoints, sTime, eTime, plevLow, pFltMask); + return i; + } + mexErrMsgTxt("SONGetMarkData not found in SON32.DLL\n"); +} + + +void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[]) +{ + + short fh; + WORD chan; + long maxpoints; + TSTime sTime; + TSTime eTime; + TpFilterMask pFltMask=NULL; + TFilterMask FilterMask; + long npoints=0, *ret; + TpSTime plTimes; + int levLow=0; + int *ptr; + int dim[2]={1,1}; + double *p; + + + + + //Used for filter + int m,n; + const int *empty[2]={0,0}; + + + if (nrhs<5) + mexErrMsgTxt("SONGetEventData: Too few arguments\n"); + + //Get input arguments + fh=mxGetScalar(prhs[0]); //File handle + chan=mxGetScalar(prhs[1]); //Channel number + maxpoints=mxGetScalar(prhs[2]); //maxpoints + sTime=mxGetScalar(prhs[3]); //Start time for data search + eTime=mxGetScalar(prhs[4]); //End Time for data search + +mexPrintf("%d\n",eTime); + + //Get and set up the filter mask + if (nrhs==5 && mxIsStruct(prhs[5])==1){ + GetFilterMask(prhs[5], &FilterMask); + pFltMask=&FilterMask; + } + else + pFltMask=NULL; + + + //Load and get pointer to the library SON32.DLL// + hinstLib = LoadLibrary(SON32); + if (hinstLib == NULL){ + mexPrintf("%s not found",SON32); + plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); + p=mxGetData(plhs[0]); + p[0]=SON_BAD_PARAM; + return; + } + +// allocate array for return of event data + if (nlhs>=2){ + dim[0]=1; + dim[1]=maxpoints; + plhs[1]= mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); + plTimes=mxGetData(plhs[1]); + } + + //Call DLL + npoints=_SONGetEventData(fh, chan, plTimes, maxpoints, sTime, eTime, &levLow, pFltMask); + fFreeResult = FreeLibrary(hinstLib); + + + //return results. This one goes in ans if no arguments + dim[0]=1; + dim[1]=1; + plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); + ret=mxGetData(plhs[0]); + *ret=npoints; + + + if (nlhs==3) { + plhs[2]=mxCreateNumericArray(2, dim, mxINT16_CLASS, mxREAL); + ptr=mxGetData(plhs[2]); + *ptr=levLow; + + } +} + + + diff --git a/src/Import/SON/SON32/C_Sources/SONGetExtMarkData.c b/Import/SON/SON32/C_Sources/SONGetExtMarkData.c similarity index 96% rename from src/Import/SON/SON32/C_Sources/SONGetExtMarkData.c rename to Import/SON/SON32/C_Sources/SONGetExtMarkData.c index 1037a559..b35e5c05 100644 --- a/src/Import/SON/SON32/C_Sources/SONGetExtMarkData.c +++ b/Import/SON/SON32/C_Sources/SONGetExtMarkData.c @@ -1,247 +1,247 @@ -/*% SONGetExtMarkData returns the timings, marker values and extra data -% for an AdcMark, RealMark or TextMark channel -% -% Implemented through SONGetExtMarkData.dll -% -% [npoints, times, markers, extra]= -% SONGETEXTMARKDATA(fh, chan, maxpoints, stime, etime{, filtermask}) -% -% INPUTS: FH = file handle -% CHAN = channel number 0 to SONMAXCHANS-1 -% MAXPOINTS = Maximum number of data values to return -% (up to 32767, if zero this will be set to -% 32767) -% STIME = the start time for the data search -% (in clock ticks) -% ETIME = the end time for teh search -% (in clock ticks) -% FILTERMASK if present is a filter mask structure -% There will be no filtering if this is -% absent. -% OUTPUTS: NPOINTS= number of data points returned -% or a negative error -% TIMES = an NPOINT column vector containing the -% timestamps (in clock ticks) -% MARKERS = an NPOINT x 4 byte array, with 4 markers -% for each of the timestamps in TIMES. -% EXTRA= An X x NPOINT array. The NPOINT columns contain -% the extra data for each marker. The length of -% the columns varies between channels. -% EXTRA is int16 for ADCMark channels, single -% for RealMark and uint8 for TextMark -% -% Note: If required, cast TextMark EXTRA data to type char in MATLAB -% If you do not need the EXTRA data, use SONGetMarkData instead -% -% For error codes, see the CED documentation -% -%ML 04/05 - - */ - - - -#include -#include -#include -#include -#include "mex.h" - -#include "son.h" -#include "machine.h" -#include "SONDef.h" - -HINSTANCE hinstLib; -BOOL fFreeResult; - - -// Calls the SON32.DLL read routine -long _SONGetExtMarkData(short fh, -WORD chan, -TpMarker pMark, -long maxpoints, -TSTime sTime, -TSTime eTime, -TpFilterMask pFltMask) -{ - long i; - FARPROC SONGetExtMarkData; - SONGetExtMarkData = GetProcAddress(hinstLib,"SONGetExtMarkData"); - i=(*SONGetExtMarkData)(fh, chan, pMark, maxpoints, sTime, eTime,pFltMask); - return i; -} - -WORD _SONItemSize(short fh, WORD chan) -{ - FARPROC SONItemSize; - WORD i; - SONItemSize=GetProcAddress(hinstLib,"SONItemSize"); - i=(*SONItemSize)(fh, chan); - return i; -} - -TDataKind _SONChanKind(short fh, WORD chan) -{ - FARPROC SONChanKind; - TDataKind i; - SONChanKind=GetProcAddress(hinstLib, "SONChanKind"); - i=(*SONChanKind)(fh, chan); - return i; -} - - -void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[]) -{ - - short fh; - WORD chan; - TpMarker pMark; - long maxpoints; - TSTime sTime; - TSTime eTime; - TSTime StartTime; - TpSTime pbTime=&StartTime; - TpFilterMask pFltMask=NULL; - TFilterMask FilterMask; - double *p; - long npoints; - int dim[2]={1,1}; - long * ret; - int markbytes; - long *MarkPtr1; - long *ptr1; - char *MarkPtr2; - char *ptr2; - int n; - TpRealMark RealPtr, ptr4; - TpAdc AdcPtr, ptr3; - - //Used for filter - int m; - const int *empty[2]={0,0}; - - if (nrhs<5) - mexErrMsgTxt("SONGetExtMarkData: Too few arguments\n"); - - //Get input arguments - fh=mxGetScalar(prhs[0]); //File handle - chan=mxGetScalar(prhs[1]); //Channel number - maxpoints=mxGetScalar(prhs[2]); //maxpoints - see below - sTime=mxGetScalar(prhs[3]); //Start time for data search - eTime=mxGetScalar(prhs[4]); //End Time for data search - - - //Get and set up the filter mask - if (nrhs==6 && mxIsStruct(prhs[5])==1){ - GetFilterMask(prhs[5], &FilterMask); - pFltMask=&FilterMask; - } - else - pFltMask=NULL; - - - //Load and get pointer to the library SON32.DLL// - hinstLib = LoadLibrary(SON32); - if (hinstLib == NULL){ - mexPrintf("%s not found",SON32); - plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); - p=mxGetPr(plhs[0]); - p[0]=SON_BAD_PARAM; - return; - } - - markbytes=max(1,_SONItemSize(fh, chan)); - pMark=mxCalloc(maxpoints,markbytes); - - - //Call DLL - npoints=_SONGetExtMarkData(fh, chan, pMark, maxpoints, sTime, eTime, pFltMask); - fFreeResult = FreeLibrary(hinstLib); - - //return results. This one goes in ans if no arguments - plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); - ret=mxGetData(plhs[0]); - *ret=npoints; - - if (npoints<0) npoints=0; - - if (nlhs>=2){ - dim[0]=max(0,npoints); - dim[1]=1; - plhs[1]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); - ptr1=mxGetData(plhs[1]); - MarkPtr1=(long *)pMark; - for (m=0; m=3) { - dim[0]=max(0,npoints); - dim[1]=4; - plhs[2]=mxCreateNumericArray(2, dim, mxUINT8_CLASS, mxREAL); - ptr2=mxGetData(plhs[2]); - MarkPtr2=(char *)pMark+sizeof(long); - for (n=0; n<4; n++) { - for (m=0; m +#include +#include +#include +#include "mex.h" + +#include "son.h" +#include "machine.h" +#include "SONDef.h" + +HINSTANCE hinstLib; +BOOL fFreeResult; + + +// Calls the SON32.DLL read routine +long _SONGetExtMarkData(short fh, +WORD chan, +TpMarker pMark, +long maxpoints, +TSTime sTime, +TSTime eTime, +TpFilterMask pFltMask) +{ + long i; + FARPROC SONGetExtMarkData; + SONGetExtMarkData = GetProcAddress(hinstLib,"SONGetExtMarkData"); + i=(*SONGetExtMarkData)(fh, chan, pMark, maxpoints, sTime, eTime,pFltMask); + return i; +} + +WORD _SONItemSize(short fh, WORD chan) +{ + FARPROC SONItemSize; + WORD i; + SONItemSize=GetProcAddress(hinstLib,"SONItemSize"); + i=(*SONItemSize)(fh, chan); + return i; +} + +TDataKind _SONChanKind(short fh, WORD chan) +{ + FARPROC SONChanKind; + TDataKind i; + SONChanKind=GetProcAddress(hinstLib, "SONChanKind"); + i=(*SONChanKind)(fh, chan); + return i; +} + + +void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[]) +{ + + short fh; + WORD chan; + TpMarker pMark; + long maxpoints; + TSTime sTime; + TSTime eTime; + TSTime StartTime; + TpSTime pbTime=&StartTime; + TpFilterMask pFltMask=NULL; + TFilterMask FilterMask; + double *p; + long npoints; + int dim[2]={1,1}; + long * ret; + int markbytes; + long *MarkPtr1; + long *ptr1; + char *MarkPtr2; + char *ptr2; + int n; + TpRealMark RealPtr, ptr4; + TpAdc AdcPtr, ptr3; + + //Used for filter + int m; + const int *empty[2]={0,0}; + + if (nrhs<5) + mexErrMsgTxt("SONGetExtMarkData: Too few arguments\n"); + + //Get input arguments + fh=mxGetScalar(prhs[0]); //File handle + chan=mxGetScalar(prhs[1]); //Channel number + maxpoints=mxGetScalar(prhs[2]); //maxpoints - see below + sTime=mxGetScalar(prhs[3]); //Start time for data search + eTime=mxGetScalar(prhs[4]); //End Time for data search + + + //Get and set up the filter mask + if (nrhs==6 && mxIsStruct(prhs[5])==1){ + GetFilterMask(prhs[5], &FilterMask); + pFltMask=&FilterMask; + } + else + pFltMask=NULL; + + + //Load and get pointer to the library SON32.DLL// + hinstLib = LoadLibrary(SON32); + if (hinstLib == NULL){ + mexPrintf("%s not found",SON32); + plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); + p=mxGetPr(plhs[0]); + p[0]=SON_BAD_PARAM; + return; + } + + markbytes=max(1,_SONItemSize(fh, chan)); + pMark=mxCalloc(maxpoints,markbytes); + + + //Call DLL + npoints=_SONGetExtMarkData(fh, chan, pMark, maxpoints, sTime, eTime, pFltMask); + fFreeResult = FreeLibrary(hinstLib); + + //return results. This one goes in ans if no arguments + plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); + ret=mxGetData(plhs[0]); + *ret=npoints; + + if (npoints<0) npoints=0; + + if (nlhs>=2){ + dim[0]=max(0,npoints); + dim[1]=1; + plhs[1]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); + ptr1=mxGetData(plhs[1]); + MarkPtr1=(long *)pMark; + for (m=0; m=3) { + dim[0]=max(0,npoints); + dim[1]=4; + plhs[2]=mxCreateNumericArray(2, dim, mxUINT8_CLASS, mxREAL); + ptr2=mxGetData(plhs[2]); + MarkPtr2=(char *)pMark+sizeof(long); + for (n=0; n<4; n++) { + for (m=0; m -#include -#include -#include -#include - -#include "son.h" -#include "machine.h" -#include "SONDef.h" - -HINSTANCE hinstLib; -BOOL fFreeResult; - - -// Calls the SON32.DLL read routine -long _SONGetMarkData(short fh, -WORD chan, -TpMarker pMark, -long maxpoints, -TSTime sTime, -TSTime eTime, -TpFilterMask pFltMask) -{ - long i; - FARPROC SONGetMarkData; - SONGetMarkData = GetProcAddress(hinstLib,"SONGetMarkData"); - if (SONGetMarkData != NULL){ - i=(*SONGetMarkData)(fh, chan, pMark, maxpoints, sTime, eTime, pFltMask); - return i; - } - mexErrMsgTxt("SONGetMarkData not found in SON32.DLL\n"); -} - - -void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[]) -{ - - short fh; - WORD chan; - long maxpoints; - TSTime sTime; - TSTime eTime; - TpFilterMask pFltMask=NULL; - TFilterMask FilterMask; - long npoints=0; - TMarker Markers[32767]; - short levLow; - unsigned char *ptr; - int dim[2]={1,1}; - double *p; - long *ret; - int i,j; - - - - //Used for filter - int m,n; - const int *empty[2]={0,0}; - - - if (nrhs<5) - mexErrMsgTxt("SONGetMarkData: Too few arguments\n"); - - //Get input arguments - fh=mxGetScalar(prhs[0]); //File handle - chan=mxGetScalar(prhs[1]); //Channel number - maxpoints=mxGetScalar(prhs[2]); //maxpoints - if ((maxpoints>32767) || (maxpoints<=0)) - maxpoints=32767; - sTime=mxGetScalar(prhs[3]); //Start time for data search - eTime=mxGetScalar(prhs[4]); //End Time for data search - - - - //Get and set up the filter mask - if (nrhs==6 && mxIsStruct(prhs[5])==1){ - GetFilterMask(prhs[5], &FilterMask); - pFltMask=&FilterMask; - } - else - pFltMask=NULL; - - - //Load and get pointer to the library SON32.DLL// - hinstLib = LoadLibrary(SON32); - if (hinstLib == NULL){ - mexPrintf("%s not found",SON32); - plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); - p=mxGetData(plhs[0]); - p[0]=SON_BAD_PARAM; - return; - } - - - - //Call DLL - npoints=_SONGetMarkData(fh, chan, &Markers, maxpoints, sTime, eTime, pFltMask); - fFreeResult = FreeLibrary(hinstLib); - - - //return results. This one goes in ans if no arguments - dim[0]=1; - dim[1]=1; - plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); - ret=mxGetData(plhs[0]); - *ret=npoints; - - - if (nlhs>=2) { - dim[0]=max(0,npoints); - plhs[1]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); - ret=mxGetData(plhs[1]); - for (i=0; i +#include +#include +#include +#include + +#include "son.h" +#include "machine.h" +#include "SONDef.h" + +HINSTANCE hinstLib; +BOOL fFreeResult; + + +// Calls the SON32.DLL read routine +long _SONGetMarkData(short fh, +WORD chan, +TpMarker pMark, +long maxpoints, +TSTime sTime, +TSTime eTime, +TpFilterMask pFltMask) +{ + long i; + FARPROC SONGetMarkData; + SONGetMarkData = GetProcAddress(hinstLib,"SONGetMarkData"); + if (SONGetMarkData != NULL){ + i=(*SONGetMarkData)(fh, chan, pMark, maxpoints, sTime, eTime, pFltMask); + return i; + } + mexErrMsgTxt("SONGetMarkData not found in SON32.DLL\n"); +} + + +void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[]) +{ + + short fh; + WORD chan; + long maxpoints; + TSTime sTime; + TSTime eTime; + TpFilterMask pFltMask=NULL; + TFilterMask FilterMask; + long npoints=0; + TMarker Markers[32767]; + short levLow; + unsigned char *ptr; + int dim[2]={1,1}; + double *p; + long *ret; + int i,j; + + + + //Used for filter + int m,n; + const int *empty[2]={0,0}; + + + if (nrhs<5) + mexErrMsgTxt("SONGetMarkData: Too few arguments\n"); + + //Get input arguments + fh=mxGetScalar(prhs[0]); //File handle + chan=mxGetScalar(prhs[1]); //Channel number + maxpoints=mxGetScalar(prhs[2]); //maxpoints + if ((maxpoints>32767) || (maxpoints<=0)) + maxpoints=32767; + sTime=mxGetScalar(prhs[3]); //Start time for data search + eTime=mxGetScalar(prhs[4]); //End Time for data search + + + + //Get and set up the filter mask + if (nrhs==6 && mxIsStruct(prhs[5])==1){ + GetFilterMask(prhs[5], &FilterMask); + pFltMask=&FilterMask; + } + else + pFltMask=NULL; + + + //Load and get pointer to the library SON32.DLL// + hinstLib = LoadLibrary(SON32); + if (hinstLib == NULL){ + mexPrintf("%s not found",SON32); + plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); + p=mxGetData(plhs[0]); + p[0]=SON_BAD_PARAM; + return; + } + + + + //Call DLL + npoints=_SONGetMarkData(fh, chan, &Markers, maxpoints, sTime, eTime, pFltMask); + fFreeResult = FreeLibrary(hinstLib); + + + //return results. This one goes in ans if no arguments + dim[0]=1; + dim[1]=1; + plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); + ret=mxGetData(plhs[0]); + *ret=npoints; + + + if (nlhs>=2) { + dim[0]=max(0,npoints); + plhs[1]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); + ret=mxGetData(plhs[1]); + for (i=0; i -#include -#include -#include -#include - -#include "son.h" -#include "machine.h" -#include "SONDef.h" - -HINSTANCE hinstLib; -BOOL fFreeResult; - - -// Calls the SON32.DLL read routine -long _SONGetRealData(short fh, -WORD chan, -TpFloat psData, -long maxpoints, -TSTime sTime, -TSTime eTime, -TpSTime pbTime, -TpFilterMask pFltMask) -{ - long i; - FARPROC SONGetRealData; - SONGetRealData = GetProcAddress(hinstLib,"SONGetRealData"); - if (SONGetRealData != NULL) { - i=(*SONGetRealData)(fh, chan, psData, maxpoints, sTime, eTime, - pbTime, pFltMask); - return i; - } - mexErrMsgTxt("SONGetRealData not found in DLL\n"); -} - -// Returns the number of clock ticks per sampling interval for channel -// chan -int ChanInterval(short fh, WORD chan) -{ - FARPROC SONGetTimePerADC, SONChanDivide; - WORD a; - TSTime b; - - SONGetTimePerADC=GetProcAddress(hinstLib,"SONGetTimePerADC"); - SONChanDivide=GetProcAddress(hinstLib,"SONChanDivide"); - if ((SONGetTimePerADC==NULL) || (SONChanDivide==NULL)) { - mexErrMsgTxt("Required routines not found in SON32.DLL"); - } - a=(*SONGetTimePerADC)(fh, 0); - b=(*SONChanDivide)(fh, chan); - return a*b ; -} - -void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[]) -{ - - short fh; - WORD chan; - TpFloat psData=NULL; - long maxpoints; - TSTime sTime; - TSTime eTime; - TSTime StartTime; - TpSTime pbTime=&StartTime; - TpFilterMask pFltMask=NULL; - TFilterMask FilterMask; - double *p; - long npoints; - int dim[2]={1,1}; - long * ret; - int mode, m; - const int empty[2]={0,0}; - - - if (nrhs<5) - mexErrMsgTxt("SONGetRealData: Too few input arguments\n"); - - //Get input arguments - fh=mxGetScalar(prhs[0]); //File handle - chan=mxGetScalar(prhs[1]); //Channel number - //maxpoints - see below - sTime=mxGetScalar(prhs[3]); //Start time for data search - eTime=mxGetScalar(prhs[4]); //End Time for data search - -//prhs[2] can be maxpoints (a scalar; =mode 1)or a pointer to a -//pre-allocated array in the matlab calling space (mode 2). - if (mxGetM(prhs[2])==1 && mxGetN(prhs[2])==1) {// scalar so mode 1 - if (nlhs<3) { - mexPrintf("SONGetRealData:Too few LHS arguments \n"); - plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); - ret=mxGetData(plhs[0]); - *ret=SON_BAD_PARAM; - for (m=1; m1)||(mxGetClassID(prhs[2])!= mxSINGLE_CLASS)) { - mexPrintf("SONGetRealData:" - "Data array must be a 16 bit float column vector\n"); - plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); - ret=mxGetData(plhs[0]); - *ret=SON_BAD_PARAM; - for (m=1; m=3) { - dim[1]=maxpoints; - plhs[2]=mxCreateNumericArray(2, dim, mxSINGLE_CLASS, mxREAL); - psData=mxGetData(plhs[2]); -} - - if(psData != NULL){ - - //Call DLL - npoints=_SONGetRealData(fh, chan, psData, maxpoints, sTime, eTime, - pbTime, pFltMask); - fFreeResult = FreeLibrary(hinstLib); - - //return results. This one goes in ans if no arguments - dim[1]=1; - plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); - ret=mxGetData(plhs[0]); - *ret=npoints; - - if (nlhs>=2){ - plhs[1]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); - ret=mxGetData(plhs[1]); - *ret=*pbTime; - } - } - -} - - +/*% SONGETREALDATA returns data for Adc, AdcMark, RealWave ( and RealMark?) +% data channels +% +% Implemented through SONGetRealData.dll +% +% [npoints, bTime, data]=SONGETREALDATA(fh, chan,... +% maxpoints, sTime, eTime{, FilterMask}) +% +% INPUTS: FH = file handle +% CHAN = channel number 0 to SONMAXCHANS-1 +% MAXPOINTS = Maximum number of data points to return +% The routine will calculate MAXPOINTS +% if this is passed as zero or less. +% STIME = the start time for the data search +% (in clock ticks) +% ETIME = the end time for teh search +% (in clock ticks) +% FILTERMASK if present is a filter mask structure +% There will be no filtering if this is +% absent. +% OUTPUTS: NPOINTS= number of data points returned +% or a negative error +% BTIME = the time for the first sample returned in +% data (in clock ticks) +% DATA = the output data array +% +% Alternative call: +% [npoints, bTime]=SONGETREALDATA(fh, chan,... +% data, sTime, eTime{, FilterMask}) +% Here, DATA must be a pre-allocated 16 bit float column vector. SON32.DLL will +% place data directly into this array in the matlab workspace. For repeated +% calls, this can be faster but it breaks normal matlab conventions. +% +% For error codes returned in NPOINTS see the CED documentation +% +% ML 03/05*/ + + +#include +#include +#include +#include +#include + +#include "son.h" +#include "machine.h" +#include "SONDef.h" + +HINSTANCE hinstLib; +BOOL fFreeResult; + + +// Calls the SON32.DLL read routine +long _SONGetRealData(short fh, +WORD chan, +TpFloat psData, +long maxpoints, +TSTime sTime, +TSTime eTime, +TpSTime pbTime, +TpFilterMask pFltMask) +{ + long i; + FARPROC SONGetRealData; + SONGetRealData = GetProcAddress(hinstLib,"SONGetRealData"); + if (SONGetRealData != NULL) { + i=(*SONGetRealData)(fh, chan, psData, maxpoints, sTime, eTime, + pbTime, pFltMask); + return i; + } + mexErrMsgTxt("SONGetRealData not found in DLL\n"); +} + +// Returns the number of clock ticks per sampling interval for channel +// chan +int ChanInterval(short fh, WORD chan) +{ + FARPROC SONGetTimePerADC, SONChanDivide; + WORD a; + TSTime b; + + SONGetTimePerADC=GetProcAddress(hinstLib,"SONGetTimePerADC"); + SONChanDivide=GetProcAddress(hinstLib,"SONChanDivide"); + if ((SONGetTimePerADC==NULL) || (SONChanDivide==NULL)) { + mexErrMsgTxt("Required routines not found in SON32.DLL"); + } + a=(*SONGetTimePerADC)(fh, 0); + b=(*SONChanDivide)(fh, chan); + return a*b ; +} + +void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[]) +{ + + short fh; + WORD chan; + TpFloat psData=NULL; + long maxpoints; + TSTime sTime; + TSTime eTime; + TSTime StartTime; + TpSTime pbTime=&StartTime; + TpFilterMask pFltMask=NULL; + TFilterMask FilterMask; + double *p; + long npoints; + int dim[2]={1,1}; + long * ret; + int mode, m; + const int empty[2]={0,0}; + + + if (nrhs<5) + mexErrMsgTxt("SONGetRealData: Too few input arguments\n"); + + //Get input arguments + fh=mxGetScalar(prhs[0]); //File handle + chan=mxGetScalar(prhs[1]); //Channel number + //maxpoints - see below + sTime=mxGetScalar(prhs[3]); //Start time for data search + eTime=mxGetScalar(prhs[4]); //End Time for data search + +//prhs[2] can be maxpoints (a scalar; =mode 1)or a pointer to a +//pre-allocated array in the matlab calling space (mode 2). + if (mxGetM(prhs[2])==1 && mxGetN(prhs[2])==1) {// scalar so mode 1 + if (nlhs<3) { + mexPrintf("SONGetRealData:Too few LHS arguments \n"); + plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); + ret=mxGetData(plhs[0]); + *ret=SON_BAD_PARAM; + for (m=1; m1)||(mxGetClassID(prhs[2])!= mxSINGLE_CLASS)) { + mexPrintf("SONGetRealData:" + "Data array must be a 16 bit float column vector\n"); + plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); + ret=mxGetData(plhs[0]); + *ret=SON_BAD_PARAM; + for (m=1; m=3) { + dim[1]=maxpoints; + plhs[2]=mxCreateNumericArray(2, dim, mxSINGLE_CLASS, mxREAL); + psData=mxGetData(plhs[2]); +} + + if(psData != NULL){ + + //Call DLL + npoints=_SONGetRealData(fh, chan, psData, maxpoints, sTime, eTime, + pbTime, pFltMask); + fFreeResult = FreeLibrary(hinstLib); + + //return results. This one goes in ans if no arguments + dim[1]=1; + plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); + ret=mxGetData(plhs[0]); + *ret=npoints; + + if (nlhs>=2){ + plhs[1]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); + ret=mxGetData(plhs[1]); + *ret=*pbTime; + } + } + +} + + diff --git a/src/Import/SON/SON32/C_Sources/SONGetVersion.c b/Import/SON/SON32/C_Sources/SONGetVersion.c similarity index 94% rename from src/Import/SON/SON32/C_Sources/SONGetVersion.c rename to Import/SON/SON32/C_Sources/SONGetVersion.c index 6c62f92f..27bda665 100644 --- a/src/Import/SON/SON32/C_Sources/SONGetVersion.c +++ b/Import/SON/SON32/C_Sources/SONGetVersion.c @@ -1,62 +1,62 @@ -#include -#include -#include -#include -#include "mex.h" - -#include "son.h" -#include "machine.h" -#include "SONDef.h" - -HINSTANCE hinstLib; -BOOL fFreeResult, fRunTimeLinkSuccess = FALSE; -char * function_name; - - -int _SONGetVersion(short fh) -{ - int j; - int (*ProcAdd)(); - - ProcAdd = GetProcAddress(hinstLib, "SONGetVersion"); - j=(ProcAdd)(fh); - return j; -} - - -void mexFunction(int nlhs, mxArray *plhs[], int nrhs, -const mxArray *prhs[]) -{ - - int *p; - int j; - short fh; - int dims[2]={1, 1}; - - -//Load and get pointer to the library SON32.DLL// - hinstLib = LoadLibrary(SON32); - if (hinstLib == NULL) - { - plhs[0]=mxCreateNumericArray(2, dims, mxINT32_CLASS, mxREAL); - p=mxGetPr(plhs[0]); - p[0]=SON_BAD_PARAM; - mexPrintf("%s NOT FOUND", SON32); - return; - } - - { - p=mxGetPr(prhs[0]); - fh=*p; - j=_SONGetVersion(fh); - plhs[0]=mxCreateNumericArray(2, dims, mxINT32_CLASS, mxREAL); - p=mxGetPr(plhs[0]); - p[0]=j; - fFreeResult = FreeLibrary(hinstLib); - } - -} - - - - +#include +#include +#include +#include +#include "mex.h" + +#include "son.h" +#include "machine.h" +#include "SONDef.h" + +HINSTANCE hinstLib; +BOOL fFreeResult, fRunTimeLinkSuccess = FALSE; +char * function_name; + + +int _SONGetVersion(short fh) +{ + int j; + int (*ProcAdd)(); + + ProcAdd = GetProcAddress(hinstLib, "SONGetVersion"); + j=(ProcAdd)(fh); + return j; +} + + +void mexFunction(int nlhs, mxArray *plhs[], int nrhs, +const mxArray *prhs[]) +{ + + int *p; + int j; + short fh; + int dims[2]={1, 1}; + + +//Load and get pointer to the library SON32.DLL// + hinstLib = LoadLibrary(SON32); + if (hinstLib == NULL) + { + plhs[0]=mxCreateNumericArray(2, dims, mxINT32_CLASS, mxREAL); + p=mxGetPr(plhs[0]); + p[0]=SON_BAD_PARAM; + mexPrintf("%s NOT FOUND", SON32); + return; + } + + { + p=mxGetPr(prhs[0]); + fh=*p; + j=_SONGetVersion(fh); + plhs[0]=mxCreateNumericArray(2, dims, mxINT32_CLASS, mxREAL); + p=mxGetPr(plhs[0]); + p[0]=j; + fFreeResult = FreeLibrary(hinstLib); + } + +} + + + + diff --git a/src/Import/SON/SON32/C_Sources/SONLastPointsTime.c b/Import/SON/SON32/C_Sources/SONLastPointsTime.c similarity index 96% rename from src/Import/SON/SON32/C_Sources/SONLastPointsTime.c rename to Import/SON/SON32/C_Sources/SONLastPointsTime.c index 30c06ad3..1b87af62 100644 --- a/src/Import/SON/SON32/C_Sources/SONLastPointsTime.c +++ b/Import/SON/SON32/C_Sources/SONLastPointsTime.c @@ -1,123 +1,123 @@ -/*% SONLASTPOINTSTIME returns the time for which a read will terminate -% -% Implemented through SONLastPointsTime.dll -% -% TIME=SONGETADCDATA(FH, CHAN, ETIME, STIME, LPOINTS, BADC {, FILTERMASK}) -% -% INPUTS: FH SON File Handle -% CHAN Channel number (1 to SONMaxChannels) -% STIME Searches back from this time -% ETIME stops search at this time (eTime must be less than sTime) -% LPOINTS the number of points it is dsired to read -% BADC ADCMark data will be treated as Adc if this set -% FILTERMASK, if present, a filter mask -% -% Returns the time at which the read will end i.e. the time of the final data -% point or a negative error code -% -% ML 05/05 -*/ - -#include -#include -#include -#include -#include "mex.h" - -#include "son.h" -#include "machine.h" -#include "SONDef.h" - -HINSTANCE hinstLib; -BOOL fFreeResult; - - -// Calls the SON32.DLL routine - -TSTime _SONLastPointsTime(short fh, - WORD chan, - TSTime sTime, - TSTime eTime, - long lpoints, - BOOL bAdc, - TpFilterMask pFltMask) -{ - FARPROC SONLastPointsTime; - TSTime ret; - - SONLastPointsTime=GetProcAddress(hinstLib, "SONLastPointsTime"); - if (SONLastPointsTime!=NULL){ - ret=(*SONLastPointsTime)(fh, chan, sTime, eTime, lpoints, bAdc, pFltMask); - return ret; - } -} - - - -void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[]) -{ - - short fh; - WORD chan; - TSTime sTime, eTime, ResTime; - TpSTime peTime; - unsigned char *ptr; - TpFilterMask pFltMask=NULL; - TFilterMask FilterMask; - BOOL bAdc; - long lpoints; - - int const dim[2]={1,1}; - int m; - - int GetFilterMask(); - - - if (nrhs<6) - mexErrMsgTxt("SONGetADCData: Too few input arguments\n"); - - //Get input arguments - fh=mxGetScalar(prhs[0]); //File handle - chan=mxGetScalar(prhs[1]); //Channel number - sTime=mxGetScalar(prhs[2]); //Start time for data search - eTime=mxGetScalar(prhs[3]); //End Time - lpoints=mxGetScalar(prhs[4]); //Number of points - bAdc=mxGetScalar(prhs[5]); // If set, treat ADCMark data - // as adc - - //Get and set up the filter mask - if (nrhs==7 && mxIsStruct(prhs[7])==1){ - GetFilterMask(prhs[7], FilterMask); - pFltMask=&FilterMask; - } - else - pFltMask=NULL; - - - //Load and get pointer to the library SON32.DLL// - hinstLib = LoadLibrary(SON32); - if (hinstLib == NULL){ - mexPrintf("%s not found",SON32); - plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); - *mxGetPr(plhs[0])=SON_BAD_PARAM; - return; - } - - - ResTime=_SONLastPointsTime(fh, chan, sTime, eTime, bAdc, lpoints, pFltMask); - fFreeResult = FreeLibrary(hinstLib); - - plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); - peTime=mxGetData(plhs[0]); - *peTime=ResTime; - - -} - - - - - - - - +/*% SONLASTPOINTSTIME returns the time for which a read will terminate +% +% Implemented through SONLastPointsTime.dll +% +% TIME=SONGETADCDATA(FH, CHAN, ETIME, STIME, LPOINTS, BADC {, FILTERMASK}) +% +% INPUTS: FH SON File Handle +% CHAN Channel number (1 to SONMaxChannels) +% STIME Searches back from this time +% ETIME stops search at this time (eTime must be less than sTime) +% LPOINTS the number of points it is dsired to read +% BADC ADCMark data will be treated as Adc if this set +% FILTERMASK, if present, a filter mask +% +% Returns the time at which the read will end i.e. the time of the final data +% point or a negative error code +% +% ML 05/05 +*/ + +#include +#include +#include +#include +#include "mex.h" + +#include "son.h" +#include "machine.h" +#include "SONDef.h" + +HINSTANCE hinstLib; +BOOL fFreeResult; + + +// Calls the SON32.DLL routine + +TSTime _SONLastPointsTime(short fh, + WORD chan, + TSTime sTime, + TSTime eTime, + long lpoints, + BOOL bAdc, + TpFilterMask pFltMask) +{ + FARPROC SONLastPointsTime; + TSTime ret; + + SONLastPointsTime=GetProcAddress(hinstLib, "SONLastPointsTime"); + if (SONLastPointsTime!=NULL){ + ret=(*SONLastPointsTime)(fh, chan, sTime, eTime, lpoints, bAdc, pFltMask); + return ret; + } +} + + + +void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[]) +{ + + short fh; + WORD chan; + TSTime sTime, eTime, ResTime; + TpSTime peTime; + unsigned char *ptr; + TpFilterMask pFltMask=NULL; + TFilterMask FilterMask; + BOOL bAdc; + long lpoints; + + int const dim[2]={1,1}; + int m; + + int GetFilterMask(); + + + if (nrhs<6) + mexErrMsgTxt("SONGetADCData: Too few input arguments\n"); + + //Get input arguments + fh=mxGetScalar(prhs[0]); //File handle + chan=mxGetScalar(prhs[1]); //Channel number + sTime=mxGetScalar(prhs[2]); //Start time for data search + eTime=mxGetScalar(prhs[3]); //End Time + lpoints=mxGetScalar(prhs[4]); //Number of points + bAdc=mxGetScalar(prhs[5]); // If set, treat ADCMark data + // as adc + + //Get and set up the filter mask + if (nrhs==7 && mxIsStruct(prhs[7])==1){ + GetFilterMask(prhs[7], FilterMask); + pFltMask=&FilterMask; + } + else + pFltMask=NULL; + + + //Load and get pointer to the library SON32.DLL// + hinstLib = LoadLibrary(SON32); + if (hinstLib == NULL){ + mexPrintf("%s not found",SON32); + plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); + *mxGetPr(plhs[0])=SON_BAD_PARAM; + return; + } + + + ResTime=_SONLastPointsTime(fh, chan, sTime, eTime, bAdc, lpoints, pFltMask); + fFreeResult = FreeLibrary(hinstLib); + + plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); + peTime=mxGetData(plhs[0]); + *peTime=ResTime; + + +} + + + + + + + + diff --git a/src/Import/SON/SON32/C_Sources/SONLastTime.c b/Import/SON/SON32/C_Sources/SONLastTime.c similarity index 96% rename from src/Import/SON/SON32/C_Sources/SONLastTime.c rename to Import/SON/SON32/C_Sources/SONLastTime.c index 08b08cc9..2490e584 100644 --- a/src/Import/SON/SON32/C_Sources/SONLastTime.c +++ b/Import/SON/SON32/C_Sources/SONLastTime.c @@ -1,149 +1,149 @@ -/*% SONLASTTIME returns information about the last entry on a channel -% before a specified time -% -% Implemented through SONLastTime.dll -% -%[time, data, markers, markerflag]=... -% SONGETADCDATA(fh, chan, eTime, sTime{, FilterMask}) -% -% INPUTS: FH SON File Handle -% CHAN Channel number (1 to SONMaxChannels) -% STIME Searches back from this time -% ETIME stops search at this time (eTime must be less than sTime) -% FILTERMASK, if present, a filter mask -% -% OUTPUTS: TIME The time of the last data point between ETIME and STIME -% or a negative error code -% DATA Value at TIME for an ADC or Real channel. -% For an EventBoth channel the InitLow value -% MARKERS the marker codes for the event at TIME for -% a marker channel -% MARKERFLAG Set to 1 if CHAN is a marker channel, 0 otherwise -% -% ML 04/05 -*/ - -#include -#include -#include -#include -#include "mex.h" - -#include "son.h" -#include "machine.h" -#include "SONDef.h" - -HINSTANCE hinstLib; -BOOL fFreeResult; - - -// Calls the SON32.DLL routine - -TSTime _SONLastTime(short fh, - WORD chan, - TSTime sTime, - TSTime eTime, - TpVoid pvVal, - TpMarkBytes pMB, - TpBOOL pbMark, - TpFilterMask pFltMask) -{ - FARPROC SONLastTime; - TSTime ret; - - SONLastTime=GetProcAddress(hinstLib, "SONLastTime"); - if (SONLastTime!=NULL){ - ret=(*SONLastTime)(fh, chan, sTime, eTime, pvVal, pMB, pbMark, pFltMask); - return ret; - } - else { - mexErrMsgTxt("SONLastTime not found in DLL"); - return -99; - } -} - - - -void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[]) -{ - - short fh; - WORD chan; - TSTime sTime, eTime, ResTime; - TpSTime peTime; - TMarkBytes MB={0,0,0,0}; - unsigned char *ptr; - BOOLEAN bMark=0; - TpFilterMask pFltMask=NULL; - TFilterMask FilterMask; - TAdc p=0; - TpAdc pdata; - int dim[2]={1,1}; - int m; - - int GetFilterMask(); - - - if (nrhs<3) - mexErrMsgTxt("SONGetADCData: Too few input arguments\n"); - - //Get input arguments - fh=mxGetScalar(prhs[0]); //File handle - chan=mxGetScalar(prhs[1]); //Channel number - sTime=mxGetScalar(prhs[2]); //Start time for data search - eTime=mxGetScalar(prhs[3]); //End Time - - //Get and set up the filter mask - if (nrhs==5 && mxIsStruct(prhs[4])==1){ - GetFilterMask(prhs[4], FilterMask); - pFltMask=&FilterMask; - } - else - pFltMask=NULL; - - - //Load and get pointer to the library SON32.DLL// - hinstLib = LoadLibrary(SON32); - if (hinstLib == NULL){ - mexPrintf("%s not found",SON32); - plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); - *mxGetPr(plhs[0])=SON_BAD_PARAM; - return; - } - - -ResTime=_SONLastTime(fh, chan, sTime, eTime, &p, MB, &bMark, pFltMask); -fFreeResult = FreeLibrary(hinstLib); - - plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); - peTime=mxGetData(plhs[0]); - *peTime=ResTime; - - if(nlhs>=2){ - plhs[1]=mxCreateNumericArray(2, dim, mxINT16_CLASS, mxREAL); - pdata=mxGetData(plhs[1]); - *pdata=p; - } - - if (nlhs>=3){ - dim[1]=4; - plhs[2]=mxCreateNumericArray(2,dim,mxUINT8_CLASS,mxREAL); - ptr=mxGetData(plhs[2]); - for (m=0; m<=3; m++) - *ptr++=MB[m]; - } - - if (nlhs==4){ - dim[1]=1; - plhs[3]=mxCreateNumericArray(2,dim,mxDOUBLE_CLASS,mxREAL); - *mxGetPr(plhs[3])=bMark; - } -} - - - - - - - - +/*% SONLASTTIME returns information about the last entry on a channel +% before a specified time +% +% Implemented through SONLastTime.dll +% +%[time, data, markers, markerflag]=... +% SONGETADCDATA(fh, chan, eTime, sTime{, FilterMask}) +% +% INPUTS: FH SON File Handle +% CHAN Channel number (1 to SONMaxChannels) +% STIME Searches back from this time +% ETIME stops search at this time (eTime must be less than sTime) +% FILTERMASK, if present, a filter mask +% +% OUTPUTS: TIME The time of the last data point between ETIME and STIME +% or a negative error code +% DATA Value at TIME for an ADC or Real channel. +% For an EventBoth channel the InitLow value +% MARKERS the marker codes for the event at TIME for +% a marker channel +% MARKERFLAG Set to 1 if CHAN is a marker channel, 0 otherwise +% +% ML 04/05 +*/ + +#include +#include +#include +#include +#include "mex.h" + +#include "son.h" +#include "machine.h" +#include "SONDef.h" + +HINSTANCE hinstLib; +BOOL fFreeResult; + + +// Calls the SON32.DLL routine + +TSTime _SONLastTime(short fh, + WORD chan, + TSTime sTime, + TSTime eTime, + TpVoid pvVal, + TpMarkBytes pMB, + TpBOOL pbMark, + TpFilterMask pFltMask) +{ + FARPROC SONLastTime; + TSTime ret; + + SONLastTime=GetProcAddress(hinstLib, "SONLastTime"); + if (SONLastTime!=NULL){ + ret=(*SONLastTime)(fh, chan, sTime, eTime, pvVal, pMB, pbMark, pFltMask); + return ret; + } + else { + mexErrMsgTxt("SONLastTime not found in DLL"); + return -99; + } +} + + + +void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[]) +{ + + short fh; + WORD chan; + TSTime sTime, eTime, ResTime; + TpSTime peTime; + TMarkBytes MB={0,0,0,0}; + unsigned char *ptr; + BOOLEAN bMark=0; + TpFilterMask pFltMask=NULL; + TFilterMask FilterMask; + TAdc p=0; + TpAdc pdata; + int dim[2]={1,1}; + int m; + + int GetFilterMask(); + + + if (nrhs<3) + mexErrMsgTxt("SONGetADCData: Too few input arguments\n"); + + //Get input arguments + fh=mxGetScalar(prhs[0]); //File handle + chan=mxGetScalar(prhs[1]); //Channel number + sTime=mxGetScalar(prhs[2]); //Start time for data search + eTime=mxGetScalar(prhs[3]); //End Time + + //Get and set up the filter mask + if (nrhs==5 && mxIsStruct(prhs[4])==1){ + GetFilterMask(prhs[4], FilterMask); + pFltMask=&FilterMask; + } + else + pFltMask=NULL; + + + //Load and get pointer to the library SON32.DLL// + hinstLib = LoadLibrary(SON32); + if (hinstLib == NULL){ + mexPrintf("%s not found",SON32); + plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); + *mxGetPr(plhs[0])=SON_BAD_PARAM; + return; + } + + +ResTime=_SONLastTime(fh, chan, sTime, eTime, &p, MB, &bMark, pFltMask); +fFreeResult = FreeLibrary(hinstLib); + + plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); + peTime=mxGetData(plhs[0]); + *peTime=ResTime; + + if(nlhs>=2){ + plhs[1]=mxCreateNumericArray(2, dim, mxINT16_CLASS, mxREAL); + pdata=mxGetData(plhs[1]); + *pdata=p; + } + + if (nlhs>=3){ + dim[1]=4; + plhs[2]=mxCreateNumericArray(2,dim,mxUINT8_CLASS,mxREAL); + ptr=mxGetData(plhs[2]); + for (m=0; m<=3; m++) + *ptr++=MB[m]; + } + + if (nlhs==4){ + dim[1]=1; + plhs[3]=mxCreateNumericArray(2,dim,mxDOUBLE_CLASS,mxREAL); + *mxGetPr(plhs[3])=bMark; + } +} + + + + + + + + diff --git a/src/Import/SON/SON32/C_Sources/SONSetMarker.c b/Import/SON/SON32/C_Sources/SONSetMarker.c similarity index 96% rename from src/Import/SON/SON32/C_Sources/SONSetMarker.c rename to Import/SON/SON32/C_Sources/SONSetMarker.c index 6f03680d..6feb05c2 100644 --- a/src/Import/SON/SON32/C_Sources/SONSetMarker.c +++ b/Import/SON/SON32/C_Sources/SONSetMarker.c @@ -1,194 +1,194 @@ -/*% SONSETMARKER replaces the data associated with a marker on disc -% -% Implemented through SONSetMarker.dll -% -% RET=SONSETMARKER(FH, CHAN, TIME, NEWTIME, {NEWMARKERS, {NEWEXTRA}}) -% FH = the SON file handle -% CHAN = the target marker channel -% TIME = the current timestamp of the target marker entry (clock ticks) -% NEWTIME = a new time that will replace the timestamp in TIME -% NEWMARKERS = if present, a set of 4 uint8 marker values that will replace -% those on disc -% NEWEXTRA = if present, the extra data to replace all or some of the -% existing extra data -% These may be: int16 (for AdcMark) -% single (for RealMark) -% or uint8 (for TextMark) -% (N.B. not char which is 16bit in matlab) -% -% The data type for NEWEXTRA must match that of the target channel (the function -% returns SON_NO_EXTRA if it does not. -% -% e.g SONSetMarker(fh, 2, 140100, 140200) -% replaces the timestamp only -% SONSetMarker (fh, 2, 140100, 14020, uint8([22 33 44 55])) -% replaces the markers also -% SONSetMarker (fh, 2, 140100, 14020, uint8([22 33 44 55]), int16([0 0])) -% also replaces the first two extra data entries with zero on an AdcMark channel -% -% Returns: 1 if the replacement occured. -% 0 if not e.g. NEWEXTRA is longer than the existing entry or the -% new timestamp would break the temporal sequence of successive -% entries -% or an negative error code -% -% -% ML 05/05 - */ - - - -#include -#include -#include -#include -#include - -#include "son.h" -#include "machine.h" -#include "SONDef.h" - -HINSTANCE hinstLib; -BOOL fFreeResult; - - -// Calls the SON32.DLL read routine -short _SONSetMarker(short fh, -WORD chan, -TSTime time, -TpMarker pMark, -WORD size) -{ - short i; - FARPROC SONSetMarker; - SONSetMarker = GetProcAddress(hinstLib,"SONSetMarker"); - if (SONSetMarker != NULL){ - i=(*SONSetMarker)(fh, chan, time, pMark, size); - return i; - } - mexErrMsgTxt("SONSetMarker not found in SON32.DLL\n"); -} - - -TDataKind _SONChanKind(short fh, WORD chan) -{ - FARPROC SONChanKind; - TDataKind i; - SONChanKind=GetProcAddress(hinstLib, "SONChanKind"); - i=(*SONChanKind)(fh, chan); - return i; -} - -void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[]) -{ - - short fh; - WORD chan; - long npoints=0; - unsigned char *ptr; - int dim[2]={1,1}; - long *p; - int err=0; - WORD size=0; - TSTime time; - TMarker Marker; - TAdcMark adcmark; - TRealMark realmark; - TTextMark textmark; - TpMarker temp=&Marker; - - - if (nrhs<4) - mexErrMsgTxt("SONSetMarker: Too few arguments\n"); - - - //Get input arguments - fh=mxGetScalar(prhs[0]); //File handle - chan=mxGetScalar(prhs[1]); //Channel number - time=mxGetScalar(prhs[2]); // time of marker - - - Marker.mark=mxGetScalar(prhs[3]); //New timestamp value - size=sizeof(TSTime); - - //New marker values if present - if(nrhs>=5) { - ptr=mxGetData(prhs[4]); - memcpy(&Marker.mvals, ptr, sizeof(TMarkBytes)); - size=sizeof(TMarker); - } - - //Load and get pointer to the library SON32.DLL// - hinstLib = LoadLibrary(SON32); - if (hinstLib == NULL){ - mexPrintf("%s not found",SON32); - plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); - p=mxGetData(plhs[0]); - p[0]=SON_BAD_PARAM; - return; - } - - //Extra data if present - if (nrhs==6) { - switch (mxGetClassID(prhs[5])){ - case mxUINT8_CLASS: - if (_SONChanKind(fh, chan)== 8) { - size=mxGetN(prhs[5])*mxGetM(prhs[5]); - memcpy(&textmark.t, mxGetData(prhs[5]), size); - textmark.m=Marker; - temp=(TpMarker)&textmark; - } - else - err=SON_NO_EXTRA; - break; - case mxINT16_CLASS: - if (_SONChanKind(fh, chan)== 6) { - size=2*mxGetN(prhs[5])*mxGetM(prhs[5]); - memcpy(&adcmark.a, mxGetData(prhs[5]), size); - adcmark.m=Marker; - temp=(TpMarker)&adcmark; - } - else - err=SON_NO_EXTRA; - break; - case mxSINGLE_CLASS: - if (_SONChanKind(fh, chan)== 7) { - size=4*mxGetN(prhs[5])*mxGetM(prhs[5]); - memcpy(&realmark.r, mxGetData(prhs[5]), size); - realmark.m=Marker; - temp=(TpMarker)&realmark; - } - else - err=SON_NO_EXTRA; - break; - } - size=size+sizeof(TMarker); - } - else - err=SON_BAD_PARAM; - - - - if (err != 0) { - plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); - p=mxGetData(plhs[0]); - p[0]=err; - return; - } - - - //Call DLL - npoints=_SONSetMarker(fh, chan, time, temp, size); - fFreeResult = FreeLibrary(hinstLib); - - - //return results. This one goes in ans if no arguments - plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); - p=mxGetData(plhs[0]); - p[0]=npoints; - - -} - - - +/*% SONSETMARKER replaces the data associated with a marker on disc +% +% Implemented through SONSetMarker.dll +% +% RET=SONSETMARKER(FH, CHAN, TIME, NEWTIME, {NEWMARKERS, {NEWEXTRA}}) +% FH = the SON file handle +% CHAN = the target marker channel +% TIME = the current timestamp of the target marker entry (clock ticks) +% NEWTIME = a new time that will replace the timestamp in TIME +% NEWMARKERS = if present, a set of 4 uint8 marker values that will replace +% those on disc +% NEWEXTRA = if present, the extra data to replace all or some of the +% existing extra data +% These may be: int16 (for AdcMark) +% single (for RealMark) +% or uint8 (for TextMark) +% (N.B. not char which is 16bit in matlab) +% +% The data type for NEWEXTRA must match that of the target channel (the function +% returns SON_NO_EXTRA if it does not. +% +% e.g SONSetMarker(fh, 2, 140100, 140200) +% replaces the timestamp only +% SONSetMarker (fh, 2, 140100, 14020, uint8([22 33 44 55])) +% replaces the markers also +% SONSetMarker (fh, 2, 140100, 14020, uint8([22 33 44 55]), int16([0 0])) +% also replaces the first two extra data entries with zero on an AdcMark channel +% +% Returns: 1 if the replacement occured. +% 0 if not e.g. NEWEXTRA is longer than the existing entry or the +% new timestamp would break the temporal sequence of successive +% entries +% or an negative error code +% +% +% ML 05/05 + */ + + + +#include +#include +#include +#include +#include + +#include "son.h" +#include "machine.h" +#include "SONDef.h" + +HINSTANCE hinstLib; +BOOL fFreeResult; + + +// Calls the SON32.DLL read routine +short _SONSetMarker(short fh, +WORD chan, +TSTime time, +TpMarker pMark, +WORD size) +{ + short i; + FARPROC SONSetMarker; + SONSetMarker = GetProcAddress(hinstLib,"SONSetMarker"); + if (SONSetMarker != NULL){ + i=(*SONSetMarker)(fh, chan, time, pMark, size); + return i; + } + mexErrMsgTxt("SONSetMarker not found in SON32.DLL\n"); +} + + +TDataKind _SONChanKind(short fh, WORD chan) +{ + FARPROC SONChanKind; + TDataKind i; + SONChanKind=GetProcAddress(hinstLib, "SONChanKind"); + i=(*SONChanKind)(fh, chan); + return i; +} + +void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[]) +{ + + short fh; + WORD chan; + long npoints=0; + unsigned char *ptr; + int dim[2]={1,1}; + long *p; + int err=0; + WORD size=0; + TSTime time; + TMarker Marker; + TAdcMark adcmark; + TRealMark realmark; + TTextMark textmark; + TpMarker temp=&Marker; + + + if (nrhs<4) + mexErrMsgTxt("SONSetMarker: Too few arguments\n"); + + + //Get input arguments + fh=mxGetScalar(prhs[0]); //File handle + chan=mxGetScalar(prhs[1]); //Channel number + time=mxGetScalar(prhs[2]); // time of marker + + + Marker.mark=mxGetScalar(prhs[3]); //New timestamp value + size=sizeof(TSTime); + + //New marker values if present + if(nrhs>=5) { + ptr=mxGetData(prhs[4]); + memcpy(&Marker.mvals, ptr, sizeof(TMarkBytes)); + size=sizeof(TMarker); + } + + //Load and get pointer to the library SON32.DLL// + hinstLib = LoadLibrary(SON32); + if (hinstLib == NULL){ + mexPrintf("%s not found",SON32); + plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); + p=mxGetData(plhs[0]); + p[0]=SON_BAD_PARAM; + return; + } + + //Extra data if present + if (nrhs==6) { + switch (mxGetClassID(prhs[5])){ + case mxUINT8_CLASS: + if (_SONChanKind(fh, chan)== 8) { + size=mxGetN(prhs[5])*mxGetM(prhs[5]); + memcpy(&textmark.t, mxGetData(prhs[5]), size); + textmark.m=Marker; + temp=(TpMarker)&textmark; + } + else + err=SON_NO_EXTRA; + break; + case mxINT16_CLASS: + if (_SONChanKind(fh, chan)== 6) { + size=2*mxGetN(prhs[5])*mxGetM(prhs[5]); + memcpy(&adcmark.a, mxGetData(prhs[5]), size); + adcmark.m=Marker; + temp=(TpMarker)&adcmark; + } + else + err=SON_NO_EXTRA; + break; + case mxSINGLE_CLASS: + if (_SONChanKind(fh, chan)== 7) { + size=4*mxGetN(prhs[5])*mxGetM(prhs[5]); + memcpy(&realmark.r, mxGetData(prhs[5]), size); + realmark.m=Marker; + temp=(TpMarker)&realmark; + } + else + err=SON_NO_EXTRA; + break; + } + size=size+sizeof(TMarker); + } + else + err=SON_BAD_PARAM; + + + + if (err != 0) { + plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); + p=mxGetData(plhs[0]); + p[0]=err; + return; + } + + + //Call DLL + npoints=_SONSetMarker(fh, chan, time, temp, size); + fFreeResult = FreeLibrary(hinstLib); + + + //return results. This one goes in ans if no arguments + plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); + p=mxGetData(plhs[0]); + p[0]=npoints; + + +} + + + diff --git a/src/Import/SON/SON32/C_Sources/SONTimeDate.c b/Import/SON/SON32/C_Sources/SONTimeDate.c similarity index 96% rename from src/Import/SON/SON32/C_Sources/SONTimeDate.c rename to Import/SON/SON32/C_Sources/SONTimeDate.c index 44326d3e..606e1d1e 100644 --- a/src/Import/SON/SON32/C_Sources/SONTimeDate.c +++ b/Import/SON/SON32/C_Sources/SONTimeDate.c @@ -1,87 +1,87 @@ -#include -#include -#include -#include -#include "mex.h" - -#include "son.h" -#include "machine.h" -#include "SONDef.h" - -HINSTANCE hinstLib; -BOOL fFreeResult; - -int _SONTimeDate(short fh, TSONTimeDate *p1, TSONTimeDate *p2) -{ - FARPROC SONTimeDate; - int i; - SONTimeDate=GetProcAddress(hinstLib,"SONTimeDate"); - if (SONTimeDate != NULL){ - i=(*SONTimeDate)(fh, p1, p2); - return i; - } - mexErrMsgTxt("SONTimeDate not found in library\n"); -} - - -void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[]) -{ - short fh, i, *ret; - TSONTimeDate Date={0,0,0,0,0,0}; - TSONTimeDate *pDate=&Date; - double *ptr, *p; - const int dim[2]={1,6}; - - if (nrhs>=1) - fh=mxGetScalar(prhs[0]); - - if (nrhs==2){ - ptr=mxGetPr(prhs[1]); - if ( (mxGetM(prhs[1])==1) && (mxGetN(prhs[1])==6) ) { - Date.wYear=*ptr++; - Date.ucMon=*ptr++; - Date.ucDay=*ptr++; - Date.ucHour=*ptr++; - Date.ucMin=*ptr++; - Date.ucSec=*ptr; - Date.ucHun=(*ptr-Date.ucSec+0.05)*10.0; - mexPrintf("%d\n",Date.ucHun); - } - else - mexErrMsgTxt("SONTimeDate: matlab clock style input required"); - } - - - - //Load and get pointer to the library SON32.DLL// - hinstLib = LoadLibrary(SON32); - if (hinstLib == NULL){ - mexPrintf("%s not found",SON32); - plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); - p=mxGetPr(plhs[0]); - p[0]=SON_BAD_PARAM; - return; - } - - if (nrhs==1) - i=_SONTimeDate(fh, pDate, NULL); //read - else { - i=_SONTimeDate(fh, NULL, pDate); //write - _SONTimeDate(fh, pDate, NULL); //and read back - } - - fFreeResult = FreeLibrary(hinstLib); - - - plhs[0]=mxCreateNumericArray(2, dim, mxDOUBLE_CLASS, mxREAL); - if (i>=0) { - ptr=mxGetData(plhs[0]); - *ptr++=Date.wYear; - *ptr++=Date.ucMon; - *ptr++=Date.ucDay; - *ptr++=Date.ucHour; - *ptr++=Date.ucMin; - *ptr=Date.ucSec+(Date.ucHun*0.1); - } - return; -} +#include +#include +#include +#include +#include "mex.h" + +#include "son.h" +#include "machine.h" +#include "SONDef.h" + +HINSTANCE hinstLib; +BOOL fFreeResult; + +int _SONTimeDate(short fh, TSONTimeDate *p1, TSONTimeDate *p2) +{ + FARPROC SONTimeDate; + int i; + SONTimeDate=GetProcAddress(hinstLib,"SONTimeDate"); + if (SONTimeDate != NULL){ + i=(*SONTimeDate)(fh, p1, p2); + return i; + } + mexErrMsgTxt("SONTimeDate not found in library\n"); +} + + +void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[]) +{ + short fh, i, *ret; + TSONTimeDate Date={0,0,0,0,0,0}; + TSONTimeDate *pDate=&Date; + double *ptr, *p; + const int dim[2]={1,6}; + + if (nrhs>=1) + fh=mxGetScalar(prhs[0]); + + if (nrhs==2){ + ptr=mxGetPr(prhs[1]); + if ( (mxGetM(prhs[1])==1) && (mxGetN(prhs[1])==6) ) { + Date.wYear=*ptr++; + Date.ucMon=*ptr++; + Date.ucDay=*ptr++; + Date.ucHour=*ptr++; + Date.ucMin=*ptr++; + Date.ucSec=*ptr; + Date.ucHun=(*ptr-Date.ucSec+0.05)*10.0; + mexPrintf("%d\n",Date.ucHun); + } + else + mexErrMsgTxt("SONTimeDate: matlab clock style input required"); + } + + + + //Load and get pointer to the library SON32.DLL// + hinstLib = LoadLibrary(SON32); + if (hinstLib == NULL){ + mexPrintf("%s not found",SON32); + plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); + p=mxGetPr(plhs[0]); + p[0]=SON_BAD_PARAM; + return; + } + + if (nrhs==1) + i=_SONTimeDate(fh, pDate, NULL); //read + else { + i=_SONTimeDate(fh, NULL, pDate); //write + _SONTimeDate(fh, pDate, NULL); //and read back + } + + fFreeResult = FreeLibrary(hinstLib); + + + plhs[0]=mxCreateNumericArray(2, dim, mxDOUBLE_CLASS, mxREAL); + if (i>=0) { + ptr=mxGetData(plhs[0]); + *ptr++=Date.wYear; + *ptr++=Date.ucMon; + *ptr++=Date.ucDay; + *ptr++=Date.ucHour; + *ptr++=Date.ucMin; + *ptr=Date.ucSec+(Date.ucHun*0.1); + } + return; +} diff --git a/src/Import/SON/SON32/C_Sources/SONWriteExtMarkBlock b/Import/SON/SON32/C_Sources/SONWriteExtMarkBlock similarity index 96% rename from src/Import/SON/SON32/C_Sources/SONWriteExtMarkBlock rename to Import/SON/SON32/C_Sources/SONWriteExtMarkBlock index 2ba8bacd..4529388a 100644 --- a/src/Import/SON/SON32/C_Sources/SONWriteExtMarkBlock +++ b/Import/SON/SON32/C_Sources/SONWriteExtMarkBlock @@ -1,140 +1,140 @@ -/*function ret=SONWriteMarkBlock(fh, chan, buffer, count) -% SONWRITEMARKBLOCK writes data to a marker channel -% -% Implemented through SONWriteMarkBlock.dll -% -% RET=SONWRITEMARKBLOCK(FH, CHAN, TIMESTAMPS, MARKERS, COUNT) -% INPUTS: FH the SON file handle -% CHAN the target channel -% TIMESTAMPS a vector of int32 timestamps for the markers -% which should be at least COUNT in length -% MARKERS the 4xCOUNT array of uint8 marker values, one set of -% 4 for each timestamp -% COUNT the number of marker items to write to the buffer -% -% Returns zero or a negative error code. -% -% For efficient use of disc space, COUNT should be a multiple of -% (BUFSIZE bytes - 20)/4 , where BUFSIZE is supplied in a prior call to -% SONSETEVENTCHAN (20 is the size of the block header on disc) -% -% see CED documentation -% -% See also SONSETEVENTCHAN, SONWRITEEVENTBLOCK, SONWRITEEXTMARKBLOCK -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London -*/ - -#include -#include -#include -#include -#include - -#include "son.h" -#include "machine.h" -#include "SONDef.h" - -HINSTANCE hinstLib; -BOOL fFreeResult; - - -// Calls the SON32.DLL read routine -short _SONWriteMarkBlock(short fh, - WORD chan, - TpMarker pMark, - long count) -{ - short i; - FARPROC SONWriteMarkBlock; - SONWriteMarkBlock = GetProcAddress(hinstLib,"SONWriteMarkBlock"); - if (SONWriteMarkBlock != NULL){ - i=(*SONWriteMarkBlock)(fh, chan, pMark, count); - return i; - } - mexErrMsgTxt("SONWriteMarkBlock not found in SON32.DLL\n"); -} - - -void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[]) -{ - - short fh; - WORD chan; - long count, n; - long npoints=0; - TSTime *pTimes; - char *pMarkers; - short ret; - long *p; - int dim[2]={1,1},i; - TpMarker pM; - - if (nrhs<5) - mexErrMsgTxt("SONWriteMarkBlock: Too few arguments\n"); - - //Get input arguments - fh=mxGetScalar(prhs[0]); //File handle - chan=mxGetScalar(prhs[1]); //Channel number - if (mxIsInt32(prhs[2])==0){ - mexPrintf("SONWriteMarkBlock: timestamps must be int32"); - plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); - p=mxGetData(plhs[0]); - *p=SON_BAD_PARAM; - return; - } - pTimes=(TSTime *)mxGetPr(prhs[2]); //Pointer to timestamps - - pMarkers=(char *)mxGetPr(prhs[3]); //Pointer to marker values - if (mxIsInt32(prhs[2])==0){ - mexPrintf("SONWriteMarkBlock: timestamps must be int32"); - plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); - p=mxGetData(plhs[0]); - *p=SON_BAD_PARAM; - return; - } - pMarkers=(char *)mxGetPr(prhs[3]); //Pointer to marker values - - count=mxGetScalar(prhs[4]); //Number to write - - pM=mxCalloc(count*8,sizeof(char)); - - - for (n=0; n +#include +#include +#include +#include + +#include "son.h" +#include "machine.h" +#include "SONDef.h" + +HINSTANCE hinstLib; +BOOL fFreeResult; + + +// Calls the SON32.DLL read routine +short _SONWriteMarkBlock(short fh, + WORD chan, + TpMarker pMark, + long count) +{ + short i; + FARPROC SONWriteMarkBlock; + SONWriteMarkBlock = GetProcAddress(hinstLib,"SONWriteMarkBlock"); + if (SONWriteMarkBlock != NULL){ + i=(*SONWriteMarkBlock)(fh, chan, pMark, count); + return i; + } + mexErrMsgTxt("SONWriteMarkBlock not found in SON32.DLL\n"); +} + + +void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[]) +{ + + short fh; + WORD chan; + long count, n; + long npoints=0; + TSTime *pTimes; + char *pMarkers; + short ret; + long *p; + int dim[2]={1,1},i; + TpMarker pM; + + if (nrhs<5) + mexErrMsgTxt("SONWriteMarkBlock: Too few arguments\n"); + + //Get input arguments + fh=mxGetScalar(prhs[0]); //File handle + chan=mxGetScalar(prhs[1]); //Channel number + if (mxIsInt32(prhs[2])==0){ + mexPrintf("SONWriteMarkBlock: timestamps must be int32"); + plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); + p=mxGetData(plhs[0]); + *p=SON_BAD_PARAM; + return; + } + pTimes=(TSTime *)mxGetPr(prhs[2]); //Pointer to timestamps + + pMarkers=(char *)mxGetPr(prhs[3]); //Pointer to marker values + if (mxIsInt32(prhs[2])==0){ + mexPrintf("SONWriteMarkBlock: timestamps must be int32"); + plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); + p=mxGetData(plhs[0]); + *p=SON_BAD_PARAM; + return; + } + pMarkers=(char *)mxGetPr(prhs[3]); //Pointer to marker values + + count=mxGetScalar(prhs[4]); //Number to write + + pM=mxCalloc(count*8,sizeof(char)); + + + for (n=0; n -#include -#include -#include -#include - -#include "son.h" -#include "machine.h" -#include "SONDef.h" - -HINSTANCE hinstLib; -BOOL fFreeResult; - - -// Calls the SON32.DLL read routine -short _SONWriteMarkBlock(short fh, - WORD chan, - TpMarker pMark, - long count) -{ - short i; - FARPROC SONWriteMarkBlock; - SONWriteMarkBlock = GetProcAddress(hinstLib,"SONWriteMarkBlock"); - if (SONWriteMarkBlock != NULL){ - i=(*SONWriteMarkBlock)(fh, chan, pMark, count); - return i; - } - mexErrMsgTxt("SONWriteMarkBlock not found in SON32.DLL\n"); -} - - -void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[]) -{ - - short fh; - WORD chan; - long count, n; - long npoints=0; - TSTime *pTimes; - char *pMarkers; - short ret; - long *p; - int dim[2]={1,1},i; - TpMarker pM; - - if (nrhs<5) - mexErrMsgTxt("SONWriteMarkBlock: Too few arguments\n"); - - //Get input arguments - fh=mxGetScalar(prhs[0]); //File handle - chan=mxGetScalar(prhs[1]); //Channel number - if (mxIsInt32(prhs[2])==0){ - mexPrintf("SONWriteMarkBlock: timestamps must be int32"); - plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); - p=mxGetData(plhs[0]); - *p=SON_BAD_PARAM; - return; - } - pTimes=(TSTime *)mxGetPr(prhs[2]); //Pointer to timestamps - - pMarkers=(char *)mxGetPr(prhs[3]); //Pointer to marker values - if (mxIsInt32(prhs[2])==0){ - mexPrintf("SONWriteMarkBlock: timestamps must be int32"); - plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); - p=mxGetData(plhs[0]); - *p=SON_BAD_PARAM; - return; - } - pMarkers=(char *)mxGetPr(prhs[3]); //Pointer to marker values - - count=mxGetScalar(prhs[4]); //Number to write - - pM=mxCalloc(count*8,sizeof(char)); - - - for (n=0; n +#include +#include +#include +#include + +#include "son.h" +#include "machine.h" +#include "SONDef.h" + +HINSTANCE hinstLib; +BOOL fFreeResult; + + +// Calls the SON32.DLL read routine +short _SONWriteMarkBlock(short fh, + WORD chan, + TpMarker pMark, + long count) +{ + short i; + FARPROC SONWriteMarkBlock; + SONWriteMarkBlock = GetProcAddress(hinstLib,"SONWriteMarkBlock"); + if (SONWriteMarkBlock != NULL){ + i=(*SONWriteMarkBlock)(fh, chan, pMark, count); + return i; + } + mexErrMsgTxt("SONWriteMarkBlock not found in SON32.DLL\n"); +} + + +void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[]) +{ + + short fh; + WORD chan; + long count, n; + long npoints=0; + TSTime *pTimes; + char *pMarkers; + short ret; + long *p; + int dim[2]={1,1},i; + TpMarker pM; + + if (nrhs<5) + mexErrMsgTxt("SONWriteMarkBlock: Too few arguments\n"); + + //Get input arguments + fh=mxGetScalar(prhs[0]); //File handle + chan=mxGetScalar(prhs[1]); //Channel number + if (mxIsInt32(prhs[2])==0){ + mexPrintf("SONWriteMarkBlock: timestamps must be int32"); + plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); + p=mxGetData(plhs[0]); + *p=SON_BAD_PARAM; + return; + } + pTimes=(TSTime *)mxGetPr(prhs[2]); //Pointer to timestamps + + pMarkers=(char *)mxGetPr(prhs[3]); //Pointer to marker values + if (mxIsInt32(prhs[2])==0){ + mexPrintf("SONWriteMarkBlock: timestamps must be int32"); + plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); + p=mxGetData(plhs[0]); + *p=SON_BAD_PARAM; + return; + } + pMarkers=(char *)mxGetPr(prhs[3]); //Pointer to marker values + + count=mxGetScalar(prhs[4]); //Number to write + + pM=mxCalloc(count*8,sizeof(char)); + + + for (n=0; n -#include -#include -#include -#include - -#include "son.h" -#include "machine.h" -#include "SONDef.h" - -HINSTANCE hinstLib; -BOOL fFreeResult; - - -// Calls the SON32.DLL read routine -short _SONWriteMarkBlock(short fh, - WORD chan, - TpMarker pMark, - long count) -{ - short i; - FARPROC SONWriteMarkBlock; - SONWriteMarkBlock = GetProcAddress(hinstLib,"SONWriteMarkBlock"); - if (SONWriteMarkBlock != NULL){ - i=(*SONWriteMarkBlock)(fh, chan, pMark, count); - return i; - } - mexErrMsgTxt("SONWriteMarkBlock not found in SON32.DLL\n"); -} - - -void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[]) -{ - - short fh; - WORD chan; - long count, n; - long npoints=0; - TSTime *pTimes; - char *pMarkers; - short ret; - long *p; - int dim[2]={1,1},i; - TpMarker pM; - - if (nrhs<5) - mexErrMsgTxt("SONWriteMarkBlock: Too few arguments\n"); - - //Get input arguments - fh=mxGetScalar(prhs[0]); //File handle - chan=mxGetScalar(prhs[1]); //Channel number - if (mxIsInt32(prhs[2])==0){ - mexPrintf("SONWriteMarkBlock: timestamps must be int32"); - plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); - p=mxGetData(plhs[0]); - *p=SON_BAD_PARAM; - return; - } - pTimes=(TSTime *)mxGetPr(prhs[2]); //Pointer to timestamps - - pMarkers=(char *)mxGetPr(prhs[3]); //Pointer to marker values - count=mxGetScalar(prhs[4]); //Number to write - - pM=mxCalloc(count*8,sizeof(char)); - - - for (n=0; n +#include +#include +#include +#include + +#include "son.h" +#include "machine.h" +#include "SONDef.h" + +HINSTANCE hinstLib; +BOOL fFreeResult; + + +// Calls the SON32.DLL read routine +short _SONWriteMarkBlock(short fh, + WORD chan, + TpMarker pMark, + long count) +{ + short i; + FARPROC SONWriteMarkBlock; + SONWriteMarkBlock = GetProcAddress(hinstLib,"SONWriteMarkBlock"); + if (SONWriteMarkBlock != NULL){ + i=(*SONWriteMarkBlock)(fh, chan, pMark, count); + return i; + } + mexErrMsgTxt("SONWriteMarkBlock not found in SON32.DLL\n"); +} + + +void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[]) +{ + + short fh; + WORD chan; + long count, n; + long npoints=0; + TSTime *pTimes; + char *pMarkers; + short ret; + long *p; + int dim[2]={1,1},i; + TpMarker pM; + + if (nrhs<5) + mexErrMsgTxt("SONWriteMarkBlock: Too few arguments\n"); + + //Get input arguments + fh=mxGetScalar(prhs[0]); //File handle + chan=mxGetScalar(prhs[1]); //Channel number + if (mxIsInt32(prhs[2])==0){ + mexPrintf("SONWriteMarkBlock: timestamps must be int32"); + plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); + p=mxGetData(plhs[0]); + *p=SON_BAD_PARAM; + return; + } + pTimes=(TSTime *)mxGetPr(prhs[2]); //Pointer to timestamps + + pMarkers=(char *)mxGetPr(prhs[3]); //Pointer to marker values + count=mxGetScalar(prhs[4]); //Number to write + + pM=mxCalloc(count*8,sizeof(char)); + + + for (n=0; n -#include -#include -#include -#include - -#include "son.h" -#include "machine.h" -#include "SONDef.h" - -HINSTANCE hinstLib; -BOOL fFreeResult; - - -// Calls the SON32.DLL read routine -short _SONWriteExtMarkBlock(short fh, - WORD chan, - TpMarker pMark, - long count) -{ - short i; - FARPROC SONWriteExtMarkBlock; - SONWriteExtMarkBlock = GetProcAddress(hinstLib,"SONWriteExtMarkBlock"); - if (SONWriteExtMarkBlock != NULL){ - i=(*SONWriteExtMarkBlock)(fh, chan, pMark, count); - return i; - } - mexErrMsgTxt("SONWriteExtMarkBlock not found in SON32.DLL\n"); -} - -WORD _SONItemSize(short fh, WORD chan) -{ - FARPROC SONItemSize; - WORD i; - SONItemSize=GetProcAddress(hinstLib,"SONItemSize"); - i=(*SONItemSize)(fh, chan); - return i; -} - -void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[]) -{ - - short fh; - WORD chan; - long count, n; - long npoints=0; - TSTime *pTimes; - char *pMarkers; - short ret; - long *p; - int dim[2]={1,1},i; - char *pM, *pM2; - char *pExtra; - WORD sz; - if (nrhs<6) - mexErrMsgTxt("SONWriteExtMarkBlock: Too few arguments\n"); - - //Get input arguments - fh=mxGetScalar(prhs[0]); //File handle - chan=mxGetScalar(prhs[1]); //Channel number - if (mxIsInt32(prhs[2])==0){ - mexPrintf("SONWriteMarkBlock: timestamps must be int32"); - plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); - p=mxGetData(plhs[0]); - *p=SON_BAD_PARAM; - return; - } - pTimes=(TSTime *)mxGetPr(prhs[2]); //Pointer to timestamps - pMarkers=(char *)mxGetPr(prhs[3]); - pExtra=(char *)mxGetPr(prhs[4]); - count=mxGetScalar(prhs[5]); //Number to write - - /*Load and get pointer to the library SON32.DLL*/ - hinstLib = LoadLibrary(SON32); - if (hinstLib == NULL){ - mexPrintf("%s not found",SON32); - plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); - p=mxGetData(plhs[0]); - p[0]=SON_BAD_PARAM; - return; - } - sz=_SONItemSize(fh, chan); - pM=(char *)mxMalloc(count*sz); - pM2=pM; - for (n=0; n +#include +#include +#include +#include + +#include "son.h" +#include "machine.h" +#include "SONDef.h" + +HINSTANCE hinstLib; +BOOL fFreeResult; + + +// Calls the SON32.DLL read routine +short _SONWriteExtMarkBlock(short fh, + WORD chan, + TpMarker pMark, + long count) +{ + short i; + FARPROC SONWriteExtMarkBlock; + SONWriteExtMarkBlock = GetProcAddress(hinstLib,"SONWriteExtMarkBlock"); + if (SONWriteExtMarkBlock != NULL){ + i=(*SONWriteExtMarkBlock)(fh, chan, pMark, count); + return i; + } + mexErrMsgTxt("SONWriteExtMarkBlock not found in SON32.DLL\n"); +} + +WORD _SONItemSize(short fh, WORD chan) +{ + FARPROC SONItemSize; + WORD i; + SONItemSize=GetProcAddress(hinstLib,"SONItemSize"); + i=(*SONItemSize)(fh, chan); + return i; +} + +void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[]) +{ + + short fh; + WORD chan; + long count, n; + long npoints=0; + TSTime *pTimes; + char *pMarkers; + short ret; + long *p; + int dim[2]={1,1},i; + char *pM, *pM2; + char *pExtra; + WORD sz; + if (nrhs<6) + mexErrMsgTxt("SONWriteExtMarkBlock: Too few arguments\n"); + + //Get input arguments + fh=mxGetScalar(prhs[0]); //File handle + chan=mxGetScalar(prhs[1]); //Channel number + if (mxIsInt32(prhs[2])==0){ + mexPrintf("SONWriteMarkBlock: timestamps must be int32"); + plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); + p=mxGetData(plhs[0]); + *p=SON_BAD_PARAM; + return; + } + pTimes=(TSTime *)mxGetPr(prhs[2]); //Pointer to timestamps + pMarkers=(char *)mxGetPr(prhs[3]); + pExtra=(char *)mxGetPr(prhs[4]); + count=mxGetScalar(prhs[5]); //Number to write + + /*Load and get pointer to the library SON32.DLL*/ + hinstLib = LoadLibrary(SON32); + if (hinstLib == NULL){ + mexPrintf("%s not found",SON32); + plhs[0]=mxCreateNumericArray(2, dim, mxINT32_CLASS, mxREAL); + p=mxGetData(plhs[0]); + p[0]=SON_BAD_PARAM; + return; + } + sz=_SONItemSize(fh, chan); + pM=(char *)mxMalloc(count*sz); + pM2=pM; + for (n=0; n 0 Query before deleting (default) -% Returns 0 if deletion successful, negative error code otherwise -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - -if nargin < 2 - ret=-1000; - return; -end; - -fh=varargin{1}; -chan=varargin{2}; -if nargin==3 - query=varargin{3}; -else - query=1; -end; - - -if query~=0 - s=sprintf('Do you really want to delete Channel %d',chan); - button = questdlg(s,'Channel Delete','No','Yes','No'); - if strcmp(button,'No') - ret=0; - return; - end; -end; - - -ret=calllib('son32','SONChanDelete',fh,chan); +function ret=SONChanDelete(varargin) +% SONCHANDELETE deletes a channel from a SON file +% RET=SONCHANDELETE(FH, CHAN {,QUERY}) +% FH = file handle +% CHAN = channel number 0 to SONMAXCHANS-1 +% QUERY (if present) = 0 Do not query +% <> 0 Query before deleting (default) +% Returns 0 if deletion successful, negative error code otherwise +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + +if nargin < 2 + ret=-1000; + return; +end; + +fh=varargin{1}; +chan=varargin{2}; +if nargin==3 + query=varargin{3}; +else + query=1; +end; + + +if query~=0 + s=sprintf('Do you really want to delete Channel %d',chan); + button = questdlg(s,'Channel Delete','No','Yes','No'); + if strcmp(button,'No') + ret=0; + return; + end; +end; + + +ret=calllib('son32','SONChanDelete',fh,chan); return; \ No newline at end of file diff --git a/src/Import/SON/SON32/SONChanDivide.m b/Import/SON/SON32/SONChanDivide.m similarity index 95% rename from src/Import/SON/SON32/SONChanDivide.m rename to Import/SON/SON32/SONChanDivide.m index 34e46a01..c98c3afa 100644 --- a/src/Import/SON/SON32/SONChanDivide.m +++ b/Import/SON/SON32/SONChanDivide.m @@ -1,21 +1,21 @@ -function [lDivide]=SONChanDivide(fh, chan) -% SONCHANDIVIDE returns the clock ticks per ADC value from the specified -% channel -% LDIVIDE=SONCHANDIVIDE(FH, CHAN) -% FH SON file handle -% CHAN Channel number -% -% See also SONGETUSPERTIME -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - -if nargin ~= 2 - lDivide=-1000; - return; -end; - - -lDivide=calllib('son32','SONChanDivide',fh,chan); -return; +function [lDivide]=SONChanDivide(fh, chan) +% SONCHANDIVIDE returns the clock ticks per ADC value from the specified +% channel +% LDIVIDE=SONCHANDIVIDE(FH, CHAN) +% FH SON file handle +% CHAN Channel number +% +% See also SONGETUSPERTIME +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + +if nargin ~= 2 + lDivide=-1000; + return; +end; + + +lDivide=calllib('son32','SONChanDivide',fh,chan); +return; diff --git a/src/Import/SON/SON32/SONChanInterleave.m b/Import/SON/SON32/SONChanInterleave.m similarity index 96% rename from src/Import/SON/SON32/SONChanInterleave.m rename to Import/SON/SON32/SONChanInterleave.m index 2f9b3852..0bd11248 100644 --- a/src/Import/SON/SON32/SONChanInterleave.m +++ b/Import/SON/SON32/SONChanInterleave.m @@ -1,14 +1,14 @@ -function interleave=SONChanInterleave(fh, chan) -% SONCHANINTERLEAVE Returns the channel interleave factor for ADCMark channels -% in SON V6 or above -% INTERLEAVE=SONCHANINTERLEAVE(FH, CHAN) -% FH SON File Handle -% Chan Channel number -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - - -interleave=calllib('son32','SONChanInterleave',fh, chan); -return; +function interleave=SONChanInterleave(fh, chan) +% SONCHANINTERLEAVE Returns the channel interleave factor for ADCMark channels +% in SON V6 or above +% INTERLEAVE=SONCHANINTERLEAVE(FH, CHAN) +% FH SON File Handle +% Chan Channel number +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + + +interleave=calllib('son32','SONChanInterleave',fh, chan); +return; diff --git a/src/Import/SON/SON32/SONChanKind.m b/Import/SON/SON32/SONChanKind.m similarity index 97% rename from src/Import/SON/SON32/SONChanKind.m rename to Import/SON/SON32/SONChanKind.m index d040971a..23a6fb5f 100644 --- a/src/Import/SON/SON32/SONChanKind.m +++ b/Import/SON/SON32/SONChanKind.m @@ -1,15 +1,15 @@ -function kind=SONChanKind(fh, chan) -% SONCHANKIND Returns the channel type -% KIND=SONCHANKIND(FH, CHAN) where FH is the file handle -% CHAN is the channel number (0 to -% SONMAXCHANS-1) -% Returns kind as an enumerated string - see CED documentation for values -% No errors returned -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - - -kind=calllib('son32','SONChanKind',fh, chan); -return; +function kind=SONChanKind(fh, chan) +% SONCHANKIND Returns the channel type +% KIND=SONCHANKIND(FH, CHAN) where FH is the file handle +% CHAN is the channel number (0 to +% SONMAXCHANS-1) +% Returns kind as an enumerated string - see CED documentation for values +% No errors returned +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + + +kind=calllib('son32','SONChanKind',fh, chan); +return; diff --git a/src/Import/SON/SON32/SONChanMaxTime.m b/Import/SON/SON32/SONChanMaxTime.m similarity index 96% rename from src/Import/SON/SON32/SONChanMaxTime.m rename to Import/SON/SON32/SONChanMaxTime.m index b1b50299..7ab52a4f 100644 --- a/src/Import/SON/SON32/SONChanMaxTime.m +++ b/Import/SON/SON32/SONChanMaxTime.m @@ -1,16 +1,16 @@ -function MaxTime=SONChanMaxTime(fh, chan) -% SONCHANMAXTIME returns the sample time for the last data item on a channel -% -% MAXTIME=SONCHANMAXTIME(FH, CHAN) -% where FH is the SON file handle -% CHAN the channel (0-SONMaxChannels()-1) -% -% MAXTIME is returned in clock ticks -% -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - -MaxTime=calllib('son32','SONChanMaxTime',fh,chan); -return; +function MaxTime=SONChanMaxTime(fh, chan) +% SONCHANMAXTIME returns the sample time for the last data item on a channel +% +% MAXTIME=SONCHANMAXTIME(FH, CHAN) +% where FH is the SON file handle +% CHAN the channel (0-SONMaxChannels()-1) +% +% MAXTIME is returned in clock ticks +% +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + +MaxTime=calllib('son32','SONChanMaxTime',fh,chan); +return; diff --git a/src/Import/SON/SON32/SONCleanUp.m b/Import/SON/SON32/SONCleanUp.m similarity index 95% rename from src/Import/SON/SON32/SONCleanUp.m rename to Import/SON/SON32/SONCleanUp.m index d9d23e93..fbf187a7 100644 --- a/src/Import/SON/SON32/SONCleanUp.m +++ b/Import/SON/SON32/SONCleanUp.m @@ -1,9 +1,9 @@ -function SONCleanUp() -% SONCLEANUP File cleanup. Not used in Windows -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - -calllib('son32','SONCleanUp'); -return; +function SONCleanUp() +% SONCLEANUP File cleanup. Not used in Windows +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + +calllib('son32','SONCleanUp'); +return; diff --git a/src/Import/SON/SON32/SONCloseFile.m b/Import/SON/SON32/SONCloseFile.m similarity index 95% rename from src/Import/SON/SON32/SONCloseFile.m rename to Import/SON/SON32/SONCloseFile.m index 51abc0cf..69abc939 100644 --- a/src/Import/SON/SON32/SONCloseFile.m +++ b/Import/SON/SON32/SONCloseFile.m @@ -1,17 +1,17 @@ -function [err]=SONCloseFile(fh) -% SONCLOSEFILE closes an opened SON file -% ERR=SONCLOSEFILE(FH) where FH is the SON32.DLL handle for the file -% Returns zero if all OK. -% -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - -if nargin ~= 1 - err=-1000; - return; -end; - -err=calllib('son32','SONCloseFile',fh); -return; +function [err]=SONCloseFile(fh) +% SONCLOSEFILE closes an opened SON file +% ERR=SONCLOSEFILE(FH) where FH is the SON32.DLL handle for the file +% Returns zero if all OK. +% +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + +if nargin ~= 1 + err=-1000; + return; +end; + +err=calllib('son32','SONCloseFile',fh); +return; diff --git a/src/Import/SON/SON32/SONCommitFile.m b/Import/SON/SON32/SONCommitFile.m similarity index 96% rename from src/Import/SON/SON32/SONCommitFile.m rename to Import/SON/SON32/SONCommitFile.m index e372a327..feec2311 100644 --- a/src/Import/SON/SON32/SONCommitFile.m +++ b/Import/SON/SON32/SONCommitFile.m @@ -1,12 +1,12 @@ -function SONCommitFile(fh, bDelete) -% SONCOMMITFILE flushes data to disc -% FH is the SON file handle -% BDELETE ,if non-zero, causes the data buffers to be deleted -% -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - -calllib('son32','SONCommitFile', fh, bDelete); -return; +function SONCommitFile(fh, bDelete) +% SONCOMMITFILE flushes data to disc +% FH is the SON file handle +% BDELETE ,if non-zero, causes the data buffers to be deleted +% +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + +calllib('son32','SONCommitFile', fh, bDelete); +return; diff --git a/src/Import/SON/SON32/SONCreateFile.m b/Import/SON/SON32/SONCreateFile.m similarity index 97% rename from src/Import/SON/SON32/SONCreateFile.m rename to Import/SON/SON32/SONCreateFile.m index 13068773..2dd8b924 100644 --- a/src/Import/SON/SON32/SONCreateFile.m +++ b/Import/SON/SON32/SONCreateFile.m @@ -1,18 +1,18 @@ -function fh=SONCreateFile(filename, nChan, extra) -% SONCREATEFILE creates a new SON file -% FH=SONCREATEFILE(FILNAME, NCHANS, EXTRA) -% FILENAME = string wiht file and path -% NCHAN = number of channels 32 to 256 -% EXTRA = number of bytes to reserve for user specified data -% area in the file header. -% Returns FH, a file handle or a negative error code -% -% This function replaces SONOpenNewFile -% See also SONOPENNEWFILE -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - -fh=calllib('son32','SONCreateFile',filename, nChan, extra); -return; +function fh=SONCreateFile(filename, nChan, extra) +% SONCREATEFILE creates a new SON file +% FH=SONCREATEFILE(FILNAME, NCHANS, EXTRA) +% FILENAME = string wiht file and path +% NCHAN = number of channels 32 to 256 +% EXTRA = number of bytes to reserve for user specified data +% area in the file header. +% Returns FH, a file handle or a negative error code +% +% This function replaces SONOpenNewFile +% See also SONOPENNEWFILE +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + +fh=calllib('son32','SONCreateFile',filename, nChan, extra); +return; diff --git a/src/Import/SON/SON32/SONDateTime.m b/Import/SON/SON32/SONDateTime.m similarity index 96% rename from src/Import/SON/SON32/SONDateTime.m rename to Import/SON/SON32/SONDateTime.m index 8071827f..31fa3fda 100644 --- a/src/Import/SON/SON32/SONDateTime.m +++ b/Import/SON/SON32/SONDateTime.m @@ -1,27 +1,27 @@ -% SONDATETIME gets or sets the creation data/time data in a SON file -% The date/time are returned in standard MATLAB format -% -% Implemented through SONDateTime.dll -% -% DATEVECTOR = SONDATETIME(FH) -% returns the creation date/time from the file -% DATEVECTOR1 = SONDATETIME(FH, DATEVECTOR2) -% sets the time/date field to DATAVECTOR2 then reads it back -% to DATAVECTOR1 (which may be the same vector) -% -% FH is the SON file handle -% DATEVECTOR is a 1x6 double vector as -% returned by the MATLAB builtin CLOCK function -% -% If an error occurs, the returned vector will be filled with zeros. -% -% Note: the date/time field is available in SON files of Version 6 and higher -% only. -% -% See also CLOCK, DATESTR -% -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - +% SONDATETIME gets or sets the creation data/time data in a SON file +% The date/time are returned in standard MATLAB format +% +% Implemented through SONDateTime.dll +% +% DATEVECTOR = SONDATETIME(FH) +% returns the creation date/time from the file +% DATEVECTOR1 = SONDATETIME(FH, DATEVECTOR2) +% sets the time/date field to DATAVECTOR2 then reads it back +% to DATAVECTOR1 (which may be the same vector) +% +% FH is the SON file handle +% DATEVECTOR is a 1x6 double vector as +% returned by the MATLAB builtin CLOCK function +% +% If an error occurs, the returned vector will be filled with zeros. +% +% Note: the date/time field is available in SON files of Version 6 and higher +% only. +% +% See also CLOCK, DATESTR +% +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + diff --git a/src/Import/SON/SON32/SONDelBlocks.m b/Import/SON/SON32/SONDelBlocks.m similarity index 94% rename from src/Import/SON/SON32/SONDelBlocks.m rename to Import/SON/SON32/SONDelBlocks.m index b6c514a2..f8bbb346 100644 --- a/src/Import/SON/SON32/SONDelBlocks.m +++ b/Import/SON/SON32/SONDelBlocks.m @@ -1,19 +1,19 @@ -function blocks=SONDelBlocks(fh, chan) -% SONDELBLOCKS returns the number of deleted blocks in file FH on channel CHAN -% -% BLOCKS=SONDELBLOCKS(FH, CHAN) -% -% -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - -if nargin<2 - blocks=-1000; - return; -end; - -blocks=calllib('son32','SONDelBlocks', fh, chan); - +function blocks=SONDelBlocks(fh, chan) +% SONDELBLOCKS returns the number of deleted blocks in file FH on channel CHAN +% +% BLOCKS=SONDELBLOCKS(FH, CHAN) +% +% +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + +if nargin<2 + blocks=-1000; + return; +end; + +blocks=calllib('son32','SONDelBlocks', fh, chan); + \ No newline at end of file diff --git a/src/Import/SON/SON32/SONEmptyFile.m b/Import/SON/SON32/SONEmptyFile.m similarity index 82% rename from src/Import/SON/SON32/SONEmptyFile.m rename to Import/SON/SON32/SONEmptyFile.m index c39536d5..4026840b 100644 --- a/src/Import/SON/SON32/SONEmptyFile.m +++ b/Import/SON/SON32/SONEmptyFile.m @@ -1,16 +1,16 @@ -function err=SONEmptyFile(fh) -% SONEMPTYFILE Deletes data written to file FH -% -% ERR=SONEMPTYFILE(FH) -% - see CED documentation for details -% -% -% Malcolm Lidierth 05/05 -% Kings College London 2005 - -if nargin<1 - err=-1000; - return; -end; - +function err=SONEmptyFile(fh) +% SONEMPTYFILE Deletes data written to file FH +% +% ERR=SONEMPTYFILE(FH) +% - see CED documentation for details +% +% +% Malcolm Lidierth 05/05 +% Kings College London 2005 + +if nargin<1 + err=-1000; + return; +end; + err=calllib('son32','SONEmptyFile',fh); \ No newline at end of file diff --git a/src/Import/SON/SON32/SONExtMarkAlign.m b/Import/SON/SON32/SONExtMarkAlign.m similarity index 96% rename from src/Import/SON/SON32/SONExtMarkAlign.m rename to Import/SON/SON32/SONExtMarkAlign.m index 18d7461a..6f1c0477 100644 --- a/src/Import/SON/SON32/SONExtMarkAlign.m +++ b/Import/SON/SON32/SONExtMarkAlign.m @@ -1,23 +1,23 @@ -function state=SONExtMarkAlign(fh, n) -% SONEXTMARKALIGN gets and sets the alignment state for marker channels -% This is a feature of V7 of the SON filing system -% Using aligned markers improves cross-platform portability of SON files -% STATE=SONEXTMARKALIGN(FH,N) -% FH= SON file handle -% N = -2, Check channel alignment -% -1, Check the file header alignment flag -% 0, Set the file header flag to unaligned -% 1, Set the file header flag to aligned -% See CED documentation for details -% -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - -if nargin<2 - state=-1000; - return; -end; - -state=calllib('son32','SONExtMarkAlign', fh, n); +function state=SONExtMarkAlign(fh, n) +% SONEXTMARKALIGN gets and sets the alignment state for marker channels +% This is a feature of V7 of the SON filing system +% Using aligned markers improves cross-platform portability of SON files +% STATE=SONEXTMARKALIGN(FH,N) +% FH= SON file handle +% N = -2, Check channel alignment +% -1, Check the file header alignment flag +% 0, Set the file header flag to unaligned +% 1, Set the file header flag to aligned +% See CED documentation for details +% +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + +if nargin<2 + state=-1000; + return; +end; + +state=calllib('son32','SONExtMarkAlign', fh, n); diff --git a/src/Import/SON/SON32/SONFActive.m b/Import/SON/SON32/SONFActive.m similarity index 83% rename from src/Import/SON/SON32/SONFActive.m rename to Import/SON/SON32/SONFActive.m index 8ed355a5..c2cfc22e 100644 --- a/src/Import/SON/SON32/SONFActive.m +++ b/Import/SON/SON32/SONFActive.m @@ -1,11 +1,11 @@ -% SONFACTIVE tests filter mask layers to see if they are active -% -% Implemented through SONFActive.dll -% -% ANS=SONFActive(FilterMask) -% -% Bits 0 to 3 are set in ANS if filter mask layers 0 to 3 are active. -% -% Author:Malcolm Lidierth -% Matlab SON library: +% SONFACTIVE tests filter mask layers to see if they are active +% +% Implemented through SONFActive.dll +% +% ANS=SONFActive(FilterMask) +% +% Bits 0 to 3 are set in ANS if filter mask layers 0 to 3 are active. +% +% Author:Malcolm Lidierth +% Matlab SON library: % Copyright 2005 Kings College London \ No newline at end of file diff --git a/src/Import/SON/SON32/SONFActive.mexw32 b/Import/SON/SON32/SONFActive.mexw32 similarity index 100% rename from src/Import/SON/SON32/SONFActive.mexw32 rename to Import/SON/SON32/SONFActive.mexw32 diff --git a/src/Import/SON/SON32/SONFControl.m b/Import/SON/SON32/SONFControl.m similarity index 97% rename from src/Import/SON/SON32/SONFControl.m rename to Import/SON/SON32/SONFControl.m index 1b255589..a40c71b6 100644 --- a/src/Import/SON/SON32/SONFControl.m +++ b/Import/SON/SON32/SONFControl.m @@ -1,26 +1,26 @@ -% Reads, sets or clears specified bits in a filter mask structure -% -% Implemented through SONFControl.dll -% -% [VAL FILTERMASK]=SONFCONTROL(FILTERMASK, LAYER, ITEM, ACTION) -% -% INPUTS: FILTERMASK, filter mask structure -% LAYER, the layer to change (0 to 3) or 'ALL' for all layers -% ITEM, the item to read or change (0 to 255) or 'ALL' for all items -% ACTION the action to take 'READ', 'SET', 'CLEAR' or 'INVERT'. -% -% OUTPUTS: VAL -% For a read: set to the state of the item or, if LAYER or ITEMS -% are 'ALL' set to 1 if all set and 0 if all are cleared -% For a write: returns 0 or a negative error -% FILTERMASK is a copy of the input filter with the required bits -% set, cleared or inverted. -% -% N.B. any non-numeric input is assumed to represent 'ALL' above. For -% string inputs only the first character is used. -% -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London +% Reads, sets or clears specified bits in a filter mask structure +% +% Implemented through SONFControl.dll +% +% [VAL FILTERMASK]=SONFCONTROL(FILTERMASK, LAYER, ITEM, ACTION) +% +% INPUTS: FILTERMASK, filter mask structure +% LAYER, the layer to change (0 to 3) or 'ALL' for all layers +% ITEM, the item to read or change (0 to 255) or 'ALL' for all items +% ACTION the action to take 'READ', 'SET', 'CLEAR' or 'INVERT'. +% +% OUTPUTS: VAL +% For a read: set to the state of the item or, if LAYER or ITEMS +% are 'ALL' set to 1 if all set and 0 if all are cleared +% For a write: returns 0 or a negative error +% FILTERMASK is a copy of the input filter with the required bits +% set, cleared or inverted. +% +% N.B. any non-numeric input is assumed to represent 'ALL' above. For +% string inputs only the first character is used. +% +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London \ No newline at end of file diff --git a/src/Import/SON/SON32/SONFControl.mexw32 b/Import/SON/SON32/SONFControl.mexw32 similarity index 100% rename from src/Import/SON/SON32/SONFControl.mexw32 rename to Import/SON/SON32/SONFControl.mexw32 diff --git a/src/Import/SON/SON32/SONFEqual.m b/Import/SON/SON32/SONFEqual.m similarity index 84% rename from src/Import/SON/SON32/SONFEqual.m rename to Import/SON/SON32/SONFEqual.m index 8b99176c..5b80e9eb 100644 --- a/src/Import/SON/SON32/SONFEqual.m +++ b/Import/SON/SON32/SONFEqual.m @@ -1,12 +1,12 @@ -% Tests a filter mask structure for active layers -% -% Implemented through SONFEqual.dll -% -% ANS=SONFEQUAL(FILTERMASK) -% -% Sets bits 1 to 4 in the output if layers 1 to 4 of the filter mask -% do anything i.e. have cleared bits -% -% Author:Malcolm Lidierth -% Matlab SON library: +% Tests a filter mask structure for active layers +% +% Implemented through SONFEqual.dll +% +% ANS=SONFEQUAL(FILTERMASK) +% +% Sets bits 1 to 4 in the output if layers 1 to 4 of the filter mask +% do anything i.e. have cleared bits +% +% Author:Malcolm Lidierth +% Matlab SON library: % Copyright 2005 Kings College London \ No newline at end of file diff --git a/src/Import/SON/SON32/SONFEqual.mexw32 b/Import/SON/SON32/SONFEqual.mexw32 similarity index 100% rename from src/Import/SON/SON32/SONFEqual.mexw32 rename to Import/SON/SON32/SONFEqual.mexw32 diff --git a/src/Import/SON/SON32/SONFMode.m b/Import/SON/SON32/SONFMode.m similarity index 93% rename from src/Import/SON/SON32/SONFMode.m rename to Import/SON/SON32/SONFMode.m index f5e1d02e..01f17993 100644 --- a/src/Import/SON/SON32/SONFMode.m +++ b/Import/SON/SON32/SONFMode.m @@ -1,23 +1,23 @@ -% SONFMODE creates a filter mask structure and/or -% sets the mode for marker filtering -% -% Implemented though SONFMode.dll -% -% FILTERMASK=SONFMODE(MODE) -% FILTERMASK=SONFMODE(FILTERMASK, MODE) -% -% INPUTS: FILTERMASK, if present, is a filter mask structure that will be -% copied to the output -% MODE is a string, currently 'OR', 'AND' or 'NOCHANGE' -% (not case sensitive) - -% N.B. only the 1st letter is examined. If 'nochange' is -% set without an input filter mask, or no mode is specified, -% 'AND' mode is selected by default. -% OUTPUT: A FILTERMASK structure with flags set according to MODE. -% If a filter mask is provided on input, mask values will be -% copied from it to the output mask filter. -% -% -% Author:Malcolm Lidierth -% Matlab SON library: +% SONFMODE creates a filter mask structure and/or +% sets the mode for marker filtering +% +% Implemented though SONFMode.dll +% +% FILTERMASK=SONFMODE(MODE) +% FILTERMASK=SONFMODE(FILTERMASK, MODE) +% +% INPUTS: FILTERMASK, if present, is a filter mask structure that will be +% copied to the output +% MODE is a string, currently 'OR', 'AND' or 'NOCHANGE' +% (not case sensitive) - +% N.B. only the 1st letter is examined. If 'nochange' is +% set without an input filter mask, or no mode is specified, +% 'AND' mode is selected by default. +% OUTPUT: A FILTERMASK structure with flags set according to MODE. +% If a filter mask is provided on input, mask values will be +% copied from it to the output mask filter. +% +% +% Author:Malcolm Lidierth +% Matlab SON library: % Copyright 2005 Kings College London \ No newline at end of file diff --git a/src/Import/SON/SON32/SONFMode.mexw32 b/Import/SON/SON32/SONFMode.mexw32 similarity index 100% rename from src/Import/SON/SON32/SONFMode.mexw32 rename to Import/SON/SON32/SONFMode.mexw32 diff --git a/src/Import/SON/SON32/SONFileBytes.m b/Import/SON/SON32/SONFileBytes.m similarity index 94% rename from src/Import/SON/SON32/SONFileBytes.m rename to Import/SON/SON32/SONFileBytes.m index e84c364e..5b4bffb6 100644 --- a/src/Import/SON/SON32/SONFileBytes.m +++ b/Import/SON/SON32/SONFileBytes.m @@ -1,11 +1,11 @@ -function bytes=SONFileBytes(fh) -% SONFILEBYTES Returns the number of bytes in the file -% BYTES=SONFILEBYTES(FH) where FH is the file handle -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - - -bytes=calllib('son32','SONFileBytes',fh); +function bytes=SONFileBytes(fh) +% SONFILEBYTES Returns the number of bytes in the file +% BYTES=SONFILEBYTES(FH) where FH is the file handle +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + + +bytes=calllib('son32','SONFileBytes',fh); return; \ No newline at end of file diff --git a/src/Import/SON/SON32/SONFileSize.m b/Import/SON/SON32/SONFileSize.m similarity index 94% rename from src/Import/SON/SON32/SONFileSize.m rename to Import/SON/SON32/SONFileSize.m index 5d2b0e5d..abbdef7f 100644 --- a/src/Import/SON/SON32/SONFileSize.m +++ b/Import/SON/SON32/SONFileSize.m @@ -1,11 +1,11 @@ -function bytes=SONFileSize(fh) -% SONFILESIZE Returns the expected size of a file -% BYTES=SONFILESIZE(FH) where FH is the file handle -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - - -bytes=calllib('son32','SONFileSize',fh); +function bytes=SONFileSize(fh) +% SONFILESIZE Returns the expected size of a file +% BYTES=SONFILESIZE(FH) where FH is the file handle +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + + +bytes=calllib('son32','SONFileSize',fh); return; \ No newline at end of file diff --git a/src/Import/SON/SON32/SONFilter.m b/Import/SON/SON32/SONFilter.m similarity index 90% rename from src/Import/SON/SON32/SONFilter.m rename to Import/SON/SON32/SONFilter.m index 6651aec3..e7539476 100644 --- a/src/Import/SON/SON32/SONFilter.m +++ b/Import/SON/SON32/SONFilter.m @@ -1,18 +1,18 @@ -% SONFILTER tests whether a set of markers are included in the set defined -% by a filter mask -% -% Implemented though SONFilter.dll -% -% ANS=SONFILTER(MARKERS, FILTERMASK) -% -% INPUTS: MARKERS is EITHER -% 1. a TMarker structure as defined in the SON system -% or -% 2. a 4-byte uint8 vector containing the marker values -% FILTERMASK is the filter mask structure -% OUTPUTS: 1= the markers are included in the filter mask, -% 0 otherwise -% -% Author:Malcolm Lidierth -% Matlab SON library: +% SONFILTER tests whether a set of markers are included in the set defined +% by a filter mask +% +% Implemented though SONFilter.dll +% +% ANS=SONFILTER(MARKERS, FILTERMASK) +% +% INPUTS: MARKERS is EITHER +% 1. a TMarker structure as defined in the SON system +% or +% 2. a 4-byte uint8 vector containing the marker values +% FILTERMASK is the filter mask structure +% OUTPUTS: 1= the markers are included in the filter mask, +% 0 otherwise +% +% Author:Malcolm Lidierth +% Matlab SON library: % Copyright 2005 Kings College London \ No newline at end of file diff --git a/src/Import/SON/SON32/SONFilter.mexw32 b/Import/SON/SON32/SONFilter.mexw32 similarity index 100% rename from src/Import/SON/SON32/SONFilter.mexw32 rename to Import/SON/SON32/SONFilter.mexw32 diff --git a/src/Import/SON/SON32/SONGetADCData.m b/Import/SON/SON32/SONGetADCData.m similarity index 97% rename from src/Import/SON/SON32/SONGetADCData.m rename to Import/SON/SON32/SONGetADCData.m index 2b0fa5ff..31d55c30 100644 --- a/src/Import/SON/SON32/SONGetADCData.m +++ b/Import/SON/SON32/SONGetADCData.m @@ -1,41 +1,41 @@ -% SONGETADCDATA returns data for Adc, AdcMark, RealWave ( and RealMark?) -% data channels -% -% Implemented through SONGetADCData.dll -% -% [npoints, bTime, data]=SONGETADCDATA(fh, chan,... -% maxpoints, sTime, eTime{, FilterMask}) -% -% INPUTS: FH = file handle -% CHAN = channel number 0 to SONMAXCHANS-1 -% MAXPOINTS = Maximum number of data points to return -% The routine will calculate MAXPOINTS -% if this is passed as zero or less. -% STIME = the start time for the data search -% (in clock ticks) -% ETIME = the end time for teh search -% (in clock ticks) -% FILTERMASK if present is a filter mask structure -% There will be no filtering if this is -% absent. -% OUTPUTS: NPOINTS= number of data points returned -% or a negative error -% BTIME = the time for the first sample returned in -% data (in clock ticks) -% DATA = the output data array -% -% Alternative call: -% [npoints, bTime]=SONGETADCDATA(fh, chan,... -% data, sTime, eTime{, FilterMask}) -% Here, DATA must be a pre-allocated int16 column vector. SON32.DLL will -% place data directly into this array in the matlab workspace. For repeated -% calls, this can be faster but it breaks normal matlab conventions. -% -% For error codes returned in NPOINTS see the CED documentation -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - - - +% SONGETADCDATA returns data for Adc, AdcMark, RealWave ( and RealMark?) +% data channels +% +% Implemented through SONGetADCData.dll +% +% [npoints, bTime, data]=SONGETADCDATA(fh, chan,... +% maxpoints, sTime, eTime{, FilterMask}) +% +% INPUTS: FH = file handle +% CHAN = channel number 0 to SONMAXCHANS-1 +% MAXPOINTS = Maximum number of data points to return +% The routine will calculate MAXPOINTS +% if this is passed as zero or less. +% STIME = the start time for the data search +% (in clock ticks) +% ETIME = the end time for teh search +% (in clock ticks) +% FILTERMASK if present is a filter mask structure +% There will be no filtering if this is +% absent. +% OUTPUTS: NPOINTS= number of data points returned +% or a negative error +% BTIME = the time for the first sample returned in +% data (in clock ticks) +% DATA = the output data array +% +% Alternative call: +% [npoints, bTime]=SONGETADCDATA(fh, chan,... +% data, sTime, eTime{, FilterMask}) +% Here, DATA must be a pre-allocated int16 column vector. SON32.DLL will +% place data directly into this array in the matlab workspace. For repeated +% calls, this can be faster but it breaks normal matlab conventions. +% +% For error codes returned in NPOINTS see the CED documentation +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + + + diff --git a/src/Import/SON/SON32/SONGetADCData.mexw32 b/Import/SON/SON32/SONGetADCData.mexw32 similarity index 100% rename from src/Import/SON/SON32/SONGetADCData.mexw32 rename to Import/SON/SON32/SONGetADCData.mexw32 diff --git a/src/Import/SON/SON32/SONGetADCInfo.m b/Import/SON/SON32/SONGetADCInfo.m similarity index 97% rename from src/Import/SON/SON32/SONGetADCInfo.m rename to Import/SON/SON32/SONGetADCInfo.m index ab346a8e..d3526111 100644 --- a/src/Import/SON/SON32/SONGetADCInfo.m +++ b/Import/SON/SON32/SONGetADCInfo.m @@ -1,28 +1,28 @@ -function [sc,of,units,points,preTrig]=SONGetADCInfo(fh, chan) -% SONGETADCINFO Returns information about an ADC data channel -% (scale{,offset{,units{,points{,preTrig}}}})=SONGetADCInfo(fh, chan) -% Inputs FH SON file handle -% CHAN Channel number 0 to SONMaxChan()-1 -% Outputs SCALE } As defined in Spike2 -% OFFSET } -% UNITS character string with units -% POINTS number of points for ADCMark channel -% PRETRIG number of pre-Trigger points for -% ADCMArk channel -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - -global SON_UNITSZ; - - -if nargin ~=2 - sc=-1000; - return; -end; - -units=char(zeros(1,SON_UNITSZ+1)); -[sc of units points preTrig]=... - calllib('son32','SONGetADCInfo',fh,chan,0,0,units,0,0); -return; +function [sc,of,units,points,preTrig]=SONGetADCInfo(fh, chan) +% SONGETADCINFO Returns information about an ADC data channel +% (scale{,offset{,units{,points{,preTrig}}}})=SONGetADCInfo(fh, chan) +% Inputs FH SON file handle +% CHAN Channel number 0 to SONMaxChan()-1 +% Outputs SCALE } As defined in Spike2 +% OFFSET } +% UNITS character string with units +% POINTS number of points for ADCMark channel +% PRETRIG number of pre-Trigger points for +% ADCMArk channel +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + +global SON_UNITSZ; + + +if nargin ~=2 + sc=-1000; + return; +end; + +units=char(zeros(1,SON_UNITSZ+1)); +[sc of units points preTrig]=... + calllib('son32','SONGetADCInfo',fh,chan,0,0,units,0,0); +return; diff --git a/src/Import/SON/SON32/SONGetChanComment.m b/Import/SON/SON32/SONGetChanComment.m similarity index 97% rename from src/Import/SON/SON32/SONGetChanComment.m rename to Import/SON/SON32/SONGetChanComment.m index 8c993713..5bcf30a4 100644 --- a/src/Import/SON/SON32/SONGetChanComment.m +++ b/Import/SON/SON32/SONGetChanComment.m @@ -1,17 +1,17 @@ -function [comment]=SONGetChanComment(fh, chan) -% SONGETCHANCOMMENT returns the comment string for the specified channel -% -% COMMENT=SONGETCHANCOMMENT(FH, CHAN) -% FH SON file handle -% CHAN Channel number (0 to SONMAXCHANS-1) -% Returns the channel comment as a string. -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - -global SON_CHANCOMSZ; - -comment=char(zeros(1,SON_CHANCOMSZ)); -comment=calllib('son32','SONGetChanComment',... - fh,chan,comment,SON_CHANCOMSZ); +function [comment]=SONGetChanComment(fh, chan) +% SONGETCHANCOMMENT returns the comment string for the specified channel +% +% COMMENT=SONGETCHANCOMMENT(FH, CHAN) +% FH SON file handle +% CHAN Channel number (0 to SONMAXCHANS-1) +% Returns the channel comment as a string. +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + +global SON_CHANCOMSZ; + +comment=char(zeros(1,SON_CHANCOMSZ)); +comment=calllib('son32','SONGetChanComment',... + fh,chan,comment,SON_CHANCOMSZ); diff --git a/src/Import/SON/SON32/SONGetChanTitle.m b/Import/SON/SON32/SONGetChanTitle.m similarity index 95% rename from src/Import/SON/SON32/SONGetChanTitle.m rename to Import/SON/SON32/SONGetChanTitle.m index 7419f6e6..d44c286b 100644 --- a/src/Import/SON/SON32/SONGetChanTitle.m +++ b/Import/SON/SON32/SONGetChanTitle.m @@ -1,16 +1,16 @@ -function chantitle=SONGetChanTitle(fh, chan) -% SONGETCHANTITLE Returns the channel title -% -% TITLE=SONGETCHANTITLE(FH, CHAN) -% -% INPUTS FH is the file handle -% CHAN is the channel number (0 to SONMaxChans()-1 -% OUTPUT the channel title as a string -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - -chantitle='0123456789'; -chantitle=calllib('son32','SONGetChanTitle', fh, chan, chantitle); +function chantitle=SONGetChanTitle(fh, chan) +% SONGETCHANTITLE Returns the channel title +% +% TITLE=SONGETCHANTITLE(FH, CHAN) +% +% INPUTS FH is the file handle +% CHAN is the channel number (0 to SONMaxChans()-1 +% OUTPUT the channel title as a string +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + +chantitle='0123456789'; +chantitle=calllib('son32','SONGetChanTitle', fh, chan, chantitle); return; \ No newline at end of file diff --git a/src/Import/SON/SON32/SONGetEventData.m b/Import/SON/SON32/SONGetEventData.m similarity index 97% rename from src/Import/SON/SON32/SONGetEventData.m rename to Import/SON/SON32/SONGetEventData.m index 9c977542..b12db243 100644 --- a/src/Import/SON/SON32/SONGetEventData.m +++ b/Import/SON/SON32/SONGetEventData.m @@ -1,31 +1,31 @@ -% SONGETEVENTDATA returns the timings for an Event or marker channel -% -% Implemented through SONGetEventData.dll -% -% [npoints, times, levlow]= -% SONGETEVENTDATA(fh, chan, maxpoints, stime, etime{, filtermask}) -% -% INPUTS: FH = file handle -% CHAN = channel number 0 to SONMAXCHANS-1 -% MAXPOINTS = Maximum number of data values to return -% STIME = the start time for the data search -% (in clock ticks) -% ETIME = the end time for teh search -% (in clock ticks) -% FILTERMASK if present is a filter mask structure -% There will be no filtering if this is -% absent. -% OUTPUTS: NPOINTS= number of data points returned -% or a negative error -% TIMES = an NPOINT column vector containing the -% timestamps (in clock ticks) -% LEVLOW = For a EventBoth (level) channel, -% this is set to 1 if the first event -% is a high to low transition, 0 otherwise -% -% -% For error codes, see the CED documentation -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London +% SONGETEVENTDATA returns the timings for an Event or marker channel +% +% Implemented through SONGetEventData.dll +% +% [npoints, times, levlow]= +% SONGETEVENTDATA(fh, chan, maxpoints, stime, etime{, filtermask}) +% +% INPUTS: FH = file handle +% CHAN = channel number 0 to SONMAXCHANS-1 +% MAXPOINTS = Maximum number of data values to return +% STIME = the start time for the data search +% (in clock ticks) +% ETIME = the end time for teh search +% (in clock ticks) +% FILTERMASK if present is a filter mask structure +% There will be no filtering if this is +% absent. +% OUTPUTS: NPOINTS= number of data points returned +% or a negative error +% TIMES = an NPOINT column vector containing the +% timestamps (in clock ticks) +% LEVLOW = For a EventBoth (level) channel, +% this is set to 1 if the first event +% is a high to low transition, 0 otherwise +% +% +% For error codes, see the CED documentation +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London diff --git a/src/Import/SON/SON32/SONGetEventData.mexw32 b/Import/SON/SON32/SONGetEventData.mexw32 similarity index 100% rename from src/Import/SON/SON32/SONGetEventData.mexw32 rename to Import/SON/SON32/SONGetEventData.mexw32 diff --git a/src/Import/SON/SON32/SONGetExtMarkData.m b/Import/SON/SON32/SONGetExtMarkData.m similarity index 98% rename from src/Import/SON/SON32/SONGetExtMarkData.m rename to Import/SON/SON32/SONGetExtMarkData.m index a2834ac4..3afc3189 100644 --- a/src/Import/SON/SON32/SONGetExtMarkData.m +++ b/Import/SON/SON32/SONGetExtMarkData.m @@ -1,40 +1,40 @@ -% SONGETEXTMARKDATA returns the timings, marker values and extra data -% for an AdcMark, RealMark or TextMark channel -% -% Implemented through SONGetExtMarkData.dll -% -% [npoints, times, markers, extra]= -% SONGETEXTMARKDATA(fh, chan, maxpoints, stime, etime{, filtermask}) -% -% INPUTS: FH = file handle -% CHAN = channel number 0 to SONMAXCHANS-1 -% MAXPOINTS = Maximum number of data values to return -% (up to 32767, if zero this will be set to -% 32767) -% STIME = the start time for the data search -% (in clock ticks) -% ETIME = the end time for teh search -% (in clock ticks) -% FILTERMASK if present is a filter mask structure -% There will be no filtering if this is -% absent. -% OUTPUTS: NPOINTS= number of data points returned -% or a negative error -% TIMES = an NPOINT column vector containing the -% timestamps (in clock ticks) -% MARKERS = an NPOINT x 4 byte array, with 4 markers -% for each of the timestamps in TIMES. -% EXTRA= An X x NPOINT array. The NPOINT columns contain -% the extra data for each marker. The length of -% the columns varies between channels. -% EXTRA is int16 for ADCMark channels, single -% for RealMark and uint8 for TextMark -% -% Note: If required, cast TextMark EXTRA data to type char in MATLAB -% If you do not need the EXTRA data, use SONGetMarkData instead -% -% For error codes, see the CED documentation -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London +% SONGETEXTMARKDATA returns the timings, marker values and extra data +% for an AdcMark, RealMark or TextMark channel +% +% Implemented through SONGetExtMarkData.dll +% +% [npoints, times, markers, extra]= +% SONGETEXTMARKDATA(fh, chan, maxpoints, stime, etime{, filtermask}) +% +% INPUTS: FH = file handle +% CHAN = channel number 0 to SONMAXCHANS-1 +% MAXPOINTS = Maximum number of data values to return +% (up to 32767, if zero this will be set to +% 32767) +% STIME = the start time for the data search +% (in clock ticks) +% ETIME = the end time for teh search +% (in clock ticks) +% FILTERMASK if present is a filter mask structure +% There will be no filtering if this is +% absent. +% OUTPUTS: NPOINTS= number of data points returned +% or a negative error +% TIMES = an NPOINT column vector containing the +% timestamps (in clock ticks) +% MARKERS = an NPOINT x 4 byte array, with 4 markers +% for each of the timestamps in TIMES. +% EXTRA= An X x NPOINT array. The NPOINT columns contain +% the extra data for each marker. The length of +% the columns varies between channels. +% EXTRA is int16 for ADCMark channels, single +% for RealMark and uint8 for TextMark +% +% Note: If required, cast TextMark EXTRA data to type char in MATLAB +% If you do not need the EXTRA data, use SONGetMarkData instead +% +% For error codes, see the CED documentation +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London diff --git a/src/Import/SON/SON32/SONGetExtMarkData.mexw32 b/Import/SON/SON32/SONGetExtMarkData.mexw32 similarity index 100% rename from src/Import/SON/SON32/SONGetExtMarkData.mexw32 rename to Import/SON/SON32/SONGetExtMarkData.mexw32 diff --git a/src/Import/SON/SON32/SONGetExtMarkInfo.m b/Import/SON/SON32/SONGetExtMarkInfo.m similarity index 96% rename from src/Import/SON/SON32/SONGetExtMarkInfo.m rename to Import/SON/SON32/SONGetExtMarkInfo.m index 399a21ca..344a09cb 100644 --- a/src/Import/SON/SON32/SONGetExtMarkInfo.m +++ b/Import/SON/SON32/SONGetExtMarkInfo.m @@ -1,29 +1,29 @@ -function [units, points, preTrig]=SONGetExtMarkInfo(fh, chan) -% SONGETEXTMARKINFO returns details about an extended marker channel -% -% [UNITS, POINTS, PRETRIG]=SONGETEXTMARKINFO(FH, CHAN) -% -% INPUTS: FH the SON file handle -% CHAN channel number (0 - SONMaxChans()-1) -% -% OUTPUTS: UNITS a string with the channel units -% POINTS the number of items of extra data -% PRETRIG the number of pre-trigger items -% -% Returns no error codes -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - -global SON_UNITSZ; - -units=char(zeros(1,SON_UNITSZ+1)); -points=uint16(0); -preTrig=int16(0); - -ppoints=libpointer('uint16Ptr',points); -ppreTrig=libpointer('int16Ptr',preTrig); - -[units, points, preTrig]=... - calllib('son32','SONGetExtMarkInfo', fh, chan, units, ppoints, ppreTrig); +function [units, points, preTrig]=SONGetExtMarkInfo(fh, chan) +% SONGETEXTMARKINFO returns details about an extended marker channel +% +% [UNITS, POINTS, PRETRIG]=SONGETEXTMARKINFO(FH, CHAN) +% +% INPUTS: FH the SON file handle +% CHAN channel number (0 - SONMaxChans()-1) +% +% OUTPUTS: UNITS a string with the channel units +% POINTS the number of items of extra data +% PRETRIG the number of pre-trigger items +% +% Returns no error codes +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + +global SON_UNITSZ; + +units=char(zeros(1,SON_UNITSZ+1)); +points=uint16(0); +preTrig=int16(0); + +ppoints=libpointer('uint16Ptr',points); +ppreTrig=libpointer('int16Ptr',preTrig); + +[units, points, preTrig]=... + calllib('son32','SONGetExtMarkInfo', fh, chan, units, ppoints, ppreTrig); diff --git a/src/Import/SON/SON32/SONGetExtraData.m b/Import/SON/SON32/SONGetExtraData.m similarity index 96% rename from src/Import/SON/SON32/SONGetExtraData.m rename to Import/SON/SON32/SONGetExtraData.m index bb3d6089..d0b5981f 100644 --- a/src/Import/SON/SON32/SONGetExtraData.m +++ b/Import/SON/SON32/SONGetExtraData.m @@ -1,73 +1,73 @@ -function [varargout]=SONGetExtraData(varargin) -% SONGETEXTRADATA reads or writes the extra data area of a SON file -% -% [ERR, BUFFER]=SONGETEXTRADATA(FH, N, DATATYPE, BYTEOFFSET, FLAG) -% or -% ERR=SONGETEXTRADATA(FH, BUFFER, BYTEOFFSET, FLAG) -% -% INPUTS: FH the SON file handle -% N the number of items to read -% DATATYPE string class descriptor for the read -% BYTEOFFSET the offset from the start of the data area -% BUFFER the data to write -% FLAG 0 to read and 1 to write data -% -% OUTPUTS ERR= 0 if OK or a negative error -% BUFFER the output data for a read -% -% e.g. [err data]=SONGetExtraData(fh, 100, 'int32', 64, 0) -% reads 100 32-bit integer values from the data area starting 64 bytes into -% the area -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - - - -if (nargin==5) - fh=varargin{1}; - n=varargin{2}; - datatype=varargin{3}; - byteoffset=varargin{4}; - flag=varargin{5}; - if (flag==0) - st=sprintf('%s(zeros(1,%d))',datatype, n); - st=eval(st); - tmp=feval('whos','st'); - st=sprintf('%s(zeros(1,%d))', datatype, tmp.bytes); - buffer=eval(st); - [err buffer]=calllib('son32','SONGetExtraData',... - fh, buffer, tmp.bytes, byteoffset, flag); - varargout{1}=err; - if (err==0 && nargout==2) - varargout{2}=eval(sprintf('%s(buffer)',datatype)); - else - if (nargout==2) - varargout{2}=eval(sprintf('%s([])',datatype)); - end; - end; - return; - end; -end; - -if (nargin==4) - fh=varargin{1}; - buffer=varargin{2}; - byteoffset=varargin{4}; - flag=varargin{4}; - if (flag==1) - tmp=whos('buffer'); - varargout{1}=calllib('son32','SONGetExtraData',... - fh, buffer, tmp.bytes, byteoffset, flag); - return; - end; -end; - -varargout{1}=-1000; -if nargout==2 - varargout{2}=[]; -end; -return; - - +function [varargout]=SONGetExtraData(varargin) +% SONGETEXTRADATA reads or writes the extra data area of a SON file +% +% [ERR, BUFFER]=SONGETEXTRADATA(FH, N, DATATYPE, BYTEOFFSET, FLAG) +% or +% ERR=SONGETEXTRADATA(FH, BUFFER, BYTEOFFSET, FLAG) +% +% INPUTS: FH the SON file handle +% N the number of items to read +% DATATYPE string class descriptor for the read +% BYTEOFFSET the offset from the start of the data area +% BUFFER the data to write +% FLAG 0 to read and 1 to write data +% +% OUTPUTS ERR= 0 if OK or a negative error +% BUFFER the output data for a read +% +% e.g. [err data]=SONGetExtraData(fh, 100, 'int32', 64, 0) +% reads 100 32-bit integer values from the data area starting 64 bytes into +% the area +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + + + +if (nargin==5) + fh=varargin{1}; + n=varargin{2}; + datatype=varargin{3}; + byteoffset=varargin{4}; + flag=varargin{5}; + if (flag==0) + st=sprintf('%s(zeros(1,%d))',datatype, n); + st=eval(st); + tmp=feval('whos','st'); + st=sprintf('%s(zeros(1,%d))', datatype, tmp.bytes); + buffer=eval(st); + [err buffer]=calllib('son32','SONGetExtraData',... + fh, buffer, tmp.bytes, byteoffset, flag); + varargout{1}=err; + if (err==0 && nargout==2) + varargout{2}=eval(sprintf('%s(buffer)',datatype)); + else + if (nargout==2) + varargout{2}=eval(sprintf('%s([])',datatype)); + end; + end; + return; + end; +end; + +if (nargin==4) + fh=varargin{1}; + buffer=varargin{2}; + byteoffset=varargin{4}; + flag=varargin{4}; + if (flag==1) + tmp=whos('buffer'); + varargout{1}=calllib('son32','SONGetExtraData',... + fh, buffer, tmp.bytes, byteoffset, flag); + return; + end; +end; + +varargout{1}=-1000; +if nargout==2 + varargout{2}=[]; +end; +return; + + diff --git a/src/Import/SON/SON32/SONGetExtraDataSize.m b/Import/SON/SON32/SONGetExtraDataSize.m similarity index 79% rename from src/Import/SON/SON32/SONGetExtraDataSize.m rename to Import/SON/SON32/SONGetExtraDataSize.m index e98a8563..1e27b0dd 100644 --- a/src/Import/SON/SON32/SONGetExtraDataSize.m +++ b/Import/SON/SON32/SONGetExtraDataSize.m @@ -1,10 +1,10 @@ -function bytes=SONGetExtraDataSize(fh) -% Returns the size of the extra data area of file FH in bytes -% -% BYTES=SONGETEXTRADATASIZE(FH) -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - +function bytes=SONGetExtraDataSize(fh) +% Returns the size of the extra data area of file FH in bytes +% +% BYTES=SONGETEXTRADATASIZE(FH) +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + bytes=calllib('son32', 'SONGetExtraDataSize', fh); \ No newline at end of file diff --git a/src/Import/SON/SON32/SONGetFileComment.m b/Import/SON/SON32/SONGetFileComment.m similarity index 97% rename from src/Import/SON/SON32/SONGetFileComment.m rename to Import/SON/SON32/SONGetFileComment.m index 2a8bcb5e..0a7ac372 100644 --- a/src/Import/SON/SON32/SONGetFileComment.m +++ b/Import/SON/SON32/SONGetFileComment.m @@ -1,12 +1,12 @@ -function string=SONGetFileComment(fh, n) -% SONGETFILECOMMENT returns the file comment -% -% STRING=SONGETFILE(FH, N) -% where FH is the file handle and N is the comment number (0-4); -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - -string=char(zeros(1,80)); +function string=SONGetFileComment(fh, n) +% SONGETFILECOMMENT returns the file comment +% +% STRING=SONGETFILE(FH, N) +% where FH is the file handle and N is the comment number (0-4); +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + +string=char(zeros(1,80)); string=calllib('son32', 'SONGetFileComment', fh, n, string, 79); \ No newline at end of file diff --git a/src/Import/SON/SON32/SONGetFreeChan.m b/Import/SON/SON32/SONGetFreeChan.m similarity index 96% rename from src/Import/SON/SON32/SONGetFreeChan.m rename to Import/SON/SON32/SONGetFreeChan.m index 113a5508..3517a017 100644 --- a/src/Import/SON/SON32/SONGetFreeChan.m +++ b/Import/SON/SON32/SONGetFreeChan.m @@ -1,11 +1,11 @@ -function chan=SONGetFreeChan(fh) -% SONGETFREECHAN returns the number of the first free channel in a file -% -% CHAN=SONGETFREECHAN(FH) -% where FH is the SON file handle -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - -chan=calllib('son32', 'SONGetFreeChan', fh); +function chan=SONGetFreeChan(fh) +% SONGETFREECHAN returns the number of the first free channel in a file +% +% CHAN=SONGETFREECHAN(FH) +% where FH is the SON file handle +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + +chan=calllib('son32', 'SONGetFreeChan', fh); diff --git a/src/Import/SON/SON32/SONGetFreeChanl.m b/Import/SON/SON32/SONGetFreeChanl.m similarity index 96% rename from src/Import/SON/SON32/SONGetFreeChanl.m rename to Import/SON/SON32/SONGetFreeChanl.m index 198bf03b..4d9b5820 100644 --- a/src/Import/SON/SON32/SONGetFreeChanl.m +++ b/Import/SON/SON32/SONGetFreeChanl.m @@ -1,11 +1,11 @@ -function chan=SONGetFreeChan(fh) -% SONGETFREECHAN returns the number of the first free channel in a file -% -% CHAN=SONGETFREECHAN(FH) -% where FH is the SON file handle -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - -chan=calllib('son32', 'SONGetFreeChan', fh); +function chan=SONGetFreeChan(fh) +% SONGETFREECHAN returns the number of the first free channel in a file +% +% CHAN=SONGETFREECHAN(FH) +% where FH is the SON file handle +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + +chan=calllib('son32', 'SONGetFreeChan', fh); diff --git a/src/Import/SON/SON32/SONGetMarkData.m b/Import/SON/SON32/SONGetMarkData.m similarity index 95% rename from src/Import/SON/SON32/SONGetMarkData.m rename to Import/SON/SON32/SONGetMarkData.m index b3743432..9ae040a8 100644 --- a/src/Import/SON/SON32/SONGetMarkData.m +++ b/Import/SON/SON32/SONGetMarkData.m @@ -1,37 +1,37 @@ -% SONGETMARKDATA returns the timings and marker values for a Marker, AdcMark, -% RealMark or TextMark channel -% -% Implemented through SONGetMarkData.dll -% -% [npoints, times, markers]= -% SONGETMARKDATA(fh, chan, maxpoints, stime, etime{, filtermask}) -% -% INPUTS: FH = file handle -% CHAN = channel number 0 to SONMAXCHANS-1 -% MAXPOINTS = Maximum number of data values to return -% (up to 32767, if zero will be set to -% 32767) -% STIME = the start time for the data search -% (in clock ticks) -% ETIME = the end time for teh search -% (in clock ticks) -% FILTERMASK if present is a filter mask structure -% There will be no filtering if this is -% absent. -% OUTPUTS: NPOINTS= number of data points returned -% or a negative error -% TIMES = an NPOINT column vector containing the -% timestamps (in clock ticks) -% DATA = an NPOINT x 4 byte array, with 4 markers -% for each of the timestamps in TIMES. -% -% Note: For easier compatability with version 1.0 of the library use a -% structure for the outputs e.g. -% [npoints, data.timings, data.markers]= -% SONGETMARKDATA(fh, chan, maxpoints, stime, etime) -% -% For error codes, see the CED documentation -% -% Author:Malcolm Lidierth -% Matlab SON library: +% SONGETMARKDATA returns the timings and marker values for a Marker, AdcMark, +% RealMark or TextMark channel +% +% Implemented through SONGetMarkData.dll +% +% [npoints, times, markers]= +% SONGETMARKDATA(fh, chan, maxpoints, stime, etime{, filtermask}) +% +% INPUTS: FH = file handle +% CHAN = channel number 0 to SONMAXCHANS-1 +% MAXPOINTS = Maximum number of data values to return +% (up to 32767, if zero will be set to +% 32767) +% STIME = the start time for the data search +% (in clock ticks) +% ETIME = the end time for teh search +% (in clock ticks) +% FILTERMASK if present is a filter mask structure +% There will be no filtering if this is +% absent. +% OUTPUTS: NPOINTS= number of data points returned +% or a negative error +% TIMES = an NPOINT column vector containing the +% timestamps (in clock ticks) +% DATA = an NPOINT x 4 byte array, with 4 markers +% for each of the timestamps in TIMES. +% +% Note: For easier compatability with version 1.0 of the library use a +% structure for the outputs e.g. +% [npoints, data.timings, data.markers]= +% SONGETMARKDATA(fh, chan, maxpoints, stime, etime) +% +% For error codes, see the CED documentation +% +% Author:Malcolm Lidierth +% Matlab SON library: % Copyright 2005 Kings College London \ No newline at end of file diff --git a/src/Import/SON/SON32/SONGetMarkData.mexw32 b/Import/SON/SON32/SONGetMarkData.mexw32 similarity index 100% rename from src/Import/SON/SON32/SONGetMarkData.mexw32 rename to Import/SON/SON32/SONGetMarkData.mexw32 diff --git a/src/Import/SON/SON32/SONGetRealData.m b/Import/SON/SON32/SONGetRealData.m similarity index 97% rename from src/Import/SON/SON32/SONGetRealData.m rename to Import/SON/SON32/SONGetRealData.m index d772e3e0..7c6f6d2b 100644 --- a/src/Import/SON/SON32/SONGetRealData.m +++ b/Import/SON/SON32/SONGetRealData.m @@ -1,41 +1,41 @@ -% SONGETREALDATA returns data for Adc, AdcMark, RealWave ( and RealMark?) -% data channels -% -% Implemented through SONGetRealData.dll -% -% [npoints, bTime, data]=SONGETREALDATA(fh, chan,... -% maxpoints, sTime, eTime{, FilterMask}) -% -% INPUTS: FH = file handle -% CHAN = channel number 0 to SONMAXCHANS-1 -% MAXPOINTS = Maximum number of data points to return -% The routine will calculate MAXPOINTS -% if this is passed as zero or less. -% STIME = the start time for the data search -% (in clock ticks) -% ETIME = the end time for teh search -% (in clock ticks) -% FILTERMASK if present is a filter mask structure -% There will be no filtering if this is -% absent. -% OUTPUTS: NPOINTS= number of data points returned -% or a negative error -% BTIME = the time for the first sample returned in -% data (in clock ticks) -% DATA = the output data array -% -% Alternative call: -% [npoints, bTime]=SONGETREALDATA(fh, chan,... -% data, sTime, eTime{, FilterMask}) -% Here, DATA must be a pre-allocated int16 column vector. SON32.DLL will -% place data directly into this array in the matlab workspace. For repeated -% calls, this can be faster but it breaks normal matlab conventions. -% -% For error codes returned in NPOINTS see the CED documentation -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - - - +% SONGETREALDATA returns data for Adc, AdcMark, RealWave ( and RealMark?) +% data channels +% +% Implemented through SONGetRealData.dll +% +% [npoints, bTime, data]=SONGETREALDATA(fh, chan,... +% maxpoints, sTime, eTime{, FilterMask}) +% +% INPUTS: FH = file handle +% CHAN = channel number 0 to SONMAXCHANS-1 +% MAXPOINTS = Maximum number of data points to return +% The routine will calculate MAXPOINTS +% if this is passed as zero or less. +% STIME = the start time for the data search +% (in clock ticks) +% ETIME = the end time for teh search +% (in clock ticks) +% FILTERMASK if present is a filter mask structure +% There will be no filtering if this is +% absent. +% OUTPUTS: NPOINTS= number of data points returned +% or a negative error +% BTIME = the time for the first sample returned in +% data (in clock ticks) +% DATA = the output data array +% +% Alternative call: +% [npoints, bTime]=SONGETREALDATA(fh, chan,... +% data, sTime, eTime{, FilterMask}) +% Here, DATA must be a pre-allocated int16 column vector. SON32.DLL will +% place data directly into this array in the matlab workspace. For repeated +% calls, this can be faster but it breaks normal matlab conventions. +% +% For error codes returned in NPOINTS see the CED documentation +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + + + diff --git a/src/Import/SON/SON32/SONGetRealData.mexw32 b/Import/SON/SON32/SONGetRealData.mexw32 similarity index 100% rename from src/Import/SON/SON32/SONGetRealData.mexw32 rename to Import/SON/SON32/SONGetRealData.mexw32 diff --git a/src/Import/SON/SON32/SONGetTimePerADC.m b/Import/SON/SON32/SONGetTimePerADC.m similarity index 94% rename from src/Import/SON/SON32/SONGetTimePerADC.m rename to Import/SON/SON32/SONGetTimePerADC.m index a5e75594..86fae15a 100644 --- a/src/Import/SON/SON32/SONGetTimePerADC.m +++ b/Import/SON/SON32/SONGetTimePerADC.m @@ -1,19 +1,19 @@ -function ticks=SONGetTimePerADC(fh) -% SONGETTIMEPERADC returns the number of clock ticks per ADC conversion -% TICKS=SONGETTIMEPERADC(FH) -% FH = file handle -% Returns the number of ticks (no error codes) -% -% See also SONGETUSPERTIME, SONCHANDIVIDE -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - -if nargin ~= 1 - ticks=-1000; - return; -end; - -ticks=calllib('son32','SONGetTimePerADC',fh); +function ticks=SONGetTimePerADC(fh) +% SONGETTIMEPERADC returns the number of clock ticks per ADC conversion +% TICKS=SONGETTIMEPERADC(FH) +% FH = file handle +% Returns the number of ticks (no error codes) +% +% See also SONGETUSPERTIME, SONCHANDIVIDE +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + +if nargin ~= 1 + ticks=-1000; + return; +end; + +ticks=calllib('son32','SONGetTimePerADC',fh); return; \ No newline at end of file diff --git a/src/Import/SON/SON32/SONGetVersion.m b/Import/SON/SON32/SONGetVersion.m similarity index 82% rename from src/Import/SON/SON32/SONGetVersion.m rename to Import/SON/SON32/SONGetVersion.m index 5a407117..7834f7ac 100644 --- a/src/Import/SON/SON32/SONGetVersion.m +++ b/Import/SON/SON32/SONGetVersion.m @@ -1,11 +1,11 @@ -function version=SONGetVersion(fh) -% SONGETVERSION returns the SON file system version number for a file -% -% VERSION=SONGETVERSION(FH) -% where fh is the SON File handle -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - +function version=SONGetVersion(fh) +% SONGETVERSION returns the SON file system version number for a file +% +% VERSION=SONGETVERSION(FH) +% where fh is the SON File handle +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + version=calllib('son32', 'SONGetVersion', fh); \ No newline at end of file diff --git a/src/Import/SON/SON32/SONGetusPerTime.m b/Import/SON/SON32/SONGetusPerTime.m similarity index 94% rename from src/Import/SON/SON32/SONGetusPerTime.m rename to Import/SON/SON32/SONGetusPerTime.m index 4cf6f798..d3aed603 100644 --- a/src/Import/SON/SON32/SONGetusPerTime.m +++ b/Import/SON/SON32/SONGetusPerTime.m @@ -1,17 +1,17 @@ -function usPerTime=SONGetusPerTime(fh) -% SONGETUSPERTIME returns the tick interval in units of SONTimeBase() -% USPERTIME=SONGETUSPERTIME(FH) -% FH SON file handle -% -% See also SONGETTIMEPERADC, SONCHANDIVIDE -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - -if nargin ~= 1 - usPerTime=-1000; - return; -end; - -usPerTime=calllib('son32','SONGetusPerTime',fh); +function usPerTime=SONGetusPerTime(fh) +% SONGETUSPERTIME returns the tick interval in units of SONTimeBase() +% USPERTIME=SONGETUSPERTIME(FH) +% FH SON file handle +% +% See also SONGETTIMEPERADC, SONCHANDIVIDE +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + +if nargin ~= 1 + usPerTime=-1000; + return; +end; + +usPerTime=calllib('son32','SONGetusPerTime',fh); return; \ No newline at end of file diff --git a/src/Import/SON/SON32/SONIdealRate.m b/Import/SON/SON32/SONIdealRate.m similarity index 89% rename from src/Import/SON/SON32/SONIdealRate.m rename to Import/SON/SON32/SONIdealRate.m index 03e0eec6..4941396e 100644 --- a/src/Import/SON/SON32/SONIdealRate.m +++ b/Import/SON/SON32/SONIdealRate.m @@ -1,23 +1,23 @@ -function rate=SONIdealRate(fh, chan, newrate) -% SONIDEALRATE gets or sets the ideal sampling rate on a channel -% -% RATE=SONIDEALRATE(FH, CHAN) -% returns the current rate on channel CHAN in file FH -% -% RATE=SONIDEALRATE(FH, CHAN, NEWRATE) -% returns the rate at the time of the call an sets a new rate if NEWRATE>0 -% Caution: this ovewrites the existing rate setting in the file -% -% FH is the SON file handle, CHAN is the channel number (0-SONMaxChans()-1) -% -% Note that the ideal rate setting does not influence the real rate of -% sampling -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - -if nargin<3 - newrate=-1; -end; +function rate=SONIdealRate(fh, chan, newrate) +% SONIDEALRATE gets or sets the ideal sampling rate on a channel +% +% RATE=SONIDEALRATE(FH, CHAN) +% returns the current rate on channel CHAN in file FH +% +% RATE=SONIDEALRATE(FH, CHAN, NEWRATE) +% returns the rate at the time of the call an sets a new rate if NEWRATE>0 +% Caution: this ovewrites the existing rate setting in the file +% +% FH is the SON file handle, CHAN is the channel number (0-SONMaxChans()-1) +% +% Note that the ideal rate setting does not influence the real rate of +% sampling +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + +if nargin<3 + newrate=-1; +end; rate=calllib('son32','SONIdealRate', fh, chan, newrate); \ No newline at end of file diff --git a/src/Import/SON/SON32/SONIsSaving.m b/Import/SON/SON32/SONIsSaving.m similarity index 97% rename from src/Import/SON/SON32/SONIsSaving.m rename to Import/SON/SON32/SONIsSaving.m index 38efd1c7..3fbbb5b4 100644 --- a/src/Import/SON/SON32/SONIsSaving.m +++ b/Import/SON/SON32/SONIsSaving.m @@ -1,13 +1,13 @@ -function state=SONIsSaving(fh, chan) -% SONISSAVING returns the save state for a specified channel -% -% STATE=SONISSAVING(FH, CHAN) -% where FH is the SON file handle and CHAN is the channel number -% (0 - SONMaxChan()-1) -% Returns 0 if not saving, 1 if saving or a negative error code -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - -state=calllib('son32','SONIsSaving', fh, chan); +function state=SONIsSaving(fh, chan) +% SONISSAVING returns the save state for a specified channel +% +% STATE=SONISSAVING(FH, CHAN) +% where FH is the SON file handle and CHAN is the channel number +% (0 - SONMaxChan()-1) +% Returns 0 if not saving, 1 if saving or a negative error code +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + +state=calllib('son32','SONIsSaving', fh, chan); diff --git a/src/Import/SON/SON32/SONItemSize.m b/Import/SON/SON32/SONItemSize.m similarity index 85% rename from src/Import/SON/SON32/SONItemSize.m rename to Import/SON/SON32/SONItemSize.m index feb4df75..eb81eb52 100644 --- a/src/Import/SON/SON32/SONItemSize.m +++ b/Import/SON/SON32/SONItemSize.m @@ -1,12 +1,12 @@ -function bytes=SONItemSize(fh, chan) -% SONITEMSIZE returns the size of a data item on the specified channel (bytes) -% -% BYTES=SONITEMSIZE(FH, CHAN) -% where FH is the SON file handle and CHAN is the channel number -% (0 - SONMaxChan()-1) -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - +function bytes=SONItemSize(fh, chan) +% SONITEMSIZE returns the size of a data item on the specified channel (bytes) +% +% BYTES=SONITEMSIZE(FH, CHAN) +% where FH is the SON file handle and CHAN is the channel number +% (0 - SONMaxChan()-1) +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + bytes=calllib('son32','SONItemSize', fh, chan); \ No newline at end of file diff --git a/src/Import/SON/SON32/SONKillRange.m b/Import/SON/SON32/SONKillRange.m similarity index 97% rename from src/Import/SON/SON32/SONKillRange.m rename to Import/SON/SON32/SONKillRange.m index 7f9834c6..3586d8b5 100644 --- a/src/Import/SON/SON32/SONKillRange.m +++ b/Import/SON/SON32/SONKillRange.m @@ -1,16 +1,16 @@ -function flag=SONKillRange(fh, chan, startTime, endTime) -% SONKILLRANGE attempts to discard data from a file between two times -% -% FLAG=SONKILLRANGE(FH, CHAN, STARTTIME, ENDTIME) -% FH is the SON file handle, CHAN is the channel number and STARTTIME and -% ENDTIME specify the time range (in clock ticks within which to discard -% data. -% -% This is only useful when data are being written to a new file. -% See CED documentation for details -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - +function flag=SONKillRange(fh, chan, startTime, endTime) +% SONKILLRANGE attempts to discard data from a file between two times +% +% FLAG=SONKILLRANGE(FH, CHAN, STARTTIME, ENDTIME) +% FH is the SON file handle, CHAN is the channel number and STARTTIME and +% ENDTIME specify the time range (in clock ticks within which to discard +% data. +% +% This is only useful when data are being written to a new file. +% See CED documentation for details +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + flag=calllib('son32','SONKillRange', fh, chan, startTime, endTime); \ No newline at end of file diff --git a/src/Import/SON/SON32/SONLastPointsTime.m b/Import/SON/SON32/SONLastPointsTime.m similarity index 92% rename from src/Import/SON/SON32/SONLastPointsTime.m rename to Import/SON/SON32/SONLastPointsTime.m index f5b364d2..e625af21 100644 --- a/src/Import/SON/SON32/SONLastPointsTime.m +++ b/Import/SON/SON32/SONLastPointsTime.m @@ -1,20 +1,20 @@ -% SONLASTPOINTSTIME returns the time for which a read will terminate -% -% Implemented through SONLastPointsTime.dll -% -% TIME=SONGETADCDATA(FH, CHAN, ETIME, STIME, LPOINTS, BADC {, FILTERMASK}) -% -% INPUTS: FH SON File Handle -% CHAN Channel number (1 to SONMaxChannels) -% STIME Searches back from this time -% ETIME stops search at this time (eTime must be less than sTime) -% LPOINTS the number of points it is dsired to read -% BADC ADCMark data will be treated as Adc if this set -% FILTERMASK, if present, a filter mask -% -% Returns the time at which the read will end i.e. the time of the final data -% point or a negative error code -% -% Author:Malcolm Lidierth -% Matlab SON library: +% SONLASTPOINTSTIME returns the time for which a read will terminate +% +% Implemented through SONLastPointsTime.dll +% +% TIME=SONGETADCDATA(FH, CHAN, ETIME, STIME, LPOINTS, BADC {, FILTERMASK}) +% +% INPUTS: FH SON File Handle +% CHAN Channel number (1 to SONMaxChannels) +% STIME Searches back from this time +% ETIME stops search at this time (eTime must be less than sTime) +% LPOINTS the number of points it is dsired to read +% BADC ADCMark data will be treated as Adc if this set +% FILTERMASK, if present, a filter mask +% +% Returns the time at which the read will end i.e. the time of the final data +% point or a negative error code +% +% Author:Malcolm Lidierth +% Matlab SON library: % Copyright 2005 Kings College London \ No newline at end of file diff --git a/src/Import/SON/SON32/SONLastPointsTime.mexw32 b/Import/SON/SON32/SONLastPointsTime.mexw32 similarity index 100% rename from src/Import/SON/SON32/SONLastPointsTime.mexw32 rename to Import/SON/SON32/SONLastPointsTime.mexw32 diff --git a/src/Import/SON/SON32/SONLastTime.m b/Import/SON/SON32/SONLastTime.m similarity index 93% rename from src/Import/SON/SON32/SONLastTime.m rename to Import/SON/SON32/SONLastTime.m index 2c4678d3..53b720c4 100644 --- a/src/Import/SON/SON32/SONLastTime.m +++ b/Import/SON/SON32/SONLastTime.m @@ -1,25 +1,25 @@ -% SONLASTTIME returns information about the last entry on a channel -% before a specified time -% -% Implemented through SONLastTime.dll -% -%[time, data, markers, markerflag]=... -% SONGETADCDATA(fh, chan, eTime, sTime{, FilterMask}) -% -% INPUTS: FH SON File Handle -% CHAN Channel number (1 to SONMaxChannels) -% STIME Searches back from this time -% ETIME stops search at this time (eTime must be less than sTime) -% FILTERMASK, if present, a filter mask -% -% OUTPUTS: TIME The time of the last data point between ETIME and STIME -% or a negative error code -% DATA Value at TIME for an ADC or Real channel. -% For an EventBoth channel the InitLow value -% MARKERS the marker codes for the event at TIME for -% a marker channel -% MARKERFLAG Set to 1 if CHAN is a marker channel, 0 otherwise -% -% Author:Malcolm Lidierth -% Matlab SON library: +% SONLASTTIME returns information about the last entry on a channel +% before a specified time +% +% Implemented through SONLastTime.dll +% +%[time, data, markers, markerflag]=... +% SONGETADCDATA(fh, chan, eTime, sTime{, FilterMask}) +% +% INPUTS: FH SON File Handle +% CHAN Channel number (1 to SONMaxChannels) +% STIME Searches back from this time +% ETIME stops search at this time (eTime must be less than sTime) +% FILTERMASK, if present, a filter mask +% +% OUTPUTS: TIME The time of the last data point between ETIME and STIME +% or a negative error code +% DATA Value at TIME for an ADC or Real channel. +% For an EventBoth channel the InitLow value +% MARKERS the marker codes for the event at TIME for +% a marker channel +% MARKERFLAG Set to 1 if CHAN is a marker channel, 0 otherwise +% +% Author:Malcolm Lidierth +% Matlab SON library: % Copyright 2005 Kings College London \ No newline at end of file diff --git a/src/Import/SON/SON32/SONLastTime.mexw32 b/Import/SON/SON32/SONLastTime.mexw32 similarity index 100% rename from src/Import/SON/SON32/SONLastTime.mexw32 rename to Import/SON/SON32/SONLastTime.mexw32 diff --git a/src/Import/SON/SON32/SONLatestTime.m b/Import/SON/SON32/SONLatestTime.m similarity index 96% rename from src/Import/SON/SON32/SONLatestTime.m rename to Import/SON/SON32/SONLatestTime.m index a0771ed5..0ea67b4a 100644 --- a/src/Import/SON/SON32/SONLatestTime.m +++ b/Import/SON/SON32/SONLatestTime.m @@ -1,15 +1,15 @@ -function flag=SONLatestTime(fh, chan, sTime) -% SONLATESTTIME is used to flush data to disk -% -% FLAG=SONLATESTTIME(FH, CHAN, STIME) -% where FH is the SON file handle, Chan is the channel, and STIME is the -% latest valid time in clock ticks -% -% See CED documentaion -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - -flag=calllib('son32','SONLatestTime', fh, chan, sTime); - +function flag=SONLatestTime(fh, chan, sTime) +% SONLATESTTIME is used to flush data to disk +% +% FLAG=SONLATESTTIME(FH, CHAN, STIME) +% where FH is the SON file handle, Chan is the channel, and STIME is the +% latest valid time in clock ticks +% +% See CED documentaion +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + +flag=calllib('son32','SONLatestTime', fh, chan, sTime); + diff --git a/src/Import/SON/SON32/SONLoad.m b/Import/SON/SON32/SONLoad.m similarity index 97% rename from src/Import/SON/SON32/SONLoad.m rename to Import/SON/SON32/SONLoad.m index 84793e76..73e99c16 100644 --- a/src/Import/SON/SON32/SONLoad.m +++ b/Import/SON/SON32/SONLoad.m @@ -1,50 +1,50 @@ -function SONLoad() -% SONLOAD loads the son32.dll library and defines global constants -% -% Version 32 of the SON library works only under Windows and requires -% version 7 of MATALAB and a copy of CED's son32.dll. -% -% The routines use CEDs son32.dll to provide I/O. This file must be present -% in a 'c:\Spike5' directory (unless you edit SONLoad AND SONDef.h and recompile -% the C source files) -% -% Routines are accessed via calllib where possible or through external dlls -% where callib can not presently provide support (i.e. where there are -% non-scalar structures or fields in the call to son32.dll) -% -% SONLoad() has no arguments and should be run before calling any -% library routines that use the MATLAB calllib function. -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - -global Version; Version=32.00; - -global SON_COMMENTSZ;SON_COMMENTSZ=79; -global SON_CHANCOMSZ; SON_CHANCOMSZ=71; -global SON_TITLESZ; SON_TITLESZ=9; -global SON_UNITSZ; SON_UNITSZ=5; -global SON_FMASKSZ; SON_FMASKSZ=32; - - -string=lower(computer); - -if (strcmp(string,'pcwin')== 0) - errordlg('This version of the SON library requires the Windows operating system\n'); - -else - if (libisloaded('son32')==0) - try - value = winqueryreg('HKEY_CLASSES_ROOT', 'Spike2Data\shell\open\command'); - catch - errordlg('No installed copy of CED''s Spike2 for Windows could be found'); - end; - try - loadlibrary('c:\spike5\son32.dll',@son32); - catch - errordlg('This MATLAB library requires son32.dll to be located in the "C:\SPIKE5" folder. Make a copy there to continue',... - 'SON32.DLL not found'); - end; - end; +function SONLoad() +% SONLOAD loads the son32.dll library and defines global constants +% +% Version 32 of the SON library works only under Windows and requires +% version 7 of MATALAB and a copy of CED's son32.dll. +% +% The routines use CEDs son32.dll to provide I/O. This file must be present +% in a 'c:\Spike5' directory (unless you edit SONLoad AND SONDef.h and recompile +% the C source files) +% +% Routines are accessed via calllib where possible or through external dlls +% where callib can not presently provide support (i.e. where there are +% non-scalar structures or fields in the call to son32.dll) +% +% SONLoad() has no arguments and should be run before calling any +% library routines that use the MATLAB calllib function. +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + +global Version; Version=32.00; + +global SON_COMMENTSZ;SON_COMMENTSZ=79; +global SON_CHANCOMSZ; SON_CHANCOMSZ=71; +global SON_TITLESZ; SON_TITLESZ=9; +global SON_UNITSZ; SON_UNITSZ=5; +global SON_FMASKSZ; SON_FMASKSZ=32; + + +string=lower(computer); + +if (strcmp(string,'pcwin')== 0) + errordlg('This version of the SON library requires the Windows operating system\n'); + +else + if (libisloaded('son32')==0) + try + value = winqueryreg('HKEY_CLASSES_ROOT', 'Spike2Data\shell\open\command'); + catch + errordlg('No installed copy of CED''s Spike2 for Windows could be found'); + end; + try + loadlibrary('c:\spike5\son32.dll',@son32); + catch + errordlg('This MATLAB library requires son32.dll to be located in the "C:\SPIKE5" folder. Make a copy there to continue',... + 'SON32.DLL not found'); + end; + end; end; \ No newline at end of file diff --git a/src/Import/SON/SON32/SONMaxChans.m b/Import/SON/SON32/SONMaxChans.m similarity index 95% rename from src/Import/SON/SON32/SONMaxChans.m rename to Import/SON/SON32/SONMaxChans.m index 40558388..2e91e6b9 100644 --- a/src/Import/SON/SON32/SONMaxChans.m +++ b/Import/SON/SON32/SONMaxChans.m @@ -1,12 +1,12 @@ -function n=SONMaxChans(fh) -% SONMAXCHANS returns the number of channels supported by a SON file -% -% N=SONMAXCHANS(FH) -% where FH is the SON file handle -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - -n=calllib('son32','SONMaxChans',fh); - +function n=SONMaxChans(fh) +% SONMAXCHANS returns the number of channels supported by a SON file +% +% N=SONMAXCHANS(FH) +% where FH is the SON file handle +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + +n=calllib('son32','SONMaxChans',fh); + diff --git a/src/Import/SON/SON32/SONMaxTime.m b/Import/SON/SON32/SONMaxTime.m similarity index 96% rename from src/Import/SON/SON32/SONMaxTime.m rename to Import/SON/SON32/SONMaxTime.m index 74065415..0e36d368 100644 --- a/src/Import/SON/SON32/SONMaxTime.m +++ b/Import/SON/SON32/SONMaxTime.m @@ -1,9 +1,9 @@ -function time=SONMaxTime(fh) -% SONMAXTIME returns the maximum time for data in a file -% -% TIME=SONMAXTIME(FH) -% where FH is the SON file handle. TIME is returned in clock ticks -% -% ML/05/05 - -time=calllib('son32','SONMaxTime', fh); +function time=SONMaxTime(fh) +% SONMAXTIME returns the maximum time for data in a file +% +% TIME=SONMAXTIME(FH) +% where FH is the SON file handle. TIME is returned in clock ticks +% +% ML/05/05 + +time=calllib('son32','SONMaxTime', fh); diff --git a/src/Import/SON/SON32/SONOpenNewFile.m b/Import/SON/SON32/SONOpenNewFile.m similarity index 83% rename from src/Import/SON/SON32/SONOpenNewFile.m rename to Import/SON/SON32/SONOpenNewFile.m index 8630f069..45841308 100644 --- a/src/Import/SON/SON32/SONOpenNewFile.m +++ b/Import/SON/SON32/SONOpenNewFile.m @@ -1,12 +1,12 @@ -function handle=SONOpenNewFile(str, extrabytes) -% SONOPENNEWFILE (obsolete) creates a new SON file and returns the handle -% -% HANDLE=SONOPENNEWFILE(STR, EXTRABYTES) -% where STR is the file name (with path). EXTRABYTES sets the size of the -% optional user data area -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - +function handle=SONOpenNewFile(str, extrabytes) +% SONOPENNEWFILE (obsolete) creates a new SON file and returns the handle +% +% HANDLE=SONOPENNEWFILE(STR, EXTRABYTES) +% where STR is the file name (with path). EXTRABYTES sets the size of the +% optional user data area +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + handle=calllib('son32','SONOpenNewFile', str, 0, extrabytes); \ No newline at end of file diff --git a/src/Import/SON/SON32/SONOpenOldFile.m b/Import/SON/SON32/SONOpenOldFile.m similarity index 95% rename from src/Import/SON/SON32/SONOpenOldFile.m rename to Import/SON/SON32/SONOpenOldFile.m index f01156a4..c4d37fe3 100644 --- a/src/Import/SON/SON32/SONOpenOldFile.m +++ b/Import/SON/SON32/SONOpenOldFile.m @@ -1,24 +1,24 @@ -function fh=SONOpenOldFile(filename, iMode) -% SONOPENOLDFILE opens an existing a SON file and returns a handle -% from SON32.DLL. Note that this is not a MATLAB handle. -% FH=SONOPENOLDFILE(filename, iMode) -% filename is a string -% iMode = 0 for Read/Write -% 1 for Read Only -% 2 for Read/Write but accept Read Only -% -% Returns the SON file handle or a negative error code -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - - -if nargin ~= 2 || iMode<0 || iMode>2 - fh=-1000; - return; -end; - - -fh=calllib('son32','SONOpenOldFile',filename,iMode); +function fh=SONOpenOldFile(filename, iMode) +% SONOPENOLDFILE opens an existing a SON file and returns a handle +% from SON32.DLL. Note that this is not a MATLAB handle. +% FH=SONOPENOLDFILE(filename, iMode) +% filename is a string +% iMode = 0 for Read/Write +% 1 for Read Only +% 2 for Read/Write but accept Read Only +% +% Returns the SON file handle or a negative error code +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + + +if nargin ~= 2 || iMode<0 || iMode>2 + fh=-1000; + return; +end; + + +fh=calllib('son32','SONOpenOldFile',filename,iMode); return; \ No newline at end of file diff --git a/src/Import/SON/SON32/SONPhyChan.m b/Import/SON/SON32/SONPhyChan.m similarity index 86% rename from src/Import/SON/SON32/SONPhyChan.m rename to Import/SON/SON32/SONPhyChan.m index f2b48f28..a1189dca 100644 --- a/src/Import/SON/SON32/SONPhyChan.m +++ b/Import/SON/SON32/SONPhyChan.m @@ -1,13 +1,13 @@ -function pchan=SONPhyChan(fh, chan) -% SONPHYCHAN returns the physical channel (hardware port) for a channel -% in a file -% -% PCHAN=SONPHYCHAN(FH, CHAN) -% where FH is the SON file handle and CHAN is the file channel number. -% PCHAN is negative for channels with no hardware port -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - +function pchan=SONPhyChan(fh, chan) +% SONPHYCHAN returns the physical channel (hardware port) for a channel +% in a file +% +% PCHAN=SONPHYCHAN(FH, CHAN) +% where FH is the SON file handle and CHAN is the file channel number. +% PCHAN is negative for channels with no hardware port +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + pchan=calllib('son32','SONPhyChan', fh, chan); \ No newline at end of file diff --git a/src/Import/SON/SON32/SONPhySz.m b/Import/SON/SON32/SONPhySz.m similarity index 96% rename from src/Import/SON/SON32/SONPhySz.m rename to Import/SON/SON32/SONPhySz.m index 6be081b0..5e29fb89 100644 --- a/src/Import/SON/SON32/SONPhySz.m +++ b/Import/SON/SON32/SONPhySz.m @@ -1,8 +1,8 @@ -function buffsize=SONPhySz(fh, chan) -% SONPHYSZ returns the buffer size for the specified chanel -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - -buffsize=calllib('son32','SONPhySz', fh, chan); +function buffsize=SONPhySz(fh, chan) +% SONPHYSZ returns the buffer size for the specified chanel +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + +buffsize=calllib('son32','SONPhySz', fh, chan); diff --git a/src/Import/SON/SON32/SONPhysChan.m b/Import/SON/SON32/SONPhysChan.m similarity index 86% rename from src/Import/SON/SON32/SONPhysChan.m rename to Import/SON/SON32/SONPhysChan.m index f2b48f28..a1189dca 100644 --- a/src/Import/SON/SON32/SONPhysChan.m +++ b/Import/SON/SON32/SONPhysChan.m @@ -1,13 +1,13 @@ -function pchan=SONPhyChan(fh, chan) -% SONPHYCHAN returns the physical channel (hardware port) for a channel -% in a file -% -% PCHAN=SONPHYCHAN(FH, CHAN) -% where FH is the SON file handle and CHAN is the file channel number. -% PCHAN is negative for channels with no hardware port -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - +function pchan=SONPhyChan(fh, chan) +% SONPHYCHAN returns the physical channel (hardware port) for a channel +% in a file +% +% PCHAN=SONPHYCHAN(FH, CHAN) +% where FH is the SON file handle and CHAN is the file channel number. +% PCHAN is negative for channels with no hardware port +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + pchan=calllib('son32','SONPhyChan', fh, chan); \ No newline at end of file diff --git a/src/Import/SON/SON32/SONSave.m b/Import/SON/SON32/SONSave.m similarity index 89% rename from src/Import/SON/SON32/SONSave.m rename to Import/SON/SON32/SONSave.m index fe2cae0c..1a68c882 100644 --- a/src/Import/SON/SON32/SONSave.m +++ b/Import/SON/SON32/SONSave.m @@ -1,20 +1,20 @@ -function flag=SONSave(fh, chan, sTime, bKeep) -% SONSAVE sets the write state for a channel from a specified time -% -% FLAG=SONSAVE(FH, CHAN, STIME, BKEEP) -% INPUTS: FH is the SON file handle -% CHAN is a channel number (0-SONMaxChans()-1) or -1 for all -% channels -% STIME the time for this write state to take effect from (clock -% ticks) -% BKEEP non-zero to keep, zero to discard data -% -% Returns 0 if changes are effective, 0 if not or a negative error code -% -% See CED documentation for further details -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - +function flag=SONSave(fh, chan, sTime, bKeep) +% SONSAVE sets the write state for a channel from a specified time +% +% FLAG=SONSAVE(FH, CHAN, STIME, BKEEP) +% INPUTS: FH is the SON file handle +% CHAN is a channel number (0-SONMaxChans()-1) or -1 for all +% channels +% STIME the time for this write state to take effect from (clock +% ticks) +% BKEEP non-zero to keep, zero to discard data +% +% Returns 0 if changes are effective, 0 if not or a negative error code +% +% See CED documentation for further details +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + flag=calllib('son32','SONSave', fh, chan, sTime, bKeep); \ No newline at end of file diff --git a/src/Import/SON/SON32/SONSaveRange.m b/Import/SON/SON32/SONSaveRange.m similarity index 97% rename from src/Import/SON/SON32/SONSaveRange.m rename to Import/SON/SON32/SONSaveRange.m index 4ea73a9e..0fdd9aa2 100644 --- a/src/Import/SON/SON32/SONSaveRange.m +++ b/Import/SON/SON32/SONSaveRange.m @@ -1,20 +1,20 @@ -function flag=SONSaveRange(fh, chan, startTime, endTime) -% SONSAVERANGE sets the write state to save for a channel in the given time range -% -% FLAG=SONSAVERANGE(FH, CHAN, STARTTIME, ENDTIME) -% INPUTS: FH is the SON file handle -% CHAN is a channel number (0-SONMaxChans()-1) or -1 for all -% channels -% STARTTIME the time to save data from -% ENDTIME the end time -% Note that times are in clock ticks -% -% Returns 0 if changes are effective, 0 if not or a negative error code -% -% See CED documentation for further details -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - +function flag=SONSaveRange(fh, chan, startTime, endTime) +% SONSAVERANGE sets the write state to save for a channel in the given time range +% +% FLAG=SONSAVERANGE(FH, CHAN, STARTTIME, ENDTIME) +% INPUTS: FH is the SON file handle +% CHAN is a channel number (0-SONMaxChans()-1) or -1 for all +% channels +% STARTTIME the time to save data from +% ENDTIME the end time +% Note that times are in clock ticks +% +% Returns 0 if changes are effective, 0 if not or a negative error code +% +% See CED documentation for further details +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + flag=calllib('son32','SONSaveRange', fh, chan, startTime, endTime); \ No newline at end of file diff --git a/src/Import/SON/SON32/SONSetADCOffset.m b/Import/SON/SON32/SONSetADCOffset.m similarity index 96% rename from src/Import/SON/SON32/SONSetADCOffset.m rename to Import/SON/SON32/SONSetADCOffset.m index 10756649..50be5fdc 100644 --- a/src/Import/SON/SON32/SONSetADCOffset.m +++ b/Import/SON/SON32/SONSetADCOffset.m @@ -1,18 +1,18 @@ -function SONSetADCOffset(fh, chan, offset) -% SONSETADCOFFSET sets the offset on an ADC channel -% -% SONADCOFFSET(FH, CHAN, OFFSET) -% where FH is the SON file handle, CHAN is the channel number and OFFSET is -% the new value to be written to the file -% -% An ADC value is converted to a real value as: -% Real value=(16-bit ADC value * scale / 6553.6) + offset -% see also: SONSetADCScale -% -% No return value -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - -calllib('son32','SONSetADCOffset', fh, chan, offset); +function SONSetADCOffset(fh, chan, offset) +% SONSETADCOFFSET sets the offset on an ADC channel +% +% SONADCOFFSET(FH, CHAN, OFFSET) +% where FH is the SON file handle, CHAN is the channel number and OFFSET is +% the new value to be written to the file +% +% An ADC value is converted to a real value as: +% Real value=(16-bit ADC value * scale / 6553.6) + offset +% see also: SONSetADCScale +% +% No return value +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + +calllib('son32','SONSetADCOffset', fh, chan, offset); diff --git a/src/Import/SON/SON32/SONSetADCScale.m b/Import/SON/SON32/SONSetADCScale.m similarity index 96% rename from src/Import/SON/SON32/SONSetADCScale.m rename to Import/SON/SON32/SONSetADCScale.m index 836a1851..ffc10ff1 100644 --- a/src/Import/SON/SON32/SONSetADCScale.m +++ b/Import/SON/SON32/SONSetADCScale.m @@ -1,19 +1,19 @@ -function SONSetADCScale(fh, chan, scale) -% SONSETADCSCALE sets the scale on an ADC channel -% -% SONADCOFFSET(FH, CHAN, SCALE) -% where FH is the SON file handle, CHAN is the channel number and SCALE is -% the new value to be written to the file -% -% An ADC value is converted to a real value as: -% Real value=(16-bit ADC value * scale / 6553.6) + offset -% -% see also: SONSetADCOffset -% -% No return value -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - -calllib('son32','SONSetADCOffset', fh, chan, scale); +function SONSetADCScale(fh, chan, scale) +% SONSETADCSCALE sets the scale on an ADC channel +% +% SONADCOFFSET(FH, CHAN, SCALE) +% where FH is the SON file handle, CHAN is the channel number and SCALE is +% the new value to be written to the file +% +% An ADC value is converted to a real value as: +% Real value=(16-bit ADC value * scale / 6553.6) + offset +% +% see also: SONSetADCOffset +% +% No return value +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + +calllib('son32','SONSetADCOffset', fh, chan, scale); diff --git a/src/Import/SON/SON32/SONSetADCUnits.m b/Import/SON/SON32/SONSetADCUnits.m similarity index 86% rename from src/Import/SON/SON32/SONSetADCUnits.m rename to Import/SON/SON32/SONSetADCUnits.m index 583c2ca9..388ee9d9 100644 --- a/src/Import/SON/SON32/SONSetADCUnits.m +++ b/Import/SON/SON32/SONSetADCUnits.m @@ -1,18 +1,18 @@ -function SONSetADCUnits(fh, chan, units) -% SONSETADCUNITS sets the units string for a channel -% -% SONADCUNITS(FH, CHAN, UNITS) -% where FH is the SON file handle, CHAN is the channel number and UNITS is -% the string to be written to the file. -% -% No return value -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - -global SON_UNITSZ; - -units=[units(1:min(length(units),SON_UNITSZ)) '']; -size(units) +function SONSetADCUnits(fh, chan, units) +% SONSETADCUNITS sets the units string for a channel +% +% SONADCUNITS(FH, CHAN, UNITS) +% where FH is the SON file handle, CHAN is the channel number and UNITS is +% the string to be written to the file. +% +% No return value +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + +global SON_UNITSZ; + +units=[units(1:min(length(units),SON_UNITSZ)) '']; +size(units) calllib('son32','SONSetADCUnits', fh, chan, units); \ No newline at end of file diff --git a/src/Import/SON/SON32/SONSetBuffSpace.m b/Import/SON/SON32/SONSetBuffSpace.m similarity index 96% rename from src/Import/SON/SON32/SONSetBuffSpace.m rename to Import/SON/SON32/SONSetBuffSpace.m index 328dc538..36e6fdf1 100644 --- a/src/Import/SON/SON32/SONSetBuffSpace.m +++ b/Import/SON/SON32/SONSetBuffSpace.m @@ -1,8 +1,8 @@ -function ret=SONSetBuffSpace(fh) -% SONSETBUFFSPACE allocates buufer space for file writes -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - -ret=calllib('son32','SONSetBuffSpace',fh); +function ret=SONSetBuffSpace(fh) +% SONSETBUFFSPACE allocates buufer space for file writes +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + +ret=calllib('son32','SONSetBuffSpace',fh); diff --git a/src/Import/SON/SON32/SONSetBuffering.m b/Import/SON/SON32/SONSetBuffering.m similarity index 76% rename from src/Import/SON/SON32/SONSetBuffering.m rename to Import/SON/SON32/SONSetBuffering.m index 5589ecb8..2623436e 100644 --- a/src/Import/SON/SON32/SONSetBuffering.m +++ b/Import/SON/SON32/SONSetBuffering.m @@ -1,8 +1,8 @@ -function ret=SONSetBuffering(fh, chan, bytes) -%SONSETBUFFERING specifies the buffer size for writing to a channel -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - +function ret=SONSetBuffering(fh, chan, bytes) +%SONSETBUFFERING specifies the buffer size for writing to a channel +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + ret=calllib('son32','SONSetBuffering', fh, chan, bytes); \ No newline at end of file diff --git a/src/Import/SON/SON32/SONSetChanComment.m b/Import/SON/SON32/SONSetChanComment.m similarity index 96% rename from src/Import/SON/SON32/SONSetChanComment.m rename to Import/SON/SON32/SONSetChanComment.m index 37a212f0..9c97daf1 100644 --- a/src/Import/SON/SON32/SONSetChanComment.m +++ b/Import/SON/SON32/SONSetChanComment.m @@ -1,13 +1,13 @@ -function SONSetChanComment(fh, chan, str) -% SONSETCHANCOMMENT sets the channel comment -% FH = SON file handle -% CHAN = channel number (0 to Max-1) -% str = string with new comment -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - -global SON_CHANCOMSZ; -str=str(1:min(SON_CHANCOMSZ,length(str))); -calllib('son32','SONSetChanComment', fh, chan, str); +function SONSetChanComment(fh, chan, str) +% SONSETCHANCOMMENT sets the channel comment +% FH = SON file handle +% CHAN = channel number (0 to Max-1) +% str = string with new comment +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + +global SON_CHANCOMSZ; +str=str(1:min(SON_CHANCOMSZ,length(str))); +calllib('son32','SONSetChanComment', fh, chan, str); diff --git a/src/Import/SON/SON32/SONSetChanTitle.m b/Import/SON/SON32/SONSetChanTitle.m similarity index 83% rename from src/Import/SON/SON32/SONSetChanTitle.m rename to Import/SON/SON32/SONSetChanTitle.m index 8da06ea3..1f9bad89 100644 --- a/src/Import/SON/SON32/SONSetChanTitle.m +++ b/Import/SON/SON32/SONSetChanTitle.m @@ -1,13 +1,13 @@ -function SONSetChanTitle(fh, chan, str) -% SONSETCHANTITLE sets the channel title -% FH = SON file handle -% CHAN = channel number (0 to Max-1) -% str = string with new title -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - -global SON_TITLESZ; -str=str(1:min(SON_TITLESZ,length(str))); +function SONSetChanTitle(fh, chan, str) +% SONSETCHANTITLE sets the channel title +% FH = SON file handle +% CHAN = channel number (0 to Max-1) +% str = string with new title +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + +global SON_TITLESZ; +str=str(1:min(SON_TITLESZ,length(str))); calllib('son32','SONSetChanTitle', fh, chan, str); \ No newline at end of file diff --git a/src/Import/SON/SON32/SONSetEventChan.m b/Import/SON/SON32/SONSetEventChan.m similarity index 92% rename from src/Import/SON/SON32/SONSetEventChan.m rename to Import/SON/SON32/SONSetEventChan.m index d1e5c3ab..bbed1ef5 100644 --- a/src/Import/SON/SON32/SONSetEventChan.m +++ b/Import/SON/SON32/SONSetEventChan.m @@ -1,45 +1,45 @@ -function err=SONSetEventChan(fh, chan, PhyCh, bufsize, comment, title, rate, kind) -% SONSETEVENTCHAN sets up a new event or marker channel -% -% ERR=SONSETEVENTCHAN(FH, CHAN, PHYCH, BUFSZ, COMMENT, TITLE, RATE, KIND) -% INPUTS: FH the SON file handle -% CHAN the channel number -% PHYCH the physical channel number -% BUFSZ size of the write buffer -% COMMENT the channel comment -% TITLE the channel title -% RATE the ideal or expected rate -% KIND is a string that sets the channel type: -% 'EventRise', 'EventFall', 'EventBoth' or 'Marker' -% -% Returns zero or a negative error code in ERR -% See CED documentation for details -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - -global SON_CHANCOMSZ; -global SON_TITLESZ; - -if (bufsize>32768) - bufsize=32768; -end; - -comment=comment(1:min(length(comment),SON_CHANCOMSZ)); -title=title(1:min(length(title),SON_TITLESZ)); -switch lower(kind) - case {'eventfall'} - type=2; - case {'eventrise'} - type=3; - case {'eventboth'} - type=4; - case {'marker'} - type=5; - otherwise - err=-1000; - return; -end; -err=calllib('son32','SONSetEventChan',... +function err=SONSetEventChan(fh, chan, PhyCh, bufsize, comment, title, rate, kind) +% SONSETEVENTCHAN sets up a new event or marker channel +% +% ERR=SONSETEVENTCHAN(FH, CHAN, PHYCH, BUFSZ, COMMENT, TITLE, RATE, KIND) +% INPUTS: FH the SON file handle +% CHAN the channel number +% PHYCH the physical channel number +% BUFSZ size of the write buffer +% COMMENT the channel comment +% TITLE the channel title +% RATE the ideal or expected rate +% KIND is a string that sets the channel type: +% 'EventRise', 'EventFall', 'EventBoth' or 'Marker' +% +% Returns zero or a negative error code in ERR +% See CED documentation for details +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + +global SON_CHANCOMSZ; +global SON_TITLESZ; + +if (bufsize>32768) + bufsize=32768; +end; + +comment=comment(1:min(length(comment),SON_CHANCOMSZ)); +title=title(1:min(length(title),SON_TITLESZ)); +switch lower(kind) + case {'eventfall'} + type=2; + case {'eventrise'} + type=3; + case {'eventboth'} + type=4; + case {'marker'} + type=5; + otherwise + err=-1000; + return; +end; +err=calllib('son32','SONSetEventChan',... fh, chan, PhyCh, bufsize, comment, title, rate, type); \ No newline at end of file diff --git a/src/Import/SON/SON32/SONSetFileClock.m b/Import/SON/SON32/SONSetFileClock.m similarity index 97% rename from src/Import/SON/SON32/SONSetFileClock.m rename to Import/SON/SON32/SONSetFileClock.m index 8d18d56d..725a655d 100644 --- a/src/Import/SON/SON32/SONSetFileClock.m +++ b/Import/SON/SON32/SONSetFileClock.m @@ -1,15 +1,15 @@ -function SONSetFileClock(fh, usPerTime, timePerADC) -% SONSETFILECLOCK sets the basic time units and the clocks per ADC conversion -% -% SONSETFILECLOCK(FH, USPERTIME, TIMEPERADC) -% INPUTS: FH the SON file handle -% USPERTIME the number of microseconds per clock tick -% TIMEPERADC the number of clock ticks per ADC conversion -% -% See CED documentation for further details -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - -calllib('son32','SONSetFileClock', fh, usPerTime, timePerADC); +function SONSetFileClock(fh, usPerTime, timePerADC) +% SONSETFILECLOCK sets the basic time units and the clocks per ADC conversion +% +% SONSETFILECLOCK(FH, USPERTIME, TIMEPERADC) +% INPUTS: FH the SON file handle +% USPERTIME the number of microseconds per clock tick +% TIMEPERADC the number of clock ticks per ADC conversion +% +% See CED documentation for further details +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + +calllib('son32','SONSetFileClock', fh, usPerTime, timePerADC); diff --git a/src/Import/SON/SON32/SONSetFileComment.m b/Import/SON/SON32/SONSetFileComment.m similarity index 96% rename from src/Import/SON/SON32/SONSetFileComment.m rename to Import/SON/SON32/SONSetFileComment.m index 31605e63..842647af 100644 --- a/src/Import/SON/SON32/SONSetFileComment.m +++ b/Import/SON/SON32/SONSetFileComment.m @@ -1,18 +1,18 @@ -function SONSetFileComment(fh, which, comment) -% SONSETFILECOMMENT sets one of the five file comment fields -% -% SONSETFILECOMMENT(FH, WHICH, COMMENT) -% FH is the SON file handle -% WHICH selects the comment (0 - 4) -% COMMENT is a string -% -% No return value -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - -global SON_COMMENTSZ; - -comment=comment(1:min(SON_COMMENTSZ,length(comment))); -calllib('son32','SONSetFileComment', fh, which, comment); +function SONSetFileComment(fh, which, comment) +% SONSETFILECOMMENT sets one of the five file comment fields +% +% SONSETFILECOMMENT(FH, WHICH, COMMENT) +% FH is the SON file handle +% WHICH selects the comment (0 - 4) +% COMMENT is a string +% +% No return value +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + +global SON_COMMENTSZ; + +comment=comment(1:min(SON_COMMENTSZ,length(comment))); +calllib('son32','SONSetFileComment', fh, which, comment); diff --git a/src/Import/SON/SON32/SONSetInitLow.m b/Import/SON/SON32/SONSetInitLow.m similarity index 87% rename from src/Import/SON/SON32/SONSetInitLow.m rename to Import/SON/SON32/SONSetInitLow.m index ff5f68c1..88527464 100644 --- a/src/Import/SON/SON32/SONSetInitLow.m +++ b/Import/SON/SON32/SONSetInitLow.m @@ -1,20 +1,20 @@ -function SONSetInitLow(fh, chan, flag) -% SONSETINITLOW sets the initial state on an EventBoth (level) channel -% -% SONSETINITLOW(FH, CHAN, FLAG) -% where FH is the SON file handle and CHAN is the channel number. -% FLAG is 'TRUE' if the first transition is high-to-low, 'FALSE' otherwise. -% No return value -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - -switch (flag(1)) - case {'T','t'} - state=1; - case {'F','f'} - state=0; -end; - +function SONSetInitLow(fh, chan, flag) +% SONSETINITLOW sets the initial state on an EventBoth (level) channel +% +% SONSETINITLOW(FH, CHAN, FLAG) +% where FH is the SON file handle and CHAN is the channel number. +% FLAG is 'TRUE' if the first transition is high-to-low, 'FALSE' otherwise. +% No return value +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + +switch (flag(1)) + case {'T','t'} + state=1; + case {'F','f'} + state=0; +end; + calllib('son32','SONSetInitLow', fh, chan, state); \ No newline at end of file diff --git a/src/Import/SON/SON32/SONSetMarker.m b/Import/SON/SON32/SONSetMarker.m similarity index 97% rename from src/Import/SON/SON32/SONSetMarker.m rename to Import/SON/SON32/SONSetMarker.m index fe45508b..dedf1d80 100644 --- a/src/Import/SON/SON32/SONSetMarker.m +++ b/Import/SON/SON32/SONSetMarker.m @@ -1,38 +1,38 @@ -% SONSETMARKER replaces the data associated with a marker on disc -% -% Implemented through SONSetMarker.dll -% -% RET=SONSETMARKER(FH, CHAN, TIME, NEWTIME, {NEWMARKERS, {NEWEXTRA}}) -% FH = the SON file handle -% CHAN = the target marker channel -% TIME = the current timestamp of the target marker entry (clock ticks) -% NEWTIME = a new time that will replace the timestamp in TIME -% NEWMARKERS = if present, a set of 4 uint8 marker values that will replace -% those on disc -% NEWEXTRA = if present, the extra data to replace all or some of the -% existing extra data -% These may be: int16 (for AdcMark) -% single (for RealMark) -% or uint8 (for TextMark) -% (N.B. not char which is 16bit in matlab) -% -% The data type for NEWEXTRA must match that of the target channel (the function -% returns SON_NO_EXTRA if it does not. -% -% e.g SONSetMarker(fh, 2, 140100, 140200) -% replaces the timestamp only -% SONSetMarker (fh, 2, 140100, 14020, uint8([22 33 44 55])) -% replaces the markers also -% SONSetMarker (fh, 2, 140100, 14020, uint8([22 33 44 55]), int16([0 0])) -% also replaces the first two extra data entries with zero on an AdcMark channel -% -% Returns: 1 if the replacement occured. -% 0 if not e.g. NEWEXTRA is longer than the existing entry or the -% new timestamp would break the temporal sequence of successive -% entries -% or an negative error code -% -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London +% SONSETMARKER replaces the data associated with a marker on disc +% +% Implemented through SONSetMarker.dll +% +% RET=SONSETMARKER(FH, CHAN, TIME, NEWTIME, {NEWMARKERS, {NEWEXTRA}}) +% FH = the SON file handle +% CHAN = the target marker channel +% TIME = the current timestamp of the target marker entry (clock ticks) +% NEWTIME = a new time that will replace the timestamp in TIME +% NEWMARKERS = if present, a set of 4 uint8 marker values that will replace +% those on disc +% NEWEXTRA = if present, the extra data to replace all or some of the +% existing extra data +% These may be: int16 (for AdcMark) +% single (for RealMark) +% or uint8 (for TextMark) +% (N.B. not char which is 16bit in matlab) +% +% The data type for NEWEXTRA must match that of the target channel (the function +% returns SON_NO_EXTRA if it does not. +% +% e.g SONSetMarker(fh, 2, 140100, 140200) +% replaces the timestamp only +% SONSetMarker (fh, 2, 140100, 14020, uint8([22 33 44 55])) +% replaces the markers also +% SONSetMarker (fh, 2, 140100, 14020, uint8([22 33 44 55]), int16([0 0])) +% also replaces the first two extra data entries with zero on an AdcMark channel +% +% Returns: 1 if the replacement occured. +% 0 if not e.g. NEWEXTRA is longer than the existing entry or the +% new timestamp would break the temporal sequence of successive +% entries +% or an negative error code +% +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London diff --git a/src/Import/SON/SON32/SONSetMarker.mexw32 b/Import/SON/SON32/SONSetMarker.mexw32 similarity index 100% rename from src/Import/SON/SON32/SONSetMarker.mexw32 rename to Import/SON/SON32/SONSetMarker.mexw32 diff --git a/src/Import/SON/SON32/SONSetRealChan.m b/Import/SON/SON32/SONSetRealChan.m similarity index 97% rename from src/Import/SON/SON32/SONSetRealChan.m rename to Import/SON/SON32/SONSetRealChan.m index 3d3684be..a17336a5 100644 --- a/src/Import/SON/SON32/SONSetRealChan.m +++ b/Import/SON/SON32/SONSetRealChan.m @@ -1,38 +1,38 @@ -function ret=SONSetRealChan(fh, chan, sPhyCh, dvd, bufsize,... - comment, chantitle, scale, offset, units) -% SONSETREALCHAN creates real wave channel -% -% RET=SONSETREALCHAN(FH, CHAN, SPHYCH, DVD, BUFSIZE,... -% COMMENT, CHANTITLE, SCALE, OFFSET, UNITS) -% -% FH = SON file handle -% CHAN = the channel number for the new channel -% SPHYCH = the physical channel number -% DVD = the number of clock ticks per sample -% BUFSIZE = the size of the internal buffer (up to 32768 bytes) -% COMMENT = channel comment string -% CHANTITLE = channel title string -% SCALE = scale factor -% OFFSET = offset -% UNITS = channel units string -% -% Returns zero or a negative error -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - -global SON_CHANCOMSZ; -global SON_UNITSZ; -global SON_TITLESZ; - -if (bufsize>32768) - bufsize=32768; -end; - -comment=comment(1 : min(length(comment), SON_CHANCOMSZ)); -chantitle=chantitle(1 : min(length(chantitle), SON_TITLESZ)); -units=units(1 : min(length(units), SON_UNITSZ)); - -ret=calllib('son32', 'SONSetRealChan',... - fh, chan, sPhyCh, dvd, bufsize,comment, chantitle, scale, offset, units); +function ret=SONSetRealChan(fh, chan, sPhyCh, dvd, bufsize,... + comment, chantitle, scale, offset, units) +% SONSETREALCHAN creates real wave channel +% +% RET=SONSETREALCHAN(FH, CHAN, SPHYCH, DVD, BUFSIZE,... +% COMMENT, CHANTITLE, SCALE, OFFSET, UNITS) +% +% FH = SON file handle +% CHAN = the channel number for the new channel +% SPHYCH = the physical channel number +% DVD = the number of clock ticks per sample +% BUFSIZE = the size of the internal buffer (up to 32768 bytes) +% COMMENT = channel comment string +% CHANTITLE = channel title string +% SCALE = scale factor +% OFFSET = offset +% UNITS = channel units string +% +% Returns zero or a negative error +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + +global SON_CHANCOMSZ; +global SON_UNITSZ; +global SON_TITLESZ; + +if (bufsize>32768) + bufsize=32768; +end; + +comment=comment(1 : min(length(comment), SON_CHANCOMSZ)); +chantitle=chantitle(1 : min(length(chantitle), SON_TITLESZ)); +units=units(1 : min(length(units), SON_UNITSZ)); + +ret=calllib('son32', 'SONSetRealChan',... + fh, chan, sPhyCh, dvd, bufsize,comment, chantitle, scale, offset, units); diff --git a/src/Import/SON/SON32/SONSetRealMarkChan.m b/Import/SON/SON32/SONSetRealMarkChan.m similarity index 96% rename from src/Import/SON/SON32/SONSetRealMarkChan.m rename to Import/SON/SON32/SONSetRealMarkChan.m index 0838bd57..674a8b59 100644 --- a/src/Import/SON/SON32/SONSetRealMarkChan.m +++ b/Import/SON/SON32/SONSetRealMarkChan.m @@ -1,40 +1,40 @@ -function ret=SONSetRealMarkChan(fh, chan, sPhyCh, bufsize, comment,... - chantitle, rate, minimum, maximum, units, points) -% SONSETREALMARKCHAN creates a REALMARK channel -% -% RET=SONSETREALMARKCHAN(FH, CHAN, SPHYCH, BUFSIZE, COMMENT,... -% CHANTITLE, RATE, MINIMUM, MAXIMUM, UNITS, POINTS) -% FH = SON file handle -% CHAN = the channel number for the new channel -% SPHYCH = the physical channel number -% BUFSIZE = the size of the internal buffer (up to 32768 bytes) -% COMMENT = channel comment string -% CHANTITLE = channel title string -% RATE = expected mean rate (only used in sampling) -% MAXIMUM = approximate maximum value (for display only) -% MINIMUM = approximate minimum value (for display only) -% UNITS = channel units string -% POINTS = number of extra data entries for each marker -% -% Returns zero or a negative error -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - -global SON_CHANCOMSZ; -global SON_UNITSZ; -global SON_TITLESZ; - -if (bufsize>32768) - bufsize=32768; -end; - -comment=comment(1 : min(length(comment), SON_CHANCOMSZ)); -chantitle=chantitle(1 : min(length(chantitle), SON_TITLESZ)); -units=units(1 : min(length(units), SON_UNITSZ)); - -ret=calllib('son32', 'SONSetRealMarkChan',... - fh, chan, sPhyCh, bufsize,... - comment, chantitle, rate, minimum, maximum, units, points); +function ret=SONSetRealMarkChan(fh, chan, sPhyCh, bufsize, comment,... + chantitle, rate, minimum, maximum, units, points) +% SONSETREALMARKCHAN creates a REALMARK channel +% +% RET=SONSETREALMARKCHAN(FH, CHAN, SPHYCH, BUFSIZE, COMMENT,... +% CHANTITLE, RATE, MINIMUM, MAXIMUM, UNITS, POINTS) +% FH = SON file handle +% CHAN = the channel number for the new channel +% SPHYCH = the physical channel number +% BUFSIZE = the size of the internal buffer (up to 32768 bytes) +% COMMENT = channel comment string +% CHANTITLE = channel title string +% RATE = expected mean rate (only used in sampling) +% MAXIMUM = approximate maximum value (for display only) +% MINIMUM = approximate minimum value (for display only) +% UNITS = channel units string +% POINTS = number of extra data entries for each marker +% +% Returns zero or a negative error +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + +global SON_CHANCOMSZ; +global SON_UNITSZ; +global SON_TITLESZ; + +if (bufsize>32768) + bufsize=32768; +end; + +comment=comment(1 : min(length(comment), SON_CHANCOMSZ)); +chantitle=chantitle(1 : min(length(chantitle), SON_TITLESZ)); +units=units(1 : min(length(units), SON_UNITSZ)); + +ret=calllib('son32', 'SONSetRealMarkChan',... + fh, chan, sPhyCh, bufsize,... + comment, chantitle, rate, minimum, maximum, units, points); \ No newline at end of file diff --git a/src/Import/SON/SON32/SONSetTextMarkChan.m b/Import/SON/SON32/SONSetTextMarkChan.m similarity index 94% rename from src/Import/SON/SON32/SONSetTextMarkChan.m rename to Import/SON/SON32/SONSetTextMarkChan.m index 642834d0..79503e09 100644 --- a/src/Import/SON/SON32/SONSetTextMarkChan.m +++ b/Import/SON/SON32/SONSetTextMarkChan.m @@ -1,34 +1,34 @@ -function ret=SONSetTextMarkChan(fh, chan, sPhyCh, bufsize,... - comment, chantitle, rate, units, points) -% SONSETTEXTMARKCHAN creates a TEXTMARK channel -% FH = SON file handle -% CHAN = the channel number for the new channel -% SPHYCH = the physical channel number -% BUFSIZE = the size of the internal buffer (up to 32768 bytes) -% COMMENT = channel comment string -% CHANTITLE = channel title string -% RATE = the expected data rate (during sampling) -% UNITS = channel units string -% POINTS = maximum number of characters per marker -% -% Returns zero or a negagtive error -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - -global SON_CHANCOMSZ; -global SON_UNITSZ; -global SON_TITLESZ; - -if (bufsize>32768) - bufsize=32768; -end; - -comment=comment(1 : min(length(comment), SON_CHANCOMSZ)); -chantitle=chantitle(1 : min(length(chantitle), SON_TITLESZ)); -units=units(1 : min(length(units), SON_UNITSZ)); - -ret=calllib('son32', 'SONSetTextMarkChan',... - fh, chan, sPhyCh, bufsize,... +function ret=SONSetTextMarkChan(fh, chan, sPhyCh, bufsize,... + comment, chantitle, rate, units, points) +% SONSETTEXTMARKCHAN creates a TEXTMARK channel +% FH = SON file handle +% CHAN = the channel number for the new channel +% SPHYCH = the physical channel number +% BUFSIZE = the size of the internal buffer (up to 32768 bytes) +% COMMENT = channel comment string +% CHANTITLE = channel title string +% RATE = the expected data rate (during sampling) +% UNITS = channel units string +% POINTS = maximum number of characters per marker +% +% Returns zero or a negagtive error +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + +global SON_CHANCOMSZ; +global SON_UNITSZ; +global SON_TITLESZ; + +if (bufsize>32768) + bufsize=32768; +end; + +comment=comment(1 : min(length(comment), SON_CHANCOMSZ)); +chantitle=chantitle(1 : min(length(chantitle), SON_TITLESZ)); +units=units(1 : min(length(units), SON_UNITSZ)); + +ret=calllib('son32', 'SONSetTextMarkChan',... + fh, chan, sPhyCh, bufsize,... comment, chantitle, rate, units, points); \ No newline at end of file diff --git a/src/Import/SON/SON32/SONSetWaveChan.m b/Import/SON/SON32/SONSetWaveChan.m similarity index 94% rename from src/Import/SON/SON32/SONSetWaveChan.m rename to Import/SON/SON32/SONSetWaveChan.m index b2b36f84..88d552dd 100644 --- a/src/Import/SON/SON32/SONSetWaveChan.m +++ b/Import/SON/SON32/SONSetWaveChan.m @@ -1,38 +1,38 @@ -function ret=SONSetWaveChan(fh, chan, sPhyCh, dvd, bufsize,... - comment, chantitle, scale, offset, units) -% SONSETWAVECHAN creates an ADC channel -% -% RET=SONSETWAVECHAN(FH, CHAN, SPHYCH, DVD, BUFSIZE,... -% COMMENT, CHANTITLE, SCALE, OFFSET, UNITS) -% -% FH = SON file handle -% CHAN = the channel number for the new channel -% SPHYCH = the physical channel number -% DVD = the number of clock ticks per sample -% BUFSIZE = the size of the internal buffer (up to 32768 bytes) -% COMMENT = channel comment string -% CHANTITLE = channel title string -% SCALE = scale factor -% OFFSET = offset -% UNITS = channel units string -% -% Returns zero or a negative error -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - -global SON_CHANCOMSZ; -global SON_UNITSZ; -global SON_TITLESZ; - -if (bufsize>32768) - bufsize=32768; -end; - -comment=comment(1 : min(length(comment), SON_CHANCOMSZ)); -chantitle=chantitle(1 : min(length(chantitle), SON_TITLESZ)); -units=units(1 : min(length(units), SON_UNITSZ)); - -ret=calllib('son32', 'SONSetWaveChan',... +function ret=SONSetWaveChan(fh, chan, sPhyCh, dvd, bufsize,... + comment, chantitle, scale, offset, units) +% SONSETWAVECHAN creates an ADC channel +% +% RET=SONSETWAVECHAN(FH, CHAN, SPHYCH, DVD, BUFSIZE,... +% COMMENT, CHANTITLE, SCALE, OFFSET, UNITS) +% +% FH = SON file handle +% CHAN = the channel number for the new channel +% SPHYCH = the physical channel number +% DVD = the number of clock ticks per sample +% BUFSIZE = the size of the internal buffer (up to 32768 bytes) +% COMMENT = channel comment string +% CHANTITLE = channel title string +% SCALE = scale factor +% OFFSET = offset +% UNITS = channel units string +% +% Returns zero or a negative error +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + +global SON_CHANCOMSZ; +global SON_UNITSZ; +global SON_TITLESZ; + +if (bufsize>32768) + bufsize=32768; +end; + +comment=comment(1 : min(length(comment), SON_CHANCOMSZ)); +chantitle=chantitle(1 : min(length(chantitle), SON_TITLESZ)); +units=units(1 : min(length(units), SON_UNITSZ)); + +ret=calllib('son32', 'SONSetWaveChan',... fh, chan, sPhyCh, dvd, bufsize,comment, chantitle, scale, offset, units); \ No newline at end of file diff --git a/src/Import/SON/SON32/SONSetWaveMarkChan.m b/Import/SON/SON32/SONSetWaveMarkChan.m similarity index 95% rename from src/Import/SON/SON32/SONSetWaveMarkChan.m rename to Import/SON/SON32/SONSetWaveMarkChan.m index c545ae9a..929f5c7c 100644 --- a/src/Import/SON/SON32/SONSetWaveMarkChan.m +++ b/Import/SON/SON32/SONSetWaveMarkChan.m @@ -1,43 +1,43 @@ -function ret=SONSetWaveMarkChan(fh, chan, sPhyCh, dvd, bufsize, comment,... - chantitle, rate, scale, offset, units, points, pretrig, ntrace) -% SONSETWAVEMARKCHAN creates a REALMARK channel -% -% RET=SONSETWAVEMARKCHAN(FH, CHAN, SPHYCH, DVD, BUFSIZE, COMMENT,... -% CHANTITLE, RATE, SCALE, OFFSET, UNITS, POINTS, PRETRIG, NTRACE) -% -% FH = SON file handle -% CHAN = the channel number for the new channel -% SPHYCH = the physical channel number -% DVD = the number of clock ticks per sample -% BUFSIZE = the size of the internal buffer (up to 32768 bytes) -% COMMENT = channel comment string -% CHANTITLE = channel title string -% RATE = expected mean rate (only used in sampling) -% SCALE = scale factor -% OFFSET = offset -% UNITS = channel units string -% POINTS = number of extra data entries for each marker -% PRETRIG = pre-trigger wvaeform points -% NTRACE = number of interleaved traces (1 to 4) -% -% Returns zero or a negative error -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - -global SON_CHANCOMSZ; -global SON_UNITSZ; -global SON_TITLESZ; - -if (bufsize>32768) - bufsize=32768; -end; - -comment=comment(1 : min(length(comment), SON_CHANCOMSZ)); -chantitle=chantitle(1 : min(length(chantitle), SON_TITLESZ)); -units=units(1 : min(length(units), SON_UNITSZ)); - -ret=calllib('son32', 'SONSetWaveMarkChan',... - fh, chan, sPhyCh, dvd, bufsize, comment,... +function ret=SONSetWaveMarkChan(fh, chan, sPhyCh, dvd, bufsize, comment,... + chantitle, rate, scale, offset, units, points, pretrig, ntrace) +% SONSETWAVEMARKCHAN creates a REALMARK channel +% +% RET=SONSETWAVEMARKCHAN(FH, CHAN, SPHYCH, DVD, BUFSIZE, COMMENT,... +% CHANTITLE, RATE, SCALE, OFFSET, UNITS, POINTS, PRETRIG, NTRACE) +% +% FH = SON file handle +% CHAN = the channel number for the new channel +% SPHYCH = the physical channel number +% DVD = the number of clock ticks per sample +% BUFSIZE = the size of the internal buffer (up to 32768 bytes) +% COMMENT = channel comment string +% CHANTITLE = channel title string +% RATE = expected mean rate (only used in sampling) +% SCALE = scale factor +% OFFSET = offset +% UNITS = channel units string +% POINTS = number of extra data entries for each marker +% PRETRIG = pre-trigger wvaeform points +% NTRACE = number of interleaved traces (1 to 4) +% +% Returns zero or a negative error +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + +global SON_CHANCOMSZ; +global SON_UNITSZ; +global SON_TITLESZ; + +if (bufsize>32768) + bufsize=32768; +end; + +comment=comment(1 : min(length(comment), SON_CHANCOMSZ)); +chantitle=chantitle(1 : min(length(chantitle), SON_TITLESZ)); +units=units(1 : min(length(units), SON_UNITSZ)); + +ret=calllib('son32', 'SONSetWaveMarkChan',... + fh, chan, sPhyCh, dvd, bufsize, comment,... chantitle, rate, scale, offset, units, points, pretrig, ntrace); \ No newline at end of file diff --git a/src/Import/SON/SON32/SONTimeBase.m b/Import/SON/SON32/SONTimeBase.m similarity index 96% rename from src/Import/SON/SON32/SONTimeBase.m rename to Import/SON/SON32/SONTimeBase.m index 38ee4453..08fadade 100644 --- a/src/Import/SON/SON32/SONTimeBase.m +++ b/Import/SON/SON32/SONTimeBase.m @@ -1,19 +1,19 @@ -function dTickLen=SONTimeBase(fh, dTb) -% SONTIMEBASE Get or set the base time units for the file -% (usually 1e-6seconds) -% DTICKLEN=SONTIMEBASE(FH, DTB) -% FH SON file handle -% DTB If <= 0 ignored -% >0 the new value to set -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - -if nargin ~=2 - dTickLen=-1000; - return; -end; - -dTickLen=calllib('son32','SONTimeBase',fh,dTb); -return; +function dTickLen=SONTimeBase(fh, dTb) +% SONTIMEBASE Get or set the base time units for the file +% (usually 1e-6seconds) +% DTICKLEN=SONTIMEBASE(FH, DTB) +% FH SON file handle +% DTB If <= 0 ignored +% >0 the new value to set +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + +if nargin ~=2 + dTickLen=-1000; + return; +end; + +dTickLen=calllib('son32','SONTimeBase',fh,dTb); +return; diff --git a/src/Import/SON/SON32/SONTimeDate.mexw32 b/Import/SON/SON32/SONTimeDate.mexw32 similarity index 100% rename from src/Import/SON/SON32/SONTimeDate.mexw32 rename to Import/SON/SON32/SONTimeDate.mexw32 diff --git a/src/Import/SON/SON32/SONUpdateStart.m b/Import/SON/SON32/SONUpdateStart.m similarity index 83% rename from src/Import/SON/SON32/SONUpdateStart.m rename to Import/SON/SON32/SONUpdateStart.m index 9d9026ab..6f35a89d 100644 --- a/src/Import/SON/SON32/SONUpdateStart.m +++ b/Import/SON/SON32/SONUpdateStart.m @@ -1,13 +1,13 @@ -function ret=SONUpdateStart(fh) -% SONUPDATESTART flushes the SON file header to disc -% -% RET=SONUPDATESTART(FH) -% where FH is the SON file handle -% -% Returns zero or a negative error -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - +function ret=SONUpdateStart(fh) +% SONUPDATESTART flushes the SON file header to disc +% +% RET=SONUPDATESTART(FH) +% where FH is the SON file handle +% +% Returns zero or a negative error +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + ret=calllib('son32', 'SONUpdateStart', fh); \ No newline at end of file diff --git a/src/Import/SON/SON32/SONVersion.m b/Import/SON/SON32/SONVersion.m similarity index 95% rename from src/Import/SON/SON32/SONVersion.m rename to Import/SON/SON32/SONVersion.m index 6b3d7883..e6f57022 100644 --- a/src/Import/SON/SON32/SONVersion.m +++ b/Import/SON/SON32/SONVersion.m @@ -1,17 +1,17 @@ -function Ver=SONVersion() -% SONVERSION returns the MATLAB library version number (Not a CED function) -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - -global Version; -title='MATLAB SON Library'; - -st=sprintf(['\nMATLAB SON Library for Windows:\n',... - 'Author: Malcolm Lidierth, ',... - '\n01.06.05 Version:%3.2f %cKing%cs College London\n\n',... - 'SON Filing system Copyright %c Cambridge Electronic Design 1988-2005\nVersion 7.0'],Version,169,39,169); - -msgbox(st,title,'modal'); +function Ver=SONVersion() +% SONVERSION returns the MATLAB library version number (Not a CED function) +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + +global Version; +title='MATLAB SON Library'; + +st=sprintf(['\nMATLAB SON Library for Windows:\n',... + 'Author: Malcolm Lidierth, ',... + '\n01.06.05 Version:%3.2f %cKing%cs College London\n\n',... + 'SON Filing system Copyright %c Cambridge Electronic Design 1988-2005\nVersion 7.0'],Version,169,39,169); + +msgbox(st,title,'modal'); Ver=Version; \ No newline at end of file diff --git a/src/Import/SON/SON32/SONWriteADCBlock.m b/Import/SON/SON32/SONWriteADCBlock.m similarity index 97% rename from src/Import/SON/SON32/SONWriteADCBlock.m rename to Import/SON/SON32/SONWriteADCBlock.m index 20e13938..16993fe5 100644 --- a/src/Import/SON/SON32/SONWriteADCBlock.m +++ b/Import/SON/SON32/SONWriteADCBlock.m @@ -1,28 +1,28 @@ -function ret=SONWriteADCBlock(fh, chan, buffer, count, startTime) -% SONWRITEADCBLOCK writes data to an ADC channel -% -% RET=SONWRITEADCBLOCK(FH, CHAN, BUFFER, COUNT, STARTTIME) -% INPUTS: FH the SON file handle -% CHAN the target channel -% BUFFER the data to be written (int16 ADC data) -% COUNT the number of data items to write from buffer -% STARTTIME the time of the first sample in buffer (in clock ticks) -% -% RET is the time for the next sample to be supplied in a subsequqnt call to -% SONWRITEADCBLOCK (assuming continuous sampling) or a negative error code. -% -% Fo efficient use of disc space, COUNT should be a multiple of -% (BUFSIZE - 20 bytes)/2 , where BUFSIZE is supplied in a prior call to -% SONSETADCCHAN (20 is the size of the block header on disc) -% -% see CED documentation -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - -if (strcmp(class(buffer),'int16')) - ret=calllib('son32','SONWriteADCBock',... - fh, chan, buffer, count, startTime); -else - ret=-22; +function ret=SONWriteADCBlock(fh, chan, buffer, count, startTime) +% SONWRITEADCBLOCK writes data to an ADC channel +% +% RET=SONWRITEADCBLOCK(FH, CHAN, BUFFER, COUNT, STARTTIME) +% INPUTS: FH the SON file handle +% CHAN the target channel +% BUFFER the data to be written (int16 ADC data) +% COUNT the number of data items to write from buffer +% STARTTIME the time of the first sample in buffer (in clock ticks) +% +% RET is the time for the next sample to be supplied in a subsequqnt call to +% SONWRITEADCBLOCK (assuming continuous sampling) or a negative error code. +% +% Fo efficient use of disc space, COUNT should be a multiple of +% (BUFSIZE - 20 bytes)/2 , where BUFSIZE is supplied in a prior call to +% SONSETADCCHAN (20 is the size of the block header on disc) +% +% see CED documentation +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + +if (strcmp(class(buffer),'int16')) + ret=calllib('son32','SONWriteADCBock',... + fh, chan, buffer, count, startTime); +else + ret=-22; diff --git a/src/Import/SON/SON32/SONWriteEventBlock.m b/Import/SON/SON32/SONWriteEventBlock.m similarity index 96% rename from src/Import/SON/SON32/SONWriteEventBlock.m rename to Import/SON/SON32/SONWriteEventBlock.m index d49f6bc8..f0e4ffda 100644 --- a/src/Import/SON/SON32/SONWriteEventBlock.m +++ b/Import/SON/SON32/SONWriteEventBlock.m @@ -1,26 +1,26 @@ -function ret=SONWriteEventBlock(fh, chan, buffer, count) -% SONWRITEEVENTBLOCK writes data to an ADC channel -% -% RET=SONWRITEEVENTBLOCK(FH, CHAN, BUFFER, COUNT) -% INPUTS: FH the SON file handle -% CHAN the target channel -% BUFFER the data to be written containing int32 timestamps -% COUNT the number of data items to write from buffer -% -% Returns zero or a negative error code. -% -% For efficient use of disc space, COUNT should be a multiple of -% (BUFSIZE bytes - 20)/4 , where BUFSIZE is supplied in a prior call to -% SONSETEVENTCHAN (20 is the size of the block header on disc) -% -% see CED documentation -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - -if (strcmp(class(buffer),'int32')) - ret=calllib('son32','SONWriteEventBlock', fh, chan, buffer, count); -else - ret=-22; +function ret=SONWriteEventBlock(fh, chan, buffer, count) +% SONWRITEEVENTBLOCK writes data to an ADC channel +% +% RET=SONWRITEEVENTBLOCK(FH, CHAN, BUFFER, COUNT) +% INPUTS: FH the SON file handle +% CHAN the target channel +% BUFFER the data to be written containing int32 timestamps +% COUNT the number of data items to write from buffer +% +% Returns zero or a negative error code. +% +% For efficient use of disc space, COUNT should be a multiple of +% (BUFSIZE bytes - 20)/4 , where BUFSIZE is supplied in a prior call to +% SONSETEVENTCHAN (20 is the size of the block header on disc) +% +% see CED documentation +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + +if (strcmp(class(buffer),'int32')) + ret=calllib('son32','SONWriteEventBlock', fh, chan, buffer, count); +else + ret=-22; end; \ No newline at end of file diff --git a/src/Import/SON/SON32/SONWriteExtMarkBlock.m b/Import/SON/SON32/SONWriteExtMarkBlock.m similarity index 100% rename from src/Import/SON/SON32/SONWriteExtMarkBlock.m rename to Import/SON/SON32/SONWriteExtMarkBlock.m diff --git a/src/Import/SON/SON32/SONWriteExtMarkBlock.mexw32 b/Import/SON/SON32/SONWriteExtMarkBlock.mexw32 similarity index 100% rename from src/Import/SON/SON32/SONWriteExtMarkBlock.mexw32 rename to Import/SON/SON32/SONWriteExtMarkBlock.mexw32 diff --git a/src/Import/SON/SON32/SONWriteMarkBlock.m b/Import/SON/SON32/SONWriteMarkBlock.m similarity index 93% rename from src/Import/SON/SON32/SONWriteMarkBlock.m rename to Import/SON/SON32/SONWriteMarkBlock.m index be370275..cd556e81 100644 --- a/src/Import/SON/SON32/SONWriteMarkBlock.m +++ b/Import/SON/SON32/SONWriteMarkBlock.m @@ -1,27 +1,27 @@ -function ret=SONWriteMarkBlock(fh, chan, buffer, count) -% SONWRITEMARKBLOCK writes data to a marker channel -% -% Implemented through SONWriteMarkBlock.dll -% -% RET=SONWRITEMARKBLOCK(FH, CHAN, TIMESTAMPS, MARKERS, COUNT) -% INPUTS: FH the SON file handle -% CHAN the target channel -% TIMESTAMPS a vector of int32 timestamps for the markers -% which should be at least COUNT in length -% MARKERS the 4xCOUNT array of uint8 marker values, one set of -% 4 for each timestamp -% COUNT the number of marker items to write to the buffer -% -% Returns zero or a negative error code. -% -% For efficient use of disc space, COUNT should be a multiple of -% (BUFSIZE bytes - 20)/4 , where BUFSIZE is supplied in a prior call to -% SONSETEVENTCHAN (20 is the size of the block header on disc) -% -% see CED documentation -% -% See also SONSETEVENTCHAN, SONWRITEEVENTBLOCK, SONWRITEEXTMARKBLOCK -% -% Author:Malcolm Lidierth -% Matlab SON library: +function ret=SONWriteMarkBlock(fh, chan, buffer, count) +% SONWRITEMARKBLOCK writes data to a marker channel +% +% Implemented through SONWriteMarkBlock.dll +% +% RET=SONWRITEMARKBLOCK(FH, CHAN, TIMESTAMPS, MARKERS, COUNT) +% INPUTS: FH the SON file handle +% CHAN the target channel +% TIMESTAMPS a vector of int32 timestamps for the markers +% which should be at least COUNT in length +% MARKERS the 4xCOUNT array of uint8 marker values, one set of +% 4 for each timestamp +% COUNT the number of marker items to write to the buffer +% +% Returns zero or a negative error code. +% +% For efficient use of disc space, COUNT should be a multiple of +% (BUFSIZE bytes - 20)/4 , where BUFSIZE is supplied in a prior call to +% SONSETEVENTCHAN (20 is the size of the block header on disc) +% +% see CED documentation +% +% See also SONSETEVENTCHAN, SONWRITEEVENTBLOCK, SONWRITEEXTMARKBLOCK +% +% Author:Malcolm Lidierth +% Matlab SON library: % Copyright 2005 Kings College London \ No newline at end of file diff --git a/src/Import/SON/SON32/SONWriteRealBlock.m b/Import/SON/SON32/SONWriteRealBlock.m similarity index 96% rename from src/Import/SON/SON32/SONWriteRealBlock.m rename to Import/SON/SON32/SONWriteRealBlock.m index 586023d1..d2e69fd6 100644 --- a/src/Import/SON/SON32/SONWriteRealBlock.m +++ b/Import/SON/SON32/SONWriteRealBlock.m @@ -1,28 +1,28 @@ -function ret=SONWriteRealBlock(fh, chan, buffer, count, startTime) -% SONWRITERealBLOCK writes data to an Real channel -% -% RET=SONWRITERealBLOCK(FH, CHAN, BUFFER, COUNT, STARTTIME) -% INPUTS: FH the SON file handle -% CHAN the target channel -% BUFFER the data to be written (single floating point) -% COUNT the number of data items to write from buffer -% STARTTIME the time of the first sample in buffer (in clock ticks) -% -% RET is the time for the next sample to be supplied in a subsequqnt call to -% SONWRITERealBLOCK (assuming continuous sampling) or a negative error code. -% -% Fo efficient use of disc space, COUNT should be a multiple of -% (BUFSIZE - 20 bytes)/4 , where BUFSIZE is supplied in a prior call to -% SONSETRealCHAN (20 is the size of the block header on disc) -% -% see CED documentation -% -% Author:Malcolm Lidierth -% Matlab SON library: -% Copyright 2005 Kings College London - -if (strcmp(class(buffer),'single')) - ret=calllib('son32','SONWriteRealBock',... - fh, chan, buffer, count, startTime); -else +function ret=SONWriteRealBlock(fh, chan, buffer, count, startTime) +% SONWRITERealBLOCK writes data to an Real channel +% +% RET=SONWRITERealBLOCK(FH, CHAN, BUFFER, COUNT, STARTTIME) +% INPUTS: FH the SON file handle +% CHAN the target channel +% BUFFER the data to be written (single floating point) +% COUNT the number of data items to write from buffer +% STARTTIME the time of the first sample in buffer (in clock ticks) +% +% RET is the time for the next sample to be supplied in a subsequqnt call to +% SONWRITERealBLOCK (assuming continuous sampling) or a negative error code. +% +% Fo efficient use of disc space, COUNT should be a multiple of +% (BUFSIZE - 20 bytes)/4 , where BUFSIZE is supplied in a prior call to +% SONSETRealCHAN (20 is the size of the block header on disc) +% +% see CED documentation +% +% Author:Malcolm Lidierth +% Matlab SON library: +% Copyright 2005 Kings College London + +if (strcmp(class(buffer),'single')) + ret=calllib('son32','SONWriteRealBock',... + fh, chan, buffer, count, startTime); +else ret=-22; \ No newline at end of file diff --git a/src/Import/SON/SON32/SONYRange.m b/Import/SON/SON32/SONYRange.m similarity index 100% rename from src/Import/SON/SON32/SONYRange.m rename to Import/SON/SON32/SONYRange.m diff --git a/src/Import/SON/SON32/gatewaySONWriteExtMarkBlock.mexw32 b/Import/SON/SON32/gatewaySONWriteExtMarkBlock.mexw32 similarity index 100% rename from src/Import/SON/SON32/gatewaySONWriteExtMarkBlock.mexw32 rename to Import/SON/SON32/gatewaySONWriteExtMarkBlock.mexw32 diff --git a/src/Import/SON/SON32/son32.m b/Import/SON/SON32/son32.m similarity index 99% rename from src/Import/SON/SON32/son32.m rename to Import/SON/SON32/son32.m index ba607d4b..56523502 100644 --- a/src/Import/SON/SON32/son32.m +++ b/Import/SON/SON32/son32.m @@ -1,192 +1,192 @@ -function [methodinfo,structs,enuminfo]=son32; -% SON32 Prototype file. Create structures to define interfaces found in 'matlab'. -%This function was generated by the perl file prototypes.pl called from loadlibary.m on Tue Mar 22 18:35:30 2005 -%perl options:'matlab.i -outfile=son32.m' -% -% This file is required by the MATLAB SON Librart for Windows -% to use son32.dll -% - -ival={cell(1,0)}; % change 0 to the actual number of functions to preallocate the data. -fcns=struct('name',ival,'calltype',ival,'LHS',ival,'RHS',ival,'alias',ival); -structs=[];enuminfo=[];fcnNum=1; -% void WINAPI SONInitFiles(void); -fcns.name{fcnNum}='SONInitFiles'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}=[]; fcns.RHS{fcnNum}=[];fcnNum=fcnNum+1; -% void WINAPI SONCleanUp(void); -fcns.name{fcnNum}='SONCleanUp'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}=[]; fcns.RHS{fcnNum}=[];fcnNum=fcnNum+1; -% short WINAPI SONOpenOldFile(TpCStr name, int iOpenMode); -fcns.name{fcnNum}='SONOpenOldFile'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int16'; fcns.RHS{fcnNum}={'string', 'int32'};fcnNum=fcnNum+1; -% short WINAPI SONOpenNewFile(TpCStr name, short fMode, WORD extra); -fcns.name{fcnNum}='SONOpenNewFile'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int16'; fcns.RHS{fcnNum}={'string', 'int16', 'uint16'};fcnNum=fcnNum+1; -% BOOLEAN WINAPI SONCanWrite(short fh); -fcns.name{fcnNum}='SONCanWrite'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int16'; fcns.RHS{fcnNum}={'int16'};fcnNum=fcnNum+1; -% short WINAPI SONCloseFile(short fh); -fcns.name{fcnNum}='SONCloseFile'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int16'; fcns.RHS{fcnNum}={'int16'};fcnNum=fcnNum+1; -% short WINAPI SONEmptyFile(short fh); -fcns.name{fcnNum}='SONEmptyFile'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int16'; fcns.RHS{fcnNum}={'int16'};fcnNum=fcnNum+1; -% short WINAPI SONSetBuffSpace(short fh); -fcns.name{fcnNum}='SONSetBuffSpace'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int16'; fcns.RHS{fcnNum}={'int16'};fcnNum=fcnNum+1; -% short WINAPI SONGetFreeChan(short fh); -fcns.name{fcnNum}='SONGetFreeChan'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int16'; fcns.RHS{fcnNum}={'int16'};fcnNum=fcnNum+1; -% void WINAPI SONSetFileClock(short fh, WORD usPerTime, WORD timePerADC); -fcns.name{fcnNum}='SONSetFileClock'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}=[]; fcns.RHS{fcnNum}={'int16', 'uint16', 'uint16'};fcnNum=fcnNum+1; -% short WINAPI SONSetADCChan(short fh, WORD chan, short sPhyCh, short dvd, long lBufSz, TpCStr szCom, TpCStr szTitle, float fRate, float scl, float offs, TpCStr szUnt); -fcns.name{fcnNum}='SONSetADCChan'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int16'; fcns.RHS{fcnNum}={'int16', 'uint16', 'int16', 'int16', 'int32', 'string', 'string', 'single', 'single', 'single', 'string'};fcnNum=fcnNum+1; -% short WINAPI SONSetADCMarkChan(short fh, WORD chan, short sPhyCh, short dvd, long lBufSz, TpCStr szCom, TpCStr szTitle, float fRate, float scl, float offs, TpCStr szUnt, WORD points, short preTrig); -fcns.name{fcnNum}='SONSetADCMarkChan'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int16'; fcns.RHS{fcnNum}={'int16', 'uint16', 'int16', 'int16', 'int32', 'string', 'string', 'single', 'single', 'single', 'string', 'uint16', 'int16'};fcnNum=fcnNum+1; -% short WINAPI SONSetWaveChan(short fh, WORD chan, short sPhyCh, TSTime dvd, long lBufSz, TpCStr szCom, TpCStr szTitle, float scl, float offs, TpCStr szUnt); -fcns.name{fcnNum}='SONSetWaveChan'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int16'; fcns.RHS{fcnNum}={'int16', 'uint16', 'int16', 'int32', 'int32', 'string', 'string', 'single', 'single', 'string'};fcnNum=fcnNum+1; -% short WINAPI SONSetWaveMarkChan(short fh, WORD chan, short sPhyCh, TSTime dvd, long lBufSz, TpCStr szCom, TpCStr szTitle, float fRate, float scl, float offs, TpCStr szUnt, WORD points, short preTrig, int nTrace); -fcns.name{fcnNum}='SONSetWaveMarkChan'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int16'; fcns.RHS{fcnNum}={'int16', 'uint16', 'int16', 'int32', 'int32', 'string', 'string', 'single', 'single', 'single', 'string', 'uint16', 'int16', 'int32'};fcnNum=fcnNum+1; -% short WINAPI SONSetRealMarkChan(short fh, WORD chan, short sPhyCh, long lBufSz, TpCStr szCom, TpCStr szTitle, float fRate, float min, float max, TpCStr szUnt, WORD points); -fcns.name{fcnNum}='SONSetRealMarkChan'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int16'; fcns.RHS{fcnNum}={'int16', 'uint16', 'int16', 'int32', 'string', 'string', 'single', 'single', 'single', 'string', 'uint16'};fcnNum=fcnNum+1; -% short WINAPI SONSetTextMarkChan(short fh, WORD chan, short sPhyCh, long lBufSz, TpCStr szCom, TpCStr szTitle, float fRate, TpCStr szUnt, WORD points); -fcns.name{fcnNum}='SONSetTextMarkChan'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int16'; fcns.RHS{fcnNum}={'int16', 'uint16', 'int16', 'int32', 'string', 'string', 'single', 'string', 'uint16'};fcnNum=fcnNum+1; -% void WINAPI SONSetInitLow(short fh, WORD chan, BOOLEAN bLow); -fcns.name{fcnNum}='SONSetInitLow'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}=[]; fcns.RHS{fcnNum}={'int16', 'uint16', 'int16'};fcnNum=fcnNum+1; -% short WINAPI SONSetEventChan(short fh, WORD chan, short sPhyCh, long lBufSz, TpCStr szCom, TpCStr szTitle, float fRate, TDataKind evtKind); -fcns.name{fcnNum}='SONSetEventChan'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int16'; fcns.RHS{fcnNum}={'int16', 'uint16', 'int16', 'int32', 'string', 'string', 'single', 'TDataKind'};fcnNum=fcnNum+1; -% short WINAPI SONSetBuffering(short fh, int nChan, int nBytes); -fcns.name{fcnNum}='SONSetBuffering'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int16'; fcns.RHS{fcnNum}={'int16', 'int32', 'int32'};fcnNum=fcnNum+1; -% short WINAPI SONUpdateStart(short fh); -fcns.name{fcnNum}='SONUpdateStart'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int16'; fcns.RHS{fcnNum}={'int16'};fcnNum=fcnNum+1; -% void WINAPI SONSetFileComment(short fh, WORD which, TpCStr szFCom); -fcns.name{fcnNum}='SONSetFileComment'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}=[]; fcns.RHS{fcnNum}={'int16', 'uint16', 'string'};fcnNum=fcnNum+1; -% void WINAPI SONGetFileComment(short fh, WORD which, TpStr pcFCom, short sMax); -fcns.name{fcnNum}='SONGetFileComment'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}=[]; fcns.RHS{fcnNum}={'int16', 'uint16', 'string', 'int16'};fcnNum=fcnNum+1; -% void WINAPI SONSetChanComment(short fh, WORD chan, TpCStr szCom); -fcns.name{fcnNum}='SONSetChanComment'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}=[]; fcns.RHS{fcnNum}={'int16', 'uint16', 'string'};fcnNum=fcnNum+1; -% void WINAPI SONGetChanComment(short fh, WORD chan, TpStr pcCom, short sMax); -fcns.name{fcnNum}='SONGetChanComment'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}=[]; fcns.RHS{fcnNum}={'int16', 'uint16', 'string', 'int16'};fcnNum=fcnNum+1; -% void WINAPI SONSetChanTitle(short fh, WORD chan, TpCStr szTitle); -fcns.name{fcnNum}='SONSetChanTitle'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}=[]; fcns.RHS{fcnNum}={'int16', 'uint16', 'string'};fcnNum=fcnNum+1; -% void WINAPI SONGetChanTitle(short fh, WORD chan, TpStr pcTitle); -fcns.name{fcnNum}='SONGetChanTitle'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}=[]; fcns.RHS{fcnNum}={'int16', 'uint16', 'string'};fcnNum=fcnNum+1; -% void WINAPI SONGetIdealLimits(short fh, WORD chan, TpFloat pfRate, TpFloat pfMin, TpFloat pfMax); -fcns.name{fcnNum}='SONGetIdealLimits'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}=[]; fcns.RHS{fcnNum}={'int16', 'uint16', 'singlePtr', 'singlePtr', 'singlePtr'};fcnNum=fcnNum+1; -% WORD WINAPI SONGetusPerTime(short fh); -fcns.name{fcnNum}='SONGetusPerTime'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='uint16'; fcns.RHS{fcnNum}={'int16'};fcnNum=fcnNum+1; -% WORD WINAPI SONGetTimePerADC(short fh); -fcns.name{fcnNum}='SONGetTimePerADC'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='uint16'; fcns.RHS{fcnNum}={'int16'};fcnNum=fcnNum+1; -% void WINAPI SONSetADCUnits(short fh, WORD chan, TpCStr szUnt); -fcns.name{fcnNum}='SONSetADCUnits'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}=[]; fcns.RHS{fcnNum}={'int16', 'uint16', 'string'};fcnNum=fcnNum+1; -% void WINAPI SONSetADCOffset(short fh, WORD chan, float offset); -fcns.name{fcnNum}='SONSetADCOffset'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}=[]; fcns.RHS{fcnNum}={'int16', 'uint16', 'single'};fcnNum=fcnNum+1; -% void WINAPI SONSetADCScale(short fh, WORD chan, float scale); -fcns.name{fcnNum}='SONSetADCScale'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}=[]; fcns.RHS{fcnNum}={'int16', 'uint16', 'single'};fcnNum=fcnNum+1; -% void WINAPI SONGetADCInfo(short fh, WORD chan, TpFloat scale, TpFloat offset, TpStr pcUnt, TpWORD points, TpShort preTrig); -fcns.name{fcnNum}='SONGetADCInfo'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}=[]; fcns.RHS{fcnNum}={'int16', 'uint16', 'singlePtr', 'singlePtr', 'string', 'uint16Ptr', 'int16Ptr'};fcnNum=fcnNum+1; -% void WINAPI SONGetExtMarkInfo(short fh, WORD chan, TpStr pcUnt, TpWORD points, TpShort preTrig); -fcns.name{fcnNum}='SONGetExtMarkInfo'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}=[]; fcns.RHS{fcnNum}={'int16', 'uint16', 'string', 'uint16Ptr', 'int16Ptr'};fcnNum=fcnNum+1; -% short WINAPI SONWriteEventBlock(short fh, WORD chan, TpSTime plBuf, long count); -fcns.name{fcnNum}='SONWriteEventBlock'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int16'; fcns.RHS{fcnNum}={'int16', 'uint16', 'int32Ptr', 'int32'};fcnNum=fcnNum+1; -% short WINAPI SONWriteMarkBlock(short fh, WORD chan, TpMarker pM, long count); -fcns.name{fcnNum}='SONWriteMarkBlock'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int16'; fcns.RHS{fcnNum}={'int16', 'uint16', 'TMarkerPtr', 'int32'};fcnNum=fcnNum+1; -% TSTime WINAPI SONWriteADCBlock(short fh, WORD chan, TpAdc psBuf, long count, TSTime sTime); -fcns.name{fcnNum}='SONWriteADCBlock'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'int16', 'uint16', 'int16Ptr', 'int32', 'int32'};fcnNum=fcnNum+1; -% short WINAPI SONWriteExtMarkBlock(short fh, WORD chan, TpMarker pM, long count); -%fcns.name{fcnNum}='SONWriteExtMarkBlock'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int16'; fcns.RHS{fcnNum}={'int16', 'uint16', 'TMarkerPtr', 'int32'};fcnNum=fcnNum+1; -% short WINAPI SONSave(short fh, int nChan, TSTime sTime, BOOLEAN bKeep); -fcns.name{fcnNum}='SONSave'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int16'; fcns.RHS{fcnNum}={'int16', 'int32', 'int32', 'int16'};fcnNum=fcnNum+1; -% short WINAPI SONSaveRange(short fh, int nChan, TSTime sTime, TSTime eTime); -fcns.name{fcnNum}='SONSaveRange'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int16'; fcns.RHS{fcnNum}={'int16', 'int32', 'int32', 'int32'};fcnNum=fcnNum+1; -% short WINAPI SONKillRange(short fh, int nChan, TSTime sTime, TSTime eTime); -fcns.name{fcnNum}='SONKillRange'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int16'; fcns.RHS{fcnNum}={'int16', 'int32', 'int32', 'int32'};fcnNum=fcnNum+1; -% short WINAPI SONIsSaving(short fh, int nChan); -fcns.name{fcnNum}='SONIsSaving'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int16'; fcns.RHS{fcnNum}={'int16', 'int32'};fcnNum=fcnNum+1; -% DWORD WINAPI SONFileBytes(short fh); -fcns.name{fcnNum}='SONFileBytes'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='uint32'; fcns.RHS{fcnNum}={'int16'};fcnNum=fcnNum+1; -% DWORD WINAPI SONChanBytes(short fh, WORD chan); -fcns.name{fcnNum}='SONChanBytes'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='uint32'; fcns.RHS{fcnNum}={'int16', 'uint16'};fcnNum=fcnNum+1; -% short WINAPI SONLatestTime(short fh, WORD chan, TSTime sTime); -fcns.name{fcnNum}='SONLatestTime'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int16'; fcns.RHS{fcnNum}={'int16', 'uint16', 'int32'};fcnNum=fcnNum+1; -% short WINAPI SONCommitIdle(short fh); -fcns.name{fcnNum}='SONCommitIdle'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int16'; fcns.RHS{fcnNum}={'int16'};fcnNum=fcnNum+1; -% short WINAPI SONCommitFile(short fh, BOOLEAN bDelete); -fcns.name{fcnNum}='SONCommitFile'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int16'; fcns.RHS{fcnNum}={'int16', 'int16'};fcnNum=fcnNum+1; -% long WINAPI SONGetEventData(short fh, WORD chan, TpSTime plTimes, long max, TSTime sTime, TSTime eTime, TpBOOL levLowP, TpFilterMask pFiltMask); -%fcns.name{fcnNum}='SONGetEventData'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'int16', 'uint16', 'int32Ptr', 'int32', 'int32', 'int32', 'int16Ptr', 'TFilterMaskPtr'};fcnNum=fcnNum+1; -% long WINAPI SONGetMarkData(short fh, WORD chan,TpMarker pMark, long max, TSTime sTime,TSTime eTime, TpFilterMask pFiltMask); -%fcns.name{fcnNum}='SONGetMarkData'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'int16', 'uint16', 'TMarkerPtr', 'int32', 'int32', 'int32', 'TFilterMaskPtr'};fcnNum=fcnNum+1; -% long WINAPI SONGetADCData(short fh,WORD chan,TpAdc adcDataP, long max, TSTime sTime,TSTime eTime,TpSTime pbTime, TpFilterMask pFiltMask); -%fcns.name{fcnNum}='SONGetADCData'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'int16', 'uint16', 'int16Ptr', 'int32', 'int32', 'int32', 'int32Ptr', 'TFilterMaskPtr'};fcnNum=fcnNum+1; -% long WINAPI SONGetExtMarkData(short fh, WORD chan, TpMarker pMark, long max, TSTime sTime,TSTime eTime, TpFilterMask pFiltMask); -%fcns.name{fcnNum}='SONGetExtMarkData'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'int16', 'uint16', 'TMarkerPtr', 'int32', 'int32', 'int32', 'TFilterMaskPtr'};fcnNum=fcnNum+1; -% long WINAPI SONGetExtraDataSize(short fh); -fcns.name{fcnNum}='SONGetExtraDataSize'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'int16'};fcnNum=fcnNum+1; -% int WINAPI SONGetVersion(short fh); -fcns.name{fcnNum}='SONGetVersion'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'int16'};fcnNum=fcnNum+1; -% short WINAPI SONGetExtraData(short fh, TpVoid buff, WORD bytes, WORD offset, BOOLEAN writeIt); -fcns.name{fcnNum}='SONGetExtraData'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int16'; fcns.RHS{fcnNum}={'int16', 'voidPtr', 'uint16', 'uint16', 'int16'};fcnNum=fcnNum+1; -% short WINAPI SONSetMarker(short fh, WORD chan, TSTime time, TpMarker pMark, WORD size); -%fcns.name{fcnNum}='SONSetMarker'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int16'; fcns.RHS{fcnNum}={'int16', 'uint16', 'int32', 'TMarkerPtr', 'uint16'};fcnNum=fcnNum+1; -% short WINAPI SONChanDelete(short fh, WORD chan); -fcns.name{fcnNum}='SONChanDelete'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int16'; fcns.RHS{fcnNum}={'int16', 'uint16'};fcnNum=fcnNum+1; -% TDataKind WINAPI SONChanKind(short fh, WORD chan); -fcns.name{fcnNum}='SONChanKind'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='TDataKind'; fcns.RHS{fcnNum}={'int16', 'uint16'};fcnNum=fcnNum+1; -% TSTime WINAPI SONChanDivide(short fh, WORD chan); -fcns.name{fcnNum}='SONChanDivide'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'int16', 'uint16'};fcnNum=fcnNum+1; -% WORD WINAPI SONItemSize(short fh, WORD chan); -%fcns.name{fcnNum}='SONItemSize'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='uint16'; fcns.RHS{fcnNum}={'int16', 'uint16'};fcnNum=fcnNum+1; -% TSTime WINAPI SONChanMaxTime(short fh, WORD chan); -fcns.name{fcnNum}='SONChanMaxTime'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'int16', 'uint16'};fcnNum=fcnNum+1; -% TSTime WINAPI SONMaxTime(short fh); -fcns.name{fcnNum}='SONMaxTime'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'int16'};fcnNum=fcnNum+1; -% TSTime WINAPI SONLastTime(short fh, WORD wChan, TSTime sTime, TSTime eTime, TpVoid pvVal, TpMarkBytes pMB, TpBOOL pbMk, TpFilterMask pFiltMask); -%fcns.name{fcnNum}='SONLastTime'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'int16', 'uint16', 'int32', 'int32', 'voidPtr', 'stringPtr', 'int16Ptr', 'TFilterMaskPtr'};fcnNum=fcnNum+1; -% TSTime WINAPI SONLastPointsTime(short fh, WORD wChan, TSTime sTime, TSTime eTime, long lPoints, BOOLEAN bAdc, TpFilterMask pFiltMask); -%fcns.name{fcnNum}='SONLastPointsTime'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'int16', 'uint16', 'int32', 'int32', 'int32', 'int16', 'TFilterMaskPtr'};fcnNum=fcnNum+1; -% long WINAPI SONFileSize(short fh); -fcns.name{fcnNum}='SONFileSize'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'int16'};fcnNum=fcnNum+1; -% int WINAPI SONMarkerItem(short fh, WORD wChan, TpMarker pBuff, int n, TpMarker pM, TpVoid pvData, BOOLEAN bSet); -fcns.name{fcnNum}='SONMarkerItem'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'int16', 'uint16', 'TMarkerPtr', 'int32', 'TMarkerPtr', 'voidPtr', 'int16'};fcnNum=fcnNum+1; -% int WINAPI SONFilter(TpMarker pM, TpFilterMask pFM); -fcns.name{fcnNum}='SONFilter'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'TMarkerPtr', 'TFilterMaskPtr'};fcnNum=fcnNum+1; -% int WINAPI SONFControl(TpFilterMask pFM, int layer, int item, int set); -%fcns.name{fcnNum}='SONFControl'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'TFilterMaskPtr', 'int32', 'int32', 'int32'};fcnNum=fcnNum+1; -% BOOLEAN WINAPI SONFEqual(TpFilterMask pFiltMask1, TpFilterMask pFiltMask2); -%fcns.name{fcnNum}='SONFEqual'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int16'; fcns.RHS{fcnNum}={'TFilterMaskPtr', 'TFilterMaskPtr'};fcnNum=fcnNum+1; -% int WINAPI SONFActive(TpFilterMask pFM); -%fcns.name{fcnNum}='SONFActive'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'TFilterMaskPtr'};fcnNum=fcnNum+1; -% long WINAPI SONFMode(TpFilterMask pFM, long lNew); -%fcns.name{fcnNum}='SONFMode'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'TFilterMaskPtr', 'int32'};fcnNum=fcnNum+1; -% short WINAPI SONCreateFile(TpCStr name, int nChannels, WORD extra); -fcns.name{fcnNum}='SONCreateFile'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int16'; fcns.RHS{fcnNum}={'string', 'int32', 'uint16'};fcnNum=fcnNum+1; -% int WINAPI SONMaxChans(short fh); -fcns.name{fcnNum}='SONMaxChans'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'int16'};fcnNum=fcnNum+1; -% int WINAPI SONPhyChan(short fh, WORD wChan); -fcns.name{fcnNum}='SONPhyChan'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'int16', 'uint16'};fcnNum=fcnNum+1; -% float WINAPI SONIdealRate(short fh, WORD wChan, float fIR); -fcns.name{fcnNum}='SONIdealRate'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='single'; fcns.RHS{fcnNum}={'int16', 'uint16', 'single'};fcnNum=fcnNum+1; -% void WINAPI SONYRange(short fh, WORD chan, TpFloat pfMin, TpFloat pfMax); -fcns.name{fcnNum}='SONYRange'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}=[]; fcns.RHS{fcnNum}={'int16', 'uint16', 'singlePtr', 'singlePtr'};fcnNum=fcnNum+1; -% int WINAPI SONYRangeSet(short fh, WORD chan, float fMin, float fMax); -fcns.name{fcnNum}='SONYRangeSet'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'int16', 'uint16', 'single', 'single'};fcnNum=fcnNum+1; -% int WINAPI SONMaxItems(short fh, WORD chan); -fcns.name{fcnNum}='SONMaxItems'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'int16', 'uint16'};fcnNum=fcnNum+1; -% int WINAPI SONPhySz(short fh, WORD chan); -fcns.name{fcnNum}='SONPhySz'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'int16', 'uint16'};fcnNum=fcnNum+1; -% int WINAPI SONBlocks(short fh, WORD chan); -fcns.name{fcnNum}='SONBlocks'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'int16', 'uint16'};fcnNum=fcnNum+1; -% int WINAPI SONDelBlocks(short fh, WORD chan); -fcns.name{fcnNum}='SONDelBlocks'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'int16', 'uint16'};fcnNum=fcnNum+1; -% int WINAPI SONSetRealChan(short fh, WORD chan, short sPhyChan, TSTime dvd, long lBufSz, TpCStr szCom, TpCStr szTitle, float scale, float offset, TpCStr szUnt); -fcns.name{fcnNum}='SONSetRealChan'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'int16', 'uint16', 'int16', 'int32', 'int32', 'string', 'string', 'single', 'single', 'string'};fcnNum=fcnNum+1; -% TSTime WINAPI SONWriteRealBlock(short fh, WORD chan, TpFloat pfBuff, long count, TSTime sTime); -fcns.name{fcnNum}='SONWriteRealBlock'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'int16', 'uint16', 'singlePtr', 'int32', 'int32'};fcnNum=fcnNum+1; -% long WINAPI SONGetRealData(short fh, WORD chan, TpFloat pfData, long max, TSTime sTime,TSTime eTime,TpSTime pbTime, TpFilterMask pFiltMask); -%fcns.name{fcnNum}='SONGetRealData'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'int16', 'uint16', 'singlePtr', 'int32', 'int32', 'int32', 'int32Ptr', 'TFilterMaskPtr'};fcnNum=fcnNum+1; -% int WINAPI SONTimeDate(short fh, TSONTimeDate* pTDGet, const TSONTimeDate* pTDSet); -%fcns.name{fcnNum}='SONTimeDate'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'int16', 'TSONTimeDatePtr', 'TSONTimeDatePtr'};fcnNum=fcnNum+1; -% double WINAPI SONTimeBase(short fh, double dTB); -fcns.name{fcnNum}='SONTimeBase'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='double'; fcns.RHS{fcnNum}={'int16', 'double'};fcnNum=fcnNum+1; -% int WINAPI SONAppID(short fh, TSONCreator* pCGet, TSONCreator* pCSet); -%fcns.name{fcnNum}='SONAppID'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'int16', 'TSONCreatorPtr', 'TSONCreatorPtr'};fcnNum=fcnNum+1; -% int WINAPI SONChanInterleave(short fh, WORD chan); -fcns.name{fcnNum}='SONChanInterleave'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'int16', 'uint16'};fcnNum=fcnNum+1; -% int WINAPI SONExtMarkAlign(short fh, int n); -fcns.name{fcnNum}='SONExtMarkAlign'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'int16', 'int32'};fcnNum=fcnNum+1; -structs.TSONTimeDate.packing=8; -structs.TSONTimeDate.members=struct('ucHun', 'uint8', 'ucSec', 'uint8', 'ucMin', 'uint8', 'ucHour', 'uint8', 'ucDay', 'uint8', 'ucMon', 'uint8', 'wYear', 'uint16'); -enuminfo.TDataKind=struct('ChanOff',0,'Adc',1,'EventFall',2,'EventRise',3,'EventBoth',4,'Marker',5,'AdcMark',6,'RealMark',7,'TextMark',8,'RealWave',9); +function [methodinfo,structs,enuminfo]=son32; +% SON32 Prototype file. Create structures to define interfaces found in 'matlab'. +%This function was generated by the perl file prototypes.pl called from loadlibary.m on Tue Mar 22 18:35:30 2005 +%perl options:'matlab.i -outfile=son32.m' +% +% This file is required by the MATLAB SON Librart for Windows +% to use son32.dll +% + +ival={cell(1,0)}; % change 0 to the actual number of functions to preallocate the data. +fcns=struct('name',ival,'calltype',ival,'LHS',ival,'RHS',ival,'alias',ival); +structs=[];enuminfo=[];fcnNum=1; +% void WINAPI SONInitFiles(void); +fcns.name{fcnNum}='SONInitFiles'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}=[]; fcns.RHS{fcnNum}=[];fcnNum=fcnNum+1; +% void WINAPI SONCleanUp(void); +fcns.name{fcnNum}='SONCleanUp'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}=[]; fcns.RHS{fcnNum}=[];fcnNum=fcnNum+1; +% short WINAPI SONOpenOldFile(TpCStr name, int iOpenMode); +fcns.name{fcnNum}='SONOpenOldFile'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int16'; fcns.RHS{fcnNum}={'string', 'int32'};fcnNum=fcnNum+1; +% short WINAPI SONOpenNewFile(TpCStr name, short fMode, WORD extra); +fcns.name{fcnNum}='SONOpenNewFile'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int16'; fcns.RHS{fcnNum}={'string', 'int16', 'uint16'};fcnNum=fcnNum+1; +% BOOLEAN WINAPI SONCanWrite(short fh); +fcns.name{fcnNum}='SONCanWrite'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int16'; fcns.RHS{fcnNum}={'int16'};fcnNum=fcnNum+1; +% short WINAPI SONCloseFile(short fh); +fcns.name{fcnNum}='SONCloseFile'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int16'; fcns.RHS{fcnNum}={'int16'};fcnNum=fcnNum+1; +% short WINAPI SONEmptyFile(short fh); +fcns.name{fcnNum}='SONEmptyFile'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int16'; fcns.RHS{fcnNum}={'int16'};fcnNum=fcnNum+1; +% short WINAPI SONSetBuffSpace(short fh); +fcns.name{fcnNum}='SONSetBuffSpace'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int16'; fcns.RHS{fcnNum}={'int16'};fcnNum=fcnNum+1; +% short WINAPI SONGetFreeChan(short fh); +fcns.name{fcnNum}='SONGetFreeChan'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int16'; fcns.RHS{fcnNum}={'int16'};fcnNum=fcnNum+1; +% void WINAPI SONSetFileClock(short fh, WORD usPerTime, WORD timePerADC); +fcns.name{fcnNum}='SONSetFileClock'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}=[]; fcns.RHS{fcnNum}={'int16', 'uint16', 'uint16'};fcnNum=fcnNum+1; +% short WINAPI SONSetADCChan(short fh, WORD chan, short sPhyCh, short dvd, long lBufSz, TpCStr szCom, TpCStr szTitle, float fRate, float scl, float offs, TpCStr szUnt); +fcns.name{fcnNum}='SONSetADCChan'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int16'; fcns.RHS{fcnNum}={'int16', 'uint16', 'int16', 'int16', 'int32', 'string', 'string', 'single', 'single', 'single', 'string'};fcnNum=fcnNum+1; +% short WINAPI SONSetADCMarkChan(short fh, WORD chan, short sPhyCh, short dvd, long lBufSz, TpCStr szCom, TpCStr szTitle, float fRate, float scl, float offs, TpCStr szUnt, WORD points, short preTrig); +fcns.name{fcnNum}='SONSetADCMarkChan'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int16'; fcns.RHS{fcnNum}={'int16', 'uint16', 'int16', 'int16', 'int32', 'string', 'string', 'single', 'single', 'single', 'string', 'uint16', 'int16'};fcnNum=fcnNum+1; +% short WINAPI SONSetWaveChan(short fh, WORD chan, short sPhyCh, TSTime dvd, long lBufSz, TpCStr szCom, TpCStr szTitle, float scl, float offs, TpCStr szUnt); +fcns.name{fcnNum}='SONSetWaveChan'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int16'; fcns.RHS{fcnNum}={'int16', 'uint16', 'int16', 'int32', 'int32', 'string', 'string', 'single', 'single', 'string'};fcnNum=fcnNum+1; +% short WINAPI SONSetWaveMarkChan(short fh, WORD chan, short sPhyCh, TSTime dvd, long lBufSz, TpCStr szCom, TpCStr szTitle, float fRate, float scl, float offs, TpCStr szUnt, WORD points, short preTrig, int nTrace); +fcns.name{fcnNum}='SONSetWaveMarkChan'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int16'; fcns.RHS{fcnNum}={'int16', 'uint16', 'int16', 'int32', 'int32', 'string', 'string', 'single', 'single', 'single', 'string', 'uint16', 'int16', 'int32'};fcnNum=fcnNum+1; +% short WINAPI SONSetRealMarkChan(short fh, WORD chan, short sPhyCh, long lBufSz, TpCStr szCom, TpCStr szTitle, float fRate, float min, float max, TpCStr szUnt, WORD points); +fcns.name{fcnNum}='SONSetRealMarkChan'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int16'; fcns.RHS{fcnNum}={'int16', 'uint16', 'int16', 'int32', 'string', 'string', 'single', 'single', 'single', 'string', 'uint16'};fcnNum=fcnNum+1; +% short WINAPI SONSetTextMarkChan(short fh, WORD chan, short sPhyCh, long lBufSz, TpCStr szCom, TpCStr szTitle, float fRate, TpCStr szUnt, WORD points); +fcns.name{fcnNum}='SONSetTextMarkChan'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int16'; fcns.RHS{fcnNum}={'int16', 'uint16', 'int16', 'int32', 'string', 'string', 'single', 'string', 'uint16'};fcnNum=fcnNum+1; +% void WINAPI SONSetInitLow(short fh, WORD chan, BOOLEAN bLow); +fcns.name{fcnNum}='SONSetInitLow'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}=[]; fcns.RHS{fcnNum}={'int16', 'uint16', 'int16'};fcnNum=fcnNum+1; +% short WINAPI SONSetEventChan(short fh, WORD chan, short sPhyCh, long lBufSz, TpCStr szCom, TpCStr szTitle, float fRate, TDataKind evtKind); +fcns.name{fcnNum}='SONSetEventChan'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int16'; fcns.RHS{fcnNum}={'int16', 'uint16', 'int16', 'int32', 'string', 'string', 'single', 'TDataKind'};fcnNum=fcnNum+1; +% short WINAPI SONSetBuffering(short fh, int nChan, int nBytes); +fcns.name{fcnNum}='SONSetBuffering'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int16'; fcns.RHS{fcnNum}={'int16', 'int32', 'int32'};fcnNum=fcnNum+1; +% short WINAPI SONUpdateStart(short fh); +fcns.name{fcnNum}='SONUpdateStart'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int16'; fcns.RHS{fcnNum}={'int16'};fcnNum=fcnNum+1; +% void WINAPI SONSetFileComment(short fh, WORD which, TpCStr szFCom); +fcns.name{fcnNum}='SONSetFileComment'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}=[]; fcns.RHS{fcnNum}={'int16', 'uint16', 'string'};fcnNum=fcnNum+1; +% void WINAPI SONGetFileComment(short fh, WORD which, TpStr pcFCom, short sMax); +fcns.name{fcnNum}='SONGetFileComment'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}=[]; fcns.RHS{fcnNum}={'int16', 'uint16', 'string', 'int16'};fcnNum=fcnNum+1; +% void WINAPI SONSetChanComment(short fh, WORD chan, TpCStr szCom); +fcns.name{fcnNum}='SONSetChanComment'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}=[]; fcns.RHS{fcnNum}={'int16', 'uint16', 'string'};fcnNum=fcnNum+1; +% void WINAPI SONGetChanComment(short fh, WORD chan, TpStr pcCom, short sMax); +fcns.name{fcnNum}='SONGetChanComment'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}=[]; fcns.RHS{fcnNum}={'int16', 'uint16', 'string', 'int16'};fcnNum=fcnNum+1; +% void WINAPI SONSetChanTitle(short fh, WORD chan, TpCStr szTitle); +fcns.name{fcnNum}='SONSetChanTitle'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}=[]; fcns.RHS{fcnNum}={'int16', 'uint16', 'string'};fcnNum=fcnNum+1; +% void WINAPI SONGetChanTitle(short fh, WORD chan, TpStr pcTitle); +fcns.name{fcnNum}='SONGetChanTitle'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}=[]; fcns.RHS{fcnNum}={'int16', 'uint16', 'string'};fcnNum=fcnNum+1; +% void WINAPI SONGetIdealLimits(short fh, WORD chan, TpFloat pfRate, TpFloat pfMin, TpFloat pfMax); +fcns.name{fcnNum}='SONGetIdealLimits'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}=[]; fcns.RHS{fcnNum}={'int16', 'uint16', 'singlePtr', 'singlePtr', 'singlePtr'};fcnNum=fcnNum+1; +% WORD WINAPI SONGetusPerTime(short fh); +fcns.name{fcnNum}='SONGetusPerTime'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='uint16'; fcns.RHS{fcnNum}={'int16'};fcnNum=fcnNum+1; +% WORD WINAPI SONGetTimePerADC(short fh); +fcns.name{fcnNum}='SONGetTimePerADC'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='uint16'; fcns.RHS{fcnNum}={'int16'};fcnNum=fcnNum+1; +% void WINAPI SONSetADCUnits(short fh, WORD chan, TpCStr szUnt); +fcns.name{fcnNum}='SONSetADCUnits'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}=[]; fcns.RHS{fcnNum}={'int16', 'uint16', 'string'};fcnNum=fcnNum+1; +% void WINAPI SONSetADCOffset(short fh, WORD chan, float offset); +fcns.name{fcnNum}='SONSetADCOffset'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}=[]; fcns.RHS{fcnNum}={'int16', 'uint16', 'single'};fcnNum=fcnNum+1; +% void WINAPI SONSetADCScale(short fh, WORD chan, float scale); +fcns.name{fcnNum}='SONSetADCScale'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}=[]; fcns.RHS{fcnNum}={'int16', 'uint16', 'single'};fcnNum=fcnNum+1; +% void WINAPI SONGetADCInfo(short fh, WORD chan, TpFloat scale, TpFloat offset, TpStr pcUnt, TpWORD points, TpShort preTrig); +fcns.name{fcnNum}='SONGetADCInfo'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}=[]; fcns.RHS{fcnNum}={'int16', 'uint16', 'singlePtr', 'singlePtr', 'string', 'uint16Ptr', 'int16Ptr'};fcnNum=fcnNum+1; +% void WINAPI SONGetExtMarkInfo(short fh, WORD chan, TpStr pcUnt, TpWORD points, TpShort preTrig); +fcns.name{fcnNum}='SONGetExtMarkInfo'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}=[]; fcns.RHS{fcnNum}={'int16', 'uint16', 'string', 'uint16Ptr', 'int16Ptr'};fcnNum=fcnNum+1; +% short WINAPI SONWriteEventBlock(short fh, WORD chan, TpSTime plBuf, long count); +fcns.name{fcnNum}='SONWriteEventBlock'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int16'; fcns.RHS{fcnNum}={'int16', 'uint16', 'int32Ptr', 'int32'};fcnNum=fcnNum+1; +% short WINAPI SONWriteMarkBlock(short fh, WORD chan, TpMarker pM, long count); +fcns.name{fcnNum}='SONWriteMarkBlock'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int16'; fcns.RHS{fcnNum}={'int16', 'uint16', 'TMarkerPtr', 'int32'};fcnNum=fcnNum+1; +% TSTime WINAPI SONWriteADCBlock(short fh, WORD chan, TpAdc psBuf, long count, TSTime sTime); +fcns.name{fcnNum}='SONWriteADCBlock'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'int16', 'uint16', 'int16Ptr', 'int32', 'int32'};fcnNum=fcnNum+1; +% short WINAPI SONWriteExtMarkBlock(short fh, WORD chan, TpMarker pM, long count); +%fcns.name{fcnNum}='SONWriteExtMarkBlock'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int16'; fcns.RHS{fcnNum}={'int16', 'uint16', 'TMarkerPtr', 'int32'};fcnNum=fcnNum+1; +% short WINAPI SONSave(short fh, int nChan, TSTime sTime, BOOLEAN bKeep); +fcns.name{fcnNum}='SONSave'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int16'; fcns.RHS{fcnNum}={'int16', 'int32', 'int32', 'int16'};fcnNum=fcnNum+1; +% short WINAPI SONSaveRange(short fh, int nChan, TSTime sTime, TSTime eTime); +fcns.name{fcnNum}='SONSaveRange'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int16'; fcns.RHS{fcnNum}={'int16', 'int32', 'int32', 'int32'};fcnNum=fcnNum+1; +% short WINAPI SONKillRange(short fh, int nChan, TSTime sTime, TSTime eTime); +fcns.name{fcnNum}='SONKillRange'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int16'; fcns.RHS{fcnNum}={'int16', 'int32', 'int32', 'int32'};fcnNum=fcnNum+1; +% short WINAPI SONIsSaving(short fh, int nChan); +fcns.name{fcnNum}='SONIsSaving'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int16'; fcns.RHS{fcnNum}={'int16', 'int32'};fcnNum=fcnNum+1; +% DWORD WINAPI SONFileBytes(short fh); +fcns.name{fcnNum}='SONFileBytes'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='uint32'; fcns.RHS{fcnNum}={'int16'};fcnNum=fcnNum+1; +% DWORD WINAPI SONChanBytes(short fh, WORD chan); +fcns.name{fcnNum}='SONChanBytes'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='uint32'; fcns.RHS{fcnNum}={'int16', 'uint16'};fcnNum=fcnNum+1; +% short WINAPI SONLatestTime(short fh, WORD chan, TSTime sTime); +fcns.name{fcnNum}='SONLatestTime'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int16'; fcns.RHS{fcnNum}={'int16', 'uint16', 'int32'};fcnNum=fcnNum+1; +% short WINAPI SONCommitIdle(short fh); +fcns.name{fcnNum}='SONCommitIdle'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int16'; fcns.RHS{fcnNum}={'int16'};fcnNum=fcnNum+1; +% short WINAPI SONCommitFile(short fh, BOOLEAN bDelete); +fcns.name{fcnNum}='SONCommitFile'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int16'; fcns.RHS{fcnNum}={'int16', 'int16'};fcnNum=fcnNum+1; +% long WINAPI SONGetEventData(short fh, WORD chan, TpSTime plTimes, long max, TSTime sTime, TSTime eTime, TpBOOL levLowP, TpFilterMask pFiltMask); +%fcns.name{fcnNum}='SONGetEventData'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'int16', 'uint16', 'int32Ptr', 'int32', 'int32', 'int32', 'int16Ptr', 'TFilterMaskPtr'};fcnNum=fcnNum+1; +% long WINAPI SONGetMarkData(short fh, WORD chan,TpMarker pMark, long max, TSTime sTime,TSTime eTime, TpFilterMask pFiltMask); +%fcns.name{fcnNum}='SONGetMarkData'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'int16', 'uint16', 'TMarkerPtr', 'int32', 'int32', 'int32', 'TFilterMaskPtr'};fcnNum=fcnNum+1; +% long WINAPI SONGetADCData(short fh,WORD chan,TpAdc adcDataP, long max, TSTime sTime,TSTime eTime,TpSTime pbTime, TpFilterMask pFiltMask); +%fcns.name{fcnNum}='SONGetADCData'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'int16', 'uint16', 'int16Ptr', 'int32', 'int32', 'int32', 'int32Ptr', 'TFilterMaskPtr'};fcnNum=fcnNum+1; +% long WINAPI SONGetExtMarkData(short fh, WORD chan, TpMarker pMark, long max, TSTime sTime,TSTime eTime, TpFilterMask pFiltMask); +%fcns.name{fcnNum}='SONGetExtMarkData'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'int16', 'uint16', 'TMarkerPtr', 'int32', 'int32', 'int32', 'TFilterMaskPtr'};fcnNum=fcnNum+1; +% long WINAPI SONGetExtraDataSize(short fh); +fcns.name{fcnNum}='SONGetExtraDataSize'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'int16'};fcnNum=fcnNum+1; +% int WINAPI SONGetVersion(short fh); +fcns.name{fcnNum}='SONGetVersion'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'int16'};fcnNum=fcnNum+1; +% short WINAPI SONGetExtraData(short fh, TpVoid buff, WORD bytes, WORD offset, BOOLEAN writeIt); +fcns.name{fcnNum}='SONGetExtraData'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int16'; fcns.RHS{fcnNum}={'int16', 'voidPtr', 'uint16', 'uint16', 'int16'};fcnNum=fcnNum+1; +% short WINAPI SONSetMarker(short fh, WORD chan, TSTime time, TpMarker pMark, WORD size); +%fcns.name{fcnNum}='SONSetMarker'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int16'; fcns.RHS{fcnNum}={'int16', 'uint16', 'int32', 'TMarkerPtr', 'uint16'};fcnNum=fcnNum+1; +% short WINAPI SONChanDelete(short fh, WORD chan); +fcns.name{fcnNum}='SONChanDelete'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int16'; fcns.RHS{fcnNum}={'int16', 'uint16'};fcnNum=fcnNum+1; +% TDataKind WINAPI SONChanKind(short fh, WORD chan); +fcns.name{fcnNum}='SONChanKind'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='TDataKind'; fcns.RHS{fcnNum}={'int16', 'uint16'};fcnNum=fcnNum+1; +% TSTime WINAPI SONChanDivide(short fh, WORD chan); +fcns.name{fcnNum}='SONChanDivide'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'int16', 'uint16'};fcnNum=fcnNum+1; +% WORD WINAPI SONItemSize(short fh, WORD chan); +%fcns.name{fcnNum}='SONItemSize'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='uint16'; fcns.RHS{fcnNum}={'int16', 'uint16'};fcnNum=fcnNum+1; +% TSTime WINAPI SONChanMaxTime(short fh, WORD chan); +fcns.name{fcnNum}='SONChanMaxTime'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'int16', 'uint16'};fcnNum=fcnNum+1; +% TSTime WINAPI SONMaxTime(short fh); +fcns.name{fcnNum}='SONMaxTime'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'int16'};fcnNum=fcnNum+1; +% TSTime WINAPI SONLastTime(short fh, WORD wChan, TSTime sTime, TSTime eTime, TpVoid pvVal, TpMarkBytes pMB, TpBOOL pbMk, TpFilterMask pFiltMask); +%fcns.name{fcnNum}='SONLastTime'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'int16', 'uint16', 'int32', 'int32', 'voidPtr', 'stringPtr', 'int16Ptr', 'TFilterMaskPtr'};fcnNum=fcnNum+1; +% TSTime WINAPI SONLastPointsTime(short fh, WORD wChan, TSTime sTime, TSTime eTime, long lPoints, BOOLEAN bAdc, TpFilterMask pFiltMask); +%fcns.name{fcnNum}='SONLastPointsTime'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'int16', 'uint16', 'int32', 'int32', 'int32', 'int16', 'TFilterMaskPtr'};fcnNum=fcnNum+1; +% long WINAPI SONFileSize(short fh); +fcns.name{fcnNum}='SONFileSize'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'int16'};fcnNum=fcnNum+1; +% int WINAPI SONMarkerItem(short fh, WORD wChan, TpMarker pBuff, int n, TpMarker pM, TpVoid pvData, BOOLEAN bSet); +fcns.name{fcnNum}='SONMarkerItem'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'int16', 'uint16', 'TMarkerPtr', 'int32', 'TMarkerPtr', 'voidPtr', 'int16'};fcnNum=fcnNum+1; +% int WINAPI SONFilter(TpMarker pM, TpFilterMask pFM); +fcns.name{fcnNum}='SONFilter'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'TMarkerPtr', 'TFilterMaskPtr'};fcnNum=fcnNum+1; +% int WINAPI SONFControl(TpFilterMask pFM, int layer, int item, int set); +%fcns.name{fcnNum}='SONFControl'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'TFilterMaskPtr', 'int32', 'int32', 'int32'};fcnNum=fcnNum+1; +% BOOLEAN WINAPI SONFEqual(TpFilterMask pFiltMask1, TpFilterMask pFiltMask2); +%fcns.name{fcnNum}='SONFEqual'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int16'; fcns.RHS{fcnNum}={'TFilterMaskPtr', 'TFilterMaskPtr'};fcnNum=fcnNum+1; +% int WINAPI SONFActive(TpFilterMask pFM); +%fcns.name{fcnNum}='SONFActive'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'TFilterMaskPtr'};fcnNum=fcnNum+1; +% long WINAPI SONFMode(TpFilterMask pFM, long lNew); +%fcns.name{fcnNum}='SONFMode'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'TFilterMaskPtr', 'int32'};fcnNum=fcnNum+1; +% short WINAPI SONCreateFile(TpCStr name, int nChannels, WORD extra); +fcns.name{fcnNum}='SONCreateFile'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int16'; fcns.RHS{fcnNum}={'string', 'int32', 'uint16'};fcnNum=fcnNum+1; +% int WINAPI SONMaxChans(short fh); +fcns.name{fcnNum}='SONMaxChans'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'int16'};fcnNum=fcnNum+1; +% int WINAPI SONPhyChan(short fh, WORD wChan); +fcns.name{fcnNum}='SONPhyChan'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'int16', 'uint16'};fcnNum=fcnNum+1; +% float WINAPI SONIdealRate(short fh, WORD wChan, float fIR); +fcns.name{fcnNum}='SONIdealRate'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='single'; fcns.RHS{fcnNum}={'int16', 'uint16', 'single'};fcnNum=fcnNum+1; +% void WINAPI SONYRange(short fh, WORD chan, TpFloat pfMin, TpFloat pfMax); +fcns.name{fcnNum}='SONYRange'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}=[]; fcns.RHS{fcnNum}={'int16', 'uint16', 'singlePtr', 'singlePtr'};fcnNum=fcnNum+1; +% int WINAPI SONYRangeSet(short fh, WORD chan, float fMin, float fMax); +fcns.name{fcnNum}='SONYRangeSet'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'int16', 'uint16', 'single', 'single'};fcnNum=fcnNum+1; +% int WINAPI SONMaxItems(short fh, WORD chan); +fcns.name{fcnNum}='SONMaxItems'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'int16', 'uint16'};fcnNum=fcnNum+1; +% int WINAPI SONPhySz(short fh, WORD chan); +fcns.name{fcnNum}='SONPhySz'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'int16', 'uint16'};fcnNum=fcnNum+1; +% int WINAPI SONBlocks(short fh, WORD chan); +fcns.name{fcnNum}='SONBlocks'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'int16', 'uint16'};fcnNum=fcnNum+1; +% int WINAPI SONDelBlocks(short fh, WORD chan); +fcns.name{fcnNum}='SONDelBlocks'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'int16', 'uint16'};fcnNum=fcnNum+1; +% int WINAPI SONSetRealChan(short fh, WORD chan, short sPhyChan, TSTime dvd, long lBufSz, TpCStr szCom, TpCStr szTitle, float scale, float offset, TpCStr szUnt); +fcns.name{fcnNum}='SONSetRealChan'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'int16', 'uint16', 'int16', 'int32', 'int32', 'string', 'string', 'single', 'single', 'string'};fcnNum=fcnNum+1; +% TSTime WINAPI SONWriteRealBlock(short fh, WORD chan, TpFloat pfBuff, long count, TSTime sTime); +fcns.name{fcnNum}='SONWriteRealBlock'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'int16', 'uint16', 'singlePtr', 'int32', 'int32'};fcnNum=fcnNum+1; +% long WINAPI SONGetRealData(short fh, WORD chan, TpFloat pfData, long max, TSTime sTime,TSTime eTime,TpSTime pbTime, TpFilterMask pFiltMask); +%fcns.name{fcnNum}='SONGetRealData'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'int16', 'uint16', 'singlePtr', 'int32', 'int32', 'int32', 'int32Ptr', 'TFilterMaskPtr'};fcnNum=fcnNum+1; +% int WINAPI SONTimeDate(short fh, TSONTimeDate* pTDGet, const TSONTimeDate* pTDSet); +%fcns.name{fcnNum}='SONTimeDate'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'int16', 'TSONTimeDatePtr', 'TSONTimeDatePtr'};fcnNum=fcnNum+1; +% double WINAPI SONTimeBase(short fh, double dTB); +fcns.name{fcnNum}='SONTimeBase'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='double'; fcns.RHS{fcnNum}={'int16', 'double'};fcnNum=fcnNum+1; +% int WINAPI SONAppID(short fh, TSONCreator* pCGet, TSONCreator* pCSet); +%fcns.name{fcnNum}='SONAppID'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'int16', 'TSONCreatorPtr', 'TSONCreatorPtr'};fcnNum=fcnNum+1; +% int WINAPI SONChanInterleave(short fh, WORD chan); +fcns.name{fcnNum}='SONChanInterleave'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'int16', 'uint16'};fcnNum=fcnNum+1; +% int WINAPI SONExtMarkAlign(short fh, int n); +fcns.name{fcnNum}='SONExtMarkAlign'; fcns.calltype{fcnNum}='stdcall'; fcns.LHS{fcnNum}='int32'; fcns.RHS{fcnNum}={'int16', 'int32'};fcnNum=fcnNum+1; +structs.TSONTimeDate.packing=8; +structs.TSONTimeDate.members=struct('ucHun', 'uint8', 'ucSec', 'uint8', 'ucMin', 'uint8', 'ucHour', 'uint8', 'ucDay', 'uint8', 'ucMon', 'uint8', 'wYear', 'uint16'); +enuminfo.TDataKind=struct('ChanOff',0,'Adc',1,'EventFall',2,'EventRise',3,'EventBoth',4,'Marker',5,'AdcMark',6,'RealMark',7,'TextMark',8,'RealWave',9); methodinfo=fcns; \ No newline at end of file diff --git a/src/Import/SON/SONADCToDouble.m b/Import/SON/SONADCToDouble.m similarity index 95% rename from src/Import/SON/SONADCToDouble.m rename to Import/SON/SONADCToDouble.m index d0feb81a..011c1254 100644 --- a/src/Import/SON/SONADCToDouble.m +++ b/Import/SON/SONADCToDouble.m @@ -1,55 +1,55 @@ -function[out,h]=SONADCToDouble(in,header) -% SONADCTODOUBLE scales a SON ADC channel to double precision floating point -% -% [OUT {, HEADER}]=SONADCTODOUBLE(IN {, HEADER}) -% -% Applies the scale and offset supplied in HEADER to the data contained in -% IN. These values are derived form the channel header on disc. -% OUT=(IN*SCALE/6553.6)+OFFSET -% If no HEADER is supplied as input, a scale of 1.0 and offset of 0.0 -% are assumed. -% If supplied as output, HEADER will be updated with fields -% for the min and max values and channel kind will be replaced with 9 (i.e. -% the RealWave channel value). -% -% -% Malcolm Lidierth 03/02 -% Updated 06/05 ML -% 2002-2005 Kings College London - -if(nargin<2) - header.scale=1; - header.offset=0; -end; - -if isstruct(header) - if(isfield(header,'kind')) - if header.kind~=1 - warning('SONADCToDouble: Not an ADC channel on input'); - out=[]; - h=[]; - return; - end; - end; -end; - -if strcmp(class(in),'int16')~=1 - warning('SONADCToDouble: 16 bit integer expected'); - out=[]; - h=[]; - return; -end; - -s=header.scale/6553.6; -o=header.offset; -out=(double(in)*s)+o; - -if(nargin==2) -h=header; -end; - -if(nargout==2) -h.max=(double(max(in(:)))*s)+o; -h.min=(double(min(in(:)))*s)+o; -h.kind=9; -end; +function[out,h]=SONADCToDouble(in,header) +% SONADCTODOUBLE scales a SON ADC channel to double precision floating point +% +% [OUT {, HEADER}]=SONADCTODOUBLE(IN {, HEADER}) +% +% Applies the scale and offset supplied in HEADER to the data contained in +% IN. These values are derived form the channel header on disc. +% OUT=(IN*SCALE/6553.6)+OFFSET +% If no HEADER is supplied as input, a scale of 1.0 and offset of 0.0 +% are assumed. +% If supplied as output, HEADER will be updated with fields +% for the min and max values and channel kind will be replaced with 9 (i.e. +% the RealWave channel value). +% +% +% Malcolm Lidierth 03/02 +% Updated 06/05 ML +% 2002-2005 Kings College London + +if(nargin<2) + header.scale=1; + header.offset=0; +end; + +if isstruct(header) + if(isfield(header,'kind')) + if header.kind~=1 + warning('SONADCToDouble: Not an ADC channel on input'); + out=[]; + h=[]; + return; + end; + end; +end; + +if strcmp(class(in),'int16')~=1 + warning('SONADCToDouble: 16 bit integer expected'); + out=[]; + h=[]; + return; +end; + +s=header.scale/6553.6; +o=header.offset; +out=(double(in)*s)+o; + +if(nargin==2) +h=header; +end; + +if(nargout==2) +h.max=(double(max(in(:)))*s)+o; +h.min=(double(min(in(:)))*s)+o; +h.kind=9; +end; diff --git a/src/Import/SON/SONADCToSingle.m b/Import/SON/SONADCToSingle.m similarity index 95% rename from src/Import/SON/SONADCToSingle.m rename to Import/SON/SONADCToSingle.m index 8e25d48a..ea29209b 100644 --- a/src/Import/SON/SONADCToSingle.m +++ b/Import/SON/SONADCToSingle.m @@ -1,53 +1,53 @@ -function[out,h]=SONADCToSingle(in,header) -% SONADCTOSINGLE scales a SON ADC channel to single precision floating point -% -% [OUT {, HEADER}]=SONADCTODOUBLE(IN {, HEADER}) -% -% Applies the scale and offset supplied in HEADER to the data contained in -% IN. These values are derived form the channel header on disc. -% OUT=(IN*SCALE/6553.6)+OFFSET -% If no HEADER is supplied as input, a scale of 1.0 and offset of 0.0 -% are assumed. -% If supplied as output, HEADER will be updated with fields -% for the min and max values and channel kind will be replaced with 9 (i.e. -% the RealWave channel value). -% -% -% Malcolm Lidierth 03/02 -% Updated 06/05 ML -% 2002-2005 Kings College London - -if(nargin<2) - header.scale=1; - header.offset=0; -end; - -if isstruct(header) - if(isfield(header,'kind')) - if header.kind~=1 - warning('SONADCToDouble: Not an ADC channel on input'); - out=[]; - h=[]; - return; - end; - end; -end; - -if strcmp(class(in),'int16')~=1 - warning('SONADCToDouble: 16 bit integer expected'); - out=[]; - h=[]; - return; -end; - -out=single((double(in)*header.scale/6553.6)+header.offset); - -if(nargin==2) -h=header; -end; - -if(nargout==2) -h.max=max(out(:)); -h.min=min(out(:)); -h.kind=9; +function[out,h]=SONADCToSingle(in,header) +% SONADCTOSINGLE scales a SON ADC channel to single precision floating point +% +% [OUT {, HEADER}]=SONADCTODOUBLE(IN {, HEADER}) +% +% Applies the scale and offset supplied in HEADER to the data contained in +% IN. These values are derived form the channel header on disc. +% OUT=(IN*SCALE/6553.6)+OFFSET +% If no HEADER is supplied as input, a scale of 1.0 and offset of 0.0 +% are assumed. +% If supplied as output, HEADER will be updated with fields +% for the min and max values and channel kind will be replaced with 9 (i.e. +% the RealWave channel value). +% +% +% Malcolm Lidierth 03/02 +% Updated 06/05 ML +% 2002-2005 Kings College London + +if(nargin<2) + header.scale=1; + header.offset=0; +end; + +if isstruct(header) + if(isfield(header,'kind')) + if header.kind~=1 + warning('SONADCToDouble: Not an ADC channel on input'); + out=[]; + h=[]; + return; + end; + end; +end; + +if strcmp(class(in),'int16')~=1 + warning('SONADCToDouble: 16 bit integer expected'); + out=[]; + h=[]; + return; +end; + +out=single((double(in)*header.scale/6553.6)+header.offset); + +if(nargin==2) +h=header; +end; + +if(nargout==2) +h.max=max(out(:)); +h.min=min(out(:)); +h.kind=9; end; \ No newline at end of file diff --git a/src/Import/SON/SONChanList.m b/Import/SON/SONChanList.m similarity index 96% rename from src/Import/SON/SONChanList.m rename to Import/SON/SONChanList.m index 052edb83..6c5a75dd 100644 --- a/src/Import/SON/SONChanList.m +++ b/Import/SON/SONChanList.m @@ -1,36 +1,36 @@ -function[ChanList]=SONChanList(fid) -% SONCHANLIST returns a structure with details of active channels in a SON file -% -% LIST=SONCHANLIST(FID) -% -% FID is the file handle. -% List is a structure with field for the channel number, kind, title, -% comment and the number of physical port data were collected from - -% Malcolm Lidierth 03/02 -% Updated 06/05 ML -% 2002-2005 Kings College London - -h=SONFileHeader(fid); - -if isempty(h) - ChanList=[]; - return; -end; - -AcChan=0; -for i=1:h.channels - c=SONChannelInfo(fid,i); - if(c.kind>0) % Only look at channels that are active - AcChan=AcChan+1; - ChanList(AcChan).number=i; - ChanList(AcChan).kind=c.kind; - ChanList(AcChan).title=c.title; - ChanList(AcChan).comment=c.comment; - ChanList(AcChan).phyChan=c.phyChan; - end -end - - - - +function[ChanList]=SONChanList(fid) +% SONCHANLIST returns a structure with details of active channels in a SON file +% +% LIST=SONCHANLIST(FID) +% +% FID is the file handle. +% List is a structure with field for the channel number, kind, title, +% comment and the number of physical port data were collected from + +% Malcolm Lidierth 03/02 +% Updated 06/05 ML +% 2002-2005 Kings College London + +h=SONFileHeader(fid); + +if isempty(h) + ChanList=[]; + return; +end; + +AcChan=0; +for i=1:h.channels + c=SONChannelInfo(fid,i); + if(c.kind>0) % Only look at channels that are active + AcChan=AcChan+1; + ChanList(AcChan).number=i; + ChanList(AcChan).kind=c.kind; + ChanList(AcChan).title=c.title; + ChanList(AcChan).comment=c.comment; + ChanList(AcChan).phyChan=c.phyChan; + end +end + + + + diff --git a/src/Import/SON/SONChannelInfo.m b/Import/SON/SONChannelInfo.m similarity index 96% rename from src/Import/SON/SONChannelInfo.m rename to Import/SON/SONChannelInfo.m index dfd2c17d..e294dd84 100644 --- a/src/Import/SON/SONChannelInfo.m +++ b/Import/SON/SONChannelInfo.m @@ -1,99 +1,99 @@ -function [TChannel]= SONChannelInfo(fid,chan) -% SONCHANNELINFO reads the SON file channel header for a channel -% Output follows the CED disk header structure but a FileName field -% is added to tag the returned structure with its source file. -% -% -% INFO=SONCHANNELINFO(FID, CHAN) -% where FID is the matlab file handle and CHAN is the channel number (1-Max) -% -% Malcolm Lidierth 02/02 -% Updated 06/05 ML -% 2002-2005 Kings College London - -% Fix: -% 25/6/05 interleave and divide reads now 'int32' instead of 'int16' -% -% 1/07/05 Change -% add channel number field and return all fields for all -% channel types - -FileH=SONFileHeader(fid); % Get file header -if(FileH.channelschar')'; -fseek(fid,pointer+71,'bof'); -TChannel.maxChanTime=fread(fid,1,'int32'); -TChannel.lChanDvd=fread(fid,1,'int32'); -TChannel.phyChan=fread(fid,1,'int16'); -bytes=fread(fid,1,'uint8'); -pointer=ftell(fid); -TChannel.title=fread(fid,bytes,'char=>char')'; -fseek(fid,pointer+9,'bof'); -TChannel.idealRate=fread(fid,1,'float32'); -TChannel.kind=fread(fid,1,'uint8'); -TChannel.pad=fread(fid,1,'int8'); - -TChannel.scale=[]; -TChannel.offset=[]; -TChannel.units=[]; -TChannel.divide=[]; -TChannel.interleave=[]; -TChannel.min=[]; -TChannel.max=[]; -TChannel.initLow=[]; -TChannel.nextLow=[]; - - switch TChannel.kind - case {1,6} - TChannel.scale=fread(fid,1,'float32'); - TChannel.offset=fread(fid,1,'float32'); - bytes=fread(fid,1,'uint8'); - pointer=ftell(fid); - TChannel.units=fread(fid,bytes,'char=>char')'; - fseek(fid,pointer+5,'bof'); - if (FileH.systemID<6) - TChannel.divide=fread(fid,1,'int32'); - else - TChannel.interleave=fread(fid,1,'int32'); - end; - case {7,9} - TChannel.min=fread(fid,1,'float32'); % With test data from Spike2 v4.05 min=scale and max=offset - TChannel.max=fread(fid,1,'float32'); % as for ADC data - bytes=fread(fid,1,'uint8'); - pointer=ftell(fid); - TChannel.units=fread(fid,bytes,'char=>char')'; - fseek(fid,pointer+5,'bof'); - if (FileH.systemID<6) - TChannel.divide=fread(fid,1,'int32'); - else - TChannel.interleave=fread(fid,1,'int32'); - end; - case 4 - TChannel.initLow=fread(fid,1,'uchar'); - TChannel.nextLow=fread(fid,1,'uchar'); - end - - - - +function [TChannel]= SONChannelInfo(fid,chan) +% SONCHANNELINFO reads the SON file channel header for a channel +% Output follows the CED disk header structure but a FileName field +% is added to tag the returned structure with its source file. +% +% +% INFO=SONCHANNELINFO(FID, CHAN) +% where FID is the matlab file handle and CHAN is the channel number (1-Max) +% +% Malcolm Lidierth 02/02 +% Updated 06/05 ML +% 2002-2005 Kings College London + +% Fix: +% 25/6/05 interleave and divide reads now 'int32' instead of 'int16' +% +% 1/07/05 Change +% add channel number field and return all fields for all +% channel types + +FileH=SONFileHeader(fid); % Get file header +if(FileH.channelschar')'; +fseek(fid,pointer+71,'bof'); +TChannel.maxChanTime=fread(fid,1,'int32'); +TChannel.lChanDvd=fread(fid,1,'int32'); +TChannel.phyChan=fread(fid,1,'int16'); +bytes=fread(fid,1,'uint8'); +pointer=ftell(fid); +TChannel.title=fread(fid,bytes,'char=>char')'; +fseek(fid,pointer+9,'bof'); +TChannel.idealRate=fread(fid,1,'float32'); +TChannel.kind=fread(fid,1,'uint8'); +TChannel.pad=fread(fid,1,'int8'); + +TChannel.scale=[]; +TChannel.offset=[]; +TChannel.units=[]; +TChannel.divide=[]; +TChannel.interleave=[]; +TChannel.min=[]; +TChannel.max=[]; +TChannel.initLow=[]; +TChannel.nextLow=[]; + + switch TChannel.kind + case {1,6} + TChannel.scale=fread(fid,1,'float32'); + TChannel.offset=fread(fid,1,'float32'); + bytes=fread(fid,1,'uint8'); + pointer=ftell(fid); + TChannel.units=fread(fid,bytes,'char=>char')'; + fseek(fid,pointer+5,'bof'); + if (FileH.systemID<6) + TChannel.divide=fread(fid,1,'int32'); + else + TChannel.interleave=fread(fid,1,'int32'); + end; + case {7,9} + TChannel.min=fread(fid,1,'float32'); % With test data from Spike2 v4.05 min=scale and max=offset + TChannel.max=fread(fid,1,'float32'); % as for ADC data + bytes=fread(fid,1,'uint8'); + pointer=ftell(fid); + TChannel.units=fread(fid,bytes,'char=>char')'; + fseek(fid,pointer+5,'bof'); + if (FileH.systemID<6) + TChannel.divide=fread(fid,1,'int32'); + else + TChannel.interleave=fread(fid,1,'int32'); + end; + case 4 + TChannel.initLow=fread(fid,1,'uchar'); + TChannel.nextLow=fread(fid,1,'uchar'); + end + + + + diff --git a/src/Import/SON/SONCreateChannel.m b/Import/SON/SONCreateChannel.m similarity index 97% rename from src/Import/SON/SONCreateChannel.m rename to Import/SON/SONCreateChannel.m index 69bfaade..cd4920f2 100644 --- a/src/Import/SON/SONCreateChannel.m +++ b/Import/SON/SONCreateChannel.m @@ -1,145 +1,145 @@ -function[freechan]=SONCreateChannel(fid,SrcChan,data,dataheader) -% Obsolete function. To write to a file use the SON32 library -% -% Create a new channel in SON file fid using the existing channel SrcChan channel header as a template. -% Channel data is contained in data. If data is type int16 a new ADC channel will be written. If floating point a -% RealWave channel will be written as long as the file is of a high enough version (6 or beyond) -% Returns the SON channel number of the created channel -% -% Malcolm Lidierth 02/02 -% -%% 14/5/03 Add feature to use title from input dataheader for new channels comment -%% 21/5/03 If writing ADC data update the units field in the channel header -%% -%% -SizeOfHeader=20; -datatype=class(data); - -[filename permission]=fopen(fid); % Is the file open for writing? -if strcmp(permission,'rb+')==0 - error('SONCreateChannel: File not opened for writing'); -end; - -FileH=SONFileHeader(fid); -if (FileH.systemID<6) & (strcmp(datatype,'int16')~=1) % ... make sure it's compatible with the file - warning('SONExportChannel: SON file is below version 6. RealWave data not allowed. Use SONUpgradeToVersion6.m first'); - return; -end; - -Failed=0; -for freechan=1:FileH.channels %Find a free channel entry - Info=SONChannelInfo(fid,freechan); - if(Info.kind==0) break; - Failed=1; - end; -end; -if (Failed==1) - error('SONCreateChannel: No free space exists in the file to write a channel header'); -end; - - - -switch datatype % Check data type... -case {'int16'} - Bytes=2; %ADC -case {'single'} - Bytes=4; % RealWave -case('double') - data=single(data); % Double so convert to single for disk save and treat as RealWave - datatype='single'; - Bytes=4; -end; - - -if (nargin<=3) | (dataheader.transpose==0) % Transpose data if needed - data should be organized in column vectors - data=data'; % Transpose by default -end; - - - -S=SONChannelInfo(fid,SrcChan); -if (S.kind~=1) & (S.kind~=9) - warning('SONExportChannel: Only waveforam channels (ADC or Real) can be written'); - return; -end; - - -header=SONGetBlockHeaders(fid,SrcChan); -BlockSize=ceil(header(5,1)*Bytes/512)*512; % Find a suitable block size - must be 512 byte multiple - -% WRITE DATA -fseek(fid,0,'eof'); % Start at the end-of-file (previously deleted blocks are not used) -[rows,columns]=size(header); -written=1; -for i=1:columns % One block per column in header - p=ftell(fid); - if (i==1) % First block in channel..... - FirstBlock=p; - fwrite(fid,-1,'int32'); - else - fwrite(fid,p-BlockSize,'int32'); % ....otherwise, pointer to preceding block - end; - if (i==columns) % Lat block in channel ..... - LastBlock=p; - fwrite(fid,-1,'int32'); - else - fwrite(fid,p+BlockSize,'int32'); % ....otherwise pointer to next block - end; - fwrite(fid,header(2,i),'int32'); % Copy header data - fwrite(fid,header(3,i),'int32'); - fwrite(fid,freechan,'int16'); - fwrite(fid,header(5,i),'int16'); - count=fwrite(fid,data(written:written+header(5,i)-1),datatype); % Write data - fwrite(fid,1:(BlockSize-20)/Bytes-count,datatype); % Pad file to next block boundary - written=written+count; % Update array pointer -end; - - - -% WRITE CHANNEL HEADER -base=512+(140*(SrcChan-1)); % Move to start of source channel header entry -fseek(fid,base,'bof'); -buffer=fread(fid,140,'int8'); -base=512+(140*(freechan-1)); %Start of new channel header -fseek(fid,base,'bof'); % Duplicate channel header -fwrite(fid,buffer,'int8'); - -fseek(fid,base+6,'bof'); % Replace firstBlock and lastBlock entries -fwrite(fid,FirstBlock,'int32'); -fwrite(fid,LastBlock,'int32'); -fseek(fid,base+26,'bof'); -bytes=fread(fid,1,'uint8'); -comment=fscanf(fid,'%c',min(63,bytes)); -if(nargin==4) & (isfield(dataheader,'comment')) % 14/5/03 Add feature to use title in input dataheader - comment=['MATLAB: ' dataheader.comment]; % -else % -comment=['MATLAB:',comment]; % -end % -fseek(fid,base+26,'bof'); % -fwrite(fid,min(63,length(comment)),'uint8'); % -fwrite(fid,comment(1:min(63,length(comment))),'char'); % 14/5/03 variable length change -fseek(fid,base+106,'bof'); -fwrite(fid,-1,'int16'); % physChan=-1, not a physical channel -fseek(fid,base+122,'bof'); -switch datatype -case 'int16' - fwrite(fid,1,'uint8'); - if(nargin==4) & (isfield(dataheader,'scale')) - fseek(fid,1,'cof'); - fwrite(fid,dataheader.scale,'float32'); - fwrite(fid,dataheader.offset,'float32'); - fwrite(fid,length(dataheader.units),'uint8'); % 21/5/03 Write units field - fwrite(fid,dataheader.units,'uint8'); - end; -case 'single' - fwrite(fid,9,'uint8'); - if(nargin==4) & (isfield(dataheader,'max')) - fseek(fid,1,'cof'); - fwrite(fid,dataheader.min,'float32'); - fwrite(fid,dataheader.max,'float32'); - end; -end; - - - - +function[freechan]=SONCreateChannel(fid,SrcChan,data,dataheader) +% Obsolete function. To write to a file use the SON32 library +% +% Create a new channel in SON file fid using the existing channel SrcChan channel header as a template. +% Channel data is contained in data. If data is type int16 a new ADC channel will be written. If floating point a +% RealWave channel will be written as long as the file is of a high enough version (6 or beyond) +% Returns the SON channel number of the created channel +% +% Malcolm Lidierth 02/02 +% +%% 14/5/03 Add feature to use title from input dataheader for new channels comment +%% 21/5/03 If writing ADC data update the units field in the channel header +%% +%% +SizeOfHeader=20; +datatype=class(data); + +[filename permission]=fopen(fid); % Is the file open for writing? +if strcmp(permission,'rb+')==0 + error('SONCreateChannel: File not opened for writing'); +end; + +FileH=SONFileHeader(fid); +if (FileH.systemID<6) & (strcmp(datatype,'int16')~=1) % ... make sure it's compatible with the file + warning('SONExportChannel: SON file is below version 6. RealWave data not allowed. Use SONUpgradeToVersion6.m first'); + return; +end; + +Failed=0; +for freechan=1:FileH.channels %Find a free channel entry + Info=SONChannelInfo(fid,freechan); + if(Info.kind==0) break; + Failed=1; + end; +end; +if (Failed==1) + error('SONCreateChannel: No free space exists in the file to write a channel header'); +end; + + + +switch datatype % Check data type... +case {'int16'} + Bytes=2; %ADC +case {'single'} + Bytes=4; % RealWave +case('double') + data=single(data); % Double so convert to single for disk save and treat as RealWave + datatype='single'; + Bytes=4; +end; + + +if (nargin<=3) | (dataheader.transpose==0) % Transpose data if needed - data should be organized in column vectors + data=data'; % Transpose by default +end; + + + +S=SONChannelInfo(fid,SrcChan); +if (S.kind~=1) & (S.kind~=9) + warning('SONExportChannel: Only waveforam channels (ADC or Real) can be written'); + return; +end; + + +header=SONGetBlockHeaders(fid,SrcChan); +BlockSize=ceil(header(5,1)*Bytes/512)*512; % Find a suitable block size - must be 512 byte multiple + +% WRITE DATA +fseek(fid,0,'eof'); % Start at the end-of-file (previously deleted blocks are not used) +[rows,columns]=size(header); +written=1; +for i=1:columns % One block per column in header + p=ftell(fid); + if (i==1) % First block in channel..... + FirstBlock=p; + fwrite(fid,-1,'int32'); + else + fwrite(fid,p-BlockSize,'int32'); % ....otherwise, pointer to preceding block + end; + if (i==columns) % Lat block in channel ..... + LastBlock=p; + fwrite(fid,-1,'int32'); + else + fwrite(fid,p+BlockSize,'int32'); % ....otherwise pointer to next block + end; + fwrite(fid,header(2,i),'int32'); % Copy header data + fwrite(fid,header(3,i),'int32'); + fwrite(fid,freechan,'int16'); + fwrite(fid,header(5,i),'int16'); + count=fwrite(fid,data(written:written+header(5,i)-1),datatype); % Write data + fwrite(fid,1:(BlockSize-20)/Bytes-count,datatype); % Pad file to next block boundary + written=written+count; % Update array pointer +end; + + + +% WRITE CHANNEL HEADER +base=512+(140*(SrcChan-1)); % Move to start of source channel header entry +fseek(fid,base,'bof'); +buffer=fread(fid,140,'int8'); +base=512+(140*(freechan-1)); %Start of new channel header +fseek(fid,base,'bof'); % Duplicate channel header +fwrite(fid,buffer,'int8'); + +fseek(fid,base+6,'bof'); % Replace firstBlock and lastBlock entries +fwrite(fid,FirstBlock,'int32'); +fwrite(fid,LastBlock,'int32'); +fseek(fid,base+26,'bof'); +bytes=fread(fid,1,'uint8'); +comment=fscanf(fid,'%c',min(63,bytes)); +if(nargin==4) & (isfield(dataheader,'comment')) % 14/5/03 Add feature to use title in input dataheader + comment=['MATLAB: ' dataheader.comment]; % +else % +comment=['MATLAB:',comment]; % +end % +fseek(fid,base+26,'bof'); % +fwrite(fid,min(63,length(comment)),'uint8'); % +fwrite(fid,comment(1:min(63,length(comment))),'char'); % 14/5/03 variable length change +fseek(fid,base+106,'bof'); +fwrite(fid,-1,'int16'); % physChan=-1, not a physical channel +fseek(fid,base+122,'bof'); +switch datatype +case 'int16' + fwrite(fid,1,'uint8'); + if(nargin==4) & (isfield(dataheader,'scale')) + fseek(fid,1,'cof'); + fwrite(fid,dataheader.scale,'float32'); + fwrite(fid,dataheader.offset,'float32'); + fwrite(fid,length(dataheader.units),'uint8'); % 21/5/03 Write units field + fwrite(fid,dataheader.units,'uint8'); + end; +case 'single' + fwrite(fid,9,'uint8'); + if(nargin==4) & (isfield(dataheader,'max')) + fseek(fid,1,'cof'); + fwrite(fid,dataheader.min,'float32'); + fwrite(fid,dataheader.max,'float32'); + end; +end; + + + + diff --git a/src/Import/SON/SONFileHeader.m b/Import/SON/SONFileHeader.m similarity index 95% rename from src/Import/SON/SONFileHeader.m rename to Import/SON/SONFileHeader.m index 9094dc91..c0106536 100644 --- a/src/Import/SON/SONFileHeader.m +++ b/Import/SON/SONFileHeader.m @@ -1,63 +1,63 @@ -function [Head]=SONFileHeader(fid) -% SONFILEHEADER reads the file header for a SON file -% -% HEADER=SONFILEHEADER(FID) -% -% Used internally by the library. -% See CED documentation of SON system for details. -% -% 24/6/05 Fix filecomment - now 5x1 not 5x5 -% -% Malcolm Lidierth 03/02 -% Updated 06/05 ML -% 2002-2005 Kings College London - -try - frewind(fid); -catch - warning(['SONFileHeader:' ferror(fid) 'Invalid file handle?' ]); - Head=[]; - return; -end; - -Head.FileIdentifier=fopen(fid); -Head.systemID=fread(fid,1,'int16'); -Head.copyright=fscanf(fid,'%c',10); -Head.Creator=fscanf(fid,'%c',8); -Head.usPerTime=fread(fid,1,'int16'); -Head.timePerADC=fread(fid,1,'int16'); -Head.filestate=fread(fid,1,'int16'); -Head.firstdata=fread(fid,1,'int32'); -Head.channels=fread(fid,1,'int16'); -Head.chansize=fread(fid,1,'int16'); -Head.extraData=fread(fid,1,'int16'); -Head.buffersize=fread(fid,1,'int16'); -Head.osFormat=fread(fid,1,'int16'); -Head.maxFTime=fread(fid,1,'int32'); -Head.dTimeBase=fread(fid,1,'float64'); -if Head.systemID<6 - Head.dTimeBase=1e-6; -end; -Head.timeDate.Detail=fread(fid,6,'uint8'); -Head.timeDate.Year=fread(fid,1,'int16'); -if Head.systemID<6 - Head.timeDate.Detail=zeros(6,1); - Head.timeDate.Year=0; -end; -Head.pad=fread(fid,52,'char=>char'); -Head.fileComment=cell(5,1); - -pointer=ftell(fid); -for i=1:5 - bytes=fread(fid,1,'uint8'); - Head.fileComment{i}=fread(fid,bytes,'char=>char')'; - pointer=pointer+80; - fseek(fid,pointer,'bof'); -end; - - - - - - - +function [Head]=SONFileHeader(fid) +% SONFILEHEADER reads the file header for a SON file +% +% HEADER=SONFILEHEADER(FID) +% +% Used internally by the library. +% See CED documentation of SON system for details. +% +% 24/6/05 Fix filecomment - now 5x1 not 5x5 +% +% Malcolm Lidierth 03/02 +% Updated 06/05 ML +% 2002-2005 Kings College London + +try + frewind(fid); +catch + warning(['SONFileHeader:' ferror(fid) 'Invalid file handle?' ]); + Head=[]; + return; +end; + +Head.FileIdentifier=fopen(fid); +Head.systemID=fread(fid,1,'int16'); +Head.copyright=fscanf(fid,'%c',10); +Head.Creator=fscanf(fid,'%c',8); +Head.usPerTime=fread(fid,1,'int16'); +Head.timePerADC=fread(fid,1,'int16'); +Head.filestate=fread(fid,1,'int16'); +Head.firstdata=fread(fid,1,'int32'); +Head.channels=fread(fid,1,'int16'); +Head.chansize=fread(fid,1,'int16'); +Head.extraData=fread(fid,1,'int16'); +Head.buffersize=fread(fid,1,'int16'); +Head.osFormat=fread(fid,1,'int16'); +Head.maxFTime=fread(fid,1,'int32'); +Head.dTimeBase=fread(fid,1,'float64'); +if Head.systemID<6 + Head.dTimeBase=1e-6; +end; +Head.timeDate.Detail=fread(fid,6,'uint8'); +Head.timeDate.Year=fread(fid,1,'int16'); +if Head.systemID<6 + Head.timeDate.Detail=zeros(6,1); + Head.timeDate.Year=0; +end; +Head.pad=fread(fid,52,'char=>char'); +Head.fileComment=cell(5,1); + +pointer=ftell(fid); +for i=1:5 + bytes=fread(fid,1,'uint8'); + Head.fileComment{i}=fread(fid,bytes,'char=>char')'; + pointer=pointer+80; + fseek(fid,pointer,'bof'); +end; + + + + + + + diff --git a/src/Import/SON/SONGetADCChannel.m b/Import/SON/SONGetADCChannel.m similarity index 97% rename from src/Import/SON/SONGetADCChannel.m rename to Import/SON/SONGetADCChannel.m index 72b6edd7..a1eb79df 100644 --- a/src/Import/SON/SONGetADCChannel.m +++ b/Import/SON/SONGetADCChannel.m @@ -1,271 +1,271 @@ -function[data,h]=SONGetADCChannel(fid, chan, varargin) -% SONGETADCCHANNEL reads an ADC (waveform) channel from a SON file. -% -% [DATA {, HEADER}]=SONGETADCCHANNEL(FID, CHAN{, START{, STOP{, OPTIONS}}}) -% FID is the matlab file handle, CHAN is the channel number (1=max) -% -% [DATA, HEADER]=SONGETADCCHANNEL(FID, 1{, OPTIONS}) -% reads all the data on channel 1 -% [DATA, HEADER]=SONGETADCCHANNEL(FID, 1, 10{, OPTIONS}) -% reads disc block 10 for continuous data or epoch 10 for triggered -% data -% [DATA, HEADER]=SONGETADCCHANNEL(FID, 1, 10, 20{, OPTIONS}) -% reads disc blocks 10-20 for continuous data or epochs 10-20 -% for triggered data -% -% When present, OPTIONS must be the last input argument. Valid options -% are: -% 'ticks', 'microseconds', 'milliseconds' and 'seconds' cause times to -% be scaled to the appropriate unit (seconds by default)in HEADER -% 'scale' - calls SONADCToDouble to apply the channel scale and offset to DATA -% which will be cast to double precision -% 'progress' - causes a progress bar to be displayed during the read. -% -% Returns the signed 16 bit integer ADC values in DATA (scaled, offset and -% cast to double if 'scale' is used as an option). If present, HEADER -% will be returned with the channel header information from the file. -% -% For continuously sampled data, DATA is a simple vector. -% If sampling was triggered, DATA will be 2-dimensional matrix -% with each epoch (frame) of data in a separate row. -% -% Examples: -% [data, header]=SONGetADCChannel(fid, 1, 'ticks') -% reads all data on channel 1 returning an int16 vector or matrix -% Times in header will be in clock ticks -% -% options={'progress' 'scale' 'ticks'} -% [data, header]=SONGetADCChannel(fid, 1, 200, 399, options{:}) -% reads epochs 200-399 from channel 1 and displays a progress bar. Data is -% returned in double-precision floating point after scaling and applying -% the offset stored on disc via SONADCToDouble. If sampling was -% continuous, data will be a vector containing data blocks 200-399. -% If triggered, data will be a 200 row matrix, each row containing one -% data epoch. -% -% in this case HEADER could have the following example field values -% FileName: source filename (and path) -% system: SON version identifier -% FileChannel: Channel number in file -% phyChan: Physical (hardware) port. -% kind: 1 (or 9 if scales) - channel type identifier -% comment: Channel comment -% title: Channel title -% sampleinterval: sampling interval in seconds -% scale: e.g. 200, scaling factor used to convert to 'units' -% offset: e.g. 1 offset applied to scaled data -% units: Channel units -% npoints: e.g. [1x200 double] number of valid data points -% in each column of DATA -% mode: 'Triggered' or 'Continuous' sampling -% start: e.g [1x200 double] start time for each column in data -% in 'TimeUnits' -% stop: e.g. [1x200 double] end time for each column in data -% in 'TimeUnits' -% Epochs: a cell array e.g. {[200] [399] 'of' [961] 'epochs'} -% lists the blocks or epochs read -% TimeUnits: e.g. 'Ticks' the time units -% transpose: default 0, a flag used to indicate if the columns and -% rows of DATA have been transposed -% -% min and max fields will also be present if the data are scaled -% -% See also SONADCTODOUBLE -% -% Malcolm Lidierth 03/02 -% Updated 06/05 ML -% 2002-2005 Kings College London - - - -Info=SONChannelInfo(fid,chan); - -if isempty (Info) - data=[]; - h=[]; - return; -end; - -if Info.kind ~=1 - warning('SONGetADCChannel: Channel %d No data or wrong channel type', chan); - data=[]; - h=[]; - return; -end; - -ShowProgress=0; -ScaleData=0; -arguments=nargin; -for i=1:length(varargin) - if ischar(varargin{i}) - arguments=arguments-1; - end; - if strcmpi(varargin{i},'progress') && Info.blocks>10 - ShowProgress=1; - progbar=progressbar(0,sprintf('Analyzing %d blocks on channel %d',Info.blocks,chan),... - 'Name',sprintf('%s',fopen(fid))); - end; - if strcmpi(varargin{i},'scale') - ScaleData=1; - end; -end; - - -FileH=SONFileHeader(fid); -SizeOfHeader=20; % Block header is 20 bytes long -header=SONGetBlockHeaders(fid,chan); - - -SampleInterval=(header(3,1)-header(2,1))/(header(5,1)-1); % Sample interval in clock ticks - - -h.FileName=Info.FileName; % Set up the header information to return -h.system=['SON' num2str(FileH.systemID)]; -h.FileChannel=chan; -h.phyChan=Info.phyChan; -h.kind=Info.kind; -%h.blocks=Info.blocks; -%h.preTrig=Info.preTrig; -h.comment=Info.comment; -h.title=Info.title; -h.sampleinterval=SONGetSampleInterval(fid,chan); -h.scale=Info.scale; -h.offset=Info.offset; -h.units=Info.units; - - - -NumFrames=1; % Number of frames. Initialize to one. -Frame(1)=1; -for i=1:Info.blocks-1 % Check for discontinuities in data record - IntervalBetweenBlocks=header(2,i+1)-header(3,i); - if IntervalBetweenBlocks>SampleInterval % If true data is discontinuous (triggered) - NumFrames=NumFrames+1; % Count discontinuities (NumFrames) - Frame(i+1)=NumFrames; % Record the frame number that each block belongs to - else - Frame(i+1)=Frame(i); % Pad between discontinuities - end; -end; - - switch arguments - case {2} - FramesToReturn=NumFrames; - h.npoints=zeros(1,FramesToReturn); - startEpoch=1; %Read all data - endEpoch=Info.blocks; - case {3} - if NumFrames==1 % Read one epoch - startEpoch=varargin{1}; - endEpoch=varargin{1}; - else - FramesToReturn=1; - h.npoints=0; - startEpoch=find(Frame<=varargin{1}); - endEpoch=startEpoch(end); - startEpoch=endEpoch; - end; - case {4} - if NumFrames==1 - startEpoch=varargin{1}; % Read a range of epochs - endEpoch=varargin{2}; - else - FramesToReturn=varargin{2}-varargin{1}+1; - h.npoints=zeros(1,FramesToReturn); - startEpoch=find(Frame==varargin{1}); - startEpoch=startEpoch(1); - endEpoch=find(Frame<=varargin{2}); - endEpoch=endEpoch(end); - end; - - end; - -% Make sure we are in range if using START and STOP - if (startEpoch>Info.blocks || startEpoch>endEpoch) - data=[]; - h=[]; - close(progbar); - warning('SONGetADCChannel: Invalid START and/or STOP') - return; - end; - if endEpoch>Info.blocks - endEpoch=Info.blocks; - end; - - - - -if NumFrames==1 -%%%%%%% Continuous sampling - one frame only. Epochs correspond to blocks -%%%%%%% in the SON file - NumberOfSamples=sum(header(5,startEpoch:endEpoch)); % Sum of samples in all blocks - data=int16(zeros(1,NumberOfSamples)); % Pre-allocate memory for data - pointer=1; - - h.mode='Continuous'; - h.epochs=[startEpoch endEpoch]; - h.npoints=NumberOfSamples; - h.start=header(2,startEpoch); % Time of first data point (clock ticks) - h.stop=header(3,endEpoch); % End of data (clock ticks) - - for i=startEpoch:endEpoch - fseek(fid,header(1,i)+SizeOfHeader,'bof'); - data(pointer:pointer+header(5,i)-1)=fread(fid,header(5,i),'int16=>int16'); - pointer=pointer+header(5,i); - if ShowProgress==1 - done=(i-startEpoch)/max(1,endEpoch-startEpoch); - progressbar(done, progbar,sprintf('Reading Channel %d.... %d%% Done',chan,(int16(done*100)/5)*5)); - end; - end; -else -%%%%%%% Frame based data - multiple frames. Epochs correspond to -%%%%%%% frames of data - NumberOfSamples=sum(header(5,startEpoch:endEpoch)); % Sum of samples in required epochs - FrameLength=max(histc(Frame,startEpoch:endEpoch))... - *max(header(5,startEpoch:endEpoch));% Maximum data points to a frame - data=int16(zeros(FramesToReturn,FrameLength)); % Pre-allocate array - p=1; % Pointer into data array for each disk data block - Frame(Info.blocks+1)=-99; % Dummy entry to avoid index error in for loop - h.mode='Triggered'; - h.start(1)=header(2,startEpoch);% Time of first data point in first returned epoch (clock ticks) - index=1; %epoch counter - for i=startEpoch:endEpoch - fseek(fid,header(1,i)+SizeOfHeader,'bof'); - data(index,p:p+header(5,i)-1)=fread(fid,header(5,i),'int16=>int16'); - h.npoints(index)=h.npoints(index)+header(5,i); - if Frame(i+1)==Frame(i) - p=p+header(5,i); % Increment pointer or..... - else - h.stop(index)=header(3,i); % End time for this frame, clock ticks - if(i10 + ShowProgress=1; + progbar=progressbar(0,sprintf('Analyzing %d blocks on channel %d',Info.blocks,chan),... + 'Name',sprintf('%s',fopen(fid))); + end; + if strcmpi(varargin{i},'scale') + ScaleData=1; + end; +end; + + +FileH=SONFileHeader(fid); +SizeOfHeader=20; % Block header is 20 bytes long +header=SONGetBlockHeaders(fid,chan); + + +SampleInterval=(header(3,1)-header(2,1))/(header(5,1)-1); % Sample interval in clock ticks + + +h.FileName=Info.FileName; % Set up the header information to return +h.system=['SON' num2str(FileH.systemID)]; +h.FileChannel=chan; +h.phyChan=Info.phyChan; +h.kind=Info.kind; +%h.blocks=Info.blocks; +%h.preTrig=Info.preTrig; +h.comment=Info.comment; +h.title=Info.title; +h.sampleinterval=SONGetSampleInterval(fid,chan); +h.scale=Info.scale; +h.offset=Info.offset; +h.units=Info.units; + + + +NumFrames=1; % Number of frames. Initialize to one. +Frame(1)=1; +for i=1:Info.blocks-1 % Check for discontinuities in data record + IntervalBetweenBlocks=header(2,i+1)-header(3,i); + if IntervalBetweenBlocks>SampleInterval % If true data is discontinuous (triggered) + NumFrames=NumFrames+1; % Count discontinuities (NumFrames) + Frame(i+1)=NumFrames; % Record the frame number that each block belongs to + else + Frame(i+1)=Frame(i); % Pad between discontinuities + end; +end; + + switch arguments + case {2} + FramesToReturn=NumFrames; + h.npoints=zeros(1,FramesToReturn); + startEpoch=1; %Read all data + endEpoch=Info.blocks; + case {3} + if NumFrames==1 % Read one epoch + startEpoch=varargin{1}; + endEpoch=varargin{1}; + else + FramesToReturn=1; + h.npoints=0; + startEpoch=find(Frame<=varargin{1}); + endEpoch=startEpoch(end); + startEpoch=endEpoch; + end; + case {4} + if NumFrames==1 + startEpoch=varargin{1}; % Read a range of epochs + endEpoch=varargin{2}; + else + FramesToReturn=varargin{2}-varargin{1}+1; + h.npoints=zeros(1,FramesToReturn); + startEpoch=find(Frame==varargin{1}); + startEpoch=startEpoch(1); + endEpoch=find(Frame<=varargin{2}); + endEpoch=endEpoch(end); + end; + + end; + +% Make sure we are in range if using START and STOP + if (startEpoch>Info.blocks || startEpoch>endEpoch) + data=[]; + h=[]; + close(progbar); + warning('SONGetADCChannel: Invalid START and/or STOP') + return; + end; + if endEpoch>Info.blocks + endEpoch=Info.blocks; + end; + + + + +if NumFrames==1 +%%%%%%% Continuous sampling - one frame only. Epochs correspond to blocks +%%%%%%% in the SON file + NumberOfSamples=sum(header(5,startEpoch:endEpoch)); % Sum of samples in all blocks + data=int16(zeros(1,NumberOfSamples)); % Pre-allocate memory for data + pointer=1; + + h.mode='Continuous'; + h.epochs=[startEpoch endEpoch]; + h.npoints=NumberOfSamples; + h.start=header(2,startEpoch); % Time of first data point (clock ticks) + h.stop=header(3,endEpoch); % End of data (clock ticks) + + for i=startEpoch:endEpoch + fseek(fid,header(1,i)+SizeOfHeader,'bof'); + data(pointer:pointer+header(5,i)-1)=fread(fid,header(5,i),'int16=>int16'); + pointer=pointer+header(5,i); + if ShowProgress==1 + done=(i-startEpoch)/max(1,endEpoch-startEpoch); + progressbar(done, progbar,sprintf('Reading Channel %d.... %d%% Done',chan,(int16(done*100)/5)*5)); + end; + end; +else +%%%%%%% Frame based data - multiple frames. Epochs correspond to +%%%%%%% frames of data + NumberOfSamples=sum(header(5,startEpoch:endEpoch)); % Sum of samples in required epochs + FrameLength=max(histc(Frame,startEpoch:endEpoch))... + *max(header(5,startEpoch:endEpoch));% Maximum data points to a frame + data=int16(zeros(FramesToReturn,FrameLength)); % Pre-allocate array + p=1; % Pointer into data array for each disk data block + Frame(Info.blocks+1)=-99; % Dummy entry to avoid index error in for loop + h.mode='Triggered'; + h.start(1)=header(2,startEpoch);% Time of first data point in first returned epoch (clock ticks) + index=1; %epoch counter + for i=startEpoch:endEpoch + fseek(fid,header(1,i)+SizeOfHeader,'bof'); + data(index,p:p+header(5,i)-1)=fread(fid,header(5,i),'int16=>int16'); + h.npoints(index)=h.npoints(index)+header(5,i); + if Frame(i+1)==Frame(i) + p=p+header(5,i); % Increment pointer or..... + else + h.stop(index)=header(3,i); % End time for this frame, clock ticks + if(i10 - ShowProgress=1; - progbar=progressbar(0,sprintf('Analyzing %d blocks on channel %d',Info.blocks,chan),... - 'Name',sprintf('%s',fopen(fid))); - end; - end; -end; - -switch arguments - case {2} - startBlock=1; - endBlock=Info.blocks; - case {3} - startBlock=varargin{1}; - endBlock=varargin{1}; - otherwise - startBlock=varargin{1}; - endBlock=min(Info.blocks,varargin{2}); -end; - - -FileH=SONFileHeader(fid); -SizeOfHeader=20; % Block header is 20 bytes long -header=SONGetBlockHeaders(fid,chan); -NumberOfMarkers=sum(header(5,startBlock:endBlock)); % Sum of samples in required blocks - - -nValues=Info.nExtra/2; % 2 because 2 bytes per int16 value -data.timings=zeros(NumberOfMarkers,1); -data.markers=uint8(zeros(NumberOfMarkers,4)); -data.adc=int16(zeros(NumberOfMarkers,nValues)); - -count=1; -for block=startBlock:endBlock - fseek(fid, header(1, block)+SizeOfHeader, 'bof'); % Start of block - for i=1:header(5,block) % loop for each marker - data.timings(count)=fread(fid,1,'int32'); % Time - data.markers(count,:)=fread(fid,4,'uint8=>uint8'); % 4x marker bytes - data.adc(count,:)=fread(fid,nValues ,'int16=>int16'); - count=count+1; - end; - if ShowProgress==1 - done=(block-startBlock)/max(1,endBlock-startBlock); - progressbar(done, progbar,sprintf('Reading Channel %d.... %d%% Done',chan,(int16(done*100)/5)*5)); - end; -end - -if(nargout>1) -h.FileName=Info.FileName; % Set up the header information to return -h.system=['SON' num2str(FileH.systemID)]; -h.FileChannel=chan; -h.phyChan=Info.phyChan; -h.kind=Info.kind; -h.npoints=NumberOfMarkers; -h.values=Info.nExtra/2; -h.preTrig=Info.preTrig; -h.comment=Info.comment; -h.title=Info.title; -h.sampleinterval=SONGetSampleInterval(fid,chan); -h.scale=Info.scale; -h.offset=Info.offset; -h.units=Info.units; -if(isfield(Info,'interleave')) - h.interleave=Info.interleave; -end; -end; - -[data.timings,h.TimeUnits]=SONTicksToSeconds(fid,data.timings,varargin{:}); % Convert time -h.Epochs={startBlock endBlock 'of' Info.blocks 'blocks'}; -if ShowProgress==1 - close(progbar); - drawnow; -end; +function[data,h]=SONGetADCMarkerChannel(fid, chan, varargin) +% SONGETADCMARKERCHANNEL reads an ADCMark channel from a SON file. +% +% [DATA {, HEADER}]=SONGETADCMARKERCHANNEL(FID, CHAN{, START{, STOP{, OPTIONS}}}) +% FID is the matlab file handle, CHAN is the channel number (1=max) +% +% [DATA, HEADER]=SONGETADCMARKERCHANNEL(FID, 1{, OPTIONS}) +% reads all the data on channel 1 +% [DATA, HEADER]=SONGETADCMARKERCHANNEL(FID, 1, 10{, OPTIONS}) +% reads disc block 10 for continuous data or epoch 10 for triggered +% data +% [DATA, HEADER]=SONGETADCMARKERCHANNEL(FID, 1, 10, 20{, OPTIONS}) +% reads disc blocks 10-20 +% +% DATA is a structure with 3 fields. +% DATA.TIMINGS contains timestamps +% DATA.MARKERS contains 4 uint8 marker values for each event +% DATA.ADC contains the ADC data associated with each timestamp +% +% When present, OPTIONS must be the last input argument. Valid options +% are: +% 'ticks', 'microseconds', 'milliseconds' and 'seconds' cause times to +% be scaled to the appropriate unit (seconds by default)in HEADER +% 'scale' - calls SONADCToDouble to apply the channel scale and offset to DATA +% which will be cast to double precision +% 'progress' - causes a progress bar to be displayed during the read. +% +% Returns the signed 16 bit integer ADC values in DATA,ADC (scaled, offset and +% cast to double if 'scale' is used as an option). If present, HEADER +% will be returned with the channel header information from the file. +% +% Example: +% options={'scale' 'microseconds'} +% [data, header]=SONGetADCMarkerChannel(fid, 1, 20, 40, options{:}) +% reads blocks 20-40 from channel 1 and displays a progress bar. +% Timestamps in data.timings wil be in microseconds +% data.adc will be returned in double-precision floating point after +% scaling and applying the offset stored on disc via SONADCToDouble. +% +% in this case HEADER could have the following example field values +% FileName: 'c:\matlab704\work\02feb00.smr' +% system: 'SON4' +% FileChannel: 3 +% phyChan: -1 +% kind: 6 +% npoints: 9273 +% values: 100 +% preTrig: 10 +% comment: 'No comment' +% title: 'Memory' +% sampleinterval: 2.0000e-004 +% scale: 1 +% offset: 0 +% units: ' volt' +% interleave: [] +% TimeUnits: 'microseconds' +% Epochs: {[20] [40] 'of' [95] 'blocks'} +% transpose: 0 +% +% Malcolm Lidierth 02/02 +% Updated 09/05 ML +% 2002-2005 Kings College London + +Info=SONChannelInfo(fid,chan); + +if isempty (Info) + data=[]; + h=[]; + return; +end; + +if Info.kind ~=6 + warning('SONGetADCMarkerChannel: Channel %d No data or wrong channel type', chan); + data=[]; + h=[]; + return; +end; + +ShowProgress=0; +arguments=nargin; +for i=1:length(varargin) + if ischar(varargin{i}) + arguments=arguments-1; + if strcmpi(varargin{i},'progress') && Info.blocks>10 + ShowProgress=1; + progbar=progressbar(0,sprintf('Analyzing %d blocks on channel %d',Info.blocks,chan),... + 'Name',sprintf('%s',fopen(fid))); + end; + end; +end; + +switch arguments + case {2} + startBlock=1; + endBlock=Info.blocks; + case {3} + startBlock=varargin{1}; + endBlock=varargin{1}; + otherwise + startBlock=varargin{1}; + endBlock=min(Info.blocks,varargin{2}); +end; + + +FileH=SONFileHeader(fid); +SizeOfHeader=20; % Block header is 20 bytes long +header=SONGetBlockHeaders(fid,chan); +NumberOfMarkers=sum(header(5,startBlock:endBlock)); % Sum of samples in required blocks + + +nValues=Info.nExtra/2; % 2 because 2 bytes per int16 value +data.timings=zeros(NumberOfMarkers,1); +data.markers=uint8(zeros(NumberOfMarkers,4)); +data.adc=int16(zeros(NumberOfMarkers,nValues)); + +count=1; +for block=startBlock:endBlock + fseek(fid, header(1, block)+SizeOfHeader, 'bof'); % Start of block + for i=1:header(5,block) % loop for each marker + data.timings(count)=fread(fid,1,'int32'); % Time + data.markers(count,:)=fread(fid,4,'uint8=>uint8'); % 4x marker bytes + data.adc(count,:)=fread(fid,nValues ,'int16=>int16'); + count=count+1; + end; + if ShowProgress==1 + done=(block-startBlock)/max(1,endBlock-startBlock); + progressbar(done, progbar,sprintf('Reading Channel %d.... %d%% Done',chan,(int16(done*100)/5)*5)); + end; +end + +if(nargout>1) +h.FileName=Info.FileName; % Set up the header information to return +h.system=['SON' num2str(FileH.systemID)]; +h.FileChannel=chan; +h.phyChan=Info.phyChan; +h.kind=Info.kind; +h.npoints=NumberOfMarkers; +h.values=Info.nExtra/2; +h.preTrig=Info.preTrig; +h.comment=Info.comment; +h.title=Info.title; +h.sampleinterval=SONGetSampleInterval(fid,chan); +h.scale=Info.scale; +h.offset=Info.offset; +h.units=Info.units; +if(isfield(Info,'interleave')) + h.interleave=Info.interleave; +end; +end; + +[data.timings,h.TimeUnits]=SONTicksToSeconds(fid,data.timings,varargin{:}); % Convert time +h.Epochs={startBlock endBlock 'of' Info.blocks 'blocks'}; +if ShowProgress==1 + close(progbar); + drawnow; +end; diff --git a/src/Import/SON/SONGetBlockHeaders.m b/Import/SON/SONGetBlockHeaders.m similarity index 97% rename from src/Import/SON/SONGetBlockHeaders.m rename to Import/SON/SONGetBlockHeaders.m index c08565a6..42057d11 100644 --- a/src/Import/SON/SONGetBlockHeaders.m +++ b/Import/SON/SONGetBlockHeaders.m @@ -1,46 +1,46 @@ -function[header]=SONGetBlockHeaders(fid,chan) -% SONGETBLOCKHEADERS returns a matrix containing the SON data block headers -% in file 'fid' for channel 'chan'. -% The returned header in memory contains, for each disk block, -% a column with rows 1-5 representing: -% Offset to start of block in file -% Start time in clock ticks -% End time in clock ticks -% Chan number -% Items -% See CED documentation for details - note this header is a modified form of -% the disk header -% -% Malcolm Lidierth 02/02 -% Updated 06/05 ML -% Kings College London 2002-2005 - -succBlock=2; -Info=SONChannelInfo(fid,chan); - -if(Info.firstblock==-1) - warning('SONGetBlockHeaders: No data on channel #%d', chan); - header=[]; - return; -end; - -header=zeros(6,Info.blocks); %Pre-allocate memory for header data -fseek(fid,Info.firstblock,'bof'); % Get first data block -header(1:4,1)=fread(fid,4,'int32'); % Last and next block pointers, Start and end times in clock ticks -header(5:6,1)=fread(fid,2,'int16'); % Channel number and number of items in block - -if(header(succBlock,1)==-1) - header(1,1)=Info.firstblock; % If only one block -else - fseek(fid,header(succBlock,1),'bof'); % Loop if more blocks - for i=2:Info.blocks - header(1:4,i)=fread(fid,4,'int32'); - header(5:6,i)=fread(fid,2,'int16'); - fseek(fid,header(succBlock,i),'bof'); - header(1,i-1)=header(1,i); - end; - header(1,Info.blocks)=header(2,Info.blocks-1); % Replace predBlock for previous column -end; -header(2,:)=[]; % Delete succBlock data - - +function[header]=SONGetBlockHeaders(fid,chan) +% SONGETBLOCKHEADERS returns a matrix containing the SON data block headers +% in file 'fid' for channel 'chan'. +% The returned header in memory contains, for each disk block, +% a column with rows 1-5 representing: +% Offset to start of block in file +% Start time in clock ticks +% End time in clock ticks +% Chan number +% Items +% See CED documentation for details - note this header is a modified form of +% the disk header +% +% Malcolm Lidierth 02/02 +% Updated 06/05 ML +% Kings College London 2002-2005 + +succBlock=2; +Info=SONChannelInfo(fid,chan); + +if(Info.firstblock==-1) + warning('SONGetBlockHeaders: No data on channel #%d', chan); + header=[]; + return; +end; + +header=zeros(6,Info.blocks); %Pre-allocate memory for header data +fseek(fid,Info.firstblock,'bof'); % Get first data block +header(1:4,1)=fread(fid,4,'int32'); % Last and next block pointers, Start and end times in clock ticks +header(5:6,1)=fread(fid,2,'int16'); % Channel number and number of items in block + +if(header(succBlock,1)==-1) + header(1,1)=Info.firstblock; % If only one block +else + fseek(fid,header(succBlock,1),'bof'); % Loop if more blocks + for i=2:Info.blocks + header(1:4,i)=fread(fid,4,'int32'); + header(5:6,i)=fread(fid,2,'int16'); + fseek(fid,header(succBlock,i),'bof'); + header(1,i-1)=header(1,i); + end; + header(1,Info.blocks)=header(2,Info.blocks-1); % Replace predBlock for previous column +end; +header(2,:)=[]; % Delete succBlock data + + diff --git a/src/Import/SON/SONGetChannel.m b/Import/SON/SONGetChannel.m similarity index 95% rename from src/Import/SON/SONGetChannel.m rename to Import/SON/SONGetChannel.m index bebf78d2..fa264920 100644 --- a/src/Import/SON/SONGetChannel.m +++ b/Import/SON/SONGetChannel.m @@ -1,86 +1,86 @@ -function[data,header]=SONGetChannel(fid, chan, varargin) -% SONGETCHANNEL provides a gateway to the individual channel read functions. -% -% [DATA{, HEADER}]=SONGETCHANNEL(FID, CHAN{, OPTIONS}); -% where: -% FID is the matlab file handle -% CHAN is the channel number to read (1 to Max) -% OPTIONS if present, are a set of one or more arguments -% (see below) -% -% DATA receives the data or structure from the read operation -% HEADER, if present, receives the channel header information -% -% -% Malcolm Lidierth 02/02 -% Updated 06/05 ML -% Kings College London 2002-2005 - -SizeOfHeader=20; % Block header is 20 bytes long - -if ischar(fid)==1 - warning('SONGetChannel: expecting a file handle from fopen(), not a string "%s" on input',fid ); - data=[]; - header=[]; - return; -end; - - -[path, name, ext]=fileparts(fopen(fid)); -if strcmpi(ext,'.smr') ~=1 - warning('SONGetChannel: file handle points to "%s". \nThis is not a valid SON file',fopen(fid)); - data=[]; - header=[]; - return; -end; - - -Info=SONChannelInfo(fid,chan); -if(Info.kind==0) - warning('SONGetChannel: Channel #%d does not exist (or has been deleted)',chan); - data=[]; - header=[]; - return; -end; - -switch Info.kind -case {1} - [data,header]=SONGetADCChannel(fid,chan,varargin{:}); -case {2,3,4} - [data,header]=SONGetEventChannel(fid,chan,varargin{:}); -case {5} - [data,header]=SONGetMarkerChannel(fid,chan,varargin{:}); -case {6} - [data,header]=SONGetADCMarkerChannel(fid,chan,varargin{:}); -case {7} - [data,header]=SONGetRealMarkerChannel(fid,chan,varargin{:}); -case {8} - [data,header]=SONGetTextMarkerChannel(fid,chan,varargin{:}); -case {9} - [data,header]=SONGetRealWaveChannel(fid,chan,varargin{:}); -otherwise - warning('SONGetChannel: Channel type not supported'); - data=[]; - header=[]; - return; -end; - - -switch Info.kind -case {1,6,7,9} - if isempty(header)==0 - header.transpose=0; - end; -end; - - - - - - - - - - - - +function[data,header]=SONGetChannel(fid, chan, varargin) +% SONGETCHANNEL provides a gateway to the individual channel read functions. +% +% [DATA{, HEADER}]=SONGETCHANNEL(FID, CHAN{, OPTIONS}); +% where: +% FID is the matlab file handle +% CHAN is the channel number to read (1 to Max) +% OPTIONS if present, are a set of one or more arguments +% (see below) +% +% DATA receives the data or structure from the read operation +% HEADER, if present, receives the channel header information +% +% +% Malcolm Lidierth 02/02 +% Updated 06/05 ML +% Kings College London 2002-2005 + +SizeOfHeader=20; % Block header is 20 bytes long + +if ischar(fid)==1 + warning('SONGetChannel: expecting a file handle from fopen(), not a string "%s" on input',fid ); + data=[]; + header=[]; + return; +end; + + +[path, name, ext]=fileparts(fopen(fid)); +if strcmpi(ext,'.smr') ~=1 + warning('SONGetChannel: file handle points to "%s". \nThis is not a valid SON file',fopen(fid)); + data=[]; + header=[]; + return; +end; + + +Info=SONChannelInfo(fid,chan); +if(Info.kind==0) + warning('SONGetChannel: Channel #%d does not exist (or has been deleted)',chan); + data=[]; + header=[]; + return; +end; + +switch Info.kind +case {1} + [data,header]=SONGetADCChannel(fid,chan,varargin{:}); +case {2,3,4} + [data,header]=SONGetEventChannel(fid,chan,varargin{:}); +case {5} + [data,header]=SONGetMarkerChannel(fid,chan,varargin{:}); +case {6} + [data,header]=SONGetADCMarkerChannel(fid,chan,varargin{:}); +case {7} + [data,header]=SONGetRealMarkerChannel(fid,chan,varargin{:}); +case {8} + [data,header]=SONGetTextMarkerChannel(fid,chan,varargin{:}); +case {9} + [data,header]=SONGetRealWaveChannel(fid,chan,varargin{:}); +otherwise + warning('SONGetChannel: Channel type not supported'); + data=[]; + header=[]; + return; +end; + + +switch Info.kind +case {1,6,7,9} + if isempty(header)==0 + header.transpose=0; + end; +end; + + + + + + + + + + + + diff --git a/src/Import/SON/SONGetEventChannel.m b/Import/SON/SONGetEventChannel.m similarity index 96% rename from src/Import/SON/SONGetEventChannel.m rename to Import/SON/SONGetEventChannel.m index 665d53ee..3df85bc2 100644 --- a/src/Import/SON/SONGetEventChannel.m +++ b/Import/SON/SONGetEventChannel.m @@ -1,112 +1,112 @@ -function[data,h]=SONGetEventChannel(fid, chan, varargin) -% SONGETEVENTCHANNEL reads an event channel from a SON file -% -% DATA{, H}]=SONGETEVENTCHANNEL(FID, CHAN{, START{, STOP{, OPTIONS}}}) -% -% FID is the matlab file handle and chan is the channel number (1-max) -% If START/STOP are absent, all data is read. When present, START or -% START and STOP together set the disc blocks to read. This allows large -% data files to be read in parts. -% OPTIONS, if present, must be a cell array of strings and must be the last -% argument in the list. Valid options: -% 'ticks', 'microseconds', 'milliseconds', 'seconds' (default). Other -% options will be ignored. -% -% DATA is returned as a double precision array with the timestamps, -% in units determined by OPTIONS. H, if present, is returned with the -% channel header. -% -% e.g. -% [data,h]=SONGetEventChannel(fid, 1, 10, 11, 'microseconds') -% reads Block 10-11 of Channel 1 and returns that data in microseconds -% [data,h]=SONGetEventChannel(fid, 1, 'ticks') -% reads all blocks returning data in clock ticks -% -% See also SONGetMarkerChannel, SONGetADCMarkerChannel, -% SONGetRealMarkerChannel, SONGetTextMarkerChannel -% -% Malcolm Lidierth 02/02 -% Updated 06/05 ML -% Kings College London 2002-2005 - - -Info=SONChannelInfo(fid,chan); - -if isempty (Info) - data=[]; - h=[]; - return; -end; - -if(Info.kind < 2 || Info.kind > 4 ) - warning('SONGetEventChannel: Channel #%d No data or not an event channel',chan); - data=[]; - h=[]; - return; -end; - -FileH=SONFileHeader(fid); -SizeOfHeader=20; % Block header is 20 bytes long -header=SONGetBlockHeaders(fid,chan); - -ShowProgress=0; -arguments=nargin; -for i=1:length(varargin) - if ischar(varargin{i}) - arguments=arguments-1; - if strcmpi(varargin{i},'progress') && Info.blocks>10 - ShowProgress=1; - progbar=progressbar(0,sprintf('Analyzing %d blocks on channel %d',Info.blocks,chan),... - 'Name',sprintf('%s',fopen(fid))); - end; - end; -end; - -switch arguments - case {2} - startBlock=1; - endBlock=Info.blocks; - case {3} - startBlock=varargin{1}; - endBlock=varargin{1}; - otherwise - startBlock=varargin{1}; - endBlock=min(Info.blocks,varargin{2}); -end; - -NumberOfSamples=sum(header(5,startBlock:endBlock)); % Sum of samples in required blocks - -data=zeros(NumberOfSamples,1); % Pre-allocate memory for data -pointer=1; - -for i=startBlock:endBlock - fseek(fid,header(1,i)+SizeOfHeader,'bof'); - data(pointer:pointer+header(5,i)-1)=fread(fid,header(5,i),'int32');%Changed from single - pointer=pointer+header(5,i); - if ShowProgress==1 - done=(i-startBlock)/max(1,endBlock-startBlock); - progressbar(done, progbar,sprintf('Reading Channel %d.... %d%% Done',chan,(int16(done*100)/5)*5)); - end; -end; - - - h.FileName=Info.FileName; % Set up the header information to return - h.system=['SON' num2str(FileH.systemID)]; % if it's been requested - h.FileChannel=chan; - h.phyChan=Info.phyChan; - h.kind=Info.kind; - h.npoints=NumberOfSamples; - h.comment=Info.comment; - h.title=Info.title; - if (Info.kind==4) - h.initLow=Info.initLow; - h.nextLow=Info.nextLow; - end; - - -[data,h.TimeUnits]=SONTicksToSeconds(fid, data, varargin{:}); % Convert time -h.Epochs={startBlock endBlock 'of' Info.blocks 'blocks'}; -if ShowProgress==1 - close(progbar); - drawnow; -end; +function[data,h]=SONGetEventChannel(fid, chan, varargin) +% SONGETEVENTCHANNEL reads an event channel from a SON file +% +% DATA{, H}]=SONGETEVENTCHANNEL(FID, CHAN{, START{, STOP{, OPTIONS}}}) +% +% FID is the matlab file handle and chan is the channel number (1-max) +% If START/STOP are absent, all data is read. When present, START or +% START and STOP together set the disc blocks to read. This allows large +% data files to be read in parts. +% OPTIONS, if present, must be a cell array of strings and must be the last +% argument in the list. Valid options: +% 'ticks', 'microseconds', 'milliseconds', 'seconds' (default). Other +% options will be ignored. +% +% DATA is returned as a double precision array with the timestamps, +% in units determined by OPTIONS. H, if present, is returned with the +% channel header. +% +% e.g. +% [data,h]=SONGetEventChannel(fid, 1, 10, 11, 'microseconds') +% reads Block 10-11 of Channel 1 and returns that data in microseconds +% [data,h]=SONGetEventChannel(fid, 1, 'ticks') +% reads all blocks returning data in clock ticks +% +% See also SONGetMarkerChannel, SONGetADCMarkerChannel, +% SONGetRealMarkerChannel, SONGetTextMarkerChannel +% +% Malcolm Lidierth 02/02 +% Updated 06/05 ML +% Kings College London 2002-2005 + + +Info=SONChannelInfo(fid,chan); + +if isempty (Info) + data=[]; + h=[]; + return; +end; + +if(Info.kind < 2 || Info.kind > 4 ) + warning('SONGetEventChannel: Channel #%d No data or not an event channel',chan); + data=[]; + h=[]; + return; +end; + +FileH=SONFileHeader(fid); +SizeOfHeader=20; % Block header is 20 bytes long +header=SONGetBlockHeaders(fid,chan); + +ShowProgress=0; +arguments=nargin; +for i=1:length(varargin) + if ischar(varargin{i}) + arguments=arguments-1; + if strcmpi(varargin{i},'progress') && Info.blocks>10 + ShowProgress=1; + progbar=progressbar(0,sprintf('Analyzing %d blocks on channel %d',Info.blocks,chan),... + 'Name',sprintf('%s',fopen(fid))); + end; + end; +end; + +switch arguments + case {2} + startBlock=1; + endBlock=Info.blocks; + case {3} + startBlock=varargin{1}; + endBlock=varargin{1}; + otherwise + startBlock=varargin{1}; + endBlock=min(Info.blocks,varargin{2}); +end; + +NumberOfSamples=sum(header(5,startBlock:endBlock)); % Sum of samples in required blocks + +data=zeros(NumberOfSamples,1); % Pre-allocate memory for data +pointer=1; + +for i=startBlock:endBlock + fseek(fid,header(1,i)+SizeOfHeader,'bof'); + data(pointer:pointer+header(5,i)-1)=fread(fid,header(5,i),'int32');%Changed from single + pointer=pointer+header(5,i); + if ShowProgress==1 + done=(i-startBlock)/max(1,endBlock-startBlock); + progressbar(done, progbar,sprintf('Reading Channel %d.... %d%% Done',chan,(int16(done*100)/5)*5)); + end; +end; + + + h.FileName=Info.FileName; % Set up the header information to return + h.system=['SON' num2str(FileH.systemID)]; % if it's been requested + h.FileChannel=chan; + h.phyChan=Info.phyChan; + h.kind=Info.kind; + h.npoints=NumberOfSamples; + h.comment=Info.comment; + h.title=Info.title; + if (Info.kind==4) + h.initLow=Info.initLow; + h.nextLow=Info.nextLow; + end; + + +[data,h.TimeUnits]=SONTicksToSeconds(fid, data, varargin{:}); % Convert time +h.Epochs={startBlock endBlock 'of' Info.blocks 'blocks'}; +if ShowProgress==1 + close(progbar); + drawnow; +end; diff --git a/src/Import/SON/SONGetMarkerChannel.m b/Import/SON/SONGetMarkerChannel.m similarity index 97% rename from src/Import/SON/SONGetMarkerChannel.m rename to Import/SON/SONGetMarkerChannel.m index 96f7f4ff..5305411d 100644 --- a/src/Import/SON/SONGetMarkerChannel.m +++ b/Import/SON/SONGetMarkerChannel.m @@ -1,102 +1,102 @@ -function[data,h]=SONGetMarkerChannel(fid, chan, varargin) -% SONGETMARKERCHANNEL reads a marker channel from a SON file. -% -% [data{, h}]=SONGETMARKER(FID, CHAN) -% FID is the MATLAB file handle and CHAN is the channel number (1 to Max) -% DATA is a structure containing: -% DATA.TIMINGS: a length n vector with the marker timestamps -% DATA.MARKERS: an n x 4 array of uint8 type, containing the marker -% values -% -% When present, OPTIONS must be the last input argument. Valid options -% are: -% 'ticks', 'microseconds', 'milliseconds' and 'seconds' cause times to -% be scaled to the appropriate unit (seconds by default)in HEADER -% 'scale' - no effect -% 'progress' - causes a progress bar to be displayed during the read. -% -% -% Malcolm Lidierth 02/02 -% Updated 06/05 ML -% Kings College London 2002-2005 - -Info=SONChannelInfo(fid,chan); -if isempty (Info) - data=[]; - h=[]; - return; -end; -if(Info.kind ~= 5) - warning('SONGetMarkerChannel: Channel #%d No data or not a marker channel', chan); - data=[]; - h=[]; - return; -end; - - -FileH=SONFileHeader(fid); -SizeOfHeader=20; % Block header is 20 bytes long -header=SONGetBlockHeaders(fid,chan); - -ShowProgress=0; -arguments=nargin; -for i=1:length(varargin) - if ischar(varargin{i}) - arguments=arguments-1; - if strcmpi(varargin{i},'progress') && Info.blocks>10 - ShowProgress=1; - progbar=progressbar(0,sprintf('Analyzing %d blocks on channel %d',Info.blocks,chan),... - 'Name',sprintf('%s',fopen(fid))); - end; - end; -end; - -switch arguments - case {2} - startBlock=1; - endBlock=Info.blocks; - case {3} - startBlock=varargin{1}; - endBlock=varargin{1}; - otherwise - startBlock=varargin{1}; - endBlock=min(Info.blocks,varargin{2}); -end; - -NumberOfMarkers=sum(header(5,startBlock:endBlock)); % Sum of samples in required blocks - -data.timings=zeros(NumberOfMarkers,1); -data.markers=uint8(zeros(NumberOfMarkers,4)); - -count=1; -for block=startBlock:endBlock - fseek(fid, header(1, block)+SizeOfHeader, 'bof'); % Start of block - for i=1:header(5,block) % loop for each marker - data.timings(count)=fread(fid,1,'int32'); % Time - data.markers(count,:)=fread(fid,4,'uint8=>uint8'); % 4x marker bytes - count=count+1; - if ShowProgress==1 - done=(i-startBlock)/max(1,endBlock-startBlock); - progressbar(done, progbar,sprintf('Reading Channel %d.... %d%% Done',chan,(int16(done*100)/5)*5)); - end; - end; -end - - -if(nargout>1) - h.FileName=Info.FileName; % Set up the header information to return - h.system=['SON' num2str(FileH.systemID)]; % if it's been requested - h.FileChannel=chan; - h.phyChan=Info.phyChan; - h.kind=Info.kind; - h.npoints=NumberOfMarkers; - h.comment=Info.comment; - h.title=Info.title; -end; - -[data.timings,h.TimeUnits]=SONTicksToSeconds(fid,data.timings, varargin{:}); % Convert time -h.Epochs={startBlock endBlock 'of' Info.blocks 'blocks'}; -if ShowProgress==1 - close(progbar); - drawnow; -end; +function[data,h]=SONGetMarkerChannel(fid, chan, varargin) +% SONGETMARKERCHANNEL reads a marker channel from a SON file. +% +% [data{, h}]=SONGETMARKER(FID, CHAN) +% FID is the MATLAB file handle and CHAN is the channel number (1 to Max) +% DATA is a structure containing: +% DATA.TIMINGS: a length n vector with the marker timestamps +% DATA.MARKERS: an n x 4 array of uint8 type, containing the marker +% values +% +% When present, OPTIONS must be the last input argument. Valid options +% are: +% 'ticks', 'microseconds', 'milliseconds' and 'seconds' cause times to +% be scaled to the appropriate unit (seconds by default)in HEADER +% 'scale' - no effect +% 'progress' - causes a progress bar to be displayed during the read. +% +% +% Malcolm Lidierth 02/02 +% Updated 06/05 ML +% Kings College London 2002-2005 + +Info=SONChannelInfo(fid,chan); +if isempty (Info) + data=[]; + h=[]; + return; +end; +if(Info.kind ~= 5) + warning('SONGetMarkerChannel: Channel #%d No data or not a marker channel', chan); + data=[]; + h=[]; + return; +end; + + +FileH=SONFileHeader(fid); +SizeOfHeader=20; % Block header is 20 bytes long +header=SONGetBlockHeaders(fid,chan); + +ShowProgress=0; +arguments=nargin; +for i=1:length(varargin) + if ischar(varargin{i}) + arguments=arguments-1; + if strcmpi(varargin{i},'progress') && Info.blocks>10 + ShowProgress=1; + progbar=progressbar(0,sprintf('Analyzing %d blocks on channel %d',Info.blocks,chan),... + 'Name',sprintf('%s',fopen(fid))); + end; + end; +end; + +switch arguments + case {2} + startBlock=1; + endBlock=Info.blocks; + case {3} + startBlock=varargin{1}; + endBlock=varargin{1}; + otherwise + startBlock=varargin{1}; + endBlock=min(Info.blocks,varargin{2}); +end; + +NumberOfMarkers=sum(header(5,startBlock:endBlock)); % Sum of samples in required blocks + +data.timings=zeros(NumberOfMarkers,1); +data.markers=uint8(zeros(NumberOfMarkers,4)); + +count=1; +for block=startBlock:endBlock + fseek(fid, header(1, block)+SizeOfHeader, 'bof'); % Start of block + for i=1:header(5,block) % loop for each marker + data.timings(count)=fread(fid,1,'int32'); % Time + data.markers(count,:)=fread(fid,4,'uint8=>uint8'); % 4x marker bytes + count=count+1; + if ShowProgress==1 + done=(i-startBlock)/max(1,endBlock-startBlock); + progressbar(done, progbar,sprintf('Reading Channel %d.... %d%% Done',chan,(int16(done*100)/5)*5)); + end; + end; +end + + +if(nargout>1) + h.FileName=Info.FileName; % Set up the header information to return + h.system=['SON' num2str(FileH.systemID)]; % if it's been requested + h.FileChannel=chan; + h.phyChan=Info.phyChan; + h.kind=Info.kind; + h.npoints=NumberOfMarkers; + h.comment=Info.comment; + h.title=Info.title; +end; + +[data.timings,h.TimeUnits]=SONTicksToSeconds(fid,data.timings, varargin{:}); % Convert time +h.Epochs={startBlock endBlock 'of' Info.blocks 'blocks'}; +if ShowProgress==1 + close(progbar); + drawnow; +end; diff --git a/src/Import/SON/SONGetRealMarkerChannel.m b/Import/SON/SONGetRealMarkerChannel.m similarity index 96% rename from src/Import/SON/SONGetRealMarkerChannel.m rename to Import/SON/SONGetRealMarkerChannel.m index fc91f0fb..3db87ecc 100644 --- a/src/Import/SON/SONGetRealMarkerChannel.m +++ b/Import/SON/SONGetRealMarkerChannel.m @@ -1,124 +1,124 @@ -function[data,h]=SONGetRealMarkerChannel(fid, chan, varargin) -% SONGETREALMARKERCHANNEL reads an RealMark channel from a SON file. -% -% [DATA {, HEADER}]=SONGETREALMARKERCHANNEL(FID, CHAN{, START{, STOP{, OPTIONS}}}) -% FID is the matlab file handle, CHAN is the channel number (1=max) -% -% [DATA, HEADER]=SONGETREALMARKERCHANNEL(FID, 1{, OPTIONS}) -% reads all the data on channel 1 -% [DATA, HEADER]=SONGETREALMARKERCHANNEL(FID, 1, 10{, OPTIONS}) -% reads disc block 10 for continuous data or epoch 10 for triggered -% data -% [DATA, HEADER]=SONGETREALMARKERCHANNEL(FID, 1, 10, 20{, OPTIONS}) -% reads disc blocks 10-20 -% -% DATA is a structure with 3 fields. -% DATA.TIMINGS contains timestamps -% DATA.MARKERS contains 4 uint8 marker values for each event -% DATA.ADC contains the realwave data associated with each timestamp -% -% When present, OPTIONS must be the last input argument. Valid options -% are: -% 'ticks', 'microseconds', 'milliseconds' and 'seconds' cause times to -% be scaled to the appropriate unit (seconds by default)in HEADER -% 'scale' - no effects -% 'progress' - causes a progress bar to be displayed during the read. -% -% -% Malcolm Lidierth 02/02 -% Updated 09/05 ML -% 2002-2005 Kings College London - - -Info=SONChannelInfo(fid,chan); - -if isempty (Info) - data=[]; - h=[]; - return; -end; - -if(Info.kind~=7) - warning('SONGetRealMarkerChannel: Channel %d No data or wrong channel type',chan); - return; -end; - - -ShowProgress=0; -arguments=nargin; -for i=1:length(varargin) - if ischar(varargin{i}) - arguments=arguments-1; - if strcmpi(varargin{i},'progress') && Info.blocks>10 - ShowProgress=1; - progbar=progressbar(0,sprintf('Analyzing %d blocks on channel %d',Info.blocks,chan),... - 'Name',sprintf('%s',fopen(fid))); - end; - end; -end; - -switch arguments - case {2} - startBlock=1; - endBlock=Info.blocks; - case {3} - startBlock=varargin{1}; - endBlock=varargin{1}; - otherwise - startBlock=varargin{1}; - endBlock=min(Info.blocks,varargin{2}); -end; - - -FileH=SONFileHeader(fid); -SizeOfHeader=20; % Block header is 20 bytes long -header=SONGetBlockHeaders(fid,chan); -NumberOfMarkers=sum(header(5,startBlock:endBlock)); % Sum of samples in required blocks - -nValues=Info.nExtra/4; % Each value has 4 bytes (single precision) -data.timings=zeros(NumberOfMarkers,1); -data.markers=char(zeros(NumberOfMarkers,4)); -data.real=single(zeros(NumberOfMarkers,nValues)); - -count=1; -for block=startBlock:endBlock - fseek(fid, header(1, block)+SizeOfHeader, 'bof'); % Start of block - for i=1:header(5,block) % loop for each marker - data.timings(count)=fread(fid,1,'int32'); % Time - data.markers(count,:)=fread(fid,4,'uint8=>uint8'); % 4x marker bytes - data.real(count,:)=fread(fid,nValues,'single=>single'); - count=count+1; - end; - if ShowProgress==1 - done=(block-startBlock)/max(1,endBlock-startBlock); - progressbar(done, progbar,sprintf('Reading Channel %d.... %d%% Done',chan,(int16(done*100)/5)*5)); - end; -end; - - -if(nargout>1) - h.FileName=Info.FileName; % Set up the header information to return - h.system=['SON' num2str(FileH.systemID)]; - h.FileChannel=chan; - h.phyChan=Info.phyChan; - h.kind=Info.kind; - h.npoints=NumberOfMarkers; - h.values=Info.nExtra/4; - h.preTrig=Info.preTrig; - h.comment=Info.comment; - h.title=Info.title; - h.sampleinterval=SONGetSampleInterval(fid,chan); - h.min=Info.min; - h.max=Info.max; - h.units=Info.units; - if(isfield(Info,'interleave')) - h.interleave=Info.interleave; - end; -end; - -[data.timings,h.TimeUnits]=SONTicksToSeconds(fid,data.timings,varargin{:}); % Convert time -h.Epochs={startBlock endBlock 'of' Info.blocks 'blocks'}; -if ShowProgress==1 - close(progbar); - drawnow; +function[data,h]=SONGetRealMarkerChannel(fid, chan, varargin) +% SONGETREALMARKERCHANNEL reads an RealMark channel from a SON file. +% +% [DATA {, HEADER}]=SONGETREALMARKERCHANNEL(FID, CHAN{, START{, STOP{, OPTIONS}}}) +% FID is the matlab file handle, CHAN is the channel number (1=max) +% +% [DATA, HEADER]=SONGETREALMARKERCHANNEL(FID, 1{, OPTIONS}) +% reads all the data on channel 1 +% [DATA, HEADER]=SONGETREALMARKERCHANNEL(FID, 1, 10{, OPTIONS}) +% reads disc block 10 for continuous data or epoch 10 for triggered +% data +% [DATA, HEADER]=SONGETREALMARKERCHANNEL(FID, 1, 10, 20{, OPTIONS}) +% reads disc blocks 10-20 +% +% DATA is a structure with 3 fields. +% DATA.TIMINGS contains timestamps +% DATA.MARKERS contains 4 uint8 marker values for each event +% DATA.ADC contains the realwave data associated with each timestamp +% +% When present, OPTIONS must be the last input argument. Valid options +% are: +% 'ticks', 'microseconds', 'milliseconds' and 'seconds' cause times to +% be scaled to the appropriate unit (seconds by default)in HEADER +% 'scale' - no effects +% 'progress' - causes a progress bar to be displayed during the read. +% +% +% Malcolm Lidierth 02/02 +% Updated 09/05 ML +% 2002-2005 Kings College London + + +Info=SONChannelInfo(fid,chan); + +if isempty (Info) + data=[]; + h=[]; + return; +end; + +if(Info.kind~=7) + warning('SONGetRealMarkerChannel: Channel %d No data or wrong channel type',chan); + return; +end; + + +ShowProgress=0; +arguments=nargin; +for i=1:length(varargin) + if ischar(varargin{i}) + arguments=arguments-1; + if strcmpi(varargin{i},'progress') && Info.blocks>10 + ShowProgress=1; + progbar=progressbar(0,sprintf('Analyzing %d blocks on channel %d',Info.blocks,chan),... + 'Name',sprintf('%s',fopen(fid))); + end; + end; +end; + +switch arguments + case {2} + startBlock=1; + endBlock=Info.blocks; + case {3} + startBlock=varargin{1}; + endBlock=varargin{1}; + otherwise + startBlock=varargin{1}; + endBlock=min(Info.blocks,varargin{2}); +end; + + +FileH=SONFileHeader(fid); +SizeOfHeader=20; % Block header is 20 bytes long +header=SONGetBlockHeaders(fid,chan); +NumberOfMarkers=sum(header(5,startBlock:endBlock)); % Sum of samples in required blocks + +nValues=Info.nExtra/4; % Each value has 4 bytes (single precision) +data.timings=zeros(NumberOfMarkers,1); +data.markers=char(zeros(NumberOfMarkers,4)); +data.real=single(zeros(NumberOfMarkers,nValues)); + +count=1; +for block=startBlock:endBlock + fseek(fid, header(1, block)+SizeOfHeader, 'bof'); % Start of block + for i=1:header(5,block) % loop for each marker + data.timings(count)=fread(fid,1,'int32'); % Time + data.markers(count,:)=fread(fid,4,'uint8=>uint8'); % 4x marker bytes + data.real(count,:)=fread(fid,nValues,'single=>single'); + count=count+1; + end; + if ShowProgress==1 + done=(block-startBlock)/max(1,endBlock-startBlock); + progressbar(done, progbar,sprintf('Reading Channel %d.... %d%% Done',chan,(int16(done*100)/5)*5)); + end; +end; + + +if(nargout>1) + h.FileName=Info.FileName; % Set up the header information to return + h.system=['SON' num2str(FileH.systemID)]; + h.FileChannel=chan; + h.phyChan=Info.phyChan; + h.kind=Info.kind; + h.npoints=NumberOfMarkers; + h.values=Info.nExtra/4; + h.preTrig=Info.preTrig; + h.comment=Info.comment; + h.title=Info.title; + h.sampleinterval=SONGetSampleInterval(fid,chan); + h.min=Info.min; + h.max=Info.max; + h.units=Info.units; + if(isfield(Info,'interleave')) + h.interleave=Info.interleave; + end; +end; + +[data.timings,h.TimeUnits]=SONTicksToSeconds(fid,data.timings,varargin{:}); % Convert time +h.Epochs={startBlock endBlock 'of' Info.blocks 'blocks'}; +if ShowProgress==1 + close(progbar); + drawnow; end; \ No newline at end of file diff --git a/src/Import/SON/SONGetRealWaveChannel.m b/Import/SON/SONGetRealWaveChannel.m similarity index 97% rename from src/Import/SON/SONGetRealWaveChannel.m rename to Import/SON/SONGetRealWaveChannel.m index 8251cba0..9bc040de 100644 --- a/src/Import/SON/SONGetRealWaveChannel.m +++ b/Import/SON/SONGetRealWaveChannel.m @@ -1,258 +1,258 @@ -function[data,h]=SONGetRealWaveChannel(fid, chan, varargin) -% SONGETREALWAVECHANNEL reads an ADC (waveform) channel from a SON file. -% -% [DATA {, HEADER}]=SONGETREALWAVECHANNEL(FID,... -% CHAN{, START{, STOP{, OPTIONS}}}) -% FID is the matlab file handle, CHAN is the channel number (1=max) -% -% [DATA, HEADER]=SONGETREALWAVECHANNEL(FID, 1{, OPTIONS}) -% reads all the data on channel 1 -% [DATA, HEADER]=SONGETREALWAVECHANNEL(FID, 1, 10{, OPTIONS}) -% reads disc block 10 for continuous data or epoch 10 for triggered -% data -% [DATA, HEADER]=SONGETREALWAVECHANNEL(FID, 1, 10, 20{, OPTIONS}) -% reads disc blocks 10-20 for continuous data or epochs 10-20 -% for triggered data -% -% When present, OPTIONS must be the last input argument. Valid options -% are: -% 'ticks', 'microseconds', 'milliseconds' and 'seconds' cause times to -% be scaled to the appropriate unit (seconds by default)in HEADER -% 'progress' - causes a progress bar to be displayed during the read. -% -% Returns the signed 16 bit integer ADC values in DATA (scaled, offset and -% cast to double if 'scale' is used as an option). If present, HEADER -% will be returned with the channel header information from the file. -% -% For continuously sampled data, DATA is a simple vector. -% If sampling was triggered, DATA will be 2-dimensional matrix -% with each epoch (frame) of data in a separate row. -% -% Examples: -% [data, header]=SONGetADCChannel(fid, 1, 'ticks') -% reads all data on channel 1 returning an int16 vector or matrix -% Times in header will be in clock ticks -% -% options={'progress' 'ticks'} -% [data, header]=SONGetRealWaveChannel(fid, 1, 200, 399, options{:}) -% reads epochs 200-399 from channel 1 and displays a progress bar. Data is -% returned in double-precision floating point. If sampling was -% continuous, data will be a vector containing data blocks 200-399. -% If triggered, data will be a 200 row matrix, each row containing one -% data epoch. -% -% in this case HEADER could have the following example field values -% FileName: source filename (and path) -% system: SON version identifier -% FileChannel: Channel number in file -% phyChan: Physical (hardware) port. -% kind: 9 - channel type identifier -% comment: Channel comment -% title: Channel title -% sampleinterval: sampling interval in seconds -% min: minimum value loaded -% max: maximum value loaded -% units: Channel units -% npoints: e.g. [1x200 double] number of valid data points -% in each column of DATA -% mode: 'Triggered' or 'Continuous' sampling -% start: e.g [1x200 double] start time for each column in data -% in 'TimeUnits' -% stop: e.g. [1x200 double] end time for each column in data -% in 'TimeUnits' -% Epochs: e.g. {[200] [399] 'of' [961] 'epochs'} lists the -% blocks or epochs read -% TimeUnits: e.g. 'Ticks' the time units -% transpose: default 0, a flag used to indicate if the columns and -% rows of DATA have been transposed -% -% See also SONGetADCChannel -% -% Malcolm Lidierth 03/02 -% Updated 06/05 ML -% Kings College London 2002-2005 - - - -Info=SONChannelInfo(fid,chan); -if isempty (Info) - data=[]; - h=[]; - return; -end; - -if Info.kind ~=9 - warning('SONGetRealWaveChannel: Channel #%d No data or not a RealWave channel',chan); - data=[]; - h=[]; - return; -end; - -ShowProgress=0; -ScaleData=0; -arguments=nargin; -for i=1:length(varargin) - if ischar(varargin{i}) - arguments=arguments-1; - if strcmpi(varargin{i},'progress') && Info.blocks>10 - ShowProgress=1; - progbar=progressbar(0,sprintf('Analyzing %d blocks on channel %d',Info.blocks,chan),... - 'Name',sprintf('%s',fopen(fid))); - end; - end; -end; - -FileH=SONFileHeader(fid); -SizeOfHeader=20; % Block header is 20 bytes long -header=SONGetBlockHeaders(fid,chan); - - -SampleInterval=(header(3,1)-header(2,1))/(header(5,1)-1); % Sample interval in clock ticks - -if(nargout>1) -h.FileName=Info.FileName; % Set up the header information to return -h.system=['SON' num2str(FileH.systemID)]; % if wanted -h.FileChannel=chan; -h.phyChan=Info.phyChan; -h.kind=Info.kind; -%h.blocks=Info.blocks; -%h.preTrig=Info.preTrig; -h.comment=Info.comment; -h.title=Info.title; -h.sampleinterval=SONGetSampleInterval(fid,chan); -h.min=Info.min; -h.max=Info.max; -h.units=Info.units; -end; - - -NumFrames=1; % Number of frames. Initialize to one. -Frame(1)=1; -for i=1:Info.blocks-1 % Check for discontinuities in data record - IntervalBetweenBlocks=header(2,i+1)-header(3,i); - if IntervalBetweenBlocks>SampleInterval % If true data is discontinuous (triggered) - NumFrames=NumFrames+1; % Count discontinuities (NumFrames) - Frame(i+1)=NumFrames; % Record the frame number that each block belongs to - else - Frame(i+1)=Frame(i); % Pad between discontinuities - end; -end; - - switch arguments - case {2} - FramesToReturn=NumFrames; - h.npoints=zeros(1,FramesToReturn); - startEpoch=1; %Read all data - endEpoch=Info.blocks; - case {3} - if NumFrames==1 % Read one epoch - startEpoch=varargin{1}; - endEpoch=varargin{1}; - else - FramesToReturn=1; - h.npoints=0; - startEpoch=find(Frame<=varargin{1}); - endEpoch=startEpoch(end); - startEpoch=endEpoch; - end; - case {4} - if NumFrames==1 - startEpoch=varargin{1}; % Read a range of epochs - endEpoch=varargin{2}; - else - FramesToReturn=varargin{2}-varargin{1}+1; - h.npoints=zeros(1,FramesToReturn); - startEpoch=find(Frame==varargin{1}); - startEpoch=startEpoch(1); - endEpoch=find(Frame<=varargin{2}); - endEpoch=endEpoch(end); - end; - - end; - -% Make sure we are in range if using START and STOP - if (startEpoch>Info.blocks || startEpoch>endEpoch) - data=[]; - h=[]; - close(progbar); - warning('SONGetADCChannel: Invalid START and/or STOP') - return; - end; - if endEpoch>Info.blocks - endEpoch=Info.blocks; - end; - - -if NumFrames==1 -%%%%%%% Continuous sampling - one frame only. Epochs correspond to blocks -%%%%%%% in the SON file - NumberOfSamples=sum(header(5,startEpoch:endEpoch)); % Sum of samples in all blocks - data=single(zeros(1,NumberOfSamples)); % Pre-allocate memory for data - pointer=1; - - h.mode='Continuous'; - h.epochs=[startEpoch endEpoch]; - h.npoints=NumberOfSamples; - h.start=header(2,startEpoch); % Time of first data point (clock ticks) - h.stop=header(3,endEpoch); % End of data (clock ticks) - - for i=startEpoch:endEpoch - fseek(fid,header(1,i)+SizeOfHeader,'bof'); - data(pointer:pointer+header(5,i)-1)=fread(fid,header(5,i),'float32=>float32'); - pointer=pointer+header(5,i); - if ShowProgress==1 - done=(i-startEpoch)/max(1,endEpoch-startEpoch); - progressbar(done, progbar,sprintf('Reading Channel %d %d%%',chan,(int16(done*100)/10)*10)); - end; - end; -else -%%%%%%% Frame based data - multiple frames. Epochs correspond to -%%%%%%% frames of data - NumberOfSamples=sum(header(5,startEpoch:endEpoch)); % Sum of samples in required epochs - FrameLength=max(histc(Frame,startEpoch:endEpoch))... - *max(header(5,startEpoch:endEpoch));% Maximum data points to a frame - data=single(zeros(FramesToReturn,FrameLength)); % Pre-allocate array - p=1; % Pointer into data array for each disk data block - Frame(Info.blocks+1)=-99; % Dummy entry to avoid index error in for loop - h.mode='Triggered'; - h.start(1)=header(2,startEpoch);% Time of first data point in first returned epoch (clock ticks) - index=1; %epoch counter - for i=startEpoch:endEpoch - fseek(fid,header(1,i)+SizeOfHeader,'bof'); - data(index,p:p+header(5,i)-1)=fread(fid,header(5,i),'float32=>float32'); - h.npoints(index)=h.npoints(index)+header(5,i); - if Frame(i+1)==Frame(i) - p=p+header(5,i); % Increment pointer or..... - else - h.stop(index)=header(3,i); % End time for this frame, clock ticks - if(i10 + ShowProgress=1; + progbar=progressbar(0,sprintf('Analyzing %d blocks on channel %d',Info.blocks,chan),... + 'Name',sprintf('%s',fopen(fid))); + end; + end; +end; + +FileH=SONFileHeader(fid); +SizeOfHeader=20; % Block header is 20 bytes long +header=SONGetBlockHeaders(fid,chan); + + +SampleInterval=(header(3,1)-header(2,1))/(header(5,1)-1); % Sample interval in clock ticks + +if(nargout>1) +h.FileName=Info.FileName; % Set up the header information to return +h.system=['SON' num2str(FileH.systemID)]; % if wanted +h.FileChannel=chan; +h.phyChan=Info.phyChan; +h.kind=Info.kind; +%h.blocks=Info.blocks; +%h.preTrig=Info.preTrig; +h.comment=Info.comment; +h.title=Info.title; +h.sampleinterval=SONGetSampleInterval(fid,chan); +h.min=Info.min; +h.max=Info.max; +h.units=Info.units; +end; + + +NumFrames=1; % Number of frames. Initialize to one. +Frame(1)=1; +for i=1:Info.blocks-1 % Check for discontinuities in data record + IntervalBetweenBlocks=header(2,i+1)-header(3,i); + if IntervalBetweenBlocks>SampleInterval % If true data is discontinuous (triggered) + NumFrames=NumFrames+1; % Count discontinuities (NumFrames) + Frame(i+1)=NumFrames; % Record the frame number that each block belongs to + else + Frame(i+1)=Frame(i); % Pad between discontinuities + end; +end; + + switch arguments + case {2} + FramesToReturn=NumFrames; + h.npoints=zeros(1,FramesToReturn); + startEpoch=1; %Read all data + endEpoch=Info.blocks; + case {3} + if NumFrames==1 % Read one epoch + startEpoch=varargin{1}; + endEpoch=varargin{1}; + else + FramesToReturn=1; + h.npoints=0; + startEpoch=find(Frame<=varargin{1}); + endEpoch=startEpoch(end); + startEpoch=endEpoch; + end; + case {4} + if NumFrames==1 + startEpoch=varargin{1}; % Read a range of epochs + endEpoch=varargin{2}; + else + FramesToReturn=varargin{2}-varargin{1}+1; + h.npoints=zeros(1,FramesToReturn); + startEpoch=find(Frame==varargin{1}); + startEpoch=startEpoch(1); + endEpoch=find(Frame<=varargin{2}); + endEpoch=endEpoch(end); + end; + + end; + +% Make sure we are in range if using START and STOP + if (startEpoch>Info.blocks || startEpoch>endEpoch) + data=[]; + h=[]; + close(progbar); + warning('SONGetADCChannel: Invalid START and/or STOP') + return; + end; + if endEpoch>Info.blocks + endEpoch=Info.blocks; + end; + + +if NumFrames==1 +%%%%%%% Continuous sampling - one frame only. Epochs correspond to blocks +%%%%%%% in the SON file + NumberOfSamples=sum(header(5,startEpoch:endEpoch)); % Sum of samples in all blocks + data=single(zeros(1,NumberOfSamples)); % Pre-allocate memory for data + pointer=1; + + h.mode='Continuous'; + h.epochs=[startEpoch endEpoch]; + h.npoints=NumberOfSamples; + h.start=header(2,startEpoch); % Time of first data point (clock ticks) + h.stop=header(3,endEpoch); % End of data (clock ticks) + + for i=startEpoch:endEpoch + fseek(fid,header(1,i)+SizeOfHeader,'bof'); + data(pointer:pointer+header(5,i)-1)=fread(fid,header(5,i),'float32=>float32'); + pointer=pointer+header(5,i); + if ShowProgress==1 + done=(i-startEpoch)/max(1,endEpoch-startEpoch); + progressbar(done, progbar,sprintf('Reading Channel %d %d%%',chan,(int16(done*100)/10)*10)); + end; + end; +else +%%%%%%% Frame based data - multiple frames. Epochs correspond to +%%%%%%% frames of data + NumberOfSamples=sum(header(5,startEpoch:endEpoch)); % Sum of samples in required epochs + FrameLength=max(histc(Frame,startEpoch:endEpoch))... + *max(header(5,startEpoch:endEpoch));% Maximum data points to a frame + data=single(zeros(FramesToReturn,FrameLength)); % Pre-allocate array + p=1; % Pointer into data array for each disk data block + Frame(Info.blocks+1)=-99; % Dummy entry to avoid index error in for loop + h.mode='Triggered'; + h.start(1)=header(2,startEpoch);% Time of first data point in first returned epoch (clock ticks) + index=1; %epoch counter + for i=startEpoch:endEpoch + fseek(fid,header(1,i)+SizeOfHeader,'bof'); + data(index,p:p+header(5,i)-1)=fread(fid,header(5,i),'float32=>float32'); + h.npoints(index)=h.npoints(index)+header(5,i); + if Frame(i+1)==Frame(i) + p=p+header(5,i); % Increment pointer or..... + else + h.stop(index)=header(3,i); % End time for this frame, clock ticks + if(i10 - ShowProgress=1; - progbar=progressbar(0,sprintf('Analyzing %d blocks on channel %d',Info.blocks,chan),... - 'Name',sprintf('%s',fopen(fid))); - end; - end; -end; - -switch arguments - case {2} - startBlock=1; - endBlock=Info.blocks; - case {3} - startBlock=varargin{1}; - endBlock=varargin{1}; - otherwise - startBlock=varargin{1}; - endBlock=min(Info.blocks,varargin{2}); -end; - -NumberOfMarkers=sum(header(5,startBlock:endBlock)); % Sum of samples in required blocks - -data.timings=zeros(NumberOfMarkers,1); -data.markers=uint8(zeros(NumberOfMarkers,4)); -data.text=char(zeros(NumberOfMarkers,Info.nExtra)); - -count=1; -for block=1:Info.blocks - fseek(fid, header(1, block)+SizeOfHeader, 'bof'); % Start of block - for i=1:header(5,block) % loop for each marker - data.timings(count,1)=fread(fid,1,'int32'); % Time - data.markers(count,:)=fread(fid,4,'int8=>int8'); % 4x marker bytes - data.text(count,:)=fread(fid,Info.nExtra,'char=>char'); - k=findstr(data.text(count,:),0); % Look for NULL terminator and clear succeeding characters - data.text(count,k(1):Info.nExtra)=0; - count=count+1; - if ShowProgress==1 - done=(i-startBlock)/max(1,endBlock-startBlock); - progressbar(done, progbar,sprintf('Reading Channel %d.... %d%% Done',chan,(int16(done*100)/5)*5)); - end; - end; -end - -[data.timings,h.TimeUnits]=SONTicksToSeconds(fid,data.timings, varargin{:}); % Convert time - -if(nargout>1) - h.FileName=Info.FileName; % Set up the header information to return - h.system=['SON' num2str(FileH.systemID)]; - h.FileChannel=chan; - h.phyChan=Info.phyChan; - h.kind=Info.kind; - h.blocks=Info.blocks; - h.npoints=NumberOfMarkers; - h.values=Info.nExtra; - h.preTrig=Info.preTrig; - h.comment=Info.comment; - h.title=Info.title; -end; -[data.timings,h.TimeUnits]=SONTicksToSeconds(fid,data.timings, varargin{:}); % Convert time -h.Epochs={startBlock endBlock 'of' Info.blocks 'blocks'}; -if ShowProgress==1 - close(progbar); - drawnow; +function[data,h]=SONGetTextMarkerChannel(fid, chan, varargin) +% SONGETTESTMARKERCHANNEL reads a marker channel from a SON file. +% +% [data{, h}]=SONGETMARKER(FID, CHAN) +% FID is the MATLAB file handle and CHAN is the channel number (1 to Max) +% DATA is a structure containing: +% DATA.TIMINGS: a length n vector with the marker timestamps +% DATA.MARKERS: an n x 4 array of uint8 type, containing the marker +% values +% DATA.TEXT: an n x m array, with m characters for each of the n tiemstamps +% When present, OPTIONS must be the last input argument. Valid options +% are: +% 'ticks', 'microseconds', 'milliseconds' and 'seconds' cause times to +% be scaled to the appropriate unit (seconds by default)in HEADER +% 'scale' - no effect +% 'progress' - causes a progress bar to be displayed during the read. +% +% +% Malcolm Lidierth 02/02 +% Updated 06/05 ML +% Kings College London 2002-20052 + +Info=SONChannelInfo(fid,chan); + +if isempty (Info) + data=[]; + h=[]; + return; +end; + +if(Info.kind~=8) + warning('SONGetTextMarkerChannel: Channel %d No data or not a TextMark channel',chan); + data=[]; + h=[]; + return; + return; +end; + +FileH=SONFileHeader(fid); +SizeOfHeader=20; % Block header is 20 bytes long +header=SONGetBlockHeaders(fid,chan); +ShowProgress=0; +arguments=nargin; +for i=1:length(varargin) + if ischar(varargin{i}) + arguments=arguments-1; + if strcmpi(varargin{i},'progress') && Info.blocks>10 + ShowProgress=1; + progbar=progressbar(0,sprintf('Analyzing %d blocks on channel %d',Info.blocks,chan),... + 'Name',sprintf('%s',fopen(fid))); + end; + end; +end; + +switch arguments + case {2} + startBlock=1; + endBlock=Info.blocks; + case {3} + startBlock=varargin{1}; + endBlock=varargin{1}; + otherwise + startBlock=varargin{1}; + endBlock=min(Info.blocks,varargin{2}); +end; + +NumberOfMarkers=sum(header(5,startBlock:endBlock)); % Sum of samples in required blocks + +data.timings=zeros(NumberOfMarkers,1); +data.markers=uint8(zeros(NumberOfMarkers,4)); +data.text=char(zeros(NumberOfMarkers,Info.nExtra)); + +count=1; +for block=1:Info.blocks + fseek(fid, header(1, block)+SizeOfHeader, 'bof'); % Start of block + for i=1:header(5,block) % loop for each marker + data.timings(count,1)=fread(fid,1,'int32'); % Time + data.markers(count,:)=fread(fid,4,'int8=>int8'); % 4x marker bytes + data.text(count,:)=fread(fid,Info.nExtra,'char=>char'); + k=findstr(data.text(count,:),0); % Look for NULL terminator and clear succeeding characters + data.text(count,k(1):Info.nExtra)=0; + count=count+1; + if ShowProgress==1 + done=(i-startBlock)/max(1,endBlock-startBlock); + progressbar(done, progbar,sprintf('Reading Channel %d.... %d%% Done',chan,(int16(done*100)/5)*5)); + end; + end; +end + +[data.timings,h.TimeUnits]=SONTicksToSeconds(fid,data.timings, varargin{:}); % Convert time + +if(nargout>1) + h.FileName=Info.FileName; % Set up the header information to return + h.system=['SON' num2str(FileH.systemID)]; + h.FileChannel=chan; + h.phyChan=Info.phyChan; + h.kind=Info.kind; + h.blocks=Info.blocks; + h.npoints=NumberOfMarkers; + h.values=Info.nExtra; + h.preTrig=Info.preTrig; + h.comment=Info.comment; + h.title=Info.title; +end; +[data.timings,h.TimeUnits]=SONTicksToSeconds(fid,data.timings, varargin{:}); % Convert time +h.Epochs={startBlock endBlock 'of' Info.blocks 'blocks'}; +if ShowProgress==1 + close(progbar); + drawnow; end; \ No newline at end of file diff --git a/src/Import/SON/SONRealToADC.m b/Import/SON/SONRealToADC.m similarity index 97% rename from src/Import/SON/SONRealToADC.m rename to Import/SON/SONRealToADC.m index fd35b534..ed644bdd 100644 --- a/src/Import/SON/SONRealToADC.m +++ b/Import/SON/SONRealToADC.m @@ -1,29 +1,29 @@ -function[out,hout]=SONRealToADC(in,header) -% SONREALTOADC Converts floating point array to int16 -% and -% -% [OUT,HOUT]=SONREALTOADC(IN, HIN) -% The input data are scaled to fill the maximum range of the int16 -% output array. Scale and offset in HOUT are updated in SON format. - -% Malcolm Lidierth 03/02 -% Updated 09/05 ML -% 2002-2005 Kings College London - - -%in=double(in); % make sure we have doubke precision -a(1)=min(in(:)); % find minimum ... -a(2)=max(in(:)); % ....and maximum of input -scale=polyfit([-32768 32767],a,1); % find slope and intercept for the line - % through {-32768,min} and {32767,max) -in=((in-scale(2)))/scale(1); % y=ax+b so find x=(y-b)/a -in=round(in); % round to nearest integer -if(max(in)>32767) | (min(in)<-32768) % Debug check that int16 conversion can't lead to overflow - warning('SONRealToADC: Outside 16bit-integer range'); - return; -end; -out=int16(in); % convert to int16 -hout=header; % copy header info -hout.scale=scale(1)*6553.6; % adjust slope to conform to SON scale format... -hout.offset=scale(2); % ... and set offset -hout.kind=1; % set kind to ADC channel +function[out,hout]=SONRealToADC(in,header) +% SONREALTOADC Converts floating point array to int16 +% and +% +% [OUT,HOUT]=SONREALTOADC(IN, HIN) +% The input data are scaled to fill the maximum range of the int16 +% output array. Scale and offset in HOUT are updated in SON format. + +% Malcolm Lidierth 03/02 +% Updated 09/05 ML +% 2002-2005 Kings College London + + +%in=double(in); % make sure we have doubke precision +a(1)=min(in(:)); % find minimum ... +a(2)=max(in(:)); % ....and maximum of input +scale=polyfit([-32768 32767],a,1); % find slope and intercept for the line + % through {-32768,min} and {32767,max) +in=((in-scale(2)))/scale(1); % y=ax+b so find x=(y-b)/a +in=round(in); % round to nearest integer +if(max(in)>32767) | (min(in)<-32768) % Debug check that int16 conversion can't lead to overflow + warning('SONRealToADC: Outside 16bit-integer range'); + return; +end; +out=int16(in); % convert to int16 +hout=header; % copy header info +hout.scale=scale(1)*6553.6; % adjust slope to conform to SON scale format... +hout.offset=scale(2); % ... and set offset +hout.kind=1; % set kind to ADC channel diff --git a/src/Import/SON/SONTest.m b/Import/SON/SONTest.m similarity index 96% rename from src/Import/SON/SONTest.m rename to Import/SON/SONTest.m index 9b786371..763b13d0 100644 --- a/src/Import/SON/SONTest.m +++ b/Import/SON/SONTest.m @@ -1,33 +1,33 @@ -function[]=SONTest(file) -% SONTEST tests the integrity of a SON File usinf CED's SonFix program. -% -% SONTEST(FILE) -% FILE may be a string or a file identifier -% If FILE contains a directory root but no filename or *.smr, all -% files in the directory will be tested. -% Files currently open for writing within Matlab will not be tested. -% The version of SonFix should be dated 18 Feb 2002 or later to cope with version 6. -% ***Edit SONTest.m to contain the correct path for the SONFIX program*** -% -% Malcolm Lidierth 03/02 -% Updated 06/05 ML -% Kings College London 2002-2005 - -if (nargin<1) - file='*.smr'; -end; - -if strcmp(class(file),'char')~=1 % If not a character string expect a file identifier - file=fopen(file); % convert to string -end; - -SONFIX='c:\Spike5\sonfix.exe'; % Edit path to point to SonFix.exe -present=dir(SONFIX); -if isempty(present) - warning('SONTest: Could not find SONFix.exe'); - return; -end; - -SONFIX=[SONFIX,' ',file]; -eval(sprintf('!%s',SONFIX)); - +function[]=SONTest(file) +% SONTEST tests the integrity of a SON File usinf CED's SonFix program. +% +% SONTEST(FILE) +% FILE may be a string or a file identifier +% If FILE contains a directory root but no filename or *.smr, all +% files in the directory will be tested. +% Files currently open for writing within Matlab will not be tested. +% The version of SonFix should be dated 18 Feb 2002 or later to cope with version 6. +% ***Edit SONTest.m to contain the correct path for the SONFIX program*** +% +% Malcolm Lidierth 03/02 +% Updated 06/05 ML +% Kings College London 2002-2005 + +if (nargin<1) + file='*.smr'; +end; + +if strcmp(class(file),'char')~=1 % If not a character string expect a file identifier + file=fopen(file); % convert to string +end; + +SONFIX='c:\Spike5\sonfix.exe'; % Edit path to point to SonFix.exe +present=dir(SONFIX); +if isempty(present) + warning('SONTest: Could not find SONFix.exe'); + return; +end; + +SONFIX=[SONFIX,' ',file]; +eval(sprintf('!%s',SONFIX)); + diff --git a/src/Import/SON/SONTicksToSeconds.m b/Import/SON/SONTicksToSeconds.m similarity index 96% rename from src/Import/SON/SONTicksToSeconds.m rename to Import/SON/SONTicksToSeconds.m index 492889e6..c25ade15 100644 --- a/src/Import/SON/SONTicksToSeconds.m +++ b/Import/SON/SONTicksToSeconds.m @@ -1,46 +1,46 @@ -function[out,timeunits]=SONTicksToSeconds(fid, in, varargin) -% SONTICKSTOSECONDS scales timestamp vector IN -% -% [OUT,{ TIMEUNITS}]= SONTICKSTOSECONDS(FID, IN{, OPTIONS}) -% FID is the matlab file handle, IN is a vector of timestamps from the file. -% -% OPTIONS if present, may contain: -% 'Ticks' : Returns the time in base clock ticks -% 'microseconds', 'milliseconds' or 'seconds' (=default): scales the output -% to the appropriate unit -% -% OUT contains the scaled timestamps. TIMEUNITS, if present, is a string -% copied from OPTIONS giving the time units -% -% Malcolm Lidierth 03/02 -% Updated 06/05 ML -% Kings College London 2002-2005 - -FileH=SONFileHeader(fid); - -if nargin>2 - for i=1:length(varargin) - if strcmpi(varargin{i},'ticks') - out=in; - timeunits='Ticks'; - end; - if strcmpi(varargin{i},'microseconds') - out=in*FileH.usPerTime*(FileH.dTimeBase*1e6); - timeunits='microseconds'; - end; - if strcmpi(varargin{i},'milliseconds') - out=in*FileH.usPerTime*(FileH.dTimeBase*1e3); - timeunits='milliseconds'; - end; - end; -end; - -% if not set default to seconds -if exist('timeunits','var')==0 - out=in*FileH.usPerTime*FileH.dTimeBase;% default, time in seconds - timeunits='seconds'; -end; - - - - +function[out,timeunits]=SONTicksToSeconds(fid, in, varargin) +% SONTICKSTOSECONDS scales timestamp vector IN +% +% [OUT,{ TIMEUNITS}]= SONTICKSTOSECONDS(FID, IN{, OPTIONS}) +% FID is the matlab file handle, IN is a vector of timestamps from the file. +% +% OPTIONS if present, may contain: +% 'Ticks' : Returns the time in base clock ticks +% 'microseconds', 'milliseconds' or 'seconds' (=default): scales the output +% to the appropriate unit +% +% OUT contains the scaled timestamps. TIMEUNITS, if present, is a string +% copied from OPTIONS giving the time units +% +% Malcolm Lidierth 03/02 +% Updated 06/05 ML +% Kings College London 2002-2005 + +FileH=SONFileHeader(fid); + +if nargin>2 + for i=1:length(varargin) + if strcmpi(varargin{i},'ticks') + out=in; + timeunits='Ticks'; + end; + if strcmpi(varargin{i},'microseconds') + out=in*FileH.usPerTime*(FileH.dTimeBase*1e6); + timeunits='microseconds'; + end; + if strcmpi(varargin{i},'milliseconds') + out=in*FileH.usPerTime*(FileH.dTimeBase*1e3); + timeunits='milliseconds'; + end; + end; +end; + +% if not set default to seconds +if exist('timeunits','var')==0 + out=in*FileH.usPerTime*FileH.dTimeBase;% default, time in seconds + timeunits='seconds'; +end; + + + + diff --git a/src/Import/SON/SONUpgradeToVersion6.m b/Import/SON/SONUpgradeToVersion6.m similarity index 95% rename from src/Import/SON/SONUpgradeToVersion6.m rename to Import/SON/SONUpgradeToVersion6.m index fca59ea6..f73fdfaa 100644 --- a/src/Import/SON/SONUpgradeToVersion6.m +++ b/Import/SON/SONUpgradeToVersion6.m @@ -1,39 +1,39 @@ -function[]=SONUpgradeToVersion6(fid) -% Obsolete function -% Upgrades SON file ADC and ADCMark data to SON version 6. -% File header date and time fields are not upgraded -% The file header creator field is set to 'MAT-TO-6' but only if it is '00000000' to begin with. -% IT IS RECOMMENDED THAT YOU BACKUP FILES BEFORE USING THIS ROUTINE. - -% Malcolm Lidierth 03/02 - -FileH=SONFileHeader(fid); -if FileH.systemID==6 % Already version 6 so do nothing - return; -end; -if FileH.systemID<3 - warning('SONUpgradeVersionTo6: This file is very old (version 1 or 2 of SON). This upgrade may not work'); - return; -end; - -for chan=1:FileH.channels %Run throught he channels - Info=SONChannelInfo(fid,chan); - if(Info.kind==1) | (Info.kind==6) % If ADC or ADCMark update them - base=512+(140*(chan-1)); % Offset due to file header and preceding channel headers - fseek(fid,base+102,'bof'); - fwrite(fid,Info.divide*FileH.timePerADC,'int32'); % Set lChanDvd - fseek(fid,base+138,'bof'); - fwrite(fid,1,'int16'); % Set adc.divide to 1 - end; -end; - -if strcmp(FileH.Creator,'00000000')==1 - fseek(fid,12,'bof'); - fprintf(fid,'MAT-TO-6'); -end; - -fseek(fid,44,'bof'); -fwrite(fid,1e-6,'float64'); % Set dTimeBase to 1e-6 seconds - -frewind(fid); +function[]=SONUpgradeToVersion6(fid) +% Obsolete function +% Upgrades SON file ADC and ADCMark data to SON version 6. +% File header date and time fields are not upgraded +% The file header creator field is set to 'MAT-TO-6' but only if it is '00000000' to begin with. +% IT IS RECOMMENDED THAT YOU BACKUP FILES BEFORE USING THIS ROUTINE. + +% Malcolm Lidierth 03/02 + +FileH=SONFileHeader(fid); +if FileH.systemID==6 % Already version 6 so do nothing + return; +end; +if FileH.systemID<3 + warning('SONUpgradeVersionTo6: This file is very old (version 1 or 2 of SON). This upgrade may not work'); + return; +end; + +for chan=1:FileH.channels %Run throught he channels + Info=SONChannelInfo(fid,chan); + if(Info.kind==1) | (Info.kind==6) % If ADC or ADCMark update them + base=512+(140*(chan-1)); % Offset due to file header and preceding channel headers + fseek(fid,base+102,'bof'); + fwrite(fid,Info.divide*FileH.timePerADC,'int32'); % Set lChanDvd + fseek(fid,base+138,'bof'); + fwrite(fid,1,'int16'); % Set adc.divide to 1 + end; +end; + +if strcmp(FileH.Creator,'00000000')==1 + fseek(fid,12,'bof'); + fprintf(fid,'MAT-TO-6'); +end; + +fseek(fid,44,'bof'); +fwrite(fid,1e-6,'float64'); % Set dTimeBase to 1e-6 seconds + +frewind(fid); fwrite(fid,6,'int16'); \ No newline at end of file diff --git a/src/Import/SON/SONVersion.m b/Import/SON/SONVersion.m similarity index 97% rename from src/Import/SON/SONVersion.m rename to Import/SON/SONVersion.m index 00cf9edc..9373d9c9 100644 --- a/src/Import/SON/SONVersion.m +++ b/Import/SON/SONVersion.m @@ -1,17 +1,17 @@ -function ver=SONVersion(varargin) -% SONVERSION returns/displays the version number of the matlab SON library -% -% VER=SONVERSION -% returns and displays the version while -% VER=SONVERSION('nodisplay') -% suppresses the display -% -% Updated 06/05 ML -% Kings College London 2002-2005 - -title='MATLAB SON Library'; -ver=1.1; -if nargin==0 || strcmpi(varargin{1},'nodisplay')~=1 -st=sprintf('Author:Malcolm Lidierth\nmalcolm.lidierth@kcl.ac.uk\n Copyright %c King%cs College London 2002-2005\n Version:%3.2f 20.06.05\n\nSON Filing system \nCopyright %c Cambridge Electronic Design 1988-2004 Version 7.0',169,39,ver,169); -(msgbox( st,title,'modal')); -end; +function ver=SONVersion(varargin) +% SONVERSION returns/displays the version number of the matlab SON library +% +% VER=SONVERSION +% returns and displays the version while +% VER=SONVERSION('nodisplay') +% suppresses the display +% +% Updated 06/05 ML +% Kings College London 2002-2005 + +title='MATLAB SON Library'; +ver=1.1; +if nargin==0 || strcmpi(varargin{1},'nodisplay')~=1 +st=sprintf('Author:Malcolm Lidierth\nmalcolm.lidierth@kcl.ac.uk\n Copyright %c King%cs College London 2002-2005\n Version:%3.2f 20.06.05\n\nSON Filing system \nCopyright %c Cambridge Electronic Design 1988-2004 Version 7.0',169,39,ver,169); +(msgbox( st,title,'modal')); +end; diff --git a/src/Import/SON/progressbar.m b/Import/SON/progressbar.m similarity index 97% rename from src/Import/SON/progressbar.m rename to Import/SON/progressbar.m index 29fb5661..e20a1ff9 100644 --- a/src/Import/SON/progressbar.m +++ b/Import/SON/progressbar.m @@ -1,240 +1,240 @@ -function fout = waitbar(x,whichbar, varargin) -%WAITBAR Display wait bar. -% H = WAITBAR(X,'title', property, value, property, value, ...) -% creates and displays a waitbar of fractional length X. The -% handle to the waitbar figure is returned in H. -% X should be between 0 and 1. Optional arguments property and -% value allow to set corresponding waitbar figure properties. -% Property can also be an action keyword 'CreateCancelBtn', in -% which case a cancel button will be added to the figure, and -% the passed value string will be executed upon clicking on the -% cancel button or the close figure button. -% -% WAITBAR(X) will set the length of the bar in the most recently -% created waitbar window to the fractional length X. -% -% WAITBAR(X,H) will set the length of the bar in waitbar H -% to the fractional length X. -% -% WAITBAR(X,H,'updated title') will update the title text in -% the waitbar figure, in addition to setting the fractional -% length to X. -% -% WAITBAR is typically used inside a FOR loop that performs a -% lengthy computation. A sample usage is shown below: -% -% h = waitbar(0,'Please wait...'); -% for i=1:100, -% % computation here % -% waitbar(i/100,h) -% end -% close(h) - -% Copyright 1984-2004 The MathWorks, Inc. -% $Revision: 701 $ $Date: 2004/10/22 19:45:14 $ - -if nargin>=2 - if ischar(whichbar) || iscellstr(whichbar) - type=2; %we are initializing - name=whichbar; - elseif isnumeric(whichbar) - type=1; %we are updating, given a handle - f=whichbar; - else - error(['Input arguments of type ' class(whichbar) ' not valid.']) - end -elseif nargin==1 - f = findobj(allchild(0),'flat','Tag','TMWWaitbar'); - - if isempty(f) - type=2; - name='Waitbar'; - else - type=1; - f=f(1); - end -else - error('Input arguments not valid.'); -end - -x = max(0,min(100*x,100)); - -switch type - case 1, % waitbar(x) update - p = findobj(f,'Type','patch'); - l = findobj(f,'Type','line'); - if isempty(f) | isempty(p) | isempty(l), - error('Couldn''t find waitbar handles.'); - end - xpatch = get(p,'XData'); - xpatch = [0 x x 0]; - set(p,'XData',xpatch) - xline = get(l,'XData'); - set(l,'XData',xline); - - if nargin>2, - % Update waitbar title: - hAxes = findobj(f,'type','axes'); - hTitle = get(hAxes,'title'); - set(hTitle,'string',varargin{1}); - end - - case 2, % waitbar(x,name) initialize - vertMargin = 0; - if nargin > 2, - % we have optional arguments: property-value pairs - if rem (nargin, 2 ) ~= 0 - error( 'Optional initialization arguments must be passed in pairs' ); - end - end - - oldRootUnits = get(0,'Units'); - - set(0, 'Units', 'points'); - screenSize = get(0,'ScreenSize'); - - axFontSize=get(0,'FactoryAxesFontSize'); - - pointsPerPixel = 72/get(0,'ScreenPixelsPerInch'); - - width = 360 * pointsPerPixel; - height = 75 * pointsPerPixel; - pos = [screenSize(3)/2-width/2 screenSize(4)/2-height/2 width height]; - f = figure(... - 'Units', 'points', ... - 'BusyAction', 'queue', ... - 'Position', pos, ... - 'Resize','off', ... - 'CreateFcn','', ... - 'NumberTitle','off', ... - 'IntegerHandle','off', ... - 'MenuBar', 'none', ... - 'Tag','TMWWaitbar',... - 'Interruptible', 'off', ... - 'DockControls', 'off', ... - 'Visible','off'); - - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - % set figure properties as passed to the fcn - % pay special attention to the 'cancel' request - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - visValue = 'on'; - if nargin > 2, - propList = varargin(1:2:end); - valueList = varargin(2:2:end); - cancelBtnCreated = 0; - - visibleExist = strmatch('vis',lower(propList)); - if ~isempty(visibleExist) - visValue = valueList{visibleExist}; - end - - for ii = 1:length( propList ) - try - if strcmp(lower(propList{ii}), 'createcancelbtn' ) & ~cancelBtnCreated - cancelBtnHeight = 23 * pointsPerPixel; - cancelBtnWidth = 60 * pointsPerPixel; - newPos = pos; - vertMargin = vertMargin + cancelBtnHeight; - newPos(4) = newPos(4)+vertMargin; - callbackFcn = [valueList{ii}]; - set( f, 'Position', newPos, 'CloseRequestFcn', callbackFcn ); - cancelButt = uicontrol('Parent',f, ... - 'Units','points', ... - 'Callback',callbackFcn, ... - 'ButtonDownFcn', callbackFcn, ... - 'Enable','on', ... - 'Interruptible','off', ... - 'Position', [pos(3)-cancelBtnWidth*1.4, 7, ... - cancelBtnWidth, cancelBtnHeight], ... - 'String','Cancel', ... - 'Tag','TMWWaitbarCancelButton'); - cancelBtnCreated = 1; - else - % simply set the prop/value pair of the figure - set( f, propList{ii}, valueList{ii}); - end - - catch - disp ( ['Warning: could not set property ''' propList{ii} ''' with value ''' num2str(valueList{ii}) '''' ] ); - end - end - end - - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - - colormap([]); - - axNorm=[.05 .3 .9 .2]; - axPos=axNorm.*[pos(3:4),pos(3:4)] + [0 vertMargin 0 0]; - - h = axes('XLim',[0 100],... - 'YLim',[0 1],... - 'Box','on', ... - 'Units','Points',... - 'FontSize', axFontSize,... - 'Position',axPos,... - 'XTickMode','manual',... - 'YTickMode','manual',... - 'XTick',[],... - 'YTick',[],... - 'XTickLabelMode','manual',... - 'XTickLabel',[],... - 'YTickLabelMode','manual',... - 'YTickLabel',[]); - - tHandle=title(name); - tHandle=get(h,'title'); - oldTitleUnits=get(tHandle,'Units'); - set(tHandle,... - 'Units', 'points',... - 'String', name); - - tExtent=get(tHandle,'Extent'); - set(tHandle,'Units',oldTitleUnits); - - titleHeight=tExtent(4)+axPos(2)+axPos(4)+5; - if titleHeight>pos(4) - pos(4)=titleHeight; - pos(2)=screenSize(4)/2-pos(4)/2; - figPosDirty=logical(1); - else - figPosDirty=logical(0); - end - - if tExtent(3)>pos(3)*1.10; - pos(3)=min(tExtent(3)*1.10,screenSize(3)); - pos(1)=screenSize(3)/2-pos(3)/2; - - axPos([1,3])=axNorm([1,3])*pos(3); - set(h,'Position',axPos); - - figPosDirty=logical(1); - end - - if figPosDirty - set(f,'Position',pos); - end - t=sprintf('MATLAB SON Library %3.2f Kings College London 2002-2005',SONVersion('nodisplay')); - text(0.2,-1,['\it' t],'FontSize',8,'Color',[0 0 0.4]); - xpatch = [0 x x 0]; - ypatch = [0 0 1 1]; - xline = [100 0 0 100 100]; - yline = [0 0 1 1 1]; - - p = patch(xpatch,ypatch,[0 0 0.5],'EdgeColor',[0 0 1],'EraseMode','none'); - l = line(xline,yline,'EraseMode','none'); - set(l,'Color',[0 0 0.7]); - - set(f,'HandleVisibility','callback','visible', visValue); - - set(0, 'Units', oldRootUnits); -end % case -drawnow; - -if nargout==1, - fout = f; -end - - +function fout = waitbar(x,whichbar, varargin) +%WAITBAR Display wait bar. +% H = WAITBAR(X,'title', property, value, property, value, ...) +% creates and displays a waitbar of fractional length X. The +% handle to the waitbar figure is returned in H. +% X should be between 0 and 1. Optional arguments property and +% value allow to set corresponding waitbar figure properties. +% Property can also be an action keyword 'CreateCancelBtn', in +% which case a cancel button will be added to the figure, and +% the passed value string will be executed upon clicking on the +% cancel button or the close figure button. +% +% WAITBAR(X) will set the length of the bar in the most recently +% created waitbar window to the fractional length X. +% +% WAITBAR(X,H) will set the length of the bar in waitbar H +% to the fractional length X. +% +% WAITBAR(X,H,'updated title') will update the title text in +% the waitbar figure, in addition to setting the fractional +% length to X. +% +% WAITBAR is typically used inside a FOR loop that performs a +% lengthy computation. A sample usage is shown below: +% +% h = waitbar(0,'Please wait...'); +% for i=1:100, +% % computation here % +% waitbar(i/100,h) +% end +% close(h) + +% Copyright 1984-2004 The MathWorks, Inc. +% $Revision: 701 $ $Date: 2004/10/22 19:45:14 $ + +if nargin>=2 + if ischar(whichbar) || iscellstr(whichbar) + type=2; %we are initializing + name=whichbar; + elseif isnumeric(whichbar) + type=1; %we are updating, given a handle + f=whichbar; + else + error(['Input arguments of type ' class(whichbar) ' not valid.']) + end +elseif nargin==1 + f = findobj(allchild(0),'flat','Tag','TMWWaitbar'); + + if isempty(f) + type=2; + name='Waitbar'; + else + type=1; + f=f(1); + end +else + error('Input arguments not valid.'); +end + +x = max(0,min(100*x,100)); + +switch type + case 1, % waitbar(x) update + p = findobj(f,'Type','patch'); + l = findobj(f,'Type','line'); + if isempty(f) | isempty(p) | isempty(l), + error('Couldn''t find waitbar handles.'); + end + xpatch = get(p,'XData'); + xpatch = [0 x x 0]; + set(p,'XData',xpatch) + xline = get(l,'XData'); + set(l,'XData',xline); + + if nargin>2, + % Update waitbar title: + hAxes = findobj(f,'type','axes'); + hTitle = get(hAxes,'title'); + set(hTitle,'string',varargin{1}); + end + + case 2, % waitbar(x,name) initialize + vertMargin = 0; + if nargin > 2, + % we have optional arguments: property-value pairs + if rem (nargin, 2 ) ~= 0 + error( 'Optional initialization arguments must be passed in pairs' ); + end + end + + oldRootUnits = get(0,'Units'); + + set(0, 'Units', 'points'); + screenSize = get(0,'ScreenSize'); + + axFontSize=get(0,'FactoryAxesFontSize'); + + pointsPerPixel = 72/get(0,'ScreenPixelsPerInch'); + + width = 360 * pointsPerPixel; + height = 75 * pointsPerPixel; + pos = [screenSize(3)/2-width/2 screenSize(4)/2-height/2 width height]; + f = figure(... + 'Units', 'points', ... + 'BusyAction', 'queue', ... + 'Position', pos, ... + 'Resize','off', ... + 'CreateFcn','', ... + 'NumberTitle','off', ... + 'IntegerHandle','off', ... + 'MenuBar', 'none', ... + 'Tag','TMWWaitbar',... + 'Interruptible', 'off', ... + 'DockControls', 'off', ... + 'Visible','off'); + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % set figure properties as passed to the fcn + % pay special attention to the 'cancel' request + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + visValue = 'on'; + if nargin > 2, + propList = varargin(1:2:end); + valueList = varargin(2:2:end); + cancelBtnCreated = 0; + + visibleExist = strmatch('vis',lower(propList)); + if ~isempty(visibleExist) + visValue = valueList{visibleExist}; + end + + for ii = 1:length( propList ) + try + if strcmp(lower(propList{ii}), 'createcancelbtn' ) & ~cancelBtnCreated + cancelBtnHeight = 23 * pointsPerPixel; + cancelBtnWidth = 60 * pointsPerPixel; + newPos = pos; + vertMargin = vertMargin + cancelBtnHeight; + newPos(4) = newPos(4)+vertMargin; + callbackFcn = [valueList{ii}]; + set( f, 'Position', newPos, 'CloseRequestFcn', callbackFcn ); + cancelButt = uicontrol('Parent',f, ... + 'Units','points', ... + 'Callback',callbackFcn, ... + 'ButtonDownFcn', callbackFcn, ... + 'Enable','on', ... + 'Interruptible','off', ... + 'Position', [pos(3)-cancelBtnWidth*1.4, 7, ... + cancelBtnWidth, cancelBtnHeight], ... + 'String','Cancel', ... + 'Tag','TMWWaitbarCancelButton'); + cancelBtnCreated = 1; + else + % simply set the prop/value pair of the figure + set( f, propList{ii}, valueList{ii}); + end + + catch + disp ( ['Warning: could not set property ''' propList{ii} ''' with value ''' num2str(valueList{ii}) '''' ] ); + end + end + end + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + + colormap([]); + + axNorm=[.05 .3 .9 .2]; + axPos=axNorm.*[pos(3:4),pos(3:4)] + [0 vertMargin 0 0]; + + h = axes('XLim',[0 100],... + 'YLim',[0 1],... + 'Box','on', ... + 'Units','Points',... + 'FontSize', axFontSize,... + 'Position',axPos,... + 'XTickMode','manual',... + 'YTickMode','manual',... + 'XTick',[],... + 'YTick',[],... + 'XTickLabelMode','manual',... + 'XTickLabel',[],... + 'YTickLabelMode','manual',... + 'YTickLabel',[]); + + tHandle=title(name); + tHandle=get(h,'title'); + oldTitleUnits=get(tHandle,'Units'); + set(tHandle,... + 'Units', 'points',... + 'String', name); + + tExtent=get(tHandle,'Extent'); + set(tHandle,'Units',oldTitleUnits); + + titleHeight=tExtent(4)+axPos(2)+axPos(4)+5; + if titleHeight>pos(4) + pos(4)=titleHeight; + pos(2)=screenSize(4)/2-pos(4)/2; + figPosDirty=logical(1); + else + figPosDirty=logical(0); + end + + if tExtent(3)>pos(3)*1.10; + pos(3)=min(tExtent(3)*1.10,screenSize(3)); + pos(1)=screenSize(3)/2-pos(3)/2; + + axPos([1,3])=axNorm([1,3])*pos(3); + set(h,'Position',axPos); + + figPosDirty=logical(1); + end + + if figPosDirty + set(f,'Position',pos); + end + t=sprintf('MATLAB SON Library %3.2f Kings College London 2002-2005',SONVersion('nodisplay')); + text(0.2,-1,['\it' t],'FontSize',8,'Color',[0 0 0.4]); + xpatch = [0 x x 0]; + ypatch = [0 0 1 1]; + xline = [100 0 0 100 100]; + yline = [0 0 1 1 1]; + + p = patch(xpatch,ypatch,[0 0 0.5],'EdgeColor',[0 0 1],'EraseMode','none'); + l = line(xline,yline,'EraseMode','none'); + set(l,'Color',[0 0 0.7]); + + set(f,'HandleVisibility','callback','visible', visValue); + + set(0, 'Units', oldRootUnits); +end % case +drawnow; + +if nargout==1, + fout = f; +end + + diff --git a/src/Import/SON/readme.txt b/Import/SON/readme.txt similarity index 96% rename from src/Import/SON/readme.txt rename to Import/SON/readme.txt index 7a99edc0..993d18f2 100644 --- a/src/Import/SON/readme.txt +++ b/Import/SON/readme.txt @@ -1,15 +1,15 @@ -The SON2 library uses features introduced with version 5 of MATLAB and will not work -with versions earlier than that. - -The SON32 library requires MATLAB version 7.1 or later. - -Unzip the files to the MATLAB work directory. This will create a SON folder containing the SON2 library. -The SON32 library will be installed into a SON\SON32 subfolder. -Add these to th MATLAB path as required. - - - - -Malcolm Lidierth -1/10/05 - +The SON2 library uses features introduced with version 5 of MATLAB and will not work +with versions earlier than that. + +The SON32 library requires MATLAB version 7.1 or later. + +Unzip the files to the MATLAB work directory. This will create a SON folder containing the SON2 library. +The SON32 library will be installed into a SON\SON32 subfolder. +Add these to th MATLAB path as required. + + + + +Malcolm Lidierth +1/10/05 + diff --git a/src/Import/acq/acqread.m b/Import/acq/acqread.m similarity index 97% rename from src/Import/acq/acqread.m rename to Import/acq/acqread.m index 51c9d952..19ce2de6 100644 --- a/src/Import/acq/acqread.m +++ b/Import/acq/acqread.m @@ -1,328 +1,328 @@ -function [info, data] = acqread(filename) -% ACQREAD Read a Biopac AcqKnowledge file. -% [INFO, DATA] = ACQREAD(FILENAME) reads the content of the AcqKnowledge -% file specified in the string FILENAME. INFO is a structure containing -% the metadata (header, markers, etc.). DATA is a cell array, indexed -% by the channel number, containing the acquired physiological signals. -% -% [INFO, DATA] = ACQREAD displays a dialog box that is used to retrieve -% the desired file. -% -% ACQREAD supports all files created with Windows/PC versions of -% AcqKnowledge (3.9.0 or below), BSL (3.7.0 or below), and BSL PRO -% (3.7.0 or below). -% -% ACQREAD supports channels that were acquired using different sampling -% rates, therefore having a different number of samples. -% -% Details of the AcqKnowledge file format are presented in Biopac's -% Application Note #156 (last updated on February 23, 2007), and -% available at : "http://www.biopac.com/Manuals/app_pdf/app156.pdf". -% -% ACQREAD, version 2.0 (2007-08-21) -% Copyright (C) 2006-2007 Sebastien Authier and Vincent Finnerty -% -% This program is free software; you can redistribute it and/or modify -% it under the terms of the GNU General Public License as published by -% the Free Software Foundation; either version 2 of the License, or -% (at your option) any later version. -% -% This program is distributed in the hope that it will be useful, -% but WITHOUT ANY WARRANTY; without even the implied warranty of -% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -% GNU General Public License for more details. -% -% You should have received a copy of the GNU General Public License -% along with this program; if not, write to the Free Software -% Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -% 02110-1301, USA - -%% Opening file... - -error(nargchk(0,1,nargin)) -if nargin==1 - if exist(filename,'file')~=2 - error(['File "',filename,'" not found.']) - else - [fid,message] = fopen(filename,'r'); - if fid==-1 - error(message) - end - end -else - [filename,pathname] = uigetfile({'*.acq','AcqKnowledge File (*.acq)';... - '*.*','All Files (*.*)'}); - if filename==0 - return - else - filename = fullfile(pathname,filename); - [fid,message] = fopen(filename,'r'); - if fid==-1 - error(message) - end - end -end - -%% GRAPH HEADER SECTION - -info.nItemHeaderLen = fread(fid,1,'*int16'); -info.lVersion = fread(fid,1,'*int32'); % File version identifier -% 30 = Pre-version 2.0 -% 31 = Version 2.0 Beta 1 -% 32 = Version 2.0 release -% 33 = Version 2.0.7 (Mac) -% 34 = Version 3.0 In-house Release 1 -% 35 = Version 3.03 -% 36 = Version 3.5x (Win 95, 98, NT) -% 37 = Version of BSL/PRO 3.6.x -% 38 = Version of Acq 3.7.0-3.7.2 (Win 98, 98SE, NT, Me, 2000) -% 39 = Version of Acq 3.7.3 or above (Win 98, 98SE, 2000, Me, XP) -% 41 = Version of Acq 3.8.1 or above (Win 98, 98SE, 2000, Me, XP) -% 42 = Version of BSL/PRO 3.7.X or above (Win 98, 98SE, 2000, Me, XP) -% 43 = Version of Acq 3.8.2 or above (Win 98, 98SE, 2000, Me, XP) -% 44 = Version of BSL/PRO 3.8.x or above -% 45 = Version of Acq 3.9.0 or above -if (info.lVersion<30) || (info.lVersion>45) - error (['Unable to read file "',filename,'" : invalid file type, or unsupported file version.']) -end -info.lExtItemHeaderLen = fread(fid,1,'*int32'); -info.nChannels = fread(fid,1,'*int16'); % Number of channels -info.nHorizAxisType = fread(fid,1,'*int16'); -info.nCurChannel = fread(fid,1,'*int16'); -info.dSampleTime = fread(fid,1,'*double'); % Number of milliseconds per sample -info.dTimeOffset = fread(fid,1,'*double'); % Initial time offset in milliseconds -info.dTimeScale = fread(fid,1,'*double'); % Time scale in milliseconds per division -info.dTimeCursor1 = fread(fid,1,'*double'); -info.dTimeCursor2 = fread(fid,1,'*double'); -info.rcWindow = fread(fid,1,'*double'); -info.nMeasurement = fread(fid,6,'*int16')'; -info.fHilite = fread(fid,1,'*int16'); -info.dFirstTimeOffset = fread(fid,1,'*double'); -info.nRescale = fread(fid,1,'*int16'); -info.szHorizUnits1 = deblank(fread(fid,40,'*char')'); % Horizontal units text -info.szHorizUnits2 = deblank(fread(fid,10,'*char')'); % Horizontal units text (abbreviated) -info.nInMemory = fread(fid,1,'*int16'); -info.fGrid = fread(fid,1,'*int16'); -info.fMarkers = fread(fid,1,'*int16'); -info.nPlotDraft = fread(fid,1,'*int16'); -info.nDispMode = fread(fid,1,'*int16'); -info.nReserved = fread(fid,1,'*int16'); - -% Version 3.0 and above... -if info.lVersion>=34 - info.BShowToolBar = fread(fid,1,'*int16'); - info.BShowChannelButtons = fread(fid,1,'*int16'); - info.BShowMeasurements = fread(fid,1,'int16'); - info.BShowMarkers = fread(fid,1,'*int16'); - info.BShowJournal = fread(fid,1,'*int16'); - info.CurXChannel = fread(fid,1,'*int16'); - info.MmtPrecision = fread(fid,1,'*int16'); -end - -% Version 3.02 and above... -if info.lVersion>=35 - info.NMeasurementRows = fread(fid,1,'*int16'); - info.mmt = fread(fid,40,'*int16')'; - info.mmtChan = fread(fid,40,'*int16')'; -end - -% Version 3.5x and above... -if info.lVersion>=36 - info.MmtCalcOpnd1 = fread(fid,40,'*int16')'; - info.MmtCalcOpnd2 = fread(fid,40,'*int16')'; - info.MmtCalcOp = fread(fid,40,'*int16')'; - info.MmtCalcConstant = fread(fid,40,'*double')'; -end - -% Version 3.7.0 and above... -if info.lVersion>=38 - tmp = fread(fid,1,'*int32'); - tmp = sprintf('%6s',dec2hex(tmp,6)); - info.bNewGridwithMinor = [hex2dec(tmp(5:6)) hex2dec(tmp(3:4)) hex2dec(tmp(1:2))]./255; - tmp = fread(fid,1,'*int32'); - tmp = sprintf('%6s',dec2hex(tmp,6)); - info.colorMajorGrid = [hex2dec(tmp(5:6)) hex2dec(tmp(3:4)) hex2dec(tmp(1:2))]./255; - info.colorMinorGrid = fread(fid,1,'*int32'); - info.wMajorGridStyle = fread(fid,1,'*int16'); - info.wMinorGridStyle = fread(fid,1,'*int16'); - info.wMajorGridWidth = fread(fid,1,'*int16'); - info.wMinorGridWidth = fread(fid,1,'*int16'); - info.bFixedUnitsDiv = fread(fid,1,'*int32'); - info.bMid_Range_Show = fread(fid,1,'*int32'); - info.dStart_Middle_Point = fread(fid,1,'*double'); - info.dOffset_Point = fread(fid,60,'*double')'; - info.hGrid = fread(fid,1,'*double'); - info.vGrid = fread(fid,60,'*double')'; - info.bEnableWaveTools = fread(fid,1,'*int32'); -end - -% Version 3.7.3 and above... -if info.lVersion>=39 - info.horizPrecision = fread(fid,1,'*int16'); -end - -% Version 3.8.1 and above... -if info.lVersion>=41 - fseek(fid,20,'cof') % RESERVED - info.bOverlapMode = fread(fid,1,'*int32'); - info.bShowHardware = fread(fid,1,'*int32'); - info.bXAutoplot = fread(fid,1,'*int32'); - info.bXAutoScroll = fread(fid,1,'*int32'); - info.bStartButtonVisible = fread(fid,1,'*int32'); - info.bCompressed = fread(fid,1,'*int32'); - info.AlwaysStartButtonVisible = fread(fid,1,'*int32'); -end - -% Version 3.8.2 and above... -if info.lVersion>=43 - info.pathVideo = deblank(fread(fid,260,'*char')'); - info.optSyncDelay = fread(fid,1,'*int32'); - info.syncDelay = fread(fid,1,'*double'); - info.bHRP_PasteMeasurements = fread(fid,1,'*int32'); -end - -% Version 3.9.0 and above... -if info.lVersion>=45 - info.graphType = fread(fid,1,'*int32')'; - for n = 1:40 - info.mmtCalcExpr{n} = deblank(fread(fid,256,'*char')'); - end - info.mmtMomentOrder = fread(fid,40,'*int32')'; - info.mmtTimeDelay = fread(fid,40,'*int32')'; - info.mmtEmbedDim = fread(fid,40,'*int32')'; - info.mmtMIDelay = fread(fid,40,'*int32')'; -end - -%% PER CHANNEL DATA SECTION - -for n = 1:info.nChannels - info.lChanHeaderLen(n) = fread(fid,1,'*int32'); - info.nNum(n) = fread(fid,1,'*int16'); - info.szCommentText{n} = deblank(fread(fid,40,'*char')'); % Comment text - tmp = fread(fid,1,'*int32'); - tmp = sprintf('%6s',dec2hex(tmp,6)); - info.rgbColor{n} = [hex2dec(tmp(5:6)) hex2dec(tmp(3:4)) hex2dec(tmp(1:2))]./255; - info.nDispChan(n) = fread(fid,1,'*int16'); - info.dVoltOffset(n) = fread(fid,1,'*double'); % Amplitude offset (volts) - info.dVoltScale(n) = fread(fid,1,'*double'); % Amplitude scale (volts/div.) - info.szUnitsText{n} = deblank(fread(fid,20,'*char')'); % Units text - info.lBufLength(n) = fread(fid,1,'*int32'); % Number of data samples - info.dAmplScale(n) = fread(fid,1,'*double'); % Units/count - info.dAmplOffset(n) = fread(fid,1,'*double'); % Units - info.nChanOrder(n) = fread(fid,1,'*int16'); - info.nDispSize(n) = fread(fid,1,'*int16'); - - % Version 3.0 and above... - if info.lVersion>=34 - info.plotMode(n) = fread(fid,1,'*int16'); - info.vMid(n) = fread(fid,1,'*double'); - end - - % Version 3.7.0 and above... - if info.lVersion>=38 - info.szDescription{n} = deblank(fread(fid,128,'*char')'); % String of channel description - info.nVarSampleDivider(n) = fread(fid,1,'*int16'); % Channel divider of main frequency - end - - % Version 3.7.3 and above... - if info.lVersion>=39 - info.vertPrecision(n) = fread(fid,1,'*int16'); - end - - % Version 3.8.2 and above... - if info.lVersion>=43 - tmp = fread(fid,1,'*int32'); - tmp = sprintf('%6s',dec2hex(tmp,6)); - info.ActiveSegmentColor{n} = [hex2dec(tmp(5:6)) hex2dec(tmp(3:4)) hex2dec(tmp(1:2))]./255; - info.ActiveSegmentStyle(n) = fread(fid,1,'*int32'); - end -end - - -%% FOREIGN DATA SECTION - -info.nLength = fread(fid,1,'*int16'); -info.nID = fread(fid,1,'*int16'); -info.ByForeignData = fread(fid,double(info.nLength-4),'*int8')'; - - -%% PER CHANNEL DATA TYPES SECTION - -for m = 1:info.nChannels - info.nSize(m) = fread(fid,1,'*int16'); % Channel data size in bytes - info.nType(m) = fread(fid,1,'*int16'); % Channel data type : 1 = double, and 2 = short (int16) -end - - -%% CHANNEL DATA SECTION - -% Raw data vector in interleaved format (indexed by bytes) -rawData = fread(fid,double(info.lBufLength)*double(info.nSize'),'*int8'); - -% Channel sequence (indexed by bytes) -cnt = 1; -for m = 1:max(info.nVarSampleDivider) - for n = 1:info.nChannels - if mod(m-1,info.nVarSampleDivider(n))==0 - channelSequence(cnt:(cnt+info.nSize(n)-1)) = int8(n); - cnt = cnt + info.nSize(n); - end - end -end - -% Raw data vector is padded with NaN's in order to have an integer number -% of channel sequence repetitions -tmp3 = numel(channelSequence) - rem(numel(rawData),numel(channelSequence)); -if tmp3>0 - rawData(end+1:end+tmp3) = NaN; -end - -% Raw data vector is reshaped into a matrix (rows correspond to the channel -% sequence, and columns correspond to each repetition of the sequence) -rawData = reshape(rawData,numel(channelSequence),[]); - -% Raw data is extracted channel by channel, and converted into the -% specified numeric type -data = cell(1,info.nChannels); -for n = 1:info.nChannels - tmpChannel = rawData(channelSequence==n,:); - if info.nType(n)==1; - typ = 'double'; - elseif info.nType(n)==2; - typ = 'int16'; - end - data{n} = typecast(tmpChannel(:),typ); - data{n}(info.lBufLength(n)+1:end) = []; -end - - -%% MARKERS HEADER SECTION - -info.lLength = fread(fid,1,'*int32'); -info.lMarkers = fread(fid,1,'*int32'); % Number of markers - - -%% MARKER ITEM SECTION - -if (info.lLength > 0) && (info.lMarkers > 0) - for n = 1:info.lMarkers - info.lSample(n) = fread(fid,1,'*int32'); % Location of marker - info.fSelected(n) = fread(fid,1,'*int16'); - info.fTextLocked(n) = fread(fid,1,'*int16'); - info.fPositionLocked(n) = fread(fid,1,'*int16'); - info.nTextLength(n) = fread(fid,1,'*int16'); % Length of marker text string - info.szText{n} = deblank(fread(fid,double(info.nTextLength(n)+1),'*char')'); % Marker text string - end -else - info.lSample = []; - info.fSelected = []; - info.fTextLocked = []; - info.fPositionLocked = []; - info.nTextLength = []; - info.szText = []; -end - - -%% Closing file... - +function [info, data] = acqread(filename) +% ACQREAD Read a Biopac AcqKnowledge file. +% [INFO, DATA] = ACQREAD(FILENAME) reads the content of the AcqKnowledge +% file specified in the string FILENAME. INFO is a structure containing +% the metadata (header, markers, etc.). DATA is a cell array, indexed +% by the channel number, containing the acquired physiological signals. +% +% [INFO, DATA] = ACQREAD displays a dialog box that is used to retrieve +% the desired file. +% +% ACQREAD supports all files created with Windows/PC versions of +% AcqKnowledge (3.9.0 or below), BSL (3.7.0 or below), and BSL PRO +% (3.7.0 or below). +% +% ACQREAD supports channels that were acquired using different sampling +% rates, therefore having a different number of samples. +% +% Details of the AcqKnowledge file format are presented in Biopac's +% Application Note #156 (last updated on February 23, 2007), and +% available at : "http://www.biopac.com/Manuals/app_pdf/app156.pdf". +% +% ACQREAD, version 2.0 (2007-08-21) +% Copyright (C) 2006-2007 Sebastien Authier and Vincent Finnerty +% +% This program is free software; you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation; either version 2 of the License, or +% (at your option) any later version. +% +% This program is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with this program; if not, write to the Free Software +% Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +% 02110-1301, USA + +%% Opening file... + +error(nargchk(0,1,nargin)) +if nargin==1 + if exist(filename,'file')~=2 + error(['File "',filename,'" not found.']) + else + [fid,message] = fopen(filename,'r'); + if fid==-1 + error(message) + end + end +else + [filename,pathname] = uigetfile({'*.acq','AcqKnowledge File (*.acq)';... + '*.*','All Files (*.*)'}); + if filename==0 + return + else + filename = fullfile(pathname,filename); + [fid,message] = fopen(filename,'r'); + if fid==-1 + error(message) + end + end +end + +%% GRAPH HEADER SECTION + +info.nItemHeaderLen = fread(fid,1,'*int16'); +info.lVersion = fread(fid,1,'*int32'); % File version identifier +% 30 = Pre-version 2.0 +% 31 = Version 2.0 Beta 1 +% 32 = Version 2.0 release +% 33 = Version 2.0.7 (Mac) +% 34 = Version 3.0 In-house Release 1 +% 35 = Version 3.03 +% 36 = Version 3.5x (Win 95, 98, NT) +% 37 = Version of BSL/PRO 3.6.x +% 38 = Version of Acq 3.7.0-3.7.2 (Win 98, 98SE, NT, Me, 2000) +% 39 = Version of Acq 3.7.3 or above (Win 98, 98SE, 2000, Me, XP) +% 41 = Version of Acq 3.8.1 or above (Win 98, 98SE, 2000, Me, XP) +% 42 = Version of BSL/PRO 3.7.X or above (Win 98, 98SE, 2000, Me, XP) +% 43 = Version of Acq 3.8.2 or above (Win 98, 98SE, 2000, Me, XP) +% 44 = Version of BSL/PRO 3.8.x or above +% 45 = Version of Acq 3.9.0 or above +if (info.lVersion<30) || (info.lVersion>45) + error (['Unable to read file "',filename,'" : invalid file type, or unsupported file version.']) +end +info.lExtItemHeaderLen = fread(fid,1,'*int32'); +info.nChannels = fread(fid,1,'*int16'); % Number of channels +info.nHorizAxisType = fread(fid,1,'*int16'); +info.nCurChannel = fread(fid,1,'*int16'); +info.dSampleTime = fread(fid,1,'*double'); % Number of milliseconds per sample +info.dTimeOffset = fread(fid,1,'*double'); % Initial time offset in milliseconds +info.dTimeScale = fread(fid,1,'*double'); % Time scale in milliseconds per division +info.dTimeCursor1 = fread(fid,1,'*double'); +info.dTimeCursor2 = fread(fid,1,'*double'); +info.rcWindow = fread(fid,1,'*double'); +info.nMeasurement = fread(fid,6,'*int16')'; +info.fHilite = fread(fid,1,'*int16'); +info.dFirstTimeOffset = fread(fid,1,'*double'); +info.nRescale = fread(fid,1,'*int16'); +info.szHorizUnits1 = deblank(fread(fid,40,'*char')'); % Horizontal units text +info.szHorizUnits2 = deblank(fread(fid,10,'*char')'); % Horizontal units text (abbreviated) +info.nInMemory = fread(fid,1,'*int16'); +info.fGrid = fread(fid,1,'*int16'); +info.fMarkers = fread(fid,1,'*int16'); +info.nPlotDraft = fread(fid,1,'*int16'); +info.nDispMode = fread(fid,1,'*int16'); +info.nReserved = fread(fid,1,'*int16'); + +% Version 3.0 and above... +if info.lVersion>=34 + info.BShowToolBar = fread(fid,1,'*int16'); + info.BShowChannelButtons = fread(fid,1,'*int16'); + info.BShowMeasurements = fread(fid,1,'int16'); + info.BShowMarkers = fread(fid,1,'*int16'); + info.BShowJournal = fread(fid,1,'*int16'); + info.CurXChannel = fread(fid,1,'*int16'); + info.MmtPrecision = fread(fid,1,'*int16'); +end + +% Version 3.02 and above... +if info.lVersion>=35 + info.NMeasurementRows = fread(fid,1,'*int16'); + info.mmt = fread(fid,40,'*int16')'; + info.mmtChan = fread(fid,40,'*int16')'; +end + +% Version 3.5x and above... +if info.lVersion>=36 + info.MmtCalcOpnd1 = fread(fid,40,'*int16')'; + info.MmtCalcOpnd2 = fread(fid,40,'*int16')'; + info.MmtCalcOp = fread(fid,40,'*int16')'; + info.MmtCalcConstant = fread(fid,40,'*double')'; +end + +% Version 3.7.0 and above... +if info.lVersion>=38 + tmp = fread(fid,1,'*int32'); + tmp = sprintf('%6s',dec2hex(tmp,6)); + info.bNewGridwithMinor = [hex2dec(tmp(5:6)) hex2dec(tmp(3:4)) hex2dec(tmp(1:2))]./255; + tmp = fread(fid,1,'*int32'); + tmp = sprintf('%6s',dec2hex(tmp,6)); + info.colorMajorGrid = [hex2dec(tmp(5:6)) hex2dec(tmp(3:4)) hex2dec(tmp(1:2))]./255; + info.colorMinorGrid = fread(fid,1,'*int32'); + info.wMajorGridStyle = fread(fid,1,'*int16'); + info.wMinorGridStyle = fread(fid,1,'*int16'); + info.wMajorGridWidth = fread(fid,1,'*int16'); + info.wMinorGridWidth = fread(fid,1,'*int16'); + info.bFixedUnitsDiv = fread(fid,1,'*int32'); + info.bMid_Range_Show = fread(fid,1,'*int32'); + info.dStart_Middle_Point = fread(fid,1,'*double'); + info.dOffset_Point = fread(fid,60,'*double')'; + info.hGrid = fread(fid,1,'*double'); + info.vGrid = fread(fid,60,'*double')'; + info.bEnableWaveTools = fread(fid,1,'*int32'); +end + +% Version 3.7.3 and above... +if info.lVersion>=39 + info.horizPrecision = fread(fid,1,'*int16'); +end + +% Version 3.8.1 and above... +if info.lVersion>=41 + fseek(fid,20,'cof') % RESERVED + info.bOverlapMode = fread(fid,1,'*int32'); + info.bShowHardware = fread(fid,1,'*int32'); + info.bXAutoplot = fread(fid,1,'*int32'); + info.bXAutoScroll = fread(fid,1,'*int32'); + info.bStartButtonVisible = fread(fid,1,'*int32'); + info.bCompressed = fread(fid,1,'*int32'); + info.AlwaysStartButtonVisible = fread(fid,1,'*int32'); +end + +% Version 3.8.2 and above... +if info.lVersion>=43 + info.pathVideo = deblank(fread(fid,260,'*char')'); + info.optSyncDelay = fread(fid,1,'*int32'); + info.syncDelay = fread(fid,1,'*double'); + info.bHRP_PasteMeasurements = fread(fid,1,'*int32'); +end + +% Version 3.9.0 and above... +if info.lVersion>=45 + info.graphType = fread(fid,1,'*int32')'; + for n = 1:40 + info.mmtCalcExpr{n} = deblank(fread(fid,256,'*char')'); + end + info.mmtMomentOrder = fread(fid,40,'*int32')'; + info.mmtTimeDelay = fread(fid,40,'*int32')'; + info.mmtEmbedDim = fread(fid,40,'*int32')'; + info.mmtMIDelay = fread(fid,40,'*int32')'; +end + +%% PER CHANNEL DATA SECTION + +for n = 1:info.nChannels + info.lChanHeaderLen(n) = fread(fid,1,'*int32'); + info.nNum(n) = fread(fid,1,'*int16'); + info.szCommentText{n} = deblank(fread(fid,40,'*char')'); % Comment text + tmp = fread(fid,1,'*int32'); + tmp = sprintf('%6s',dec2hex(tmp,6)); + info.rgbColor{n} = [hex2dec(tmp(5:6)) hex2dec(tmp(3:4)) hex2dec(tmp(1:2))]./255; + info.nDispChan(n) = fread(fid,1,'*int16'); + info.dVoltOffset(n) = fread(fid,1,'*double'); % Amplitude offset (volts) + info.dVoltScale(n) = fread(fid,1,'*double'); % Amplitude scale (volts/div.) + info.szUnitsText{n} = deblank(fread(fid,20,'*char')'); % Units text + info.lBufLength(n) = fread(fid,1,'*int32'); % Number of data samples + info.dAmplScale(n) = fread(fid,1,'*double'); % Units/count + info.dAmplOffset(n) = fread(fid,1,'*double'); % Units + info.nChanOrder(n) = fread(fid,1,'*int16'); + info.nDispSize(n) = fread(fid,1,'*int16'); + + % Version 3.0 and above... + if info.lVersion>=34 + info.plotMode(n) = fread(fid,1,'*int16'); + info.vMid(n) = fread(fid,1,'*double'); + end + + % Version 3.7.0 and above... + if info.lVersion>=38 + info.szDescription{n} = deblank(fread(fid,128,'*char')'); % String of channel description + info.nVarSampleDivider(n) = fread(fid,1,'*int16'); % Channel divider of main frequency + end + + % Version 3.7.3 and above... + if info.lVersion>=39 + info.vertPrecision(n) = fread(fid,1,'*int16'); + end + + % Version 3.8.2 and above... + if info.lVersion>=43 + tmp = fread(fid,1,'*int32'); + tmp = sprintf('%6s',dec2hex(tmp,6)); + info.ActiveSegmentColor{n} = [hex2dec(tmp(5:6)) hex2dec(tmp(3:4)) hex2dec(tmp(1:2))]./255; + info.ActiveSegmentStyle(n) = fread(fid,1,'*int32'); + end +end + + +%% FOREIGN DATA SECTION + +info.nLength = fread(fid,1,'*int16'); +info.nID = fread(fid,1,'*int16'); +info.ByForeignData = fread(fid,double(info.nLength-4),'*int8')'; + + +%% PER CHANNEL DATA TYPES SECTION + +for m = 1:info.nChannels + info.nSize(m) = fread(fid,1,'*int16'); % Channel data size in bytes + info.nType(m) = fread(fid,1,'*int16'); % Channel data type : 1 = double, and 2 = short (int16) +end + + +%% CHANNEL DATA SECTION + +% Raw data vector in interleaved format (indexed by bytes) +rawData = fread(fid,double(info.lBufLength)*double(info.nSize'),'*int8'); + +% Channel sequence (indexed by bytes) +cnt = 1; +for m = 1:max(info.nVarSampleDivider) + for n = 1:info.nChannels + if mod(m-1,info.nVarSampleDivider(n))==0 + channelSequence(cnt:(cnt+info.nSize(n)-1)) = int8(n); + cnt = cnt + info.nSize(n); + end + end +end + +% Raw data vector is padded with NaN's in order to have an integer number +% of channel sequence repetitions +tmp3 = numel(channelSequence) - rem(numel(rawData),numel(channelSequence)); +if tmp3>0 + rawData(end+1:end+tmp3) = NaN; +end + +% Raw data vector is reshaped into a matrix (rows correspond to the channel +% sequence, and columns correspond to each repetition of the sequence) +rawData = reshape(rawData,numel(channelSequence),[]); + +% Raw data is extracted channel by channel, and converted into the +% specified numeric type +data = cell(1,info.nChannels); +for n = 1:info.nChannels + tmpChannel = rawData(channelSequence==n,:); + if info.nType(n)==1; + typ = 'double'; + elseif info.nType(n)==2; + typ = 'int16'; + end + data{n} = typecast(tmpChannel(:),typ); + data{n}(info.lBufLength(n)+1:end) = []; +end + + +%% MARKERS HEADER SECTION + +info.lLength = fread(fid,1,'*int32'); +info.lMarkers = fread(fid,1,'*int32'); % Number of markers + + +%% MARKER ITEM SECTION + +if (info.lLength > 0) && (info.lMarkers > 0) + for n = 1:info.lMarkers + info.lSample(n) = fread(fid,1,'*int32'); % Location of marker + info.fSelected(n) = fread(fid,1,'*int16'); + info.fTextLocked(n) = fread(fid,1,'*int16'); + info.fPositionLocked(n) = fread(fid,1,'*int16'); + info.nTextLength(n) = fread(fid,1,'*int16'); % Length of marker text string + info.szText{n} = deblank(fread(fid,double(info.nTextLength(n)+1),'*char')'); % Marker text string + end +else + info.lSample = []; + info.fSelected = []; + info.fTextLocked = []; + info.fPositionLocked = []; + info.nTextLength = []; + info.szText = []; +end + + +%% Closing file... + fclose(fid); \ No newline at end of file diff --git a/src/Import/acq/app156.pdf b/Import/acq/app156.pdf similarity index 100% rename from src/Import/acq/app156.pdf rename to Import/acq/app156.pdf diff --git a/src/Import/acq/license.txt b/Import/acq/license.txt similarity index 98% rename from src/Import/acq/license.txt rename to Import/acq/license.txt index 18f750e3..b1a417c4 100644 --- a/src/Import/acq/license.txt +++ b/Import/acq/license.txt @@ -1,24 +1,24 @@ -Copyright (c) 2008, Sebastien Authier -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. +Copyright (c) 2008, Sebastien Authier +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/src/Import/biograph/SA7913 BioGraph Infiniti Getting Started.pdf b/Import/biograph/SA7913 BioGraph Infiniti Getting Started.pdf similarity index 100% rename from src/Import/biograph/SA7913 BioGraph Infiniti Getting Started.pdf rename to Import/biograph/SA7913 BioGraph Infiniti Getting Started.pdf diff --git a/src/Import/eyelink/import_eyelink.m b/Import/eyelink/import_eyelink.m similarity index 100% rename from src/Import/eyelink/import_eyelink.m rename to Import/eyelink/import_eyelink.m diff --git a/src/Import/fieldtrip/fileio/COPYING b/Import/fieldtrip/fileio/COPYING similarity index 100% rename from src/Import/fieldtrip/fileio/COPYING rename to Import/fieldtrip/fileio/COPYING diff --git a/src/Import/fieldtrip/fileio/README b/Import/fieldtrip/fileio/README similarity index 100% rename from src/Import/fieldtrip/fileio/README rename to Import/fieldtrip/fileio/README diff --git a/src/Import/fieldtrip/fileio/ft_chantype.m b/Import/fieldtrip/fileio/ft_chantype.m similarity index 100% rename from src/Import/fieldtrip/fileio/ft_chantype.m rename to Import/fieldtrip/fileio/ft_chantype.m diff --git a/src/Import/fieldtrip/fileio/ft_chanunit.m b/Import/fieldtrip/fileio/ft_chanunit.m similarity index 100% rename from src/Import/fieldtrip/fileio/ft_chanunit.m rename to Import/fieldtrip/fileio/ft_chanunit.m diff --git a/src/Import/fieldtrip/fileio/ft_create_buffer.m b/Import/fieldtrip/fileio/ft_create_buffer.m similarity index 100% rename from src/Import/fieldtrip/fileio/ft_create_buffer.m rename to Import/fieldtrip/fileio/ft_create_buffer.m diff --git a/src/Import/fieldtrip/fileio/ft_destroy_buffer.m b/Import/fieldtrip/fileio/ft_destroy_buffer.m similarity index 100% rename from src/Import/fieldtrip/fileio/ft_destroy_buffer.m rename to Import/fieldtrip/fileio/ft_destroy_buffer.m diff --git a/src/Import/fieldtrip/fileio/ft_filetype.m b/Import/fieldtrip/fileio/ft_filetype.m similarity index 100% rename from src/Import/fieldtrip/fileio/ft_filetype.m rename to Import/fieldtrip/fileio/ft_filetype.m diff --git a/src/Import/fieldtrip/fileio/ft_filter_event.m b/Import/fieldtrip/fileio/ft_filter_event.m similarity index 100% rename from src/Import/fieldtrip/fileio/ft_filter_event.m rename to Import/fieldtrip/fileio/ft_filter_event.m diff --git a/src/Import/fieldtrip/fileio/ft_flush_data.m b/Import/fieldtrip/fileio/ft_flush_data.m similarity index 100% rename from src/Import/fieldtrip/fileio/ft_flush_data.m rename to Import/fieldtrip/fileio/ft_flush_data.m diff --git a/src/Import/fieldtrip/fileio/ft_flush_event.m b/Import/fieldtrip/fileio/ft_flush_event.m similarity index 100% rename from src/Import/fieldtrip/fileio/ft_flush_event.m rename to Import/fieldtrip/fileio/ft_flush_event.m diff --git a/src/Import/fieldtrip/fileio/ft_flush_header.m b/Import/fieldtrip/fileio/ft_flush_header.m similarity index 100% rename from src/Import/fieldtrip/fileio/ft_flush_header.m rename to Import/fieldtrip/fileio/ft_flush_header.m diff --git a/src/Import/fieldtrip/fileio/ft_poll_buffer.m b/Import/fieldtrip/fileio/ft_poll_buffer.m similarity index 100% rename from src/Import/fieldtrip/fileio/ft_poll_buffer.m rename to Import/fieldtrip/fileio/ft_poll_buffer.m diff --git a/src/Import/fieldtrip/fileio/ft_read_atlas.m b/Import/fieldtrip/fileio/ft_read_atlas.m similarity index 100% rename from src/Import/fieldtrip/fileio/ft_read_atlas.m rename to Import/fieldtrip/fileio/ft_read_atlas.m diff --git a/src/Import/fieldtrip/fileio/ft_read_cifti.m b/Import/fieldtrip/fileio/ft_read_cifti.m similarity index 100% rename from src/Import/fieldtrip/fileio/ft_read_cifti.m rename to Import/fieldtrip/fileio/ft_read_cifti.m diff --git a/src/Import/fieldtrip/fileio/ft_read_data.m b/Import/fieldtrip/fileio/ft_read_data.m similarity index 100% rename from src/Import/fieldtrip/fileio/ft_read_data.m rename to Import/fieldtrip/fileio/ft_read_data.m diff --git a/src/Import/fieldtrip/fileio/ft_read_event.m b/Import/fieldtrip/fileio/ft_read_event.m similarity index 100% rename from src/Import/fieldtrip/fileio/ft_read_event.m rename to Import/fieldtrip/fileio/ft_read_event.m diff --git a/src/Import/fieldtrip/fileio/ft_read_header.m b/Import/fieldtrip/fileio/ft_read_header.m similarity index 100% rename from src/Import/fieldtrip/fileio/ft_read_header.m rename to Import/fieldtrip/fileio/ft_read_header.m diff --git a/src/Import/fieldtrip/fileio/ft_read_headshape.m b/Import/fieldtrip/fileio/ft_read_headshape.m similarity index 100% rename from src/Import/fieldtrip/fileio/ft_read_headshape.m rename to Import/fieldtrip/fileio/ft_read_headshape.m diff --git a/src/Import/fieldtrip/fileio/ft_read_mri.m b/Import/fieldtrip/fileio/ft_read_mri.m similarity index 100% rename from src/Import/fieldtrip/fileio/ft_read_mri.m rename to Import/fieldtrip/fileio/ft_read_mri.m diff --git a/src/Import/fieldtrip/fileio/ft_read_sens.m b/Import/fieldtrip/fileio/ft_read_sens.m similarity index 100% rename from src/Import/fieldtrip/fileio/ft_read_sens.m rename to Import/fieldtrip/fileio/ft_read_sens.m diff --git a/src/Import/fieldtrip/fileio/ft_read_spike.m b/Import/fieldtrip/fileio/ft_read_spike.m similarity index 100% rename from src/Import/fieldtrip/fileio/ft_read_spike.m rename to Import/fieldtrip/fileio/ft_read_spike.m diff --git a/src/Import/fieldtrip/fileio/ft_read_vol.m b/Import/fieldtrip/fileio/ft_read_vol.m similarity index 100% rename from src/Import/fieldtrip/fileio/ft_read_vol.m rename to Import/fieldtrip/fileio/ft_read_vol.m diff --git a/src/Import/fieldtrip/fileio/ft_write_cifti.m b/Import/fieldtrip/fileio/ft_write_cifti.m similarity index 100% rename from src/Import/fieldtrip/fileio/ft_write_cifti.m rename to Import/fieldtrip/fileio/ft_write_cifti.m diff --git a/src/Import/fieldtrip/fileio/ft_write_data.m b/Import/fieldtrip/fileio/ft_write_data.m similarity index 100% rename from src/Import/fieldtrip/fileio/ft_write_data.m rename to Import/fieldtrip/fileio/ft_write_data.m diff --git a/src/Import/fieldtrip/fileio/ft_write_event.m b/Import/fieldtrip/fileio/ft_write_event.m similarity index 100% rename from src/Import/fieldtrip/fileio/ft_write_event.m rename to Import/fieldtrip/fileio/ft_write_event.m diff --git a/src/Import/fieldtrip/fileio/ft_write_headshape.m b/Import/fieldtrip/fileio/ft_write_headshape.m similarity index 100% rename from src/Import/fieldtrip/fileio/ft_write_headshape.m rename to Import/fieldtrip/fileio/ft_write_headshape.m diff --git a/src/Import/fieldtrip/fileio/ft_write_mri.m b/Import/fieldtrip/fileio/ft_write_mri.m similarity index 100% rename from src/Import/fieldtrip/fileio/ft_write_mri.m rename to Import/fieldtrip/fileio/ft_write_mri.m diff --git a/src/Import/fieldtrip/fileio/ft_write_spike.m b/Import/fieldtrip/fileio/ft_write_spike.m similarity index 100% rename from src/Import/fieldtrip/fileio/ft_write_spike.m rename to Import/fieldtrip/fileio/ft_write_spike.m diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/abs.c b/Import/fieldtrip/fileio/matlablt2010b/@uint64/abs.c similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/abs.c rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/abs.c diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/abs.m b/Import/fieldtrip/fileio/matlablt2010b/@uint64/abs.m similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/abs.m rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/abs.m diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/abs.mexa64 b/Import/fieldtrip/fileio/matlablt2010b/@uint64/abs.mexa64 similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/abs.mexa64 rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/abs.mexa64 diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/abs.mexglx b/Import/fieldtrip/fileio/matlablt2010b/@uint64/abs.mexglx similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/abs.mexglx rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/abs.mexglx diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/abs.mexmaci b/Import/fieldtrip/fileio/matlablt2010b/@uint64/abs.mexmaci similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/abs.mexmaci rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/abs.mexmaci diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/abs.mexmaci64 b/Import/fieldtrip/fileio/matlablt2010b/@uint64/abs.mexmaci64 similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/abs.mexmaci64 rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/abs.mexmaci64 diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/abs.mexw32 b/Import/fieldtrip/fileio/matlablt2010b/@uint64/abs.mexw32 similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/abs.mexw32 rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/abs.mexw32 diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/abs.mexw64 b/Import/fieldtrip/fileio/matlablt2010b/@uint64/abs.mexw64 similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/abs.mexw64 rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/abs.mexw64 diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/all.m b/Import/fieldtrip/fileio/matlablt2010b/@uint64/all.m similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/all.m rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/all.m diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/any.m b/Import/fieldtrip/fileio/matlablt2010b/@uint64/any.m similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/any.m rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/any.m diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/compile_uint64.m b/Import/fieldtrip/fileio/matlablt2010b/@uint64/compile_uint64.m similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/compile_uint64.m rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/compile_uint64.m diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/diff.m b/Import/fieldtrip/fileio/matlablt2010b/@uint64/diff.m similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/diff.m rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/diff.m diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/max.c b/Import/fieldtrip/fileio/matlablt2010b/@uint64/max.c similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/max.c rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/max.c diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/max.m b/Import/fieldtrip/fileio/matlablt2010b/@uint64/max.m similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/max.m rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/max.m diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/max.mexa64 b/Import/fieldtrip/fileio/matlablt2010b/@uint64/max.mexa64 similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/max.mexa64 rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/max.mexa64 diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/max.mexglx b/Import/fieldtrip/fileio/matlablt2010b/@uint64/max.mexglx similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/max.mexglx rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/max.mexglx diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/max.mexmac b/Import/fieldtrip/fileio/matlablt2010b/@uint64/max.mexmac similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/max.mexmac rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/max.mexmac diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/max.mexmaci b/Import/fieldtrip/fileio/matlablt2010b/@uint64/max.mexmaci similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/max.mexmaci rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/max.mexmaci diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/max.mexmaci64 b/Import/fieldtrip/fileio/matlablt2010b/@uint64/max.mexmaci64 similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/max.mexmaci64 rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/max.mexmaci64 diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/max.mexw32 b/Import/fieldtrip/fileio/matlablt2010b/@uint64/max.mexw32 similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/max.mexw32 rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/max.mexw32 diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/max.mexw64 b/Import/fieldtrip/fileio/matlablt2010b/@uint64/max.mexw64 similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/max.mexw64 rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/max.mexw64 diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/min.c b/Import/fieldtrip/fileio/matlablt2010b/@uint64/min.c similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/min.c rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/min.c diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/min.m b/Import/fieldtrip/fileio/matlablt2010b/@uint64/min.m similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/min.m rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/min.m diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/min.mexa64 b/Import/fieldtrip/fileio/matlablt2010b/@uint64/min.mexa64 similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/min.mexa64 rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/min.mexa64 diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/min.mexglx b/Import/fieldtrip/fileio/matlablt2010b/@uint64/min.mexglx similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/min.mexglx rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/min.mexglx diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/min.mexmac b/Import/fieldtrip/fileio/matlablt2010b/@uint64/min.mexmac similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/min.mexmac rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/min.mexmac diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/min.mexmaci b/Import/fieldtrip/fileio/matlablt2010b/@uint64/min.mexmaci similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/min.mexmaci rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/min.mexmaci diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/min.mexmaci64 b/Import/fieldtrip/fileio/matlablt2010b/@uint64/min.mexmaci64 similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/min.mexmaci64 rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/min.mexmaci64 diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/min.mexw32 b/Import/fieldtrip/fileio/matlablt2010b/@uint64/min.mexw32 similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/min.mexw32 rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/min.mexw32 diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/min.mexw64 b/Import/fieldtrip/fileio/matlablt2010b/@uint64/min.mexw64 similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/min.mexw64 rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/min.mexw64 diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/minus.c b/Import/fieldtrip/fileio/matlablt2010b/@uint64/minus.c similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/minus.c rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/minus.c diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/minus.m b/Import/fieldtrip/fileio/matlablt2010b/@uint64/minus.m similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/minus.m rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/minus.m diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/minus.mexa64 b/Import/fieldtrip/fileio/matlablt2010b/@uint64/minus.mexa64 similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/minus.mexa64 rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/minus.mexa64 diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/minus.mexglx b/Import/fieldtrip/fileio/matlablt2010b/@uint64/minus.mexglx similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/minus.mexglx rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/minus.mexglx diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/minus.mexmac b/Import/fieldtrip/fileio/matlablt2010b/@uint64/minus.mexmac similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/minus.mexmac rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/minus.mexmac diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/minus.mexmaci b/Import/fieldtrip/fileio/matlablt2010b/@uint64/minus.mexmaci similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/minus.mexmaci rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/minus.mexmaci diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/minus.mexmaci64 b/Import/fieldtrip/fileio/matlablt2010b/@uint64/minus.mexmaci64 similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/minus.mexmaci64 rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/minus.mexmaci64 diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/minus.mexw32 b/Import/fieldtrip/fileio/matlablt2010b/@uint64/minus.mexw32 similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/minus.mexw32 rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/minus.mexw32 diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/minus.mexw64 b/Import/fieldtrip/fileio/matlablt2010b/@uint64/minus.mexw64 similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/minus.mexw64 rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/minus.mexw64 diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/plus.c b/Import/fieldtrip/fileio/matlablt2010b/@uint64/plus.c similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/plus.c rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/plus.c diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/plus.m b/Import/fieldtrip/fileio/matlablt2010b/@uint64/plus.m similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/plus.m rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/plus.m diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/plus.mexa64 b/Import/fieldtrip/fileio/matlablt2010b/@uint64/plus.mexa64 similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/plus.mexa64 rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/plus.mexa64 diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/plus.mexglx b/Import/fieldtrip/fileio/matlablt2010b/@uint64/plus.mexglx similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/plus.mexglx rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/plus.mexglx diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/plus.mexmac b/Import/fieldtrip/fileio/matlablt2010b/@uint64/plus.mexmac similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/plus.mexmac rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/plus.mexmac diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/plus.mexmaci b/Import/fieldtrip/fileio/matlablt2010b/@uint64/plus.mexmaci similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/plus.mexmaci rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/plus.mexmaci diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/plus.mexmaci64 b/Import/fieldtrip/fileio/matlablt2010b/@uint64/plus.mexmaci64 similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/plus.mexmaci64 rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/plus.mexmaci64 diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/plus.mexw32 b/Import/fieldtrip/fileio/matlablt2010b/@uint64/plus.mexw32 similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/plus.mexw32 rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/plus.mexw32 diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/plus.mexw64 b/Import/fieldtrip/fileio/matlablt2010b/@uint64/plus.mexw64 similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/plus.mexw64 rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/plus.mexw64 diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/rdivide.c b/Import/fieldtrip/fileio/matlablt2010b/@uint64/rdivide.c similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/rdivide.c rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/rdivide.c diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/rdivide.m b/Import/fieldtrip/fileio/matlablt2010b/@uint64/rdivide.m similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/rdivide.m rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/rdivide.m diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/rdivide.mexa64 b/Import/fieldtrip/fileio/matlablt2010b/@uint64/rdivide.mexa64 similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/rdivide.mexa64 rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/rdivide.mexa64 diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/rdivide.mexglx b/Import/fieldtrip/fileio/matlablt2010b/@uint64/rdivide.mexglx similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/rdivide.mexglx rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/rdivide.mexglx diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/rdivide.mexmac b/Import/fieldtrip/fileio/matlablt2010b/@uint64/rdivide.mexmac similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/rdivide.mexmac rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/rdivide.mexmac diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/rdivide.mexmaci b/Import/fieldtrip/fileio/matlablt2010b/@uint64/rdivide.mexmaci similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/rdivide.mexmaci rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/rdivide.mexmaci diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/rdivide.mexmaci64 b/Import/fieldtrip/fileio/matlablt2010b/@uint64/rdivide.mexmaci64 similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/rdivide.mexmaci64 rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/rdivide.mexmaci64 diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/rdivide.mexw32 b/Import/fieldtrip/fileio/matlablt2010b/@uint64/rdivide.mexw32 similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/rdivide.mexw32 rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/rdivide.mexw32 diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/rdivide.mexw64 b/Import/fieldtrip/fileio/matlablt2010b/@uint64/rdivide.mexw64 similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/rdivide.mexw64 rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/rdivide.mexw64 diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/test.m b/Import/fieldtrip/fileio/matlablt2010b/@uint64/test.m similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/test.m rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/test.m diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/times.c b/Import/fieldtrip/fileio/matlablt2010b/@uint64/times.c similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/times.c rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/times.c diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/times.m b/Import/fieldtrip/fileio/matlablt2010b/@uint64/times.m similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/times.m rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/times.m diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/times.mexa64 b/Import/fieldtrip/fileio/matlablt2010b/@uint64/times.mexa64 similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/times.mexa64 rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/times.mexa64 diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/times.mexglx b/Import/fieldtrip/fileio/matlablt2010b/@uint64/times.mexglx similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/times.mexglx rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/times.mexglx diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/times.mexmac b/Import/fieldtrip/fileio/matlablt2010b/@uint64/times.mexmac similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/times.mexmac rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/times.mexmac diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/times.mexmaci b/Import/fieldtrip/fileio/matlablt2010b/@uint64/times.mexmaci similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/times.mexmaci rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/times.mexmaci diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/times.mexmaci64 b/Import/fieldtrip/fileio/matlablt2010b/@uint64/times.mexmaci64 similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/times.mexmaci64 rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/times.mexmaci64 diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/times.mexw32 b/Import/fieldtrip/fileio/matlablt2010b/@uint64/times.mexw32 similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/times.mexw32 rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/times.mexw32 diff --git a/src/Import/fieldtrip/fileio/matlablt2010b/@uint64/times.mexw64 b/Import/fieldtrip/fileio/matlablt2010b/@uint64/times.mexw64 similarity index 100% rename from src/Import/fieldtrip/fileio/matlablt2010b/@uint64/times.mexw64 rename to Import/fieldtrip/fileio/matlablt2010b/@uint64/times.mexw64 diff --git a/src/Import/fieldtrip/fileio/private/ReadHeader.m b/Import/fieldtrip/fileio/private/ReadHeader.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/ReadHeader.m rename to Import/fieldtrip/fileio/private/ReadHeader.m diff --git a/src/Import/fieldtrip/fileio/private/add_mex_source.m b/Import/fieldtrip/fileio/private/add_mex_source.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/add_mex_source.m rename to Import/fieldtrip/fileio/private/add_mex_source.m diff --git a/src/Import/fieldtrip/fileio/private/ama2vol.m b/Import/fieldtrip/fileio/private/ama2vol.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/ama2vol.m rename to Import/fieldtrip/fileio/private/ama2vol.m diff --git a/src/Import/fieldtrip/fileio/private/appendevent.m b/Import/fieldtrip/fileio/private/appendevent.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/appendevent.m rename to Import/fieldtrip/fileio/private/appendevent.m diff --git a/src/Import/fieldtrip/fileio/private/avw_hdr_read.m b/Import/fieldtrip/fileio/private/avw_hdr_read.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/avw_hdr_read.m rename to Import/fieldtrip/fileio/private/avw_hdr_read.m diff --git a/src/Import/fieldtrip/fileio/private/avw_img_read.m b/Import/fieldtrip/fileio/private/avw_img_read.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/avw_img_read.m rename to Import/fieldtrip/fileio/private/avw_img_read.m diff --git a/src/Import/fieldtrip/fileio/private/bigendian.m b/Import/fieldtrip/fileio/private/bigendian.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/bigendian.m rename to Import/fieldtrip/fileio/private/bigendian.m diff --git a/src/Import/fieldtrip/fileio/private/bounding_mesh.m b/Import/fieldtrip/fileio/private/bounding_mesh.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/bounding_mesh.m rename to Import/fieldtrip/fileio/private/bounding_mesh.m diff --git a/src/Import/fieldtrip/fileio/private/bti2grad.m b/Import/fieldtrip/fileio/private/bti2grad.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/bti2grad.m rename to Import/fieldtrip/fileio/private/bti2grad.m diff --git a/src/Import/fieldtrip/fileio/private/buffer.mexa64 b/Import/fieldtrip/fileio/private/buffer.mexa64 similarity index 100% rename from src/Import/fieldtrip/fileio/private/buffer.mexa64 rename to Import/fieldtrip/fileio/private/buffer.mexa64 diff --git a/src/Import/fieldtrip/fileio/private/buffer.mexglx b/Import/fieldtrip/fileio/private/buffer.mexglx similarity index 100% rename from src/Import/fieldtrip/fileio/private/buffer.mexglx rename to Import/fieldtrip/fileio/private/buffer.mexglx diff --git a/src/Import/fieldtrip/fileio/private/buffer.mexmac b/Import/fieldtrip/fileio/private/buffer.mexmac similarity index 100% rename from src/Import/fieldtrip/fileio/private/buffer.mexmac rename to Import/fieldtrip/fileio/private/buffer.mexmac diff --git a/src/Import/fieldtrip/fileio/private/buffer.mexmaci b/Import/fieldtrip/fileio/private/buffer.mexmaci similarity index 100% rename from src/Import/fieldtrip/fileio/private/buffer.mexmaci rename to Import/fieldtrip/fileio/private/buffer.mexmaci diff --git a/src/Import/fieldtrip/fileio/private/buffer.mexmaci64 b/Import/fieldtrip/fileio/private/buffer.mexmaci64 similarity index 100% rename from src/Import/fieldtrip/fileio/private/buffer.mexmaci64 rename to Import/fieldtrip/fileio/private/buffer.mexmaci64 diff --git a/src/Import/fieldtrip/fileio/private/buffer.mexw32 b/Import/fieldtrip/fileio/private/buffer.mexw32 similarity index 100% rename from src/Import/fieldtrip/fileio/private/buffer.mexw32 rename to Import/fieldtrip/fileio/private/buffer.mexw32 diff --git a/src/Import/fieldtrip/fileio/private/buffer.mexw64 b/Import/fieldtrip/fileio/private/buffer.mexw64 similarity index 100% rename from src/Import/fieldtrip/fileio/private/buffer.mexw64 rename to Import/fieldtrip/fileio/private/buffer.mexw64 diff --git a/src/Import/fieldtrip/fileio/private/buffer_wait_dat.m b/Import/fieldtrip/fileio/private/buffer_wait_dat.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/buffer_wait_dat.m rename to Import/fieldtrip/fileio/private/buffer_wait_dat.m diff --git a/src/Import/fieldtrip/fileio/private/channelposition.m b/Import/fieldtrip/fileio/private/channelposition.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/channelposition.m rename to Import/fieldtrip/fileio/private/channelposition.m diff --git a/src/Import/fieldtrip/fileio/private/compile_mex_list.m b/Import/fieldtrip/fileio/private/compile_mex_list.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/compile_mex_list.m rename to Import/fieldtrip/fileio/private/compile_mex_list.m diff --git a/src/Import/fieldtrip/fileio/private/cornerpoints.m b/Import/fieldtrip/fileio/private/cornerpoints.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/cornerpoints.m rename to Import/fieldtrip/fileio/private/cornerpoints.m diff --git a/src/Import/fieldtrip/fileio/private/cstructdecode.m b/Import/fieldtrip/fileio/private/cstructdecode.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/cstructdecode.m rename to Import/fieldtrip/fileio/private/cstructdecode.m diff --git a/src/Import/fieldtrip/fileio/private/ctf2grad.m b/Import/fieldtrip/fileio/private/ctf2grad.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/ctf2grad.m rename to Import/fieldtrip/fileio/private/ctf2grad.m diff --git a/src/Import/fieldtrip/fileio/private/dataset2files.m b/Import/fieldtrip/fileio/private/dataset2files.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/dataset2files.m rename to Import/fieldtrip/fileio/private/dataset2files.m diff --git a/src/Import/fieldtrip/fileio/private/db_close.m b/Import/fieldtrip/fileio/private/db_close.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/db_close.m rename to Import/fieldtrip/fileio/private/db_close.m diff --git a/src/Import/fieldtrip/fileio/private/db_insert.m b/Import/fieldtrip/fileio/private/db_insert.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/db_insert.m rename to Import/fieldtrip/fileio/private/db_insert.m diff --git a/src/Import/fieldtrip/fileio/private/db_insert_blob.m b/Import/fieldtrip/fileio/private/db_insert_blob.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/db_insert_blob.m rename to Import/fieldtrip/fileio/private/db_insert_blob.m diff --git a/src/Import/fieldtrip/fileio/private/db_open.m b/Import/fieldtrip/fileio/private/db_open.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/db_open.m rename to Import/fieldtrip/fileio/private/db_open.m diff --git a/src/Import/fieldtrip/fileio/private/db_select.m b/Import/fieldtrip/fileio/private/db_select.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/db_select.m rename to Import/fieldtrip/fileio/private/db_select.m diff --git a/src/Import/fieldtrip/fileio/private/db_select_blob.m b/Import/fieldtrip/fileio/private/db_select_blob.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/db_select_blob.m rename to Import/fieldtrip/fileio/private/db_select_blob.m diff --git a/src/Import/fieldtrip/fileio/private/decode_fif.m b/Import/fieldtrip/fileio/private/decode_fif.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/decode_fif.m rename to Import/fieldtrip/fileio/private/decode_fif.m diff --git a/src/Import/fieldtrip/fileio/private/decode_nifti1.m b/Import/fieldtrip/fileio/private/decode_nifti1.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/decode_nifti1.m rename to Import/fieldtrip/fileio/private/decode_nifti1.m diff --git a/src/Import/fieldtrip/fileio/private/decode_res4.m b/Import/fieldtrip/fileio/private/decode_res4.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/decode_res4.m rename to Import/fieldtrip/fileio/private/decode_res4.m diff --git a/src/Import/fieldtrip/fileio/private/dimlength.m b/Import/fieldtrip/fileio/private/dimlength.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/dimlength.m rename to Import/fieldtrip/fileio/private/dimlength.m diff --git a/src/Import/fieldtrip/fileio/private/elproj.m b/Import/fieldtrip/fileio/private/elproj.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/elproj.m rename to Import/fieldtrip/fileio/private/elproj.m diff --git a/src/Import/fieldtrip/fileio/private/encode_nifti1.m b/Import/fieldtrip/fileio/private/encode_nifti1.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/encode_nifti1.m rename to Import/fieldtrip/fileio/private/encode_nifti1.m diff --git a/src/Import/fieldtrip/fileio/private/fetch_url.m b/Import/fieldtrip/fileio/private/fetch_url.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/fetch_url.m rename to Import/fieldtrip/fileio/private/fetch_url.m diff --git a/src/Import/fieldtrip/fileio/private/fif2grad.m b/Import/fieldtrip/fileio/private/fif2grad.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/fif2grad.m rename to Import/fieldtrip/fileio/private/fif2grad.m diff --git a/src/Import/fieldtrip/fileio/private/fiff_open_le.m b/Import/fieldtrip/fileio/private/fiff_open_le.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/fiff_open_le.m rename to Import/fieldtrip/fileio/private/fiff_open_le.m diff --git a/src/Import/fieldtrip/fileio/private/filetype_check_extension.m b/Import/fieldtrip/fileio/private/filetype_check_extension.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/filetype_check_extension.m rename to Import/fieldtrip/fileio/private/filetype_check_extension.m diff --git a/src/Import/fieldtrip/fileio/private/filetype_check_header.m b/Import/fieldtrip/fileio/private/filetype_check_header.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/filetype_check_header.m rename to Import/fieldtrip/fileio/private/filetype_check_header.m diff --git a/src/Import/fieldtrip/fileio/private/filetype_check_uri.m b/Import/fieldtrip/fileio/private/filetype_check_uri.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/filetype_check_uri.m rename to Import/fieldtrip/fileio/private/filetype_check_uri.m diff --git a/src/Import/fieldtrip/fileio/private/find_outermost_boundary.m b/Import/fieldtrip/fileio/private/find_outermost_boundary.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/find_outermost_boundary.m rename to Import/fieldtrip/fileio/private/find_outermost_boundary.m diff --git a/src/Import/fieldtrip/fileio/private/fixdimord.m b/Import/fieldtrip/fileio/private/fixdimord.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/fixdimord.m rename to Import/fieldtrip/fileio/private/fixdimord.m diff --git a/src/Import/fieldtrip/fileio/private/fixinside.m b/Import/fieldtrip/fileio/private/fixinside.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/fixinside.m rename to Import/fieldtrip/fileio/private/fixinside.m diff --git a/src/Import/fieldtrip/fileio/private/fixname.m b/Import/fieldtrip/fileio/private/fixname.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/fixname.m rename to Import/fieldtrip/fileio/private/fixname.m diff --git a/src/Import/fieldtrip/fileio/private/fixpos.m b/Import/fieldtrip/fileio/private/fixpos.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/fixpos.m rename to Import/fieldtrip/fileio/private/fixpos.m diff --git a/src/Import/fieldtrip/fileio/private/fixsampleinfo.m b/Import/fieldtrip/fileio/private/fixsampleinfo.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/fixsampleinfo.m rename to Import/fieldtrip/fileio/private/fixsampleinfo.m diff --git a/src/Import/fieldtrip/fileio/private/ft_apply_montage.m b/Import/fieldtrip/fileio/private/ft_apply_montage.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/ft_apply_montage.m rename to Import/fieldtrip/fileio/private/ft_apply_montage.m diff --git a/src/Import/fieldtrip/fileio/private/ft_checkdata.m b/Import/fieldtrip/fileio/private/ft_checkdata.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/ft_checkdata.m rename to Import/fieldtrip/fileio/private/ft_checkdata.m diff --git a/src/Import/fieldtrip/fileio/private/ft_convert_units.m b/Import/fieldtrip/fileio/private/ft_convert_units.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/ft_convert_units.m rename to Import/fieldtrip/fileio/private/ft_convert_units.m diff --git a/src/Import/fieldtrip/fileio/private/ft_datatype.m b/Import/fieldtrip/fileio/private/ft_datatype.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/ft_datatype.m rename to Import/fieldtrip/fileio/private/ft_datatype.m diff --git a/src/Import/fieldtrip/fileio/private/ft_datatype_comp.m b/Import/fieldtrip/fileio/private/ft_datatype_comp.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/ft_datatype_comp.m rename to Import/fieldtrip/fileio/private/ft_datatype_comp.m diff --git a/src/Import/fieldtrip/fileio/private/ft_datatype_dip.m b/Import/fieldtrip/fileio/private/ft_datatype_dip.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/ft_datatype_dip.m rename to Import/fieldtrip/fileio/private/ft_datatype_dip.m diff --git a/src/Import/fieldtrip/fileio/private/ft_datatype_freq.m b/Import/fieldtrip/fileio/private/ft_datatype_freq.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/ft_datatype_freq.m rename to Import/fieldtrip/fileio/private/ft_datatype_freq.m diff --git a/src/Import/fieldtrip/fileio/private/ft_datatype_headmodel.m b/Import/fieldtrip/fileio/private/ft_datatype_headmodel.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/ft_datatype_headmodel.m rename to Import/fieldtrip/fileio/private/ft_datatype_headmodel.m diff --git a/src/Import/fieldtrip/fileio/private/ft_datatype_mvar.m b/Import/fieldtrip/fileio/private/ft_datatype_mvar.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/ft_datatype_mvar.m rename to Import/fieldtrip/fileio/private/ft_datatype_mvar.m diff --git a/src/Import/fieldtrip/fileio/private/ft_datatype_raw.m b/Import/fieldtrip/fileio/private/ft_datatype_raw.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/ft_datatype_raw.m rename to Import/fieldtrip/fileio/private/ft_datatype_raw.m diff --git a/src/Import/fieldtrip/fileio/private/ft_datatype_sens.m b/Import/fieldtrip/fileio/private/ft_datatype_sens.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/ft_datatype_sens.m rename to Import/fieldtrip/fileio/private/ft_datatype_sens.m diff --git a/src/Import/fieldtrip/fileio/private/ft_datatype_source.m b/Import/fieldtrip/fileio/private/ft_datatype_source.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/ft_datatype_source.m rename to Import/fieldtrip/fileio/private/ft_datatype_source.m diff --git a/src/Import/fieldtrip/fileio/private/ft_datatype_spike.m b/Import/fieldtrip/fileio/private/ft_datatype_spike.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/ft_datatype_spike.m rename to Import/fieldtrip/fileio/private/ft_datatype_spike.m diff --git a/src/Import/fieldtrip/fileio/private/ft_datatype_timelock.m b/Import/fieldtrip/fileio/private/ft_datatype_timelock.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/ft_datatype_timelock.m rename to Import/fieldtrip/fileio/private/ft_datatype_timelock.m diff --git a/src/Import/fieldtrip/fileio/private/ft_datatype_vol.m b/Import/fieldtrip/fileio/private/ft_datatype_vol.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/ft_datatype_vol.m rename to Import/fieldtrip/fileio/private/ft_datatype_vol.m diff --git a/src/Import/fieldtrip/fileio/private/ft_estimate_units.m b/Import/fieldtrip/fileio/private/ft_estimate_units.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/ft_estimate_units.m rename to Import/fieldtrip/fileio/private/ft_estimate_units.m diff --git a/src/Import/fieldtrip/fileio/private/ft_fetch_data.m b/Import/fieldtrip/fileio/private/ft_fetch_data.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/ft_fetch_data.m rename to Import/fieldtrip/fileio/private/ft_fetch_data.m diff --git a/src/Import/fieldtrip/fileio/private/ft_fetch_header.m b/Import/fieldtrip/fileio/private/ft_fetch_header.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/ft_fetch_header.m rename to Import/fieldtrip/fileio/private/ft_fetch_header.m diff --git a/src/Import/fieldtrip/fileio/private/ft_findcfg.m b/Import/fieldtrip/fileio/private/ft_findcfg.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/ft_findcfg.m rename to Import/fieldtrip/fileio/private/ft_findcfg.m diff --git a/src/Import/fieldtrip/fileio/private/ft_getopt.m b/Import/fieldtrip/fileio/private/ft_getopt.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/ft_getopt.m rename to Import/fieldtrip/fileio/private/ft_getopt.m diff --git a/src/Import/fieldtrip/fileio/private/ft_getopt.mexa64 b/Import/fieldtrip/fileio/private/ft_getopt.mexa64 similarity index 100% rename from src/Import/fieldtrip/fileio/private/ft_getopt.mexa64 rename to Import/fieldtrip/fileio/private/ft_getopt.mexa64 diff --git a/src/Import/fieldtrip/fileio/private/ft_getopt.mexglx b/Import/fieldtrip/fileio/private/ft_getopt.mexglx similarity index 100% rename from src/Import/fieldtrip/fileio/private/ft_getopt.mexglx rename to Import/fieldtrip/fileio/private/ft_getopt.mexglx diff --git a/src/Import/fieldtrip/fileio/private/ft_getopt.mexmaci b/Import/fieldtrip/fileio/private/ft_getopt.mexmaci similarity index 100% rename from src/Import/fieldtrip/fileio/private/ft_getopt.mexmaci rename to Import/fieldtrip/fileio/private/ft_getopt.mexmaci diff --git a/src/Import/fieldtrip/fileio/private/ft_getopt.mexmaci64 b/Import/fieldtrip/fileio/private/ft_getopt.mexmaci64 similarity index 100% rename from src/Import/fieldtrip/fileio/private/ft_getopt.mexmaci64 rename to Import/fieldtrip/fileio/private/ft_getopt.mexmaci64 diff --git a/src/Import/fieldtrip/fileio/private/ft_getopt.mexw32 b/Import/fieldtrip/fileio/private/ft_getopt.mexw32 similarity index 100% rename from src/Import/fieldtrip/fileio/private/ft_getopt.mexw32 rename to Import/fieldtrip/fileio/private/ft_getopt.mexw32 diff --git a/src/Import/fieldtrip/fileio/private/ft_getopt.mexw64 b/Import/fieldtrip/fileio/private/ft_getopt.mexw64 similarity index 100% rename from src/Import/fieldtrip/fileio/private/ft_getopt.mexw64 rename to Import/fieldtrip/fileio/private/ft_getopt.mexw64 diff --git a/src/Import/fieldtrip/fileio/private/ft_hastoolbox.m b/Import/fieldtrip/fileio/private/ft_hastoolbox.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/ft_hastoolbox.m rename to Import/fieldtrip/fileio/private/ft_hastoolbox.m diff --git a/src/Import/fieldtrip/fileio/private/ft_headcoordinates.m b/Import/fieldtrip/fileio/private/ft_headcoordinates.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/ft_headcoordinates.m rename to Import/fieldtrip/fileio/private/ft_headcoordinates.m diff --git a/src/Import/fieldtrip/fileio/private/ft_platform_supports.m b/Import/fieldtrip/fileio/private/ft_platform_supports.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/ft_platform_supports.m rename to Import/fieldtrip/fileio/private/ft_platform_supports.m diff --git a/src/Import/fieldtrip/fileio/private/ft_progress.m b/Import/fieldtrip/fileio/private/ft_progress.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/ft_progress.m rename to Import/fieldtrip/fileio/private/ft_progress.m diff --git a/src/Import/fieldtrip/fileio/private/ft_scalingfactor.m b/Import/fieldtrip/fileio/private/ft_scalingfactor.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/ft_scalingfactor.m rename to Import/fieldtrip/fileio/private/ft_scalingfactor.m diff --git a/src/Import/fieldtrip/fileio/private/ft_senslabel.m b/Import/fieldtrip/fileio/private/ft_senslabel.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/ft_senslabel.m rename to Import/fieldtrip/fileio/private/ft_senslabel.m diff --git a/src/Import/fieldtrip/fileio/private/ft_senstype.m b/Import/fieldtrip/fileio/private/ft_senstype.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/ft_senstype.m rename to Import/fieldtrip/fileio/private/ft_senstype.m diff --git a/src/Import/fieldtrip/fileio/private/ft_voltype.m b/Import/fieldtrip/fileio/private/ft_voltype.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/ft_voltype.m rename to Import/fieldtrip/fileio/private/ft_voltype.m diff --git a/src/Import/fieldtrip/fileio/private/ft_warning.m b/Import/fieldtrip/fileio/private/ft_warning.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/ft_warning.m rename to Import/fieldtrip/fileio/private/ft_warning.m diff --git a/src/Import/fieldtrip/fileio/private/ft_warp_apply.m b/Import/fieldtrip/fileio/private/ft_warp_apply.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/ft_warp_apply.m rename to Import/fieldtrip/fileio/private/ft_warp_apply.m diff --git a/src/Import/fieldtrip/fileio/private/getdatfield.m b/Import/fieldtrip/fileio/private/getdatfield.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/getdatfield.m rename to Import/fieldtrip/fileio/private/getdatfield.m diff --git a/src/Import/fieldtrip/fileio/private/getdimord.m b/Import/fieldtrip/fileio/private/getdimord.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/getdimord.m rename to Import/fieldtrip/fileio/private/getdimord.m diff --git a/src/Import/fieldtrip/fileio/private/getdimsiz.m b/Import/fieldtrip/fileio/private/getdimsiz.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/getdimsiz.m rename to Import/fieldtrip/fileio/private/getdimsiz.m diff --git a/src/Import/fieldtrip/fileio/private/getsubfield.m b/Import/fieldtrip/fileio/private/getsubfield.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/getsubfield.m rename to Import/fieldtrip/fileio/private/getsubfield.m diff --git a/src/Import/fieldtrip/fileio/private/hasyokogawa.m b/Import/fieldtrip/fileio/private/hasyokogawa.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/hasyokogawa.m rename to Import/fieldtrip/fileio/private/hasyokogawa.m diff --git a/src/Import/fieldtrip/fileio/private/in_fopen_manscan.m b/Import/fieldtrip/fileio/private/in_fopen_manscan.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/in_fopen_manscan.m rename to Import/fieldtrip/fileio/private/in_fopen_manscan.m diff --git a/src/Import/fieldtrip/fileio/private/in_fread_manscan.m b/Import/fieldtrip/fileio/private/in_fread_manscan.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/in_fread_manscan.m rename to Import/fieldtrip/fileio/private/in_fread_manscan.m diff --git a/src/Import/fieldtrip/fileio/private/inflate_file.m b/Import/fieldtrip/fileio/private/inflate_file.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/inflate_file.m rename to Import/fieldtrip/fileio/private/inflate_file.m diff --git a/src/Import/fieldtrip/fileio/private/inifile.m b/Import/fieldtrip/fileio/private/inifile.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/inifile.m rename to Import/fieldtrip/fileio/private/inifile.m diff --git a/src/Import/fieldtrip/fileio/private/issubfield.m b/Import/fieldtrip/fileio/private/issubfield.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/issubfield.m rename to Import/fieldtrip/fileio/private/issubfield.m diff --git a/src/Import/fieldtrip/fileio/private/istrue.m b/Import/fieldtrip/fileio/private/istrue.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/istrue.m rename to Import/fieldtrip/fileio/private/istrue.m diff --git a/src/Import/fieldtrip/fileio/private/itab2grad.m b/Import/fieldtrip/fileio/private/itab2grad.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/itab2grad.m rename to Import/fieldtrip/fileio/private/itab2grad.m diff --git a/src/Import/fieldtrip/fileio/private/jaga16_packet.m b/Import/fieldtrip/fileio/private/jaga16_packet.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/jaga16_packet.m rename to Import/fieldtrip/fileio/private/jaga16_packet.m diff --git a/src/Import/fieldtrip/fileio/private/keyval.m b/Import/fieldtrip/fileio/private/keyval.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/keyval.m rename to Import/fieldtrip/fileio/private/keyval.m diff --git a/src/Import/fieldtrip/fileio/private/labelcmb2indx.m b/Import/fieldtrip/fileio/private/labelcmb2indx.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/labelcmb2indx.m rename to Import/fieldtrip/fileio/private/labelcmb2indx.m diff --git a/src/Import/fieldtrip/fileio/private/littleendian.m b/Import/fieldtrip/fileio/private/littleendian.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/littleendian.m rename to Import/fieldtrip/fileio/private/littleendian.m diff --git a/src/Import/fieldtrip/fileio/private/loadama.m b/Import/fieldtrip/fileio/private/loadama.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/loadama.m rename to Import/fieldtrip/fileio/private/loadama.m diff --git a/src/Import/fieldtrip/fileio/private/loadvar.m b/Import/fieldtrip/fileio/private/loadvar.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/loadvar.m rename to Import/fieldtrip/fileio/private/loadvar.m diff --git a/src/Import/fieldtrip/fileio/private/match_str.m b/Import/fieldtrip/fileio/private/match_str.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/match_str.m rename to Import/fieldtrip/fileio/private/match_str.m diff --git a/src/Import/fieldtrip/fileio/private/mne2grad.m b/Import/fieldtrip/fileio/private/mne2grad.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/mne2grad.m rename to Import/fieldtrip/fileio/private/mne2grad.m diff --git a/src/Import/fieldtrip/fileio/private/mxDeserialize.m b/Import/fieldtrip/fileio/private/mxDeserialize.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/mxDeserialize.m rename to Import/fieldtrip/fileio/private/mxDeserialize.m diff --git a/src/Import/fieldtrip/fileio/private/mxDeserialize_c.mexa64 b/Import/fieldtrip/fileio/private/mxDeserialize_c.mexa64 similarity index 100% rename from src/Import/fieldtrip/fileio/private/mxDeserialize_c.mexa64 rename to Import/fieldtrip/fileio/private/mxDeserialize_c.mexa64 diff --git a/src/Import/fieldtrip/fileio/private/mxDeserialize_c.mexglx b/Import/fieldtrip/fileio/private/mxDeserialize_c.mexglx similarity index 100% rename from src/Import/fieldtrip/fileio/private/mxDeserialize_c.mexglx rename to Import/fieldtrip/fileio/private/mxDeserialize_c.mexglx diff --git a/src/Import/fieldtrip/fileio/private/mxDeserialize_c.mexmac b/Import/fieldtrip/fileio/private/mxDeserialize_c.mexmac similarity index 100% rename from src/Import/fieldtrip/fileio/private/mxDeserialize_c.mexmac rename to Import/fieldtrip/fileio/private/mxDeserialize_c.mexmac diff --git a/src/Import/fieldtrip/fileio/private/mxDeserialize_c.mexmaci b/Import/fieldtrip/fileio/private/mxDeserialize_c.mexmaci similarity index 100% rename from src/Import/fieldtrip/fileio/private/mxDeserialize_c.mexmaci rename to Import/fieldtrip/fileio/private/mxDeserialize_c.mexmaci diff --git a/src/Import/fieldtrip/fileio/private/mxDeserialize_c.mexmaci64 b/Import/fieldtrip/fileio/private/mxDeserialize_c.mexmaci64 similarity index 100% rename from src/Import/fieldtrip/fileio/private/mxDeserialize_c.mexmaci64 rename to Import/fieldtrip/fileio/private/mxDeserialize_c.mexmaci64 diff --git a/src/Import/fieldtrip/fileio/private/mxDeserialize_c.mexw32 b/Import/fieldtrip/fileio/private/mxDeserialize_c.mexw32 similarity index 100% rename from src/Import/fieldtrip/fileio/private/mxDeserialize_c.mexw32 rename to Import/fieldtrip/fileio/private/mxDeserialize_c.mexw32 diff --git a/src/Import/fieldtrip/fileio/private/mxDeserialize_c.mexw64 b/Import/fieldtrip/fileio/private/mxDeserialize_c.mexw64 similarity index 100% rename from src/Import/fieldtrip/fileio/private/mxDeserialize_c.mexw64 rename to Import/fieldtrip/fileio/private/mxDeserialize_c.mexw64 diff --git a/src/Import/fieldtrip/fileio/private/mxDeserialize_cpp.mexa64 b/Import/fieldtrip/fileio/private/mxDeserialize_cpp.mexa64 similarity index 100% rename from src/Import/fieldtrip/fileio/private/mxDeserialize_cpp.mexa64 rename to Import/fieldtrip/fileio/private/mxDeserialize_cpp.mexa64 diff --git a/src/Import/fieldtrip/fileio/private/mxDeserialize_cpp.mexmaci64 b/Import/fieldtrip/fileio/private/mxDeserialize_cpp.mexmaci64 similarity index 100% rename from src/Import/fieldtrip/fileio/private/mxDeserialize_cpp.mexmaci64 rename to Import/fieldtrip/fileio/private/mxDeserialize_cpp.mexmaci64 diff --git a/src/Import/fieldtrip/fileio/private/mxDeserialize_cpp.mexw32 b/Import/fieldtrip/fileio/private/mxDeserialize_cpp.mexw32 similarity index 100% rename from src/Import/fieldtrip/fileio/private/mxDeserialize_cpp.mexw32 rename to Import/fieldtrip/fileio/private/mxDeserialize_cpp.mexw32 diff --git a/src/Import/fieldtrip/fileio/private/mxSerialize.m b/Import/fieldtrip/fileio/private/mxSerialize.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/mxSerialize.m rename to Import/fieldtrip/fileio/private/mxSerialize.m diff --git a/src/Import/fieldtrip/fileio/private/mxSerialize_c.mexa64 b/Import/fieldtrip/fileio/private/mxSerialize_c.mexa64 similarity index 100% rename from src/Import/fieldtrip/fileio/private/mxSerialize_c.mexa64 rename to Import/fieldtrip/fileio/private/mxSerialize_c.mexa64 diff --git a/src/Import/fieldtrip/fileio/private/mxSerialize_c.mexglx b/Import/fieldtrip/fileio/private/mxSerialize_c.mexglx similarity index 100% rename from src/Import/fieldtrip/fileio/private/mxSerialize_c.mexglx rename to Import/fieldtrip/fileio/private/mxSerialize_c.mexglx diff --git a/src/Import/fieldtrip/fileio/private/mxSerialize_c.mexmac b/Import/fieldtrip/fileio/private/mxSerialize_c.mexmac similarity index 100% rename from src/Import/fieldtrip/fileio/private/mxSerialize_c.mexmac rename to Import/fieldtrip/fileio/private/mxSerialize_c.mexmac diff --git a/src/Import/fieldtrip/fileio/private/mxSerialize_c.mexmaci b/Import/fieldtrip/fileio/private/mxSerialize_c.mexmaci similarity index 100% rename from src/Import/fieldtrip/fileio/private/mxSerialize_c.mexmaci rename to Import/fieldtrip/fileio/private/mxSerialize_c.mexmaci diff --git a/src/Import/fieldtrip/fileio/private/mxSerialize_c.mexmaci64 b/Import/fieldtrip/fileio/private/mxSerialize_c.mexmaci64 similarity index 100% rename from src/Import/fieldtrip/fileio/private/mxSerialize_c.mexmaci64 rename to Import/fieldtrip/fileio/private/mxSerialize_c.mexmaci64 diff --git a/src/Import/fieldtrip/fileio/private/mxSerialize_c.mexw32 b/Import/fieldtrip/fileio/private/mxSerialize_c.mexw32 similarity index 100% rename from src/Import/fieldtrip/fileio/private/mxSerialize_c.mexw32 rename to Import/fieldtrip/fileio/private/mxSerialize_c.mexw32 diff --git a/src/Import/fieldtrip/fileio/private/mxSerialize_c.mexw64 b/Import/fieldtrip/fileio/private/mxSerialize_c.mexw64 similarity index 100% rename from src/Import/fieldtrip/fileio/private/mxSerialize_c.mexw64 rename to Import/fieldtrip/fileio/private/mxSerialize_c.mexw64 diff --git a/src/Import/fieldtrip/fileio/private/mxSerialize_cpp.mexa64 b/Import/fieldtrip/fileio/private/mxSerialize_cpp.mexa64 similarity index 100% rename from src/Import/fieldtrip/fileio/private/mxSerialize_cpp.mexa64 rename to Import/fieldtrip/fileio/private/mxSerialize_cpp.mexa64 diff --git a/src/Import/fieldtrip/fileio/private/mxSerialize_cpp.mexmaci64 b/Import/fieldtrip/fileio/private/mxSerialize_cpp.mexmaci64 similarity index 100% rename from src/Import/fieldtrip/fileio/private/mxSerialize_cpp.mexmaci64 rename to Import/fieldtrip/fileio/private/mxSerialize_cpp.mexmaci64 diff --git a/src/Import/fieldtrip/fileio/private/mxSerialize_cpp.mexw32 b/Import/fieldtrip/fileio/private/mxSerialize_cpp.mexw32 similarity index 100% rename from src/Import/fieldtrip/fileio/private/mxSerialize_cpp.mexw32 rename to Import/fieldtrip/fileio/private/mxSerialize_cpp.mexw32 diff --git a/src/Import/fieldtrip/fileio/private/mxSerialize_cpp.mexw64 b/Import/fieldtrip/fileio/private/mxSerialize_cpp.mexw64 similarity index 100% rename from src/Import/fieldtrip/fileio/private/mxSerialize_cpp.mexw64 rename to Import/fieldtrip/fileio/private/mxSerialize_cpp.mexw64 diff --git a/src/Import/fieldtrip/fileio/private/ndgrid.m b/Import/fieldtrip/fileio/private/ndgrid.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/ndgrid.m rename to Import/fieldtrip/fileio/private/ndgrid.m diff --git a/src/Import/fieldtrip/fileio/private/netmeg2grad.m b/Import/fieldtrip/fileio/private/netmeg2grad.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/netmeg2grad.m rename to Import/fieldtrip/fileio/private/netmeg2grad.m diff --git a/src/Import/fieldtrip/fileio/private/neuralynx_crc.m b/Import/fieldtrip/fileio/private/neuralynx_crc.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/neuralynx_crc.m rename to Import/fieldtrip/fileio/private/neuralynx_crc.m diff --git a/src/Import/fieldtrip/fileio/private/neuralynx_getheader.m b/Import/fieldtrip/fileio/private/neuralynx_getheader.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/neuralynx_getheader.m rename to Import/fieldtrip/fileio/private/neuralynx_getheader.m diff --git a/src/Import/fieldtrip/fileio/private/neuralynx_timestamp.m b/Import/fieldtrip/fileio/private/neuralynx_timestamp.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/neuralynx_timestamp.m rename to Import/fieldtrip/fileio/private/neuralynx_timestamp.m diff --git a/src/Import/fieldtrip/fileio/private/np_read_splitted_fileinfo.m b/Import/fieldtrip/fileio/private/np_read_splitted_fileinfo.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/np_read_splitted_fileinfo.m rename to Import/fieldtrip/fileio/private/np_read_splitted_fileinfo.m diff --git a/src/Import/fieldtrip/fileio/private/np_readdata.m b/Import/fieldtrip/fileio/private/np_readdata.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/np_readdata.m rename to Import/fieldtrip/fileio/private/np_readdata.m diff --git a/src/Import/fieldtrip/fileio/private/np_readfileinfo.m b/Import/fieldtrip/fileio/private/np_readfileinfo.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/np_readfileinfo.m rename to Import/fieldtrip/fileio/private/np_readfileinfo.m diff --git a/src/Import/fieldtrip/fileio/private/np_readmarker.m b/Import/fieldtrip/fileio/private/np_readmarker.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/np_readmarker.m rename to Import/fieldtrip/fileio/private/np_readmarker.m diff --git a/src/Import/fieldtrip/fileio/private/openbdf.m b/Import/fieldtrip/fileio/private/openbdf.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/openbdf.m rename to Import/fieldtrip/fileio/private/openbdf.m diff --git a/src/Import/fieldtrip/fileio/private/parameterselection.m b/Import/fieldtrip/fileio/private/parameterselection.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/parameterselection.m rename to Import/fieldtrip/fileio/private/parameterselection.m diff --git a/src/Import/fieldtrip/fileio/private/plx_orig_header.m b/Import/fieldtrip/fileio/private/plx_orig_header.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/plx_orig_header.m rename to Import/fieldtrip/fileio/private/plx_orig_header.m diff --git a/src/Import/fieldtrip/fileio/private/pos2dim.m b/Import/fieldtrip/fileio/private/pos2dim.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/pos2dim.m rename to Import/fieldtrip/fileio/private/pos2dim.m diff --git a/src/Import/fieldtrip/fileio/private/pos2dim3d.m b/Import/fieldtrip/fileio/private/pos2dim3d.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/pos2dim3d.m rename to Import/fieldtrip/fileio/private/pos2dim3d.m diff --git a/src/Import/fieldtrip/fileio/private/pos2transform.m b/Import/fieldtrip/fileio/private/pos2transform.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/pos2transform.m rename to Import/fieldtrip/fileio/private/pos2transform.m diff --git a/src/Import/fieldtrip/fileio/private/pthreadGC2-w64.dll b/Import/fieldtrip/fileio/private/pthreadGC2-w64.dll similarity index 100% rename from src/Import/fieldtrip/fileio/private/pthreadGC2-w64.dll rename to Import/fieldtrip/fileio/private/pthreadGC2-w64.dll diff --git a/src/Import/fieldtrip/fileio/private/pthreadGC2.dll b/Import/fieldtrip/fileio/private/pthreadGC2.dll similarity index 100% rename from src/Import/fieldtrip/fileio/private/pthreadGC2.dll rename to Import/fieldtrip/fileio/private/pthreadGC2.dll diff --git a/src/Import/fieldtrip/fileio/private/pthreadVC2.dll b/Import/fieldtrip/fileio/private/pthreadVC2.dll similarity index 100% rename from src/Import/fieldtrip/fileio/private/pthreadVC2.dll rename to Import/fieldtrip/fileio/private/pthreadVC2.dll diff --git a/src/Import/fieldtrip/fileio/private/quaternion.m b/Import/fieldtrip/fileio/private/quaternion.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/quaternion.m rename to Import/fieldtrip/fileio/private/quaternion.m diff --git a/src/Import/fieldtrip/fileio/private/read_16bit.mexa64 b/Import/fieldtrip/fileio/private/read_16bit.mexa64 similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_16bit.mexa64 rename to Import/fieldtrip/fileio/private/read_16bit.mexa64 diff --git a/src/Import/fieldtrip/fileio/private/read_16bit.mexglx b/Import/fieldtrip/fileio/private/read_16bit.mexglx similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_16bit.mexglx rename to Import/fieldtrip/fileio/private/read_16bit.mexglx diff --git a/src/Import/fieldtrip/fileio/private/read_16bit.mexmaci b/Import/fieldtrip/fileio/private/read_16bit.mexmaci similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_16bit.mexmaci rename to Import/fieldtrip/fileio/private/read_16bit.mexmaci diff --git a/src/Import/fieldtrip/fileio/private/read_16bit.mexmaci64 b/Import/fieldtrip/fileio/private/read_16bit.mexmaci64 similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_16bit.mexmaci64 rename to Import/fieldtrip/fileio/private/read_16bit.mexmaci64 diff --git a/src/Import/fieldtrip/fileio/private/read_16bit.mexw32 b/Import/fieldtrip/fileio/private/read_16bit.mexw32 similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_16bit.mexw32 rename to Import/fieldtrip/fileio/private/read_16bit.mexw32 diff --git a/src/Import/fieldtrip/fileio/private/read_16bit.mexw64 b/Import/fieldtrip/fileio/private/read_16bit.mexw64 similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_16bit.mexw64 rename to Import/fieldtrip/fileio/private/read_16bit.mexw64 diff --git a/src/Import/fieldtrip/fileio/private/read_24bit.mexa64 b/Import/fieldtrip/fileio/private/read_24bit.mexa64 similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_24bit.mexa64 rename to Import/fieldtrip/fileio/private/read_24bit.mexa64 diff --git a/src/Import/fieldtrip/fileio/private/read_24bit.mexglx b/Import/fieldtrip/fileio/private/read_24bit.mexglx similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_24bit.mexglx rename to Import/fieldtrip/fileio/private/read_24bit.mexglx diff --git a/src/Import/fieldtrip/fileio/private/read_24bit.mexmac b/Import/fieldtrip/fileio/private/read_24bit.mexmac similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_24bit.mexmac rename to Import/fieldtrip/fileio/private/read_24bit.mexmac diff --git a/src/Import/fieldtrip/fileio/private/read_24bit.mexmaci b/Import/fieldtrip/fileio/private/read_24bit.mexmaci similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_24bit.mexmaci rename to Import/fieldtrip/fileio/private/read_24bit.mexmaci diff --git a/src/Import/fieldtrip/fileio/private/read_24bit.mexmaci64 b/Import/fieldtrip/fileio/private/read_24bit.mexmaci64 similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_24bit.mexmaci64 rename to Import/fieldtrip/fileio/private/read_24bit.mexmaci64 diff --git a/src/Import/fieldtrip/fileio/private/read_24bit.mexw32 b/Import/fieldtrip/fileio/private/read_24bit.mexw32 similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_24bit.mexw32 rename to Import/fieldtrip/fileio/private/read_24bit.mexw32 diff --git a/src/Import/fieldtrip/fileio/private/read_24bit.mexw64 b/Import/fieldtrip/fileio/private/read_24bit.mexw64 similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_24bit.mexw64 rename to Import/fieldtrip/fileio/private/read_24bit.mexw64 diff --git a/src/Import/fieldtrip/fileio/private/read_4d_hdr.m b/Import/fieldtrip/fileio/private/read_4d_hdr.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_4d_hdr.m rename to Import/fieldtrip/fileio/private/read_4d_hdr.m diff --git a/src/Import/fieldtrip/fileio/private/read_ah5_data.m b/Import/fieldtrip/fileio/private/read_ah5_data.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_ah5_data.m rename to Import/fieldtrip/fileio/private/read_ah5_data.m diff --git a/src/Import/fieldtrip/fileio/private/read_ah5_markers.m b/Import/fieldtrip/fileio/private/read_ah5_markers.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_ah5_markers.m rename to Import/fieldtrip/fileio/private/read_ah5_markers.m diff --git a/src/Import/fieldtrip/fileio/private/read_ahdf5_hdr.m b/Import/fieldtrip/fileio/private/read_ahdf5_hdr.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_ahdf5_hdr.m rename to Import/fieldtrip/fileio/private/read_ahdf5_hdr.m diff --git a/src/Import/fieldtrip/fileio/private/read_asa.m b/Import/fieldtrip/fileio/private/read_asa.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_asa.m rename to Import/fieldtrip/fileio/private/read_asa.m diff --git a/src/Import/fieldtrip/fileio/private/read_asa_bnd.m b/Import/fieldtrip/fileio/private/read_asa_bnd.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_asa_bnd.m rename to Import/fieldtrip/fileio/private/read_asa_bnd.m diff --git a/src/Import/fieldtrip/fileio/private/read_asa_dip.m b/Import/fieldtrip/fileio/private/read_asa_dip.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_asa_dip.m rename to Import/fieldtrip/fileio/private/read_asa_dip.m diff --git a/src/Import/fieldtrip/fileio/private/read_asa_elc.m b/Import/fieldtrip/fileio/private/read_asa_elc.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_asa_elc.m rename to Import/fieldtrip/fileio/private/read_asa_elc.m diff --git a/src/Import/fieldtrip/fileio/private/read_asa_mri.m b/Import/fieldtrip/fileio/private/read_asa_mri.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_asa_mri.m rename to Import/fieldtrip/fileio/private/read_asa_mri.m diff --git a/src/Import/fieldtrip/fileio/private/read_asa_msr.m b/Import/fieldtrip/fileio/private/read_asa_msr.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_asa_msr.m rename to Import/fieldtrip/fileio/private/read_asa_msr.m diff --git a/src/Import/fieldtrip/fileio/private/read_asa_vol.m b/Import/fieldtrip/fileio/private/read_asa_vol.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_asa_vol.m rename to Import/fieldtrip/fileio/private/read_asa_vol.m diff --git a/src/Import/fieldtrip/fileio/private/read_besa_avr.m b/Import/fieldtrip/fileio/private/read_besa_avr.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_besa_avr.m rename to Import/fieldtrip/fileio/private/read_besa_avr.m diff --git a/src/Import/fieldtrip/fileio/private/read_besa_besa.m b/Import/fieldtrip/fileio/private/read_besa_besa.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_besa_besa.m rename to Import/fieldtrip/fileio/private/read_besa_besa.m diff --git a/src/Import/fieldtrip/fileio/private/read_besa_sfp.m b/Import/fieldtrip/fileio/private/read_besa_sfp.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_besa_sfp.m rename to Import/fieldtrip/fileio/private/read_besa_sfp.m diff --git a/src/Import/fieldtrip/fileio/private/read_besa_swf.m b/Import/fieldtrip/fileio/private/read_besa_swf.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_besa_swf.m rename to Import/fieldtrip/fileio/private/read_besa_swf.m diff --git a/src/Import/fieldtrip/fileio/private/read_bham.m b/Import/fieldtrip/fileio/private/read_bham.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_bham.m rename to Import/fieldtrip/fileio/private/read_bham.m diff --git a/src/Import/fieldtrip/fileio/private/read_biff.m b/Import/fieldtrip/fileio/private/read_biff.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_biff.m rename to Import/fieldtrip/fileio/private/read_biff.m diff --git a/src/Import/fieldtrip/fileio/private/read_biosemi_bdf.m b/Import/fieldtrip/fileio/private/read_biosemi_bdf.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_biosemi_bdf.m rename to Import/fieldtrip/fileio/private/read_biosemi_bdf.m diff --git a/src/Import/fieldtrip/fileio/private/read_biosig_data.m b/Import/fieldtrip/fileio/private/read_biosig_data.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_biosig_data.m rename to Import/fieldtrip/fileio/private/read_biosig_data.m diff --git a/src/Import/fieldtrip/fileio/private/read_biosig_header.m b/Import/fieldtrip/fileio/private/read_biosig_header.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_biosig_header.m rename to Import/fieldtrip/fileio/private/read_biosig_header.m diff --git a/src/Import/fieldtrip/fileio/private/read_brainvision_eeg.m b/Import/fieldtrip/fileio/private/read_brainvision_eeg.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_brainvision_eeg.m rename to Import/fieldtrip/fileio/private/read_brainvision_eeg.m diff --git a/src/Import/fieldtrip/fileio/private/read_brainvision_pos.m b/Import/fieldtrip/fileio/private/read_brainvision_pos.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_brainvision_pos.m rename to Import/fieldtrip/fileio/private/read_brainvision_pos.m diff --git a/src/Import/fieldtrip/fileio/private/read_brainvision_vhdr.m b/Import/fieldtrip/fileio/private/read_brainvision_vhdr.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_brainvision_vhdr.m rename to Import/fieldtrip/fileio/private/read_brainvision_vhdr.m diff --git a/src/Import/fieldtrip/fileio/private/read_brainvision_vmrk.m b/Import/fieldtrip/fileio/private/read_brainvision_vmrk.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_brainvision_vmrk.m rename to Import/fieldtrip/fileio/private/read_brainvision_vmrk.m diff --git a/src/Import/fieldtrip/fileio/private/read_bti_ascii.m b/Import/fieldtrip/fileio/private/read_bti_ascii.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_bti_ascii.m rename to Import/fieldtrip/fileio/private/read_bti_ascii.m diff --git a/src/Import/fieldtrip/fileio/private/read_bti_hs.m b/Import/fieldtrip/fileio/private/read_bti_hs.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_bti_hs.m rename to Import/fieldtrip/fileio/private/read_bti_hs.m diff --git a/src/Import/fieldtrip/fileio/private/read_bti_m4d.m b/Import/fieldtrip/fileio/private/read_bti_m4d.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_bti_m4d.m rename to Import/fieldtrip/fileio/private/read_bti_m4d.m diff --git a/src/Import/fieldtrip/fileio/private/read_bucn_nirsdata.m b/Import/fieldtrip/fileio/private/read_bucn_nirsdata.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_bucn_nirsdata.m rename to Import/fieldtrip/fileio/private/read_bucn_nirsdata.m diff --git a/src/Import/fieldtrip/fileio/private/read_bucn_nirsevent.m b/Import/fieldtrip/fileio/private/read_bucn_nirsevent.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_bucn_nirsevent.m rename to Import/fieldtrip/fileio/private/read_bucn_nirsevent.m diff --git a/src/Import/fieldtrip/fileio/private/read_bucn_nirshdr.m b/Import/fieldtrip/fileio/private/read_bucn_nirshdr.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_bucn_nirshdr.m rename to Import/fieldtrip/fileio/private/read_bucn_nirshdr.m diff --git a/src/Import/fieldtrip/fileio/private/read_buffer_offline_data.m b/Import/fieldtrip/fileio/private/read_buffer_offline_data.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_buffer_offline_data.m rename to Import/fieldtrip/fileio/private/read_buffer_offline_data.m diff --git a/src/Import/fieldtrip/fileio/private/read_buffer_offline_events.m b/Import/fieldtrip/fileio/private/read_buffer_offline_events.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_buffer_offline_events.m rename to Import/fieldtrip/fileio/private/read_buffer_offline_events.m diff --git a/src/Import/fieldtrip/fileio/private/read_buffer_offline_header.m b/Import/fieldtrip/fileio/private/read_buffer_offline_header.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_buffer_offline_header.m rename to Import/fieldtrip/fileio/private/read_buffer_offline_header.m diff --git a/src/Import/fieldtrip/fileio/private/read_bv_srf.m b/Import/fieldtrip/fileio/private/read_bv_srf.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_bv_srf.m rename to Import/fieldtrip/fileio/private/read_bv_srf.m diff --git a/src/Import/fieldtrip/fileio/private/read_caret_spec.m b/Import/fieldtrip/fileio/private/read_caret_spec.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_caret_spec.m rename to Import/fieldtrip/fileio/private/read_caret_spec.m diff --git a/src/Import/fieldtrip/fileio/private/read_ced_son.m b/Import/fieldtrip/fileio/private/read_ced_son.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_ced_son.m rename to Import/fieldtrip/fileio/private/read_ced_son.m diff --git a/src/Import/fieldtrip/fileio/private/read_combined_ds.m b/Import/fieldtrip/fileio/private/read_combined_ds.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_combined_ds.m rename to Import/fieldtrip/fileio/private/read_combined_ds.m diff --git a/src/Import/fieldtrip/fileio/private/read_ctf_ascii.m b/Import/fieldtrip/fileio/private/read_ctf_ascii.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_ctf_ascii.m rename to Import/fieldtrip/fileio/private/read_ctf_ascii.m diff --git a/src/Import/fieldtrip/fileio/private/read_ctf_cls.m b/Import/fieldtrip/fileio/private/read_ctf_cls.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_ctf_cls.m rename to Import/fieldtrip/fileio/private/read_ctf_cls.m diff --git a/src/Import/fieldtrip/fileio/private/read_ctf_coef.m b/Import/fieldtrip/fileio/private/read_ctf_coef.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_ctf_coef.m rename to Import/fieldtrip/fileio/private/read_ctf_coef.m diff --git a/src/Import/fieldtrip/fileio/private/read_ctf_dat.m b/Import/fieldtrip/fileio/private/read_ctf_dat.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_ctf_dat.m rename to Import/fieldtrip/fileio/private/read_ctf_dat.m diff --git a/src/Import/fieldtrip/fileio/private/read_ctf_hc.m b/Import/fieldtrip/fileio/private/read_ctf_hc.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_ctf_hc.m rename to Import/fieldtrip/fileio/private/read_ctf_hc.m diff --git a/src/Import/fieldtrip/fileio/private/read_ctf_hdm.m b/Import/fieldtrip/fileio/private/read_ctf_hdm.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_ctf_hdm.m rename to Import/fieldtrip/fileio/private/read_ctf_hdm.m diff --git a/src/Import/fieldtrip/fileio/private/read_ctf_hist.m b/Import/fieldtrip/fileio/private/read_ctf_hist.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_ctf_hist.m rename to Import/fieldtrip/fileio/private/read_ctf_hist.m diff --git a/src/Import/fieldtrip/fileio/private/read_ctf_meg4.m b/Import/fieldtrip/fileio/private/read_ctf_meg4.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_ctf_meg4.m rename to Import/fieldtrip/fileio/private/read_ctf_meg4.m diff --git a/src/Import/fieldtrip/fileio/private/read_ctf_mri.m b/Import/fieldtrip/fileio/private/read_ctf_mri.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_ctf_mri.m rename to Import/fieldtrip/fileio/private/read_ctf_mri.m diff --git a/src/Import/fieldtrip/fileio/private/read_ctf_mri4.m b/Import/fieldtrip/fileio/private/read_ctf_mri4.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_ctf_mri4.m rename to Import/fieldtrip/fileio/private/read_ctf_mri4.m diff --git a/src/Import/fieldtrip/fileio/private/read_ctf_pos.m b/Import/fieldtrip/fileio/private/read_ctf_pos.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_ctf_pos.m rename to Import/fieldtrip/fileio/private/read_ctf_pos.m diff --git a/src/Import/fieldtrip/fileio/private/read_ctf_res4.m b/Import/fieldtrip/fileio/private/read_ctf_res4.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_ctf_res4.m rename to Import/fieldtrip/fileio/private/read_ctf_res4.m diff --git a/src/Import/fieldtrip/fileio/private/read_ctf_sens.m b/Import/fieldtrip/fileio/private/read_ctf_sens.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_ctf_sens.m rename to Import/fieldtrip/fileio/private/read_ctf_sens.m diff --git a/src/Import/fieldtrip/fileio/private/read_ctf_shape.m b/Import/fieldtrip/fileio/private/read_ctf_shape.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_ctf_shape.m rename to Import/fieldtrip/fileio/private/read_ctf_shape.m diff --git a/src/Import/fieldtrip/fileio/private/read_ctf_shm.m b/Import/fieldtrip/fileio/private/read_ctf_shm.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_ctf_shm.m rename to Import/fieldtrip/fileio/private/read_ctf_shm.m diff --git a/src/Import/fieldtrip/fileio/private/read_ctf_shm.mexglx b/Import/fieldtrip/fileio/private/read_ctf_shm.mexglx similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_ctf_shm.mexglx rename to Import/fieldtrip/fileio/private/read_ctf_shm.mexglx diff --git a/src/Import/fieldtrip/fileio/private/read_ctf_svl.m b/Import/fieldtrip/fileio/private/read_ctf_svl.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_ctf_svl.m rename to Import/fieldtrip/fileio/private/read_ctf_svl.m diff --git a/src/Import/fieldtrip/fileio/private/read_ctf_trigger.m b/Import/fieldtrip/fileio/private/read_ctf_trigger.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_ctf_trigger.m rename to Import/fieldtrip/fileio/private/read_ctf_trigger.m diff --git a/src/Import/fieldtrip/fileio/private/read_curry.m b/Import/fieldtrip/fileio/private/read_curry.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_curry.m rename to Import/fieldtrip/fileio/private/read_curry.m diff --git a/src/Import/fieldtrip/fileio/private/read_deymed_dat.m b/Import/fieldtrip/fileio/private/read_deymed_dat.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_deymed_dat.m rename to Import/fieldtrip/fileio/private/read_deymed_dat.m diff --git a/src/Import/fieldtrip/fileio/private/read_deymed_ini.m b/Import/fieldtrip/fileio/private/read_deymed_ini.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_deymed_ini.m rename to Import/fieldtrip/fileio/private/read_deymed_ini.m diff --git a/src/Import/fieldtrip/fileio/private/read_edf.m b/Import/fieldtrip/fileio/private/read_edf.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_edf.m rename to Import/fieldtrip/fileio/private/read_edf.m diff --git a/src/Import/fieldtrip/fileio/private/read_eeglabdata.m b/Import/fieldtrip/fileio/private/read_eeglabdata.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_eeglabdata.m rename to Import/fieldtrip/fileio/private/read_eeglabdata.m diff --git a/src/Import/fieldtrip/fileio/private/read_eeglabevent.m b/Import/fieldtrip/fileio/private/read_eeglabevent.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_eeglabevent.m rename to Import/fieldtrip/fileio/private/read_eeglabevent.m diff --git a/src/Import/fieldtrip/fileio/private/read_eeglabheader.m b/Import/fieldtrip/fileio/private/read_eeglabheader.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_eeglabheader.m rename to Import/fieldtrip/fileio/private/read_eeglabheader.m diff --git a/src/Import/fieldtrip/fileio/private/read_egis_data.m b/Import/fieldtrip/fileio/private/read_egis_data.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_egis_data.m rename to Import/fieldtrip/fileio/private/read_egis_data.m diff --git a/src/Import/fieldtrip/fileio/private/read_egis_header.m b/Import/fieldtrip/fileio/private/read_egis_header.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_egis_header.m rename to Import/fieldtrip/fileio/private/read_egis_header.m diff --git a/src/Import/fieldtrip/fileio/private/read_elec.m b/Import/fieldtrip/fileio/private/read_elec.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_elec.m rename to Import/fieldtrip/fileio/private/read_elec.m diff --git a/src/Import/fieldtrip/fileio/private/read_erplabdata.m b/Import/fieldtrip/fileio/private/read_erplabdata.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_erplabdata.m rename to Import/fieldtrip/fileio/private/read_erplabdata.m diff --git a/src/Import/fieldtrip/fileio/private/read_erplabevent.m b/Import/fieldtrip/fileio/private/read_erplabevent.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_erplabevent.m rename to Import/fieldtrip/fileio/private/read_erplabevent.m diff --git a/src/Import/fieldtrip/fileio/private/read_erplabheader.m b/Import/fieldtrip/fileio/private/read_erplabheader.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_erplabheader.m rename to Import/fieldtrip/fileio/private/read_erplabheader.m diff --git a/src/Import/fieldtrip/fileio/private/read_eyelink_asc.m b/Import/fieldtrip/fileio/private/read_eyelink_asc.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_eyelink_asc.m rename to Import/fieldtrip/fileio/private/read_eyelink_asc.m diff --git a/src/Import/fieldtrip/fileio/private/read_fcdc_trl.m b/Import/fieldtrip/fileio/private/read_fcdc_trl.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_fcdc_trl.m rename to Import/fieldtrip/fileio/private/read_fcdc_trl.m diff --git a/src/Import/fieldtrip/fileio/private/read_itab_mhd.m b/Import/fieldtrip/fileio/private/read_itab_mhd.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_itab_mhd.m rename to Import/fieldtrip/fileio/private/read_itab_mhd.m diff --git a/src/Import/fieldtrip/fileio/private/read_mat.m b/Import/fieldtrip/fileio/private/read_mat.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_mat.m rename to Import/fieldtrip/fileio/private/read_mat.m diff --git a/src/Import/fieldtrip/fileio/private/read_mclust_t.m b/Import/fieldtrip/fileio/private/read_mclust_t.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_mclust_t.m rename to Import/fieldtrip/fileio/private/read_mclust_t.m diff --git a/src/Import/fieldtrip/fileio/private/read_mff_bin.m b/Import/fieldtrip/fileio/private/read_mff_bin.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_mff_bin.m rename to Import/fieldtrip/fileio/private/read_mff_bin.m diff --git a/src/Import/fieldtrip/fileio/private/read_micromed_event.m b/Import/fieldtrip/fileio/private/read_micromed_event.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_micromed_event.m rename to Import/fieldtrip/fileio/private/read_micromed_event.m diff --git a/src/Import/fieldtrip/fileio/private/read_micromed_trc.m b/Import/fieldtrip/fileio/private/read_micromed_trc.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_micromed_trc.m rename to Import/fieldtrip/fileio/private/read_micromed_trc.m diff --git a/src/Import/fieldtrip/fileio/private/read_mpi_dap.m b/Import/fieldtrip/fileio/private/read_mpi_dap.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_mpi_dap.m rename to Import/fieldtrip/fileio/private/read_mpi_dap.m diff --git a/src/Import/fieldtrip/fileio/private/read_mpi_ds.m b/Import/fieldtrip/fileio/private/read_mpi_ds.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_mpi_ds.m rename to Import/fieldtrip/fileio/private/read_mpi_ds.m diff --git a/src/Import/fieldtrip/fileio/private/read_nervus_data.m b/Import/fieldtrip/fileio/private/read_nervus_data.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_nervus_data.m rename to Import/fieldtrip/fileio/private/read_nervus_data.m diff --git a/src/Import/fieldtrip/fileio/private/read_nervus_header.m b/Import/fieldtrip/fileio/private/read_nervus_header.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_nervus_header.m rename to Import/fieldtrip/fileio/private/read_nervus_header.m diff --git a/src/Import/fieldtrip/fileio/private/read_neuralynx_bin.m b/Import/fieldtrip/fileio/private/read_neuralynx_bin.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_neuralynx_bin.m rename to Import/fieldtrip/fileio/private/read_neuralynx_bin.m diff --git a/src/Import/fieldtrip/fileio/private/read_neuralynx_cds.m b/Import/fieldtrip/fileio/private/read_neuralynx_cds.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_neuralynx_cds.m rename to Import/fieldtrip/fileio/private/read_neuralynx_cds.m diff --git a/src/Import/fieldtrip/fileio/private/read_neuralynx_dma.m b/Import/fieldtrip/fileio/private/read_neuralynx_dma.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_neuralynx_dma.m rename to Import/fieldtrip/fileio/private/read_neuralynx_dma.m diff --git a/src/Import/fieldtrip/fileio/private/read_neuralynx_ds.m b/Import/fieldtrip/fileio/private/read_neuralynx_ds.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_neuralynx_ds.m rename to Import/fieldtrip/fileio/private/read_neuralynx_ds.m diff --git a/src/Import/fieldtrip/fileio/private/read_neuralynx_ncs.m b/Import/fieldtrip/fileio/private/read_neuralynx_ncs.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_neuralynx_ncs.m rename to Import/fieldtrip/fileio/private/read_neuralynx_ncs.m diff --git a/src/Import/fieldtrip/fileio/private/read_neuralynx_nev.m b/Import/fieldtrip/fileio/private/read_neuralynx_nev.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_neuralynx_nev.m rename to Import/fieldtrip/fileio/private/read_neuralynx_nev.m diff --git a/src/Import/fieldtrip/fileio/private/read_neuralynx_nse.m b/Import/fieldtrip/fileio/private/read_neuralynx_nse.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_neuralynx_nse.m rename to Import/fieldtrip/fileio/private/read_neuralynx_nse.m diff --git a/src/Import/fieldtrip/fileio/private/read_neuralynx_nst.m b/Import/fieldtrip/fileio/private/read_neuralynx_nst.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_neuralynx_nst.m rename to Import/fieldtrip/fileio/private/read_neuralynx_nst.m diff --git a/src/Import/fieldtrip/fileio/private/read_neuralynx_nts.m b/Import/fieldtrip/fileio/private/read_neuralynx_nts.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_neuralynx_nts.m rename to Import/fieldtrip/fileio/private/read_neuralynx_nts.m diff --git a/src/Import/fieldtrip/fileio/private/read_neuralynx_ntt.m b/Import/fieldtrip/fileio/private/read_neuralynx_ntt.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_neuralynx_ntt.m rename to Import/fieldtrip/fileio/private/read_neuralynx_ntt.m diff --git a/src/Import/fieldtrip/fileio/private/read_neuralynx_sdma.m b/Import/fieldtrip/fileio/private/read_neuralynx_sdma.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_neuralynx_sdma.m rename to Import/fieldtrip/fileio/private/read_neuralynx_sdma.m diff --git a/src/Import/fieldtrip/fileio/private/read_neuralynx_ttl.m b/Import/fieldtrip/fileio/private/read_neuralynx_ttl.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_neuralynx_ttl.m rename to Import/fieldtrip/fileio/private/read_neuralynx_ttl.m diff --git a/src/Import/fieldtrip/fileio/private/read_neuromag_eve.m b/Import/fieldtrip/fileio/private/read_neuromag_eve.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_neuromag_eve.m rename to Import/fieldtrip/fileio/private/read_neuromag_eve.m diff --git a/src/Import/fieldtrip/fileio/private/read_neuromag_hc.m b/Import/fieldtrip/fileio/private/read_neuromag_hc.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_neuromag_hc.m rename to Import/fieldtrip/fileio/private/read_neuromag_hc.m diff --git a/src/Import/fieldtrip/fileio/private/read_neuroshare.m b/Import/fieldtrip/fileio/private/read_neuroshare.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_neuroshare.m rename to Import/fieldtrip/fileio/private/read_neuroshare.m diff --git a/src/Import/fieldtrip/fileio/private/read_neurosim_evolution.m b/Import/fieldtrip/fileio/private/read_neurosim_evolution.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_neurosim_evolution.m rename to Import/fieldtrip/fileio/private/read_neurosim_evolution.m diff --git a/src/Import/fieldtrip/fileio/private/read_neurosim_signals.m b/Import/fieldtrip/fileio/private/read_neurosim_signals.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_neurosim_signals.m rename to Import/fieldtrip/fileio/private/read_neurosim_signals.m diff --git a/src/Import/fieldtrip/fileio/private/read_neurosim_spikes.m b/Import/fieldtrip/fileio/private/read_neurosim_spikes.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_neurosim_spikes.m rename to Import/fieldtrip/fileio/private/read_neurosim_spikes.m diff --git a/src/Import/fieldtrip/fileio/private/read_nex_data.m b/Import/fieldtrip/fileio/private/read_nex_data.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_nex_data.m rename to Import/fieldtrip/fileio/private/read_nex_data.m diff --git a/src/Import/fieldtrip/fileio/private/read_nex_event.m b/Import/fieldtrip/fileio/private/read_nex_event.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_nex_event.m rename to Import/fieldtrip/fileio/private/read_nex_event.m diff --git a/src/Import/fieldtrip/fileio/private/read_nex_header.m b/Import/fieldtrip/fileio/private/read_nex_header.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_nex_header.m rename to Import/fieldtrip/fileio/private/read_nex_header.m diff --git a/src/Import/fieldtrip/fileio/private/read_nexstim_event.m b/Import/fieldtrip/fileio/private/read_nexstim_event.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_nexstim_event.m rename to Import/fieldtrip/fileio/private/read_nexstim_event.m diff --git a/src/Import/fieldtrip/fileio/private/read_nexstim_nxe.m b/Import/fieldtrip/fileio/private/read_nexstim_nxe.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_nexstim_nxe.m rename to Import/fieldtrip/fileio/private/read_nexstim_nxe.m diff --git a/src/Import/fieldtrip/fileio/private/read_nifti2_hdr.m b/Import/fieldtrip/fileio/private/read_nifti2_hdr.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_nifti2_hdr.m rename to Import/fieldtrip/fileio/private/read_nifti2_hdr.m diff --git a/src/Import/fieldtrip/fileio/private/read_nihonkohden_hdr.m b/Import/fieldtrip/fileio/private/read_nihonkohden_hdr.m similarity index 96% rename from src/Import/fieldtrip/fileio/private/read_nihonkohden_hdr.m rename to Import/fieldtrip/fileio/private/read_nihonkohden_hdr.m index 1954726b..89679cf6 100644 --- a/src/Import/fieldtrip/fileio/private/read_nihonkohden_hdr.m +++ b/Import/fieldtrip/fileio/private/read_nihonkohden_hdr.m @@ -1,104 +1,104 @@ -function [hdr] = read_nihonkohden_hdr(filename) - -% READ_NIHONKOHDEN_HDR reads the known items from the Nihon Kohden EEG -% system header file (*.m00) and returns them in a structure. This reading -% function is an adaptation of get_nkheader.m written by Timothy Ellmore -% -% Use as -% hdr = read_nihonkoden_hdr(filename) -% -% This returns a header structure with -% hdr.nSamples number of data points per channel -% hdr.nchannels number of channels sampled during recording -% hdr.bsweep begin sweep (ms) -% hdr.sampintms sampling interval in ms -% hdr.binsuV number of bins per microvolts -% hdr.start_time starting time of recording -% hdr.label char array of channel names -% -% See also READ_NIHONKOHDEN_M00 - -% Copyright (C) 2016, Diego Lozano-Soldevilla -% -% This file is part of FieldTrip, see http://www.fieldtriptoolbox.org -% for the documentation and details. -% -% FieldTrip is free software: you can redistribute it and/or modify -% it under the terms of the GNU General Public License as published by -% the Free Software Foundation, either version 3 of the License, or -% (at your option) any later version. -% -% FieldTrip is distributed in the hope that it will be useful, -% but WITHOUT ANY WARRANTY; without even the implied warranty of -% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -% GNU General Public License for more details. -% -% You should have received a copy of the GNU General Public License -% along with FieldTrip. If not, see . -% -% $Id: read_nihonkohden_hdr.m 395 2016-12-19 13:51:00Z tmoser $ - -% the name of the ascii file -fid=fopen(filename,'r'); - -%header line 1: acquisition information -hline1 = fgets(fid); - -% get the six different fields in the header, store in cell array -%hd=textscan(hline1,'%s %s %s %s %s %s'); -[hd]=strread(hline1,'%s'); - -fprintf('\nNihon Kohden ASCII EEG header fields:'); -fprintf('\n-------------------------------------'); - -% number of timepoints -[txt,hdr.nSamples]=strread(char(hd{1}),'%s%d','delimiter','='); -fprintf('\n%s is %d',char(txt),hdr.nSamples); - -% number of channels sampled -[txt,hdr.nChans]=strread(char(hd{2}),'%s%d','delimiter','='); -fprintf('\nNumber of %s is %d',char(txt),hdr.nChans); - -% begin sweep in ms -[txt,hdr.bsweep]=strread(char(hd{3}),'%s%f','delimiter','='); -fprintf('\n%s is %2.2f',char(txt),hdr.bsweep); - -% sampling interval in ms -[txt,hdr.sampintms]=strread(char(hd{4}),'%s%f','delimiter','='); -fprintf('\n%s is %1.2f (or %2.1f Hz)',char(txt),hdr.sampintms,(1000./hdr.sampintms)); -hdr.Fs = 1000./hdr.sampintms; - -% bins per micro volt -[txt,hdr.binsuV]=strread(char(hd{5}),'%s%f','delimiter','='); -fprintf('\n%s is %1.2f',char(txt),hdr.binsuV); - -% start time -tt=char(hd{6}); -hdr.start_time=tt(end-7:end); -fprintf('\nStart Time is %s\n',hdr.start_time); - -% header line 2: names of recording channels -hline2 = fgets(fid); - -% channel names as cell array -%ch_names=textscan(hline2,'%s'); -[hdr.label]=strread(hline2,'%s'); -hdr.nTrials = 1; -hdr.nSamplesPre = 0; -% convert to char array -%ch_names=char(ch_names{1}); - - -dc = textscan(fid,'%f',hdr.nChans*hdr.nSamples,'delimiter','\n','headerlines',0); -df = dc{1};clear dc; -df = df.*10; % multiply by 10, don't forget to divide when reading in data! -fprintf('converting ASCII floats to 16-bit signed ints'); - -dat = reshape(df,hdr.nChans,hdr.nSamples); -clear df; -dat = int16(dat)./10; -hdr.dat = double(dat); -clear dat; - -% close input file +function [hdr] = read_nihonkohden_hdr(filename) + +% READ_NIHONKOHDEN_HDR reads the known items from the Nihon Kohden EEG +% system header file (*.m00) and returns them in a structure. This reading +% function is an adaptation of get_nkheader.m written by Timothy Ellmore +% +% Use as +% hdr = read_nihonkoden_hdr(filename) +% +% This returns a header structure with +% hdr.nSamples number of data points per channel +% hdr.nchannels number of channels sampled during recording +% hdr.bsweep begin sweep (ms) +% hdr.sampintms sampling interval in ms +% hdr.binsuV number of bins per microvolts +% hdr.start_time starting time of recording +% hdr.label char array of channel names +% +% See also READ_NIHONKOHDEN_M00 + +% Copyright (C) 2016, Diego Lozano-Soldevilla +% +% This file is part of FieldTrip, see http://www.fieldtriptoolbox.org +% for the documentation and details. +% +% FieldTrip is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% FieldTrip is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with FieldTrip. If not, see . +% +% $Id: read_nihonkohden_hdr.m 395 2016-12-19 13:51:00Z tmoser $ + +% the name of the ascii file +fid=fopen(filename,'r'); + +%header line 1: acquisition information +hline1 = fgets(fid); + +% get the six different fields in the header, store in cell array +%hd=textscan(hline1,'%s %s %s %s %s %s'); +[hd]=strread(hline1,'%s'); + +fprintf('\nNihon Kohden ASCII EEG header fields:'); +fprintf('\n-------------------------------------'); + +% number of timepoints +[txt,hdr.nSamples]=strread(char(hd{1}),'%s%d','delimiter','='); +fprintf('\n%s is %d',char(txt),hdr.nSamples); + +% number of channels sampled +[txt,hdr.nChans]=strread(char(hd{2}),'%s%d','delimiter','='); +fprintf('\nNumber of %s is %d',char(txt),hdr.nChans); + +% begin sweep in ms +[txt,hdr.bsweep]=strread(char(hd{3}),'%s%f','delimiter','='); +fprintf('\n%s is %2.2f',char(txt),hdr.bsweep); + +% sampling interval in ms +[txt,hdr.sampintms]=strread(char(hd{4}),'%s%f','delimiter','='); +fprintf('\n%s is %1.2f (or %2.1f Hz)',char(txt),hdr.sampintms,(1000./hdr.sampintms)); +hdr.Fs = 1000./hdr.sampintms; + +% bins per micro volt +[txt,hdr.binsuV]=strread(char(hd{5}),'%s%f','delimiter','='); +fprintf('\n%s is %1.2f',char(txt),hdr.binsuV); + +% start time +tt=char(hd{6}); +hdr.start_time=tt(end-7:end); +fprintf('\nStart Time is %s\n',hdr.start_time); + +% header line 2: names of recording channels +hline2 = fgets(fid); + +% channel names as cell array +%ch_names=textscan(hline2,'%s'); +[hdr.label]=strread(hline2,'%s'); +hdr.nTrials = 1; +hdr.nSamplesPre = 0; +% convert to char array +%ch_names=char(ch_names{1}); + + +dc = textscan(fid,'%f',hdr.nChans*hdr.nSamples,'delimiter','\n','headerlines',0); +df = dc{1};clear dc; +df = df.*10; % multiply by 10, don't forget to divide when reading in data! +fprintf('converting ASCII floats to 16-bit signed ints'); + +dat = reshape(df,hdr.nChans,hdr.nSamples); +clear df; +dat = int16(dat)./10; +hdr.dat = double(dat); +clear dat; + +% close input file fclose(fid); \ No newline at end of file diff --git a/src/Import/fieldtrip/fileio/private/read_nihonkohden_m00.m b/Import/fieldtrip/fileio/private/read_nihonkohden_m00.m similarity index 97% rename from src/Import/fieldtrip/fileio/private/read_nihonkohden_m00.m rename to Import/fieldtrip/fileio/private/read_nihonkohden_m00.m index a7490d9a..91d9ca3d 100644 --- a/src/Import/fieldtrip/fileio/private/read_nihonkohden_m00.m +++ b/Import/fieldtrip/fileio/private/read_nihonkohden_m00.m @@ -1,68 +1,68 @@ -function [dat] = read_nihonkohden_m00(filename, begsample, endsample) - -% READ_NIHONKOHDEN_M00 reads data Nihon Kohden EEG system and converts the -% floating point ASCII values to 16-bit signed integers from *.m00 file -% format. This function is an adaptation of convert_nkascii2mat.m written -% by Timothy Ellmore -% -% Use as -% dat = read_nihonkohden_m00(filename) -% -% This returns a header structure with -% hdr.nSamples number of data points per channel -% hdr.nchannels number of channels sampled during recording -% hdr.bsweep begin sweep (ms) -% hdr.sampintms sampling interval in ms -% hdr.binsuV number of bins per microvolts -% hdr.start_time starting time of recording -% hdr.label char array of channel names -% -% See also READ_NIHONKOHDEN_HDR - -% Copyright (C) 2016, Diego Lozano-Soldevilla -% -% This file is part of FieldTrip, see http://www.fieldtriptoolbox.org -% for the documentation and details. -% -% FieldTrip is free software: you can redistribute it and/or modify -% it under the terms of the GNU General Public License as published by -% the Free Software Foundation, either version 3 of the License, or -% (at your option) any later version. -% -% FieldTrip is distributed in the hope that it will be useful, -% but WITHOUT ANY WARRANTY; without even the implied warranty of -% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -% GNU General Public License for more details. -% -% You should have received a copy of the GNU General Public License -% along with FieldTrip. If not, see . -% -% $Id: read_nihonkohden_m00.m 395 2016-12-19 13:51:00Z tmoser $ - -hdr = read_nihonkohden_hdr(filename); -mult = 10;% a multiplier; divide stored value by this to floats -nsmp = (endsample-begsample+1); - -% the name of the ascii file -fid=fopen(filename,'r'); - -% skip header information -hline1 = fgets(fid); -hline2 = fgets(fid); - -fprintf('\nWill read from %d to %d sample points: %d seconds \n',begsample,endsample,nsmp/hdr.Fs); - -dc = textscan(fid,'%f',hdr.nChans*nsmp,'delimiter','\n','headerlines',begsample-1); -df = dc{1};clear dc; -df = df.*mult; % multiply by 10, don't forget to divide when reading in data! - -fprintf('converting ASCII floats to 16-bit signed ints'); - -dat = reshape(df,hdr.nChans,nsmp); -clear df; -dat = int16(dat)./mult; -dat = double(dat); -% should we double it? No clue why the int16 and the multiplier. -% Later convert data has to be multiplied to transform it into microvolts -% nkdata.eeg=nkdata.eeg./nkdata.multiplier; (Diego) -fclose(fid); +function [dat] = read_nihonkohden_m00(filename, begsample, endsample) + +% READ_NIHONKOHDEN_M00 reads data Nihon Kohden EEG system and converts the +% floating point ASCII values to 16-bit signed integers from *.m00 file +% format. This function is an adaptation of convert_nkascii2mat.m written +% by Timothy Ellmore +% +% Use as +% dat = read_nihonkohden_m00(filename) +% +% This returns a header structure with +% hdr.nSamples number of data points per channel +% hdr.nchannels number of channels sampled during recording +% hdr.bsweep begin sweep (ms) +% hdr.sampintms sampling interval in ms +% hdr.binsuV number of bins per microvolts +% hdr.start_time starting time of recording +% hdr.label char array of channel names +% +% See also READ_NIHONKOHDEN_HDR + +% Copyright (C) 2016, Diego Lozano-Soldevilla +% +% This file is part of FieldTrip, see http://www.fieldtriptoolbox.org +% for the documentation and details. +% +% FieldTrip is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% FieldTrip is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with FieldTrip. If not, see . +% +% $Id: read_nihonkohden_m00.m 395 2016-12-19 13:51:00Z tmoser $ + +hdr = read_nihonkohden_hdr(filename); +mult = 10;% a multiplier; divide stored value by this to floats +nsmp = (endsample-begsample+1); + +% the name of the ascii file +fid=fopen(filename,'r'); + +% skip header information +hline1 = fgets(fid); +hline2 = fgets(fid); + +fprintf('\nWill read from %d to %d sample points: %d seconds \n',begsample,endsample,nsmp/hdr.Fs); + +dc = textscan(fid,'%f',hdr.nChans*nsmp,'delimiter','\n','headerlines',begsample-1); +df = dc{1};clear dc; +df = df.*mult; % multiply by 10, don't forget to divide when reading in data! + +fprintf('converting ASCII floats to 16-bit signed ints'); + +dat = reshape(df,hdr.nChans,nsmp); +clear df; +dat = int16(dat)./mult; +dat = double(dat); +% should we double it? No clue why the int16 and the multiplier. +% Later convert data has to be multiplied to transform it into microvolts +% nkdata.eeg=nkdata.eeg./nkdata.multiplier; (Diego) +fclose(fid); diff --git a/src/Import/fieldtrip/fileio/private/read_nimh_cortex.m b/Import/fieldtrip/fileio/private/read_nimh_cortex.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_nimh_cortex.m rename to Import/fieldtrip/fileio/private/read_nimh_cortex.m diff --git a/src/Import/fieldtrip/fileio/private/read_nmc_archive_k_data.m b/Import/fieldtrip/fileio/private/read_nmc_archive_k_data.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_nmc_archive_k_data.m rename to Import/fieldtrip/fileio/private/read_nmc_archive_k_data.m diff --git a/src/Import/fieldtrip/fileio/private/read_nmc_archive_k_event.m b/Import/fieldtrip/fileio/private/read_nmc_archive_k_event.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_nmc_archive_k_event.m rename to Import/fieldtrip/fileio/private/read_nmc_archive_k_event.m diff --git a/src/Import/fieldtrip/fileio/private/read_nmc_archive_k_hdr.m b/Import/fieldtrip/fileio/private/read_nmc_archive_k_hdr.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_nmc_archive_k_hdr.m rename to Import/fieldtrip/fileio/private/read_nmc_archive_k_hdr.m diff --git a/src/Import/fieldtrip/fileio/private/read_ns_avg.m b/Import/fieldtrip/fileio/private/read_ns_avg.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_ns_avg.m rename to Import/fieldtrip/fileio/private/read_ns_avg.m diff --git a/src/Import/fieldtrip/fileio/private/read_ns_eeg.m b/Import/fieldtrip/fileio/private/read_ns_eeg.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_ns_eeg.m rename to Import/fieldtrip/fileio/private/read_ns_eeg.m diff --git a/src/Import/fieldtrip/fileio/private/read_ns_hdr.m b/Import/fieldtrip/fileio/private/read_ns_hdr.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_ns_hdr.m rename to Import/fieldtrip/fileio/private/read_ns_hdr.m diff --git a/src/Import/fieldtrip/fileio/private/read_off.m b/Import/fieldtrip/fileio/private/read_off.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_off.m rename to Import/fieldtrip/fileio/private/read_off.m diff --git a/src/Import/fieldtrip/fileio/private/read_plexon_ddt.m b/Import/fieldtrip/fileio/private/read_plexon_ddt.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_plexon_ddt.m rename to Import/fieldtrip/fileio/private/read_plexon_ddt.m diff --git a/src/Import/fieldtrip/fileio/private/read_plexon_ds.m b/Import/fieldtrip/fileio/private/read_plexon_ds.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_plexon_ds.m rename to Import/fieldtrip/fileio/private/read_plexon_ds.m diff --git a/src/Import/fieldtrip/fileio/private/read_plexon_nex.m b/Import/fieldtrip/fileio/private/read_plexon_nex.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_plexon_nex.m rename to Import/fieldtrip/fileio/private/read_plexon_nex.m diff --git a/src/Import/fieldtrip/fileio/private/read_plexon_plx.m b/Import/fieldtrip/fileio/private/read_plexon_plx.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_plexon_plx.m rename to Import/fieldtrip/fileio/private/read_plexon_plx.m diff --git a/src/Import/fieldtrip/fileio/private/read_ply.m b/Import/fieldtrip/fileio/private/read_ply.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_ply.m rename to Import/fieldtrip/fileio/private/read_ply.m diff --git a/src/Import/fieldtrip/fileio/private/read_polhemus_fil.m b/Import/fieldtrip/fileio/private/read_polhemus_fil.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_polhemus_fil.m rename to Import/fieldtrip/fileio/private/read_polhemus_fil.m diff --git a/src/Import/fieldtrip/fileio/private/read_sbin_data.m b/Import/fieldtrip/fileio/private/read_sbin_data.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_sbin_data.m rename to Import/fieldtrip/fileio/private/read_sbin_data.m diff --git a/src/Import/fieldtrip/fileio/private/read_sbin_events.m b/Import/fieldtrip/fileio/private/read_sbin_events.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_sbin_events.m rename to Import/fieldtrip/fileio/private/read_sbin_events.m diff --git a/src/Import/fieldtrip/fileio/private/read_sbin_header.m b/Import/fieldtrip/fileio/private/read_sbin_header.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_sbin_header.m rename to Import/fieldtrip/fileio/private/read_sbin_header.m diff --git a/src/Import/fieldtrip/fileio/private/read_serial_event.m b/Import/fieldtrip/fileio/private/read_serial_event.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_serial_event.m rename to Import/fieldtrip/fileio/private/read_serial_event.m diff --git a/src/Import/fieldtrip/fileio/private/read_shm_data.m b/Import/fieldtrip/fileio/private/read_shm_data.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_shm_data.m rename to Import/fieldtrip/fileio/private/read_shm_data.m diff --git a/src/Import/fieldtrip/fileio/private/read_shm_event.m b/Import/fieldtrip/fileio/private/read_shm_event.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_shm_event.m rename to Import/fieldtrip/fileio/private/read_shm_event.m diff --git a/src/Import/fieldtrip/fileio/private/read_shm_header.m b/Import/fieldtrip/fileio/private/read_shm_header.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_shm_header.m rename to Import/fieldtrip/fileio/private/read_shm_header.m diff --git a/src/Import/fieldtrip/fileio/private/read_smi_txt.m b/Import/fieldtrip/fileio/private/read_smi_txt.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_smi_txt.m rename to Import/fieldtrip/fileio/private/read_smi_txt.m diff --git a/src/Import/fieldtrip/fileio/private/read_spike6mat_data.m b/Import/fieldtrip/fileio/private/read_spike6mat_data.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_spike6mat_data.m rename to Import/fieldtrip/fileio/private/read_spike6mat_data.m diff --git a/src/Import/fieldtrip/fileio/private/read_spike6mat_header.m b/Import/fieldtrip/fileio/private/read_spike6mat_header.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_spike6mat_header.m rename to Import/fieldtrip/fileio/private/read_spike6mat_header.m diff --git a/src/Import/fieldtrip/fileio/private/read_spmeeg_data.m b/Import/fieldtrip/fileio/private/read_spmeeg_data.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_spmeeg_data.m rename to Import/fieldtrip/fileio/private/read_spmeeg_data.m diff --git a/src/Import/fieldtrip/fileio/private/read_spmeeg_event.m b/Import/fieldtrip/fileio/private/read_spmeeg_event.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_spmeeg_event.m rename to Import/fieldtrip/fileio/private/read_spmeeg_event.m diff --git a/src/Import/fieldtrip/fileio/private/read_spmeeg_header.m b/Import/fieldtrip/fileio/private/read_spmeeg_header.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_spmeeg_header.m rename to Import/fieldtrip/fileio/private/read_spmeeg_header.m diff --git a/src/Import/fieldtrip/fileio/private/read_stl.m b/Import/fieldtrip/fileio/private/read_stl.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_stl.m rename to Import/fieldtrip/fileio/private/read_stl.m diff --git a/src/Import/fieldtrip/fileio/private/read_tdt_sev.m b/Import/fieldtrip/fileio/private/read_tdt_sev.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_tdt_sev.m rename to Import/fieldtrip/fileio/private/read_tdt_sev.m diff --git a/src/Import/fieldtrip/fileio/private/read_tdt_tbk.m b/Import/fieldtrip/fileio/private/read_tdt_tbk.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_tdt_tbk.m rename to Import/fieldtrip/fileio/private/read_tdt_tbk.m diff --git a/src/Import/fieldtrip/fileio/private/read_tdt_tdx.m b/Import/fieldtrip/fileio/private/read_tdt_tdx.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_tdt_tdx.m rename to Import/fieldtrip/fileio/private/read_tdt_tdx.m diff --git a/src/Import/fieldtrip/fileio/private/read_tdt_tev.m b/Import/fieldtrip/fileio/private/read_tdt_tev.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_tdt_tev.m rename to Import/fieldtrip/fileio/private/read_tdt_tev.m diff --git a/src/Import/fieldtrip/fileio/private/read_tdt_tsq.m b/Import/fieldtrip/fileio/private/read_tdt_tsq.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_tdt_tsq.m rename to Import/fieldtrip/fileio/private/read_tdt_tsq.m diff --git a/src/Import/fieldtrip/fileio/private/read_tmsi_poly5.m b/Import/fieldtrip/fileio/private/read_tmsi_poly5.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_tmsi_poly5.m rename to Import/fieldtrip/fileio/private/read_tmsi_poly5.m diff --git a/src/Import/fieldtrip/fileio/private/read_tobii_tsv.m b/Import/fieldtrip/fileio/private/read_tobii_tsv.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_tobii_tsv.m rename to Import/fieldtrip/fileio/private/read_tobii_tsv.m diff --git a/src/Import/fieldtrip/fileio/private/read_trigger.m b/Import/fieldtrip/fileio/private/read_trigger.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_trigger.m rename to Import/fieldtrip/fileio/private/read_trigger.m diff --git a/src/Import/fieldtrip/fileio/private/read_videomeg_aud.m b/Import/fieldtrip/fileio/private/read_videomeg_aud.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_videomeg_aud.m rename to Import/fieldtrip/fileio/private/read_videomeg_aud.m diff --git a/src/Import/fieldtrip/fileio/private/read_videomeg_vid.m b/Import/fieldtrip/fileio/private/read_videomeg_vid.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_videomeg_vid.m rename to Import/fieldtrip/fileio/private/read_videomeg_vid.m diff --git a/src/Import/fieldtrip/fileio/private/read_vtk.m b/Import/fieldtrip/fileio/private/read_vtk.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_vtk.m rename to Import/fieldtrip/fileio/private/read_vtk.m diff --git a/src/Import/fieldtrip/fileio/private/read_wdq_data.m b/Import/fieldtrip/fileio/private/read_wdq_data.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_wdq_data.m rename to Import/fieldtrip/fileio/private/read_wdq_data.m diff --git a/src/Import/fieldtrip/fileio/private/read_wdq_header.m b/Import/fieldtrip/fileio/private/read_wdq_header.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_wdq_header.m rename to Import/fieldtrip/fileio/private/read_wdq_header.m diff --git a/src/Import/fieldtrip/fileio/private/read_yokogawa_data.m b/Import/fieldtrip/fileio/private/read_yokogawa_data.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_yokogawa_data.m rename to Import/fieldtrip/fileio/private/read_yokogawa_data.m diff --git a/src/Import/fieldtrip/fileio/private/read_yokogawa_data_new.m b/Import/fieldtrip/fileio/private/read_yokogawa_data_new.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_yokogawa_data_new.m rename to Import/fieldtrip/fileio/private/read_yokogawa_data_new.m diff --git a/src/Import/fieldtrip/fileio/private/read_yokogawa_event.m b/Import/fieldtrip/fileio/private/read_yokogawa_event.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_yokogawa_event.m rename to Import/fieldtrip/fileio/private/read_yokogawa_event.m diff --git a/src/Import/fieldtrip/fileio/private/read_yokogawa_header.m b/Import/fieldtrip/fileio/private/read_yokogawa_header.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_yokogawa_header.m rename to Import/fieldtrip/fileio/private/read_yokogawa_header.m diff --git a/src/Import/fieldtrip/fileio/private/read_yokogawa_header_new.m b/Import/fieldtrip/fileio/private/read_yokogawa_header_new.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_yokogawa_header_new.m rename to Import/fieldtrip/fileio/private/read_yokogawa_header_new.m diff --git a/src/Import/fieldtrip/fileio/private/read_zebris.m b/Import/fieldtrip/fileio/private/read_zebris.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/read_zebris.m rename to Import/fieldtrip/fileio/private/read_zebris.m diff --git a/src/Import/fieldtrip/fileio/private/readbdf.m b/Import/fieldtrip/fileio/private/readbdf.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/readbdf.m rename to Import/fieldtrip/fileio/private/readbdf.m diff --git a/src/Import/fieldtrip/fileio/private/readmarkerfile.m b/Import/fieldtrip/fileio/private/readmarkerfile.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/readmarkerfile.m rename to Import/fieldtrip/fileio/private/readmarkerfile.m diff --git a/src/Import/fieldtrip/fileio/private/refine.m b/Import/fieldtrip/fileio/private/refine.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/refine.m rename to Import/fieldtrip/fileio/private/refine.m diff --git a/src/Import/fieldtrip/fileio/private/rfbevent.mexa64 b/Import/fieldtrip/fileio/private/rfbevent.mexa64 similarity index 100% rename from src/Import/fieldtrip/fileio/private/rfbevent.mexa64 rename to Import/fieldtrip/fileio/private/rfbevent.mexa64 diff --git a/src/Import/fieldtrip/fileio/private/rfbevent.mexglx b/Import/fieldtrip/fileio/private/rfbevent.mexglx similarity index 100% rename from src/Import/fieldtrip/fileio/private/rfbevent.mexglx rename to Import/fieldtrip/fileio/private/rfbevent.mexglx diff --git a/src/Import/fieldtrip/fileio/private/rfbevent.mexmac b/Import/fieldtrip/fileio/private/rfbevent.mexmac similarity index 100% rename from src/Import/fieldtrip/fileio/private/rfbevent.mexmac rename to Import/fieldtrip/fileio/private/rfbevent.mexmac diff --git a/src/Import/fieldtrip/fileio/private/rfbevent.mexmaci b/Import/fieldtrip/fileio/private/rfbevent.mexmaci similarity index 100% rename from src/Import/fieldtrip/fileio/private/rfbevent.mexmaci rename to Import/fieldtrip/fileio/private/rfbevent.mexmaci diff --git a/src/Import/fieldtrip/fileio/private/rfbevent.mexmaci64 b/Import/fieldtrip/fileio/private/rfbevent.mexmaci64 similarity index 100% rename from src/Import/fieldtrip/fileio/private/rfbevent.mexmaci64 rename to Import/fieldtrip/fileio/private/rfbevent.mexmaci64 diff --git a/src/Import/fieldtrip/fileio/private/rmsubfield.m b/Import/fieldtrip/fileio/private/rmsubfield.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/rmsubfield.m rename to Import/fieldtrip/fileio/private/rmsubfield.m diff --git a/src/Import/fieldtrip/fileio/private/rotate.m b/Import/fieldtrip/fileio/private/rotate.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/rotate.m rename to Import/fieldtrip/fileio/private/rotate.m diff --git a/src/Import/fieldtrip/fileio/private/sap2matlab.mexa64 b/Import/fieldtrip/fileio/private/sap2matlab.mexa64 similarity index 100% rename from src/Import/fieldtrip/fileio/private/sap2matlab.mexa64 rename to Import/fieldtrip/fileio/private/sap2matlab.mexa64 diff --git a/src/Import/fieldtrip/fileio/private/sap2matlab.mexmaci64 b/Import/fieldtrip/fileio/private/sap2matlab.mexmaci64 similarity index 100% rename from src/Import/fieldtrip/fileio/private/sap2matlab.mexmaci64 rename to Import/fieldtrip/fileio/private/sap2matlab.mexmaci64 diff --git a/src/Import/fieldtrip/fileio/private/sap2matlab.mexw32 b/Import/fieldtrip/fileio/private/sap2matlab.mexw32 similarity index 100% rename from src/Import/fieldtrip/fileio/private/sap2matlab.mexw32 rename to Import/fieldtrip/fileio/private/sap2matlab.mexw32 diff --git a/src/Import/fieldtrip/fileio/private/setsubfield.m b/Import/fieldtrip/fileio/private/setsubfield.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/setsubfield.m rename to Import/fieldtrip/fileio/private/setsubfield.m diff --git a/src/Import/fieldtrip/fileio/private/solid_angle.m b/Import/fieldtrip/fileio/private/solid_angle.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/solid_angle.m rename to Import/fieldtrip/fileio/private/solid_angle.m diff --git a/src/Import/fieldtrip/fileio/private/solid_angle.mexa64 b/Import/fieldtrip/fileio/private/solid_angle.mexa64 similarity index 100% rename from src/Import/fieldtrip/fileio/private/solid_angle.mexa64 rename to Import/fieldtrip/fileio/private/solid_angle.mexa64 diff --git a/src/Import/fieldtrip/fileio/private/surf_to_tetgen.m b/Import/fieldtrip/fileio/private/surf_to_tetgen.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/surf_to_tetgen.m rename to Import/fieldtrip/fileio/private/surf_to_tetgen.m diff --git a/src/Import/fieldtrip/fileio/private/time2offset.m b/Import/fieldtrip/fileio/private/time2offset.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/time2offset.m rename to Import/fieldtrip/fileio/private/time2offset.m diff --git a/src/Import/fieldtrip/fileio/private/timestamp_neuralynx.m b/Import/fieldtrip/fileio/private/timestamp_neuralynx.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/timestamp_neuralynx.m rename to Import/fieldtrip/fileio/private/timestamp_neuralynx.m diff --git a/src/Import/fieldtrip/fileio/private/timestamp_plexon.m b/Import/fieldtrip/fileio/private/timestamp_plexon.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/timestamp_plexon.m rename to Import/fieldtrip/fileio/private/timestamp_plexon.m diff --git a/src/Import/fieldtrip/fileio/private/tokenize.m b/Import/fieldtrip/fileio/private/tokenize.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/tokenize.m rename to Import/fieldtrip/fileio/private/tokenize.m diff --git a/src/Import/fieldtrip/fileio/private/translate.m b/Import/fieldtrip/fileio/private/translate.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/translate.m rename to Import/fieldtrip/fileio/private/translate.m diff --git a/src/Import/fieldtrip/fileio/private/undobalancing.m b/Import/fieldtrip/fileio/private/undobalancing.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/undobalancing.m rename to Import/fieldtrip/fileio/private/undobalancing.m diff --git a/src/Import/fieldtrip/fileio/private/volumewrite_spm.m b/Import/fieldtrip/fileio/private/volumewrite_spm.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/volumewrite_spm.m rename to Import/fieldtrip/fileio/private/volumewrite_spm.m diff --git a/src/Import/fieldtrip/fileio/private/write_brainvision_eeg.m b/Import/fieldtrip/fileio/private/write_brainvision_eeg.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/write_brainvision_eeg.m rename to Import/fieldtrip/fileio/private/write_brainvision_eeg.m diff --git a/src/Import/fieldtrip/fileio/private/write_ctf_shm.m b/Import/fieldtrip/fileio/private/write_ctf_shm.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/write_ctf_shm.m rename to Import/fieldtrip/fileio/private/write_ctf_shm.m diff --git a/src/Import/fieldtrip/fileio/private/write_ctf_shm.mexglx b/Import/fieldtrip/fileio/private/write_ctf_shm.mexglx similarity index 100% rename from src/Import/fieldtrip/fileio/private/write_ctf_shm.mexglx rename to Import/fieldtrip/fileio/private/write_ctf_shm.mexglx diff --git a/src/Import/fieldtrip/fileio/private/write_edf.m b/Import/fieldtrip/fileio/private/write_edf.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/write_edf.m rename to Import/fieldtrip/fileio/private/write_edf.m diff --git a/src/Import/fieldtrip/fileio/private/write_gdf.m b/Import/fieldtrip/fileio/private/write_gdf.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/write_gdf.m rename to Import/fieldtrip/fileio/private/write_gdf.m diff --git a/src/Import/fieldtrip/fileio/private/write_neuralynx_ncs.m b/Import/fieldtrip/fileio/private/write_neuralynx_ncs.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/write_neuralynx_ncs.m rename to Import/fieldtrip/fileio/private/write_neuralynx_ncs.m diff --git a/src/Import/fieldtrip/fileio/private/write_neuralynx_nts.m b/Import/fieldtrip/fileio/private/write_neuralynx_nts.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/write_neuralynx_nts.m rename to Import/fieldtrip/fileio/private/write_neuralynx_nts.m diff --git a/src/Import/fieldtrip/fileio/private/write_nifti2_hdr.m b/Import/fieldtrip/fileio/private/write_nifti2_hdr.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/write_nifti2_hdr.m rename to Import/fieldtrip/fileio/private/write_nifti2_hdr.m diff --git a/src/Import/fieldtrip/fileio/private/write_off.m b/Import/fieldtrip/fileio/private/write_off.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/write_off.m rename to Import/fieldtrip/fileio/private/write_off.m diff --git a/src/Import/fieldtrip/fileio/private/write_plexon_nex.m b/Import/fieldtrip/fileio/private/write_plexon_nex.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/write_plexon_nex.m rename to Import/fieldtrip/fileio/private/write_plexon_nex.m diff --git a/src/Import/fieldtrip/fileio/private/write_ply.m b/Import/fieldtrip/fileio/private/write_ply.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/write_ply.m rename to Import/fieldtrip/fileio/private/write_ply.m diff --git a/src/Import/fieldtrip/fileio/private/write_serial_event.m b/Import/fieldtrip/fileio/private/write_serial_event.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/write_serial_event.m rename to Import/fieldtrip/fileio/private/write_serial_event.m diff --git a/src/Import/fieldtrip/fileio/private/write_stl.m b/Import/fieldtrip/fileio/private/write_stl.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/write_stl.m rename to Import/fieldtrip/fileio/private/write_stl.m diff --git a/src/Import/fieldtrip/fileio/private/write_vtk.m b/Import/fieldtrip/fileio/private/write_vtk.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/write_vtk.m rename to Import/fieldtrip/fileio/private/write_vtk.m diff --git a/src/Import/fieldtrip/fileio/private/xml2struct.m b/Import/fieldtrip/fileio/private/xml2struct.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/xml2struct.m rename to Import/fieldtrip/fileio/private/xml2struct.m diff --git a/src/Import/fieldtrip/fileio/private/yokogawa2grad.m b/Import/fieldtrip/fileio/private/yokogawa2grad.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/yokogawa2grad.m rename to Import/fieldtrip/fileio/private/yokogawa2grad.m diff --git a/src/Import/fieldtrip/fileio/private/yokogawa2grad_new.m b/Import/fieldtrip/fileio/private/yokogawa2grad_new.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/yokogawa2grad_new.m rename to Import/fieldtrip/fileio/private/yokogawa2grad_new.m diff --git a/src/Import/fieldtrip/fileio/private/yokogawa2vol.m b/Import/fieldtrip/fileio/private/yokogawa2vol.m similarity index 100% rename from src/Import/fieldtrip/fileio/private/yokogawa2vol.m rename to Import/fieldtrip/fileio/private/yokogawa2vol.m diff --git a/src/Import/labchart/adi/+adi/+binary/channel_writer.m b/Import/labchart/adi/+adi/+binary/channel_writer.m similarity index 96% rename from src/Import/labchart/adi/+adi/+binary/channel_writer.m rename to Import/labchart/adi/+adi/+binary/channel_writer.m index 9fa4799f..8ca2c19d 100644 --- a/src/Import/labchart/adi/+adi/+binary/channel_writer.m +++ b/Import/labchart/adi/+adi/+binary/channel_writer.m @@ -1,62 +1,62 @@ -classdef (Hidden) channel_writer - % - % Class: - % adi.channel_writer - % - % This class facilities writing a channel to the binary file format. - % More details can be found in adi.binary_file_writer - % - % See Also: - % adi.binary_file_writer - - - %{ - Each channel header has the following format: - type name description - char Title[32] channel title - char Units[32] units name - double scale see text - double offset see text - double RangeHigh see text - double RangeLow see text - %} - - properties - name - units - data - fs - %These are only needed for 16 bit data, although they must be in - %the binary. - scale = 1 - offset = 0 - end - - methods - function obj = channel_writer(channel_name,units,fs,data) - %TODO: Check name size - obj.name = channel_name; - obj.units = units; - obj.data = data; - obj.fs = fs; - end - function writeHeader(obj,fid) - %pass - - temp_title = zeros(1,32,'uint8'); - temp_units = zeros(1,32,'uint8'); - temp_title(1:length(obj.name)) = uint8(obj.name); - temp_units(1:length(obj.units)) = uint8(obj.units); - - fwrite(fid,temp_title,'*char'); - fwrite(fid,temp_units,'*char'); - fwrite(fid,obj.scale,'double'); - fwrite(fid,obj.offset,'double'); - %Range high and low ... - not currently used - fwrite(fid,Inf,'double'); - fwrite(fid,-Inf,'double'); - end - end - -end - +classdef (Hidden) channel_writer + % + % Class: + % adi.channel_writer + % + % This class facilities writing a channel to the binary file format. + % More details can be found in adi.binary_file_writer + % + % See Also: + % adi.binary_file_writer + + + %{ + Each channel header has the following format: + type name description + char Title[32] channel title + char Units[32] units name + double scale see text + double offset see text + double RangeHigh see text + double RangeLow see text + %} + + properties + name + units + data + fs + %These are only needed for 16 bit data, although they must be in + %the binary. + scale = 1 + offset = 0 + end + + methods + function obj = channel_writer(channel_name,units,fs,data) + %TODO: Check name size + obj.name = channel_name; + obj.units = units; + obj.data = data; + obj.fs = fs; + end + function writeHeader(obj,fid) + %pass + + temp_title = zeros(1,32,'uint8'); + temp_units = zeros(1,32,'uint8'); + temp_title(1:length(obj.name)) = uint8(obj.name); + temp_units(1:length(obj.units)) = uint8(obj.units); + + fwrite(fid,temp_title,'*char'); + fwrite(fid,temp_units,'*char'); + fwrite(fid,obj.scale,'double'); + fwrite(fid,obj.offset,'double'); + %Range high and low ... - not currently used + fwrite(fid,Inf,'double'); + fwrite(fid,-Inf,'double'); + end + end + +end + diff --git a/src/Import/labchart/adi/+adi/+binary/file_writer.m b/Import/labchart/adi/+adi/+binary/file_writer.m similarity index 97% rename from src/Import/labchart/adi/+adi/+binary/file_writer.m rename to Import/labchart/adi/+adi/+binary/file_writer.m index 461b635c..bc171aa1 100644 --- a/src/Import/labchart/adi/+adi/+binary/file_writer.m +++ b/Import/labchart/adi/+adi/+binary/file_writer.m @@ -1,184 +1,184 @@ -classdef file_writer < handle - % - % Class: - % adi.binary.file_writer - % - % This is meant to handle the binary file format which is publically - % available online. The binary format only supports writing one - % record. There is no SDK for this format. Instead low - % level read/write options are used. - % - % This was written RATHER HASTILY. It works but it isn't pretty. - % - % Limitations of Binary Format: - % ----------------------------- - % - no record support - % - no comment support - % - all channels are written to file at the same rate (leads to - % larger file sizes) - % - channel data are not compressed - % - % Example Code: - % ------------- - % file_path = 'C:\repos\test_bin.adibin'; - % obj = adi.binary_file_writer(file_path) - % %FORMAT: channel name, units, sampling_rate, data - % obj.addNewChannel('Pressure','cmH2O',1000,1:2000); - % obj.addNewChannel('EUS EMG Corrected','mV',20000,1:40000); - % obj.addNewChannel('Stim','V',20000,1:40000); - % obj.write(); - % - % See Also: - % adi.binary.channel_writer - - %{ - %Test code: - %---------- - file_path = 'C:\repos\test_bin.adibin'; - obj = adi.binary.file_writer(file_path) - obj.addNewChannel('Pressure','cmH2O',1000,1:1000); - obj.addNewChannel('EUS EMG Corrected','mV',20000,1:20000); - obj.addNewChannel('Stim','V',20000,1:20000); - obj.write(); - %} - - properties - file_path - date_number = now - pre_trigger_time = 0 %pre_rigger time in seconds - %time_channel - 1 => time included, how would that happen? - %which one is the time channel? - % - channels = [] - samples_per_channel %We take the channel with the highest sampling rate - end - - properties (Dependent) - fs %Check all channels, use the highest rate - n_channels - end - - methods - function value = get.n_channels(obj) - value = length(obj.channels); - end - function value = get.fs(obj) - if isempty(obj.channels) - value = NaN; - else - value = max([obj.channels.fs]); - end - end - function value = get.samples_per_channel(obj) - if isempty(obj.channels) - value = NaN; - else - [~,I] = max([obj.channels.fs]); - value = length(obj.channels(I).data); - end - end - end - - methods - function obj = file_writer(file_path) - % - % obj = adi.binary.file_writer(file_path) - % - % See the examples at the top of this file - obj.file_path = file_path; - end - function addNewChannel(obj,channel_name,units,fs,data) - %TODO: one could provide the object instead. => addChannel - temp = adi.binary_channel_writer(channel_name,units,fs,data); - if isempty(obj.channels) - obj.channels = temp; - else - obj.channels = [obj.channels temp]; - end - end - function write(obj) - %Checks: - %- at least 1 channel is defined - - %{ - File Header - The file header has the following format: - type name description - char magic[4] CFWB - long Version 1 - double secPerTick sample period in - seconds - long Year 4-digit year - long Month month 1-12 - long Day day of month 1-31 - long Hour hour 0-23 - long Minute minute 0-59 - double Seconds seconds - double trigger pre-trigger time in - seconds - long NChannels number of channels - long SamplesPer - Channel - number of samples per - channel - long TimeChannel 1 => time included - long DataFormat 1 = double - 2 = float - 3 = short - The file header has a size of 68 bytes. Note that the sample period (secPerTick) is the - reciprocal of the sampling rate, so for example 0.01 represents 100 samples per second. - %} - - if exist(obj.file_path,'file') - error('Please delete existing file before running this code') - end - - fid = fopen(obj.file_path,'w'); - - fwrite(fid, 'CFWB', '*char'); - fwrite(fid, 1, 'long'); - fwrite(fid, 1/obj.fs, 'double'); - - [Y,MO,D,H,MI,S] = datevec(obj.date_number); - - fwrite(fid, Y, 'long'); - fwrite(fid, MO, 'long'); - fwrite(fid, D, 'long'); - fwrite(fid, H, 'long'); - fwrite(fid, MI, 'long'); - fwrite(fid, S, 'double') - fwrite(fid, obj.pre_trigger_time, 'double'); - fwrite(fid, length(obj.channels), 'long'); - fwrite(fid, obj.samples_per_channel, 'long'); - fwrite(fid, false, 'long'); - fwrite(fid, 2, 'long'); %Float - - fs_max = obj.fs; - final_data = zeros(obj.n_channels,obj.samples_per_channel,'single'); - for iChan = 1:obj.n_channels - cur_channel = obj.channels(iChan); - cur_channel.writeHeader(fid); - if cur_channel.fs == fs_max - final_data(iChan,:) = single(cur_channel.data); - else - temp_data = cur_channel.data; - if size(temp_data,1) > size(temp_data,2) - temp_data = temp_data'; - end - n_up = fs_max/cur_channel.fs; - sample_and_held_data = repmat(temp_data,[n_up 1]); - - final_data(iChan,:) = single(sample_and_held_data(:)); - - end - end - - fwrite(fid,final_data(:),'float32'); - - fclose(fid); - - end - end - -end - +classdef file_writer < handle + % + % Class: + % adi.binary.file_writer + % + % This is meant to handle the binary file format which is publically + % available online. The binary format only supports writing one + % record. There is no SDK for this format. Instead low + % level read/write options are used. + % + % This was written RATHER HASTILY. It works but it isn't pretty. + % + % Limitations of Binary Format: + % ----------------------------- + % - no record support + % - no comment support + % - all channels are written to file at the same rate (leads to + % larger file sizes) + % - channel data are not compressed + % + % Example Code: + % ------------- + % file_path = 'C:\repos\test_bin.adibin'; + % obj = adi.binary_file_writer(file_path) + % %FORMAT: channel name, units, sampling_rate, data + % obj.addNewChannel('Pressure','cmH2O',1000,1:2000); + % obj.addNewChannel('EUS EMG Corrected','mV',20000,1:40000); + % obj.addNewChannel('Stim','V',20000,1:40000); + % obj.write(); + % + % See Also: + % adi.binary.channel_writer + + %{ + %Test code: + %---------- + file_path = 'C:\repos\test_bin.adibin'; + obj = adi.binary.file_writer(file_path) + obj.addNewChannel('Pressure','cmH2O',1000,1:1000); + obj.addNewChannel('EUS EMG Corrected','mV',20000,1:20000); + obj.addNewChannel('Stim','V',20000,1:20000); + obj.write(); + %} + + properties + file_path + date_number = now + pre_trigger_time = 0 %pre_rigger time in seconds + %time_channel - 1 => time included, how would that happen? + %which one is the time channel? + % + channels = [] + samples_per_channel %We take the channel with the highest sampling rate + end + + properties (Dependent) + fs %Check all channels, use the highest rate + n_channels + end + + methods + function value = get.n_channels(obj) + value = length(obj.channels); + end + function value = get.fs(obj) + if isempty(obj.channels) + value = NaN; + else + value = max([obj.channels.fs]); + end + end + function value = get.samples_per_channel(obj) + if isempty(obj.channels) + value = NaN; + else + [~,I] = max([obj.channels.fs]); + value = length(obj.channels(I).data); + end + end + end + + methods + function obj = file_writer(file_path) + % + % obj = adi.binary.file_writer(file_path) + % + % See the examples at the top of this file + obj.file_path = file_path; + end + function addNewChannel(obj,channel_name,units,fs,data) + %TODO: one could provide the object instead. => addChannel + temp = adi.binary_channel_writer(channel_name,units,fs,data); + if isempty(obj.channels) + obj.channels = temp; + else + obj.channels = [obj.channels temp]; + end + end + function write(obj) + %Checks: + %- at least 1 channel is defined + + %{ + File Header + The file header has the following format: + type name description + char magic[4] CFWB + long Version 1 + double secPerTick sample period in + seconds + long Year 4-digit year + long Month month 1-12 + long Day day of month 1-31 + long Hour hour 0-23 + long Minute minute 0-59 + double Seconds seconds + double trigger pre-trigger time in + seconds + long NChannels number of channels + long SamplesPer + Channel + number of samples per + channel + long TimeChannel 1 => time included + long DataFormat 1 = double + 2 = float + 3 = short + The file header has a size of 68 bytes. Note that the sample period (secPerTick) is the + reciprocal of the sampling rate, so for example 0.01 represents 100 samples per second. + %} + + if exist(obj.file_path,'file') + error('Please delete existing file before running this code') + end + + fid = fopen(obj.file_path,'w'); + + fwrite(fid, 'CFWB', '*char'); + fwrite(fid, 1, 'long'); + fwrite(fid, 1/obj.fs, 'double'); + + [Y,MO,D,H,MI,S] = datevec(obj.date_number); + + fwrite(fid, Y, 'long'); + fwrite(fid, MO, 'long'); + fwrite(fid, D, 'long'); + fwrite(fid, H, 'long'); + fwrite(fid, MI, 'long'); + fwrite(fid, S, 'double') + fwrite(fid, obj.pre_trigger_time, 'double'); + fwrite(fid, length(obj.channels), 'long'); + fwrite(fid, obj.samples_per_channel, 'long'); + fwrite(fid, false, 'long'); + fwrite(fid, 2, 'long'); %Float + + fs_max = obj.fs; + final_data = zeros(obj.n_channels,obj.samples_per_channel,'single'); + for iChan = 1:obj.n_channels + cur_channel = obj.channels(iChan); + cur_channel.writeHeader(fid); + if cur_channel.fs == fs_max + final_data(iChan,:) = single(cur_channel.data); + else + temp_data = cur_channel.data; + if size(temp_data,1) > size(temp_data,2) + temp_data = temp_data'; + end + n_up = fs_max/cur_channel.fs; + sample_and_held_data = repmat(temp_data,[n_up 1]); + + final_data(iChan,:) = single(sample_and_held_data(:)); + + end + end + + fwrite(fid,final_data(:),'float32'); + + fclose(fid); + + end + end + +end + diff --git a/src/Import/labchart/adi/+adi/+examples/conversion_speed_testing.m b/Import/labchart/adi/+adi/+examples/conversion_speed_testing.m similarity index 94% rename from src/Import/labchart/adi/+adi/+examples/conversion_speed_testing.m rename to Import/labchart/adi/+adi/+examples/conversion_speed_testing.m index f935d4e7..5625ef47 100644 --- a/src/Import/labchart/adi/+adi/+examples/conversion_speed_testing.m +++ b/Import/labchart/adi/+adi/+examples/conversion_speed_testing.m @@ -1,73 +1,73 @@ -function conversion_speed_testing -% -% -% conversion_speed_testing -% -% -% TODO: This should be moved to the testing package. - -root_path = 'C:\Data\GSK\ChrisRaw'; -root_path = 'C:\D\GSK_Data'; - -base_file = '140207 control cmg.'; -file_path = fullfile(root_path,[base_file 'adicht']); -mat_fpath = fullfile(root_path,[base_file 'mat']); -h5_fpath = fullfile(root_path,[base_file 'h5']); - -%Converting the file to mat format -%--------------------------------- -if false -tic; -adinstruments.convert(file_path,'format','mat'); -toc; -end - -%Summary: -%File Size : 105 MB -%Total Time: 28 seconds -%163 reads of 21 channels (105 MB total) - 7.4 s -%Remaining time is mostly writing - -%Converting the file to h5 format -%-------------------------------- -if false -tic; -adinstruments.convert(file_path,'format','h5'); -toc; -end - -if false -tic; -h = load(mat_fpath,'data__chan_3_rec_4'); -toc; -end -%# Values: 91,434,500 - 730 MB in memory - on disk maybe 50 MB -%Channel read time: 2.637 seconds - - - -if false -tic -wtf = adinstruments.readFile(h5_fpath); -toc - -c = wtf.channel_specs(3); - -tic -data = c.getAllData(2); -toc - -tic -h = load(mat_fpath,'data__chan_3_rec_2'); -toc -end - -file_obj = h5m.file.open(h5_fpath); - -keyboard - -group_obj = h5m.group.open(file_obj,'/data__chan_3_rec_2'); - - - - +function conversion_speed_testing +% +% +% conversion_speed_testing +% +% +% TODO: This should be moved to the testing package. + +root_path = 'C:\Data\GSK\ChrisRaw'; +root_path = 'C:\D\GSK_Data'; + +base_file = '140207 control cmg.'; +file_path = fullfile(root_path,[base_file 'adicht']); +mat_fpath = fullfile(root_path,[base_file 'mat']); +h5_fpath = fullfile(root_path,[base_file 'h5']); + +%Converting the file to mat format +%--------------------------------- +if false +tic; +adinstruments.convert(file_path,'format','mat'); +toc; +end + +%Summary: +%File Size : 105 MB +%Total Time: 28 seconds +%163 reads of 21 channels (105 MB total) - 7.4 s +%Remaining time is mostly writing + +%Converting the file to h5 format +%-------------------------------- +if false +tic; +adinstruments.convert(file_path,'format','h5'); +toc; +end + +if false +tic; +h = load(mat_fpath,'data__chan_3_rec_4'); +toc; +end +%# Values: 91,434,500 - 730 MB in memory - on disk maybe 50 MB +%Channel read time: 2.637 seconds + + + +if false +tic +wtf = adinstruments.readFile(h5_fpath); +toc + +c = wtf.channel_specs(3); + +tic +data = c.getAllData(2); +toc + +tic +h = load(mat_fpath,'data__chan_3_rec_2'); +toc +end + +file_obj = h5m.file.open(h5_fpath); + +keyboard + +group_obj = h5m.group.open(file_obj,'/data__chan_3_rec_2'); + + + + diff --git a/src/Import/labchart/adi/+adi/+examples/e001_writeFileFromScratch.m b/Import/labchart/adi/+adi/+examples/e001_writeFileFromScratch.m similarity index 95% rename from src/Import/labchart/adi/+adi/+examples/e001_writeFileFromScratch.m rename to Import/labchart/adi/+adi/+examples/e001_writeFileFromScratch.m index 1f380e13..69d19111 100644 --- a/src/Import/labchart/adi/+adi/+examples/e001_writeFileFromScratch.m +++ b/Import/labchart/adi/+adi/+examples/e001_writeFileFromScratch.m @@ -1,60 +1,60 @@ -function e001_writeFileFromScratch -% -% adi.examples.e001_writeFileFromScratch -% -% In this file I wrote many more eus samples than presssure but the -% Labchart loader didn't show all of the eus data -% -% I'm not sure why this is occuring but the big lesson seems to be that -% the program doesn't completely freak out if this happens -% -% TODO: See if we can do this from a template file - -N_RECORDS = 4; - -%file_path = 'C:\Users\RNEL\Desktop\merge_adi_test\wtf.adicht'; -file_path = 'C:\Users\Jim\Desktop\merge_adi_test\wtf.adicht'; - -if exist(file_path,'file') - delete(file_path) -end - -fw = adi.createFile(file_path); -%fw : adi.file_writer - -%fw.addComment(1,300,'Does this actually work?') -%fw.addComment(7,300,'Does this actually work?') - -pres_w = fw.addChannel(1,'Pressure',1000,'cmH2O'); -eus_w = fw.addChannel(2,'eus',200,'uV'); - -for iRecord = 1:2 %N_RECORDS -fw.startRecord; - -%fprintf(2,'Pressure \n'); -pres_w.addSamples((1:1000)/1000) -pres_w.addSamples((1:1000)/1000) -pres_w.addSamples((1:1000)/1000) -pres_w.addSamples((1:1000)/1000) -pres_w.addSamples((1:1000)/1000) -%t=0:0.001:2; - -%fprintf(2,'Onto EUS \n'); -t = 0.001:0.001:1; - -y=chirp(t,0,1,150); -eus_w.addSamples(y); - -%fw.addComment(1,2,'Cheeseburgers are great'); - -c_number = fw.addComment(iRecord,3,'Testing3','channel',1); -fw.addComment(iRecord,4,'Testing4'); -fw.addComment(iRecord,5,'Testing5'); - -fw.stopRecord; -end - - - -fw.save; +function e001_writeFileFromScratch +% +% adi.examples.e001_writeFileFromScratch +% +% In this file I wrote many more eus samples than presssure but the +% Labchart loader didn't show all of the eus data +% +% I'm not sure why this is occuring but the big lesson seems to be that +% the program doesn't completely freak out if this happens +% +% TODO: See if we can do this from a template file + +N_RECORDS = 4; + +%file_path = 'C:\Users\RNEL\Desktop\merge_adi_test\wtf.adicht'; +file_path = 'C:\Users\Jim\Desktop\merge_adi_test\wtf.adicht'; + +if exist(file_path,'file') + delete(file_path) +end + +fw = adi.createFile(file_path); +%fw : adi.file_writer + +%fw.addComment(1,300,'Does this actually work?') +%fw.addComment(7,300,'Does this actually work?') + +pres_w = fw.addChannel(1,'Pressure',1000,'cmH2O'); +eus_w = fw.addChannel(2,'eus',200,'uV'); + +for iRecord = 1:2 %N_RECORDS +fw.startRecord; + +%fprintf(2,'Pressure \n'); +pres_w.addSamples((1:1000)/1000) +pres_w.addSamples((1:1000)/1000) +pres_w.addSamples((1:1000)/1000) +pres_w.addSamples((1:1000)/1000) +pres_w.addSamples((1:1000)/1000) +%t=0:0.001:2; + +%fprintf(2,'Onto EUS \n'); +t = 0.001:0.001:1; + +y=chirp(t,0,1,150); +eus_w.addSamples(y); + +%fw.addComment(1,2,'Cheeseburgers are great'); + +c_number = fw.addComment(iRecord,3,'Testing3','channel',1); +fw.addComment(iRecord,4,'Testing4'); +fw.addComment(iRecord,5,'Testing5'); + +fw.stopRecord; +end + + + +fw.save; clear fw \ No newline at end of file diff --git a/src/Import/labchart/adi/+adi/+examples/e002_addCommentsToAnExistingFile.m b/Import/labchart/adi/+adi/+examples/e002_addCommentsToAnExistingFile.m similarity index 94% rename from src/Import/labchart/adi/+adi/+examples/e002_addCommentsToAnExistingFile.m rename to Import/labchart/adi/+adi/+examples/e002_addCommentsToAnExistingFile.m index 2b15284f..eae1fb74 100644 --- a/src/Import/labchart/adi/+adi/+examples/e002_addCommentsToAnExistingFile.m +++ b/Import/labchart/adi/+adi/+examples/e002_addCommentsToAnExistingFile.m @@ -1,17 +1,17 @@ -function e002_addCommentsToAnExistingFile() -% -% Why doesn't this work??? -% -% Is there some problem with modifying old adicht files that -% weren't created with the sdk? - -file_path = 'C:\temp\example_labchart_file.adicht'; - -fw = adi.editFile(file_path); - -%fw.addComment(1,300,'Does this actually work?') -fw.addComment(7,300,'Does this actually work?') - - -%Fails on this line +function e002_addCommentsToAnExistingFile() +% +% Why doesn't this work??? +% +% Is there some problem with modifying old adicht files that +% weren't created with the sdk? + +file_path = 'C:\temp\example_labchart_file.adicht'; + +fw = adi.editFile(file_path); + +%fw.addComment(1,300,'Does this actually work?') +fw.addComment(7,300,'Does this actually work?') + + +%Fails on this line fw.save \ No newline at end of file diff --git a/src/Import/labchart/adi/+adi/+postp/mergeComments.m b/Import/labchart/adi/+adi/+postp/mergeComments.m similarity index 96% rename from src/Import/labchart/adi/+adi/+postp/mergeComments.m rename to Import/labchart/adi/+adi/+postp/mergeComments.m index 776ad946..ee53ada1 100644 --- a/src/Import/labchart/adi/+adi/+postp/mergeComments.m +++ b/Import/labchart/adi/+adi/+postp/mergeComments.m @@ -1,135 +1,135 @@ -function mergeComments(final_file_path,source_file_paths) -%x Takes comments from files and merges them in to an older file -% -% adi.postp.mergeComments(*final_file_path,*source_file_paths) -% -% Optional Inputs: -% ---------------- -% final_file_path : string (default, selection) -% Path to the file to which comments are added -% source_file_paths : string or cellstr -% -% -% Examples: -% --------- -% 1) -% final_path = 'D:\adi_comment_merging\140903_C_01_pelvic _and hypogastric_PGE2.adicht'; -% file_with_comments = 'D:\adi_comment_merging\140903_C_01_pelvic _and hypogastric_PGE2_CMG NVC Analysis.adicht'; -% adi.postp.mergeComments(final_path,file_with_comments) -% -% To Handle -% --------- -% 1) -% -% Improvements: -% ------------- -% 1) We need to verify that the final_file_path is indeed an original -% that contains the various sources. - - - - -% in.final_file_path = ''; -% in.source_file_paths = {}; -% in = sl.in.processVarargin(in,varargin); - -if nargin < 1 - final_file_path = ''; -elseif nargin < 2 - source_file_paths = ''; -end - -if isempty(final_file_path) - final_file_path = adi.uiGetChartFile('prompt','select file to add comments to'); -elseif ~exist(final_file_path,'file') - %TODO: Build in call to the file missing error, requires moving from the - %sl to this package - error('Final file path does not point to a file that exists') -end - -if ischar(source_file_paths) && ~isempty(source_file_paths) - source_file_paths = {source_file_paths}; -end - -%commented_files -if isempty(source_file_paths) -source_file_paths = adi.uiGetChartFile('multi_select',true,'prompt',... - 'Select files that contain new comments to move'); -else - for iFile = 1:length(source_file_paths) - if ~exist(source_file_paths{iFile},'file') - error('Specified file does not exist') - end - end -end - -if ischar(source_file_paths) - source_file_paths = {source_file_paths}; -end - -final_h = adi.editFile(final_file_path); - -for iFile = 1:length(source_file_paths) - cur_file_h = adi.readFile(source_file_paths{iFile}); - - cur_comments = cur_file_h.getAllComments(); - - h__getCommentInstructions(final_h.comments,cur_comments) - - keyboard -end -%final_file = adi.readFile(final_file_path); - -keyboard - -end - -function h__getCommentInstructions(old_comments,new_comments) -%Comment Merging Rules -%{ - -The ID should not change for a comment. Adding new comments -will create a new ID. This can cause a problem however if we take multiple -new files since they are not in sync. - -i.e. - - original_file - - subset1 - - subset2 - The files subset1 & subset2 don't know about each other, so presumably - they have ids which overlap. - -How do we want to handle - -String content change ---------------------- - -Channel change --------------- - -Time difference ---------------- -- use the new one -- - -Approach --------- -Find the best match for any comment in the source in the original. This may -or may not exist. If it exists, the do nothing for now. Eventually we need -to figure out how to handle any discrepancies. -If it doesn't exist, add it. - -%} - %TODO: Implement this - %I'd like a set of instructions - %- create - %- delete - %- edit - %as well as a comment by comment analysis - %- keeping - %- deleting - %- merging with new - %- same as old - %- creating - %- merging with old +function mergeComments(final_file_path,source_file_paths) +%x Takes comments from files and merges them in to an older file +% +% adi.postp.mergeComments(*final_file_path,*source_file_paths) +% +% Optional Inputs: +% ---------------- +% final_file_path : string (default, selection) +% Path to the file to which comments are added +% source_file_paths : string or cellstr +% +% +% Examples: +% --------- +% 1) +% final_path = 'D:\adi_comment_merging\140903_C_01_pelvic _and hypogastric_PGE2.adicht'; +% file_with_comments = 'D:\adi_comment_merging\140903_C_01_pelvic _and hypogastric_PGE2_CMG NVC Analysis.adicht'; +% adi.postp.mergeComments(final_path,file_with_comments) +% +% To Handle +% --------- +% 1) +% +% Improvements: +% ------------- +% 1) We need to verify that the final_file_path is indeed an original +% that contains the various sources. + + + + +% in.final_file_path = ''; +% in.source_file_paths = {}; +% in = sl.in.processVarargin(in,varargin); + +if nargin < 1 + final_file_path = ''; +elseif nargin < 2 + source_file_paths = ''; +end + +if isempty(final_file_path) + final_file_path = adi.uiGetChartFile('prompt','select file to add comments to'); +elseif ~exist(final_file_path,'file') + %TODO: Build in call to the file missing error, requires moving from the + %sl to this package + error('Final file path does not point to a file that exists') +end + +if ischar(source_file_paths) && ~isempty(source_file_paths) + source_file_paths = {source_file_paths}; +end + +%commented_files +if isempty(source_file_paths) +source_file_paths = adi.uiGetChartFile('multi_select',true,'prompt',... + 'Select files that contain new comments to move'); +else + for iFile = 1:length(source_file_paths) + if ~exist(source_file_paths{iFile},'file') + error('Specified file does not exist') + end + end +end + +if ischar(source_file_paths) + source_file_paths = {source_file_paths}; +end + +final_h = adi.editFile(final_file_path); + +for iFile = 1:length(source_file_paths) + cur_file_h = adi.readFile(source_file_paths{iFile}); + + cur_comments = cur_file_h.getAllComments(); + + h__getCommentInstructions(final_h.comments,cur_comments) + + keyboard +end +%final_file = adi.readFile(final_file_path); + +keyboard + +end + +function h__getCommentInstructions(old_comments,new_comments) +%Comment Merging Rules +%{ + +The ID should not change for a comment. Adding new comments +will create a new ID. This can cause a problem however if we take multiple +new files since they are not in sync. + +i.e. + - original_file + - subset1 + - subset2 + The files subset1 & subset2 don't know about each other, so presumably + they have ids which overlap. + +How do we want to handle + +String content change +--------------------- + +Channel change +-------------- + +Time difference +--------------- +- use the new one +- + +Approach +-------- +Find the best match for any comment in the source in the original. This may +or may not exist. If it exists, the do nothing for now. Eventually we need +to figure out how to handle any discrepancies. +If it doesn't exist, add it. + +%} + %TODO: Implement this + %I'd like a set of instructions + %- create + %- delete + %- edit + %as well as a comment by comment analysis + %- keeping + %- deleting + %- merging with new + %- same as old + %- creating + %- merging with old end \ No newline at end of file diff --git a/src/Import/labchart/adi/+adi/+sdk/ReadMe.md b/Import/labchart/adi/+adi/+sdk/ReadMe.md similarity index 60% rename from src/Import/labchart/adi/+adi/+sdk/ReadMe.md rename to Import/labchart/adi/+adi/+sdk/ReadMe.md index dd7e401a..70b63ca0 100644 --- a/src/Import/labchart/adi/+adi/+sdk/ReadMe.md +++ b/Import/labchart/adi/+adi/+sdk/ReadMe.md @@ -1,3 +1,3 @@ -I'd eventually like to move all the SDKs into this folder. - +I'd eventually like to move all the SDKs into this folder. + The main sdk would be the LabChart SDK \ No newline at end of file diff --git a/src/Import/labchart/adi/+adi/+sl/+array/uniqueWithGroupIndices.m b/Import/labchart/adi/+adi/+sl/+array/uniqueWithGroupIndices.m similarity index 95% rename from src/Import/labchart/adi/+adi/+sl/+array/uniqueWithGroupIndices.m rename to Import/labchart/adi/+adi/+sl/+array/uniqueWithGroupIndices.m index 6171dfd2..1787b3a1 100644 --- a/src/Import/labchart/adi/+adi/+sl/+array/uniqueWithGroupIndices.m +++ b/Import/labchart/adi/+adi/+sl/+array/uniqueWithGroupIndices.m @@ -1,100 +1,100 @@ -function [u,uI] = uniqueWithGroupIndices(A) -%unique2 Returns groupings for each unique element -% -% [u,uI] = sl.array.uniqueWithGroupIndices(A) -% -% This function is a quicker way of getting the indices which -% match a particular unique value. -% -% INPUTS -% ============================================================ -% A : must be sortable via sort() -% -% OUTPUTS -% ============================================================ -% u : unique values -% uI : (cell array), each entry holds the indices of A which match u -% -% EXAMPLE -% ============================================================ -% [u,uI] = uniqueWithGroupIndices([3 5 3 5 5]) -% u => [3 5] -% uI{1} => [1 3]; -% uI{2} => [2 4 5]; -% -% NOTE: u(#) has the same value as all A(uI{#}) - - - -% SPEED NOTE -% ========================================== -% r = randi(100,1,100000); -% -% METHOD 1 - takes time T -% [u,uI] = unique2(r); -% -% METHOD 2 - takes time 3T -% [u2,~,J] = unique_2011b(r); -% uI2 = cell(1,length(u2)); -% for iChan = 1:length(u2) -% uI2{iChan} = strfind(J,u2(iChan)); -% end -% -% METHOD 3 - takes time 5T -% [u3,~,J] = unique_2011b(r); -% uI3 = cell(1,length(u3)); -% for iChan = 1:length(u3) -% uI3{iChan} = find(J == u3(iChan)); -% end - -%Add error checking -%1) input must be number -%2) NaN handling - -if isempty(A) - u = []; - uI = {}; - return -elseif length(A) == 1 - u = A; - uI = {1}; - return -end - -%JAH TODO: Document code -[Y,I2] = sort(A(:)); - -if isnumeric(Y) - if isnan(Y) - error('NaN handling not yet supported') - end - Itemp = find(diff(Y) ~= 0); -else - %could add case sensitivity - Itemp = find(~strcmp(Y(1:end-1),Y(2:end))); -end - -Istart = [1; Itemp+1]; -Iend = [Itemp; length(A)]; - -u = Y(Istart); - -%Handling row vectors, note that matrices will come out -%as column vectors, just like for unique() -rows = size(A,1); -cols = size(A,2); -if (rows == 1) && (cols > 1) - u = u'; - I2 = I2'; -end - -%Population of uI -%----------------------------- -uI = cell(1,length(u)); -for iUnique = 1:length(u) - uI{iUnique} = I2(Istart(iUnique):Iend(iUnique)); -end - - - - +function [u,uI] = uniqueWithGroupIndices(A) +%unique2 Returns groupings for each unique element +% +% [u,uI] = sl.array.uniqueWithGroupIndices(A) +% +% This function is a quicker way of getting the indices which +% match a particular unique value. +% +% INPUTS +% ============================================================ +% A : must be sortable via sort() +% +% OUTPUTS +% ============================================================ +% u : unique values +% uI : (cell array), each entry holds the indices of A which match u +% +% EXAMPLE +% ============================================================ +% [u,uI] = uniqueWithGroupIndices([3 5 3 5 5]) +% u => [3 5] +% uI{1} => [1 3]; +% uI{2} => [2 4 5]; +% +% NOTE: u(#) has the same value as all A(uI{#}) + + + +% SPEED NOTE +% ========================================== +% r = randi(100,1,100000); +% +% METHOD 1 - takes time T +% [u,uI] = unique2(r); +% +% METHOD 2 - takes time 3T +% [u2,~,J] = unique_2011b(r); +% uI2 = cell(1,length(u2)); +% for iChan = 1:length(u2) +% uI2{iChan} = strfind(J,u2(iChan)); +% end +% +% METHOD 3 - takes time 5T +% [u3,~,J] = unique_2011b(r); +% uI3 = cell(1,length(u3)); +% for iChan = 1:length(u3) +% uI3{iChan} = find(J == u3(iChan)); +% end + +%Add error checking +%1) input must be number +%2) NaN handling + +if isempty(A) + u = []; + uI = {}; + return +elseif length(A) == 1 + u = A; + uI = {1}; + return +end + +%JAH TODO: Document code +[Y,I2] = sort(A(:)); + +if isnumeric(Y) + if isnan(Y) + error('NaN handling not yet supported') + end + Itemp = find(diff(Y) ~= 0); +else + %could add case sensitivity + Itemp = find(~strcmp(Y(1:end-1),Y(2:end))); +end + +Istart = [1; Itemp+1]; +Iend = [Itemp; length(A)]; + +u = Y(Istart); + +%Handling row vectors, note that matrices will come out +%as column vectors, just like for unique() +rows = size(A,1); +cols = size(A,2); +if (rows == 1) && (cols > 1) + u = u'; + I2 = I2'; +end + +%Population of uI +%----------------------------- +uI = cell(1,length(u)); +for iUnique = 1:length(u) + uI{iUnique} = I2(Istart(iUnique):Iend(iUnique)); +end + + + + diff --git a/src/Import/labchart/adi/+adi/+sl/+cellstr/join.m b/Import/labchart/adi/+adi/+sl/+cellstr/join.m similarity index 96% rename from src/Import/labchart/adi/+adi/+sl/+cellstr/join.m rename to Import/labchart/adi/+adi/+sl/+cellstr/join.m index 7550d601..f959644f 100644 --- a/src/Import/labchart/adi/+adi/+sl/+cellstr/join.m +++ b/Import/labchart/adi/+adi/+sl/+cellstr/join.m @@ -1,48 +1,48 @@ -function str = join(cellstr_input,varargin) -%toString -% -% str = sl.cellstr.join(cellstr_input,varargin) -% -% INPUTS -% ======================================================================= -% cellstr : A cell array of strings to combine. -% -% OPTIONAL INPUTS -% ======================================================================= -% d : (default ','), delimiter string to use in combining strings -% -% To treat a delimiter as a literal escape the backlash with a -% backlash. For example, this '\\t' will join strings with '\t' -% instead of a tab. Percents should be escaped with a percent. -% -% The final delimiter => sprintf(delim) -% -% remove_empty : (default false), if true empty values are removed -% -% EXAMPLES -% ======================================================================= -% -% TODO: Finish Documentation - -in.d = ','; -in.remove_empty = false; -in = adi.sl.in.processVarargin(in,varargin); - -if isempty(cellstr_input) - str = ''; -elseif ~iscell(cellstr_input) - error('Input to %s must be a cell array',mfilename) -else - P = cellstr_input(:)'; - if in.remove_empty - P(cellfun('isempty',P)) = []; - if isempty(P) - str = ''; - return - end - end - P(2,:) = {sprintf(in.d)} ; %Added on printing to handle things like \t and \n - - P{2,end} = [] ; - str = sprintf('%s',P{:}); +function str = join(cellstr_input,varargin) +%toString +% +% str = sl.cellstr.join(cellstr_input,varargin) +% +% INPUTS +% ======================================================================= +% cellstr : A cell array of strings to combine. +% +% OPTIONAL INPUTS +% ======================================================================= +% d : (default ','), delimiter string to use in combining strings +% +% To treat a delimiter as a literal escape the backlash with a +% backlash. For example, this '\\t' will join strings with '\t' +% instead of a tab. Percents should be escaped with a percent. +% +% The final delimiter => sprintf(delim) +% +% remove_empty : (default false), if true empty values are removed +% +% EXAMPLES +% ======================================================================= +% +% TODO: Finish Documentation + +in.d = ','; +in.remove_empty = false; +in = adi.sl.in.processVarargin(in,varargin); + +if isempty(cellstr_input) + str = ''; +elseif ~iscell(cellstr_input) + error('Input to %s must be a cell array',mfilename) +else + P = cellstr_input(:)'; + if in.remove_empty + P(cellfun('isempty',P)) = []; + if isempty(P) + str = ''; + return + end + end + P(2,:) = {sprintf(in.d)} ; %Added on printing to handle things like \t and \n + + P{2,end} = [] ; + str = sprintf('%s',P{:}); end \ No newline at end of file diff --git a/src/Import/labchart/adi/+adi/+sl/+datetime/getTimeZone.m b/Import/labchart/adi/+adi/+sl/+datetime/getTimeZone.m similarity index 91% rename from src/Import/labchart/adi/+adi/+sl/+datetime/getTimeZone.m rename to Import/labchart/adi/+adi/+sl/+datetime/getTimeZone.m index afed5c23..83efce4d 100644 --- a/src/Import/labchart/adi/+adi/+sl/+datetime/getTimeZone.m +++ b/Import/labchart/adi/+adi/+sl/+datetime/getTimeZone.m @@ -1,21 +1,21 @@ -function utc_offset = getTimeZone -%getTimeZone Returns the time zone of the operating system. -% -% utc_offset = sl.datetime.getTimeZone -% -% Uses a Java call. This function is necessary for converting between -% Matlab time which is local based, and many other time codes which are -% all UTC based. -% -% OUTPUTS -% ======================================================================= -% utc_offset : # of hours different from UTC the computer is. For -% example, a computer using Eastern Standard Time will return -5 - - -%Java call -tz = java.util.TimeZone.getDefault; %in ms - -%convert to hours -%1000 ms/s * 60 s/min * 60 min/hour +function utc_offset = getTimeZone +%getTimeZone Returns the time zone of the operating system. +% +% utc_offset = sl.datetime.getTimeZone +% +% Uses a Java call. This function is necessary for converting between +% Matlab time which is local based, and many other time codes which are +% all UTC based. +% +% OUTPUTS +% ======================================================================= +% utc_offset : # of hours different from UTC the computer is. For +% example, a computer using Eastern Standard Time will return -5 + + +%Java call +tz = java.util.TimeZone.getDefault; %in ms + +%convert to hours +%1000 ms/s * 60 s/min * 60 min/hour utc_offset = tz.getRawOffset/3600000; \ No newline at end of file diff --git a/src/Import/labchart/adi/+adi/+sl/+datetime/unixToMatlab.m b/Import/labchart/adi/+adi/+sl/+datetime/unixToMatlab.m similarity index 96% rename from src/Import/labchart/adi/+adi/+sl/+datetime/unixToMatlab.m rename to Import/labchart/adi/+adi/+sl/+datetime/unixToMatlab.m index 2d28c4a7..9d958b86 100644 --- a/src/Import/labchart/adi/+adi/+sl/+datetime/unixToMatlab.m +++ b/Import/labchart/adi/+adi/+sl/+datetime/unixToMatlab.m @@ -1,30 +1,30 @@ -function matlab_time = unixToMatlab(unix_time,utc_offset) -%unixTimeToMatlabTime Converts unix time to Matlab time -% -% matlab_time = sl.datetime.unixToMatlab(unix_time,*utc_offset) -% -% INPUTS -% ======================================================================= -% unixTime - (element or vector), unix time, # of non-leap seconds since -% January 1, 1970 -% -% OPTIONAL INPUTS -% ======================================================================= -% utc_offset - (default, use local), -5 corresponds to EST -% -% OUTPUTS -% ======================================================================= -% matlab_time - double, fraction represents seconds, the integer part of -% the #, floor(matlabTime) represents the # of days since A.D. -% -% See Also: -% sl.datetime.getTimeZone - - -if ~exist('utc_offset','var') || isempty(utc_offset) - utc_offset = adi.sl.datetime.getTimeZone; -end - -SECONDS_IN_DAY = 86400; -UNIX_EPOCH = 719529; +function matlab_time = unixToMatlab(unix_time,utc_offset) +%unixTimeToMatlabTime Converts unix time to Matlab time +% +% matlab_time = sl.datetime.unixToMatlab(unix_time,*utc_offset) +% +% INPUTS +% ======================================================================= +% unixTime - (element or vector), unix time, # of non-leap seconds since +% January 1, 1970 +% +% OPTIONAL INPUTS +% ======================================================================= +% utc_offset - (default, use local), -5 corresponds to EST +% +% OUTPUTS +% ======================================================================= +% matlab_time - double, fraction represents seconds, the integer part of +% the #, floor(matlabTime) represents the # of days since A.D. +% +% See Also: +% sl.datetime.getTimeZone + + +if ~exist('utc_offset','var') || isempty(utc_offset) + utc_offset = adi.sl.datetime.getTimeZone; +end + +SECONDS_IN_DAY = 86400; +UNIX_EPOCH = 719529; matlab_time = unix_time./SECONDS_IN_DAY + UNIX_EPOCH + utc_offset/24; \ No newline at end of file diff --git a/src/Import/labchart/adi/+adi/+sl/+dir/changeFileExtension.m b/Import/labchart/adi/+adi/+sl/+dir/changeFileExtension.m similarity index 96% rename from src/Import/labchart/adi/+adi/+sl/+dir/changeFileExtension.m rename to Import/labchart/adi/+adi/+sl/+dir/changeFileExtension.m index a5bcf0db..52c63680 100644 --- a/src/Import/labchart/adi/+adi/+sl/+dir/changeFileExtension.m +++ b/Import/labchart/adi/+adi/+sl/+dir/changeFileExtension.m @@ -1,33 +1,33 @@ -function new_file_path = changeFileExtension(file_path,new_extension) -% -% new_file_path = sl.dir.changeFileExtension(file_path,new_extension) -% -% This is a simple helper function that makes it obvious what is being -% done (i.e. changing the file extension). -% -% Inputs: -% ------- -% file_path: str -% Path to the file. It may be absolute or relative. -% new_extension: str -% The extension that the file_path should have when returned from -% this function. This may or may not contain a leading period. -% -% Example: -% -------- -% file_path = 'C:\a\b.mat' -% new_file_path = sl.dir.changeFileExtension(file_path,'txt') -% new_file_path => 'C:\a\b.txt' - - -%Ensure dot is present as first character -if new_extension(1) ~= '.' - new_extension = ['.' new_extension]; -end - -[a,b] = fileparts(file_path); - -new_file_path = fullfile(a,[b new_extension]); - - +function new_file_path = changeFileExtension(file_path,new_extension) +% +% new_file_path = sl.dir.changeFileExtension(file_path,new_extension) +% +% This is a simple helper function that makes it obvious what is being +% done (i.e. changing the file extension). +% +% Inputs: +% ------- +% file_path: str +% Path to the file. It may be absolute or relative. +% new_extension: str +% The extension that the file_path should have when returned from +% this function. This may or may not contain a leading period. +% +% Example: +% -------- +% file_path = 'C:\a\b.mat' +% new_file_path = sl.dir.changeFileExtension(file_path,'txt') +% new_file_path => 'C:\a\b.txt' + + +%Ensure dot is present as first character +if new_extension(1) ~= '.' + new_extension = ['.' new_extension]; +end + +[a,b] = fileparts(file_path); + +new_file_path = fullfile(a,[b new_extension]); + + end \ No newline at end of file diff --git a/src/Import/labchart/adi/+adi/+sl/+dir/createFolderIfNoExist.m b/Import/labchart/adi/+adi/+sl/+dir/createFolderIfNoExist.m similarity index 96% rename from src/Import/labchart/adi/+adi/+sl/+dir/createFolderIfNoExist.m rename to Import/labchart/adi/+adi/+sl/+dir/createFolderIfNoExist.m index 7aff0474..4150b17a 100644 --- a/src/Import/labchart/adi/+adi/+sl/+dir/createFolderIfNoExist.m +++ b/Import/labchart/adi/+adi/+sl/+dir/createFolderIfNoExist.m @@ -1,48 +1,48 @@ -function output_path = createFolderIfNoExist(varargin) -%createIfNecessary: Creates a folder if it doesn't exist -% -% This function creates a folder if it does not exist. In addition it can -% be used to: -% - construct the path of the folder -% - construct the path to a file, ensuring that the folder path to -% the file exists -% -% If multiple folders are missing in the path they will all be created. -% -% Function Forms: -% --------------- -% #1 - just create the folder if necessary -% folder_path = sl.dir.createFolderIfNoExist(folderPath) - creates the folderPath -% if it doesn't exist -% -% #2 - build path with multiple directories -% folder_path = createFolderIfNoExist(folderPath,subdir1,subdir2,...,subdirN) - create -% a directory tree starting at folderPath -% -% #3 - build file name, last input is file name -% file_path = createFolderIfNoExist(true,folderPath,subdir1,subdir2,file_name) -% -% - - -if islogical(varargin{1}) - if varargin{1} - file_name = varargin{end}; - varargin([1 end]) = []; - else - varargin(1) = []; - end -else - file_name = ''; -end - -output_path = fullfile(varargin{:}); -if ~exist(output_path,'dir') - mkdir(output_path) -end - -if ~isempty(file_name) - output_path = fullfile(output_path,file_name); -end - -end +function output_path = createFolderIfNoExist(varargin) +%createIfNecessary: Creates a folder if it doesn't exist +% +% This function creates a folder if it does not exist. In addition it can +% be used to: +% - construct the path of the folder +% - construct the path to a file, ensuring that the folder path to +% the file exists +% +% If multiple folders are missing in the path they will all be created. +% +% Function Forms: +% --------------- +% #1 - just create the folder if necessary +% folder_path = sl.dir.createFolderIfNoExist(folderPath) - creates the folderPath +% if it doesn't exist +% +% #2 - build path with multiple directories +% folder_path = createFolderIfNoExist(folderPath,subdir1,subdir2,...,subdirN) - create +% a directory tree starting at folderPath +% +% #3 - build file name, last input is file name +% file_path = createFolderIfNoExist(true,folderPath,subdir1,subdir2,file_name) +% +% + + +if islogical(varargin{1}) + if varargin{1} + file_name = varargin{end}; + varargin([1 end]) = []; + else + varargin(1) = []; + end +else + file_name = ''; +end + +output_path = fullfile(varargin{:}); +if ~exist(output_path,'dir') + mkdir(output_path) +end + +if ~isempty(file_name) + output_path = fullfile(output_path,file_name); +end + +end diff --git a/src/Import/labchart/adi/+adi/+sl/+dir/filepartsx.m b/Import/labchart/adi/+adi/+sl/+dir/filepartsx.m similarity index 95% rename from src/Import/labchart/adi/+adi/+sl/+dir/filepartsx.m rename to Import/labchart/adi/+adi/+sl/+dir/filepartsx.m index 661327fd..8b42157f 100644 --- a/src/Import/labchart/adi/+adi/+sl/+dir/filepartsx.m +++ b/Import/labchart/adi/+adi/+sl/+dir/filepartsx.m @@ -1,25 +1,25 @@ -function path_out = filepartsx(file_or_folder_path,N) -%filepartsx Applies fileparts() function numerous times -% -% path_out = sl.dir.filepartsx(file_or_folder_path,N) -% -% Small function to help clean up stripping of the path. -% -% INPUTS: -% ------- -% file_or_folder_path : path to file or folder -% N : # of times to apply fileparts() function -% -% Example: -% -------- -% file_path = 'C:\my_dir1\my_dir2\my_file.txt'; -% path_out = sl.dir.filepartsx(file_path,2); -% -% path_out => 'C:\my_dir1' - -path_out = file_or_folder_path; -for iN = 1:N - path_out = fileparts(path_out); -end - +function path_out = filepartsx(file_or_folder_path,N) +%filepartsx Applies fileparts() function numerous times +% +% path_out = sl.dir.filepartsx(file_or_folder_path,N) +% +% Small function to help clean up stripping of the path. +% +% INPUTS: +% ------- +% file_or_folder_path : path to file or folder +% N : # of times to apply fileparts() function +% +% Example: +% -------- +% file_path = 'C:\my_dir1\my_dir2\my_file.txt'; +% path_out = sl.dir.filepartsx(file_path,2); +% +% path_out => 'C:\my_dir1' + +path_out = file_or_folder_path; +for iN = 1:N + path_out = fileparts(path_out); +end + end \ No newline at end of file diff --git a/src/Import/labchart/adi/+adi/+sl/+in/processVarargin.m b/Import/labchart/adi/+adi/+sl/+in/processVarargin.m similarity index 96% rename from src/Import/labchart/adi/+adi/+sl/+in/processVarargin.m rename to Import/labchart/adi/+adi/+sl/+in/processVarargin.m index 4c64d57c..d3f656de 100644 --- a/src/Import/labchart/adi/+adi/+sl/+in/processVarargin.m +++ b/Import/labchart/adi/+adi/+sl/+in/processVarargin.m @@ -1,210 +1,210 @@ -function [in,extras] = processVarargin(in,v,varargin) -%processVarargin Processes varargin and overrides defaults -% -% Function to override default options. -% -% [in,extras] = sl.in.processVarargin(in,v,varargin) -% -% INPUTS -% ======================================================================= -% in : structure containing default values that may be overridden -% by user inputs -% v : varargin input from calling function, prop/value pairs or -% structure with fields -% -% varargin : see optional inputs, prop/value or structure with fields -% -% OPTIONAL INPUTS (specify via prop/value pairs or struct) -% ======================================================================= -% Rules for these are: -% - case insensitive -% - non-matches not allowed ... -% -% case_sensitive : (default false) -% allow_non_matches : (default false) -% -% -% % allow_duplicates : (default false) NOT YET IMPLEMENTED -% partial_match : (default false) NOT YET IMPLEMENTED -% -% OUTPUTS -% ======================================================================= -% extras : Class: sl.in.process_varargin_result -% -% TODO: Provide link -% EXAMPLES -% ======================================================================= -% 1) -% function test(varargin) -% in.a = 1 -% in.b = 2 -% in = processVarargin(in,varargin,'allow_duplicates',true) -% -% Similar functions: -% http://www.mathworks.com/matlabcentral/fileexchange/22671 -% http://www.mathworks.com/matlabcentral/fileexchange/10670 -% -% IMPROVEMENTS -% ======================================================================= -% 1) For non-matched inputs, provide link to offending caller -% -% -% See Also: -% sl.in.tests.processVarargin - - - -%Check to exit code quickly when it is not used ... -if isempty(v) && nargout == 1 - %Possible improvement - %- provide code that allows this to return quicker if nargout == 2 - return -end - -c.case_sensitive = false; -% % % c.allow_duplicates = false; -% % % c.partial_match = false; -c.allow_non_matches = false; -c.allow_spaces = true; - - -%Update instructions on how to parse the optional inputs -%-------------------------------------------------------------------------- -%This type of code would allow a bit more flexibility on how to process -%the processing options if we ever decided they needed to be different -% -% -% c2 = c; -% c2.case_sensitive = false; -% -%NOTE: If we don't pass in any instructions on how to parse the data -%differently we can skip this step ... -if ~isempty(varargin) - %Updates c based on varargin from user - %c = processVararginHelper(c,varargin,c2,1); - c = processVararginHelper(c,varargin,c,true); -end - -%Update optional inputs of calling function with this function's options now set -[in,extras] = processVararginHelper(in,v,c,false); - -end - - - -function [in,extras] = processVararginHelper(in,v,c,is_parsing_options) -%processVararginHelper -% -% [in,extras] = processVararginHelper(in,v,c,is_parsing_options) -% -% This function does the actual work. It is a separate function because -% we use this function to handle the options on how this function should -% work for the user's inputs. We use the same approach for the processing -% options as we do the user's inputs. -% -% INPUTS -% ======================================================================= -% in - (structure input) -% v - varargin input, might be structure or prop/value pairs -% c - options for processing -% is_parsing_options - specifies we are parsing the parsing options - -extras = adi.sl.in.process_varargin_result(in,v); - -%Checking the optional inputs, either a structure or a prop/value cell -%array is allowed, or various forms of empty ... -if isempty(v) - %do nothing - parse_input = false; -elseif isstruct(v) - %This case should generally not happen - %It will if varargin is not used in the calling function - parse_input = true; -elseif isstruct(v{1}) && length(v) == 1 - %Single structure was passed in as sole argument for varargin - v = v{1}; - parse_input = true; -elseif iscell(v) && length(v) == 1 && isempty(v{1}) - %User passed in empty cell option to varargin instead of just ommitting input - parse_input = false; -else - parse_input = true; - is_str_mask = cellfun('isclass',v,'char'); - - %Improvement: - %------------------------------------------------- - %Analyze calling information ... - %Provide stack trace for editing ... - % - % Functions needed: - % 1) prototype of caller - % 2) calling format of parent - % 3) links to offending lines ... - % - % NOTE: is_parsing_options would allow us to have different - % error messages ... - if ~all(is_str_mask(1:2:end)) - error('Unexpected format for varargin, not all properties are strings') - end - if mod(length(v),2) ~= 0 - error('Property/value pairs are not balanced, length of input: %d',length(v)) - end - - if c.allow_spaces - %strrep would be faster if we could guarantee - %only single spaces :/ - v(1:2:end) = regexprep(v(1:2:end),'\s+','_'); - end - - v = v(:)'; %Ensure row vector - v = cell2struct(v(2:2:end),v(1:2:end),2); -end - -if ~parse_input - return -end - -extras.struct_mod_input = v; - -%At this point we should have a structure ... -fn__new_values = fieldnames(v); -fn__input_struct = fieldnames(in); -extras.fn__new_values = fn__new_values; -extras.fn__input_struct = fn__input_struct; - - -%Matching location -%-------------------------------------------------------------------------- -if c.case_sensitive - [is_present,loc] = ismember(fn__new_values,fn__input_struct); -else - [is_present,loc] = ismember(upper(fn__new_values),upper(fn__input_struct)); - %NOTE: I don't currently do a check here for uniqueness of matches ... - %Could have many fields which case-insensitive are the same ... -end -extras.is_present = is_present; -extras.loc = loc; - -if ~all(is_present) - if c.allow_non_matches - %Lazy evaluation in result class - else - %NOTE: This would be improved by adding on the restrictions we used in mapping - badVariables = fn__new_values(~is_present); - error(['Bad variable names given in input structure: ' ... - '\n--------------------------------- \n %s' ... - ' \n--------------------------------------'],... - adi.sl.cellstr.join(badVariables,'d',',')) - end -end - -%Actual assignment -%--------------------------------------------------------------- -for i = 1:length(fn__new_values) - if is_present(i) - %NOTE: By using fn_i we ensure case matching - in.(fn__input_struct{loc(i)}) = v.(fn__new_values{i}); - end -end - -end +function [in,extras] = processVarargin(in,v,varargin) +%processVarargin Processes varargin and overrides defaults +% +% Function to override default options. +% +% [in,extras] = sl.in.processVarargin(in,v,varargin) +% +% INPUTS +% ======================================================================= +% in : structure containing default values that may be overridden +% by user inputs +% v : varargin input from calling function, prop/value pairs or +% structure with fields +% +% varargin : see optional inputs, prop/value or structure with fields +% +% OPTIONAL INPUTS (specify via prop/value pairs or struct) +% ======================================================================= +% Rules for these are: +% - case insensitive +% - non-matches not allowed ... +% +% case_sensitive : (default false) +% allow_non_matches : (default false) +% +% +% % allow_duplicates : (default false) NOT YET IMPLEMENTED +% partial_match : (default false) NOT YET IMPLEMENTED +% +% OUTPUTS +% ======================================================================= +% extras : Class: sl.in.process_varargin_result +% +% TODO: Provide link +% EXAMPLES +% ======================================================================= +% 1) +% function test(varargin) +% in.a = 1 +% in.b = 2 +% in = processVarargin(in,varargin,'allow_duplicates',true) +% +% Similar functions: +% http://www.mathworks.com/matlabcentral/fileexchange/22671 +% http://www.mathworks.com/matlabcentral/fileexchange/10670 +% +% IMPROVEMENTS +% ======================================================================= +% 1) For non-matched inputs, provide link to offending caller +% +% +% See Also: +% sl.in.tests.processVarargin + + + +%Check to exit code quickly when it is not used ... +if isempty(v) && nargout == 1 + %Possible improvement + %- provide code that allows this to return quicker if nargout == 2 + return +end + +c.case_sensitive = false; +% % % c.allow_duplicates = false; +% % % c.partial_match = false; +c.allow_non_matches = false; +c.allow_spaces = true; + + +%Update instructions on how to parse the optional inputs +%-------------------------------------------------------------------------- +%This type of code would allow a bit more flexibility on how to process +%the processing options if we ever decided they needed to be different +% +% +% c2 = c; +% c2.case_sensitive = false; +% +%NOTE: If we don't pass in any instructions on how to parse the data +%differently we can skip this step ... +if ~isempty(varargin) + %Updates c based on varargin from user + %c = processVararginHelper(c,varargin,c2,1); + c = processVararginHelper(c,varargin,c,true); +end + +%Update optional inputs of calling function with this function's options now set +[in,extras] = processVararginHelper(in,v,c,false); + +end + + + +function [in,extras] = processVararginHelper(in,v,c,is_parsing_options) +%processVararginHelper +% +% [in,extras] = processVararginHelper(in,v,c,is_parsing_options) +% +% This function does the actual work. It is a separate function because +% we use this function to handle the options on how this function should +% work for the user's inputs. We use the same approach for the processing +% options as we do the user's inputs. +% +% INPUTS +% ======================================================================= +% in - (structure input) +% v - varargin input, might be structure or prop/value pairs +% c - options for processing +% is_parsing_options - specifies we are parsing the parsing options + +extras = adi.sl.in.process_varargin_result(in,v); + +%Checking the optional inputs, either a structure or a prop/value cell +%array is allowed, or various forms of empty ... +if isempty(v) + %do nothing + parse_input = false; +elseif isstruct(v) + %This case should generally not happen + %It will if varargin is not used in the calling function + parse_input = true; +elseif isstruct(v{1}) && length(v) == 1 + %Single structure was passed in as sole argument for varargin + v = v{1}; + parse_input = true; +elseif iscell(v) && length(v) == 1 && isempty(v{1}) + %User passed in empty cell option to varargin instead of just ommitting input + parse_input = false; +else + parse_input = true; + is_str_mask = cellfun('isclass',v,'char'); + + %Improvement: + %------------------------------------------------- + %Analyze calling information ... + %Provide stack trace for editing ... + % + % Functions needed: + % 1) prototype of caller + % 2) calling format of parent + % 3) links to offending lines ... + % + % NOTE: is_parsing_options would allow us to have different + % error messages ... + if ~all(is_str_mask(1:2:end)) + error('Unexpected format for varargin, not all properties are strings') + end + if mod(length(v),2) ~= 0 + error('Property/value pairs are not balanced, length of input: %d',length(v)) + end + + if c.allow_spaces + %strrep would be faster if we could guarantee + %only single spaces :/ + v(1:2:end) = regexprep(v(1:2:end),'\s+','_'); + end + + v = v(:)'; %Ensure row vector + v = cell2struct(v(2:2:end),v(1:2:end),2); +end + +if ~parse_input + return +end + +extras.struct_mod_input = v; + +%At this point we should have a structure ... +fn__new_values = fieldnames(v); +fn__input_struct = fieldnames(in); +extras.fn__new_values = fn__new_values; +extras.fn__input_struct = fn__input_struct; + + +%Matching location +%-------------------------------------------------------------------------- +if c.case_sensitive + [is_present,loc] = ismember(fn__new_values,fn__input_struct); +else + [is_present,loc] = ismember(upper(fn__new_values),upper(fn__input_struct)); + %NOTE: I don't currently do a check here for uniqueness of matches ... + %Could have many fields which case-insensitive are the same ... +end +extras.is_present = is_present; +extras.loc = loc; + +if ~all(is_present) + if c.allow_non_matches + %Lazy evaluation in result class + else + %NOTE: This would be improved by adding on the restrictions we used in mapping + badVariables = fn__new_values(~is_present); + error(['Bad variable names given in input structure: ' ... + '\n--------------------------------- \n %s' ... + ' \n--------------------------------------'],... + adi.sl.cellstr.join(badVariables,'d',',')) + end +end + +%Actual assignment +%--------------------------------------------------------------- +for i = 1:length(fn__new_values) + if is_present(i) + %NOTE: By using fn_i we ensure case matching + in.(fn__input_struct{loc(i)}) = v.(fn__new_values{i}); + end +end + +end diff --git a/src/Import/labchart/adi/+adi/+sl/+in/process_varargin_result.m b/Import/labchart/adi/+adi/+sl/+in/process_varargin_result.m similarity index 97% rename from src/Import/labchart/adi/+adi/+sl/+in/process_varargin_result.m rename to Import/labchart/adi/+adi/+sl/+in/process_varargin_result.m index bbb2586e..ac8dff7b 100644 --- a/src/Import/labchart/adi/+adi/+sl/+in/process_varargin_result.m +++ b/Import/labchart/adi/+adi/+sl/+in/process_varargin_result.m @@ -1,121 +1,121 @@ -classdef (Hidden) process_varargin_result < handle - % - % Class: - % sl.in.process_varargin_result - % - % This is a result class from running sl.in.processVarargin - % - % See Also: - % sl.in.processVarargin - - %Inputs ============================================================== - properties - d1 = '---- Inputs -----' - input_structure - raw_mod_input %The raw modification instructions ... - end - - %The following may not be populated if the input is empty ... - %Ideally they would have defaults that don't cause an error on display - %... - properties - % FORM: - % - [] - % - struct - % - cell array with - struct_mod_input = struct([]) %modification instructions as - %a structure - end - - properties (Hidden) - fn__new_values = {} - fn__input_struct = {} - - %Result of ismember(new_values,original) - is_present - loc - end - - %Outputs ============================================================== - properties (Hidden) - %NOTE: Ideally we could use a lazy evaluator which - %removed the get method after the first evaluation - %so that the default retrieval would be used ... :/ - non_match_names_initialized = false - unmatched_args_as_cell_initialized = false - umatched_args_as_struct_initialized = false - is_modified_initialized = false - end - - properties - d2 = '---- Outputs ----' - non_match_names %(cellstr) - umatched_args_as_cell %(?rename) - umatched_args_as_struct %(?rename) - is_modified - end - - properties (Dependent) - non_matches %alias of non_match_names - poor name choice :/ - %Might remove, not sure if anything was using this ... - end - - %Lazy get methods ===================================================== - methods - function value = get.non_matches(obj) - value = obj.non_match_names; - end - function value = get.non_match_names(obj) - if ~obj.non_match_names_initialized - obj.non_match_names = obj.fn__new_values(~obj.is_present); - obj.non_match_names_initialized = true; - end - value = obj.non_match_names; - end - function value = get.umatched_args_as_cell(obj) - if ~obj.unmatched_args_as_cell_initialized - s = obj.umatched_args_as_struct; - - not_matched_names = fieldnames(s); - n_bad = length(not_matched_names); - - c = cell(1,n_bad*2); - c(2:2:end) = struct2cell(s); - c(1:2:end) = not_matched_names; - obj.umatched_args_as_cell = c; - - obj.unmatched_args_as_cell_initialized = true; - end - value = obj.umatched_args_as_cell; - end - function value = get.umatched_args_as_struct(obj) - if ~obj.umatched_args_as_struct_initialized - obj.umatched_args_as_struct = rmfield(obj.struct_mod_input,obj.non_match_names); - obj.umatched_args_as_struct_initialized = true; - end - value = obj.umatched_args_as_struct; - end - function value = get.is_modified(obj) - if ~obj.is_modified_initialized - fn_local = obj.fn__input_struct; - n_fields = length(fn_local); - - changed_mask = false(1,n_fields); - changed_mask(obj.loc(obj.is_present)) = true; - - obj.is_modified = cell2struct(num2cell(changed_mask),fn_local); - obj.is_modified_initialized = true; - end - value = obj.is_modified; - end - end - - methods - function obj = process_varargin_result(input_structure,raw_mod_input) - obj.input_structure = input_structure; - obj.raw_mod_input = raw_mod_input; - end - end - -end - +classdef (Hidden) process_varargin_result < handle + % + % Class: + % sl.in.process_varargin_result + % + % This is a result class from running sl.in.processVarargin + % + % See Also: + % sl.in.processVarargin + + %Inputs ============================================================== + properties + d1 = '---- Inputs -----' + input_structure + raw_mod_input %The raw modification instructions ... + end + + %The following may not be populated if the input is empty ... + %Ideally they would have defaults that don't cause an error on display + %... + properties + % FORM: + % - [] + % - struct + % - cell array with + struct_mod_input = struct([]) %modification instructions as + %a structure + end + + properties (Hidden) + fn__new_values = {} + fn__input_struct = {} + + %Result of ismember(new_values,original) + is_present + loc + end + + %Outputs ============================================================== + properties (Hidden) + %NOTE: Ideally we could use a lazy evaluator which + %removed the get method after the first evaluation + %so that the default retrieval would be used ... :/ + non_match_names_initialized = false + unmatched_args_as_cell_initialized = false + umatched_args_as_struct_initialized = false + is_modified_initialized = false + end + + properties + d2 = '---- Outputs ----' + non_match_names %(cellstr) + umatched_args_as_cell %(?rename) + umatched_args_as_struct %(?rename) + is_modified + end + + properties (Dependent) + non_matches %alias of non_match_names - poor name choice :/ + %Might remove, not sure if anything was using this ... + end + + %Lazy get methods ===================================================== + methods + function value = get.non_matches(obj) + value = obj.non_match_names; + end + function value = get.non_match_names(obj) + if ~obj.non_match_names_initialized + obj.non_match_names = obj.fn__new_values(~obj.is_present); + obj.non_match_names_initialized = true; + end + value = obj.non_match_names; + end + function value = get.umatched_args_as_cell(obj) + if ~obj.unmatched_args_as_cell_initialized + s = obj.umatched_args_as_struct; + + not_matched_names = fieldnames(s); + n_bad = length(not_matched_names); + + c = cell(1,n_bad*2); + c(2:2:end) = struct2cell(s); + c(1:2:end) = not_matched_names; + obj.umatched_args_as_cell = c; + + obj.unmatched_args_as_cell_initialized = true; + end + value = obj.umatched_args_as_cell; + end + function value = get.umatched_args_as_struct(obj) + if ~obj.umatched_args_as_struct_initialized + obj.umatched_args_as_struct = rmfield(obj.struct_mod_input,obj.non_match_names); + obj.umatched_args_as_struct_initialized = true; + end + value = obj.umatched_args_as_struct; + end + function value = get.is_modified(obj) + if ~obj.is_modified_initialized + fn_local = obj.fn__input_struct; + n_fields = length(fn_local); + + changed_mask = false(1,n_fields); + changed_mask(obj.loc(obj.is_present)) = true; + + obj.is_modified = cell2struct(num2cell(changed_mask),fn_local); + obj.is_modified_initialized = true; + end + value = obj.is_modified; + end + end + + methods + function obj = process_varargin_result(input_structure,raw_mod_input) + obj.input_structure = input_structure; + obj.raw_mod_input = raw_mod_input; + end + end + +end + diff --git a/src/Import/labchart/adi/+adi/+sl/+stack/calling_function_info.m b/Import/labchart/adi/+adi/+sl/+stack/calling_function_info.m similarity index 96% rename from src/Import/labchart/adi/+adi/+sl/+stack/calling_function_info.m rename to Import/labchart/adi/+adi/+sl/+stack/calling_function_info.m index 40be43d5..ae848885 100644 --- a/src/Import/labchart/adi/+adi/+sl/+stack/calling_function_info.m +++ b/Import/labchart/adi/+adi/+sl/+stack/calling_function_info.m @@ -1,72 +1,72 @@ -classdef calling_function_info < handle - % - % Class: - % sl.stack.calling_function_info - % - % See Also: - % sl.warning.deprecated - % - % IMPROVEMENTS: - % =================================================================== - % 1) We might eventually add on a workspace grab of the level - % requested - % 2) Multiple levels??? - % 3) Add on an option for a fully resolved name (make a separate - % property) -> i.e. for when things are in packages - - properties - line_number = NaN - file_path = '' - name %file_name or 'CommandWindow' when called from command window - %Notes about name: - % - % 1) The file name lacks an extension - % 2) For classes, a function will contain the class name (at - % least for static methods ...) - % 3) The name lacks the package - is_cmd_window = false - end - - methods - function obj = calling_function_info(level) - %calling_function_info Returns the caller of the calling function. - % - % obj = sl.stack.calling_function_info(*level) - % - % - % INPUTS - % ============================================================ - % level : (scalar, default: 2) which caller to retrieve, - % where 1 denotes caller of this function, 2 caller of - % the function calling this function, etc - % - % Known Users: - % sl.warning.deprecated - % - % tags: utility, display - - if nargin < 1 - level = 2; - end - - s = dbstack('-completenames'); - assert(level > 0,'The input ''level'' must be > 0, %d observed',level); - - %NOTE: Stack has most recent on top - %this - index 1 - %caller - index 2 - %etc - - if length(s) == 1 - obj.name = 'CommandWindow'; - obj.is_cmd_window = true; - else - idx = level + 1; - obj.name = s(idx).name; - obj.file_path = s(idx).file; - obj.line_number = s(idx).line; - end - end - end -end - +classdef calling_function_info < handle + % + % Class: + % sl.stack.calling_function_info + % + % See Also: + % sl.warning.deprecated + % + % IMPROVEMENTS: + % =================================================================== + % 1) We might eventually add on a workspace grab of the level + % requested + % 2) Multiple levels??? + % 3) Add on an option for a fully resolved name (make a separate + % property) -> i.e. for when things are in packages + + properties + line_number = NaN + file_path = '' + name %file_name or 'CommandWindow' when called from command window + %Notes about name: + % + % 1) The file name lacks an extension + % 2) For classes, a function will contain the class name (at + % least for static methods ...) + % 3) The name lacks the package + is_cmd_window = false + end + + methods + function obj = calling_function_info(level) + %calling_function_info Returns the caller of the calling function. + % + % obj = sl.stack.calling_function_info(*level) + % + % + % INPUTS + % ============================================================ + % level : (scalar, default: 2) which caller to retrieve, + % where 1 denotes caller of this function, 2 caller of + % the function calling this function, etc + % + % Known Users: + % sl.warning.deprecated + % + % tags: utility, display + + if nargin < 1 + level = 2; + end + + s = dbstack('-completenames'); + assert(level > 0,'The input ''level'' must be > 0, %d observed',level); + + %NOTE: Stack has most recent on top + %this - index 1 + %caller - index 2 + %etc + + if length(s) == 1 + obj.name = 'CommandWindow'; + obj.is_cmd_window = true; + else + idx = level + 1; + obj.name = s(idx).name; + obj.file_path = s(idx).file; + obj.line_number = s(idx).line; + end + end + end +end + diff --git a/src/Import/labchart/adi/+adi/+sl/+stack/getMyBasePath.m b/Import/labchart/adi/+adi/+sl/+stack/getMyBasePath.m similarity index 96% rename from src/Import/labchart/adi/+adi/+sl/+stack/getMyBasePath.m rename to Import/labchart/adi/+adi/+sl/+stack/getMyBasePath.m index 6e0e1be1..9af43050 100644 --- a/src/Import/labchart/adi/+adi/+sl/+stack/getMyBasePath.m +++ b/Import/labchart/adi/+adi/+sl/+stack/getMyBasePath.m @@ -1,81 +1,81 @@ -function base_path = getMyBasePath(file_name,varargin) -%getMyPath Returns base path of calling function -% -% base_path = sl.stack.getMyBasePath(*file_name,varargin) -% -% Outputs: -% -------- -% base_path : path to cotaining folder of function that is calling -% this function. -% -% Inputs: -% ------- -% file_name : (default '') -% If empty, examines calling function, otherwise it runs which() on -% the name to resolve the path. When called from a script or command -% line returns the current directory. -% -% Optional Inputs: -% ---------------- -% n_dirs_up : (default 0) -% If not 0, the returned value is stripped of the path by the -% specified number of directories. For example a value that would -% normally be: -% /Users/Jim/my/returned/path/testing -% with a 'n_dirs_up' value of 2 would return: -% /Users/Jim/my/returned/ -% n_callers_up: (default 0) -% Normally this returns the path of the caller. If for some reason -% you wanted to get the path of the function calling the function -% that calls this function, set 'n_callers_up' to 1. Higher values can -% also be used to get 'higher order' callers. -% -% Examples: -% --------- -% 1) Typical usage case: -% -% base_path = getMyBasePath(); -% -% 2) Useful for executing in a script where you want the script path -% -% base_path = getMyBasePath('myScriptsName') -% -% 3) TODO: Provide example with n_dirs_up being used -% -% Improvements: -% ------------- -% 1) Provide specific examples ... -% -% -% See Also: -% sl.dir.filepartsx - -in.n_dirs_up = 0; -in.n_callers_up = 0; -in = adi.sl.in.processVarargin(in,varargin); - - -%NOTE: the function mfilename() can't be used with evalin -% (as of 2009b) - -%We use the stack to get the path -if nargin == 0 || isempty(file_name) - stack = dbstack('-completenames'); - if length(stack) == 1 - base_path = cd; - else - %NOTE: - % - 1 refers to this function - % - 2 refers to the calling function - base_path = fileparts(stack(2 + in.n_callers_up).file); - end -else - filePath = which(file_name); - base_path = fileparts(filePath); -end - -if in.n_dirs_up ~= 0 - base_path = adi.sl.dir.filepartsx(base_path,in.n_dirs_up); -end - +function base_path = getMyBasePath(file_name,varargin) +%getMyPath Returns base path of calling function +% +% base_path = sl.stack.getMyBasePath(*file_name,varargin) +% +% Outputs: +% -------- +% base_path : path to cotaining folder of function that is calling +% this function. +% +% Inputs: +% ------- +% file_name : (default '') +% If empty, examines calling function, otherwise it runs which() on +% the name to resolve the path. When called from a script or command +% line returns the current directory. +% +% Optional Inputs: +% ---------------- +% n_dirs_up : (default 0) +% If not 0, the returned value is stripped of the path by the +% specified number of directories. For example a value that would +% normally be: +% /Users/Jim/my/returned/path/testing +% with a 'n_dirs_up' value of 2 would return: +% /Users/Jim/my/returned/ +% n_callers_up: (default 0) +% Normally this returns the path of the caller. If for some reason +% you wanted to get the path of the function calling the function +% that calls this function, set 'n_callers_up' to 1. Higher values can +% also be used to get 'higher order' callers. +% +% Examples: +% --------- +% 1) Typical usage case: +% +% base_path = getMyBasePath(); +% +% 2) Useful for executing in a script where you want the script path +% +% base_path = getMyBasePath('myScriptsName') +% +% 3) TODO: Provide example with n_dirs_up being used +% +% Improvements: +% ------------- +% 1) Provide specific examples ... +% +% +% See Also: +% sl.dir.filepartsx + +in.n_dirs_up = 0; +in.n_callers_up = 0; +in = adi.sl.in.processVarargin(in,varargin); + + +%NOTE: the function mfilename() can't be used with evalin +% (as of 2009b) + +%We use the stack to get the path +if nargin == 0 || isempty(file_name) + stack = dbstack('-completenames'); + if length(stack) == 1 + base_path = cd; + else + %NOTE: + % - 1 refers to this function + % - 2 refers to the calling function + base_path = fileparts(stack(2 + in.n_callers_up).file); + end +else + filePath = which(file_name); + base_path = fileparts(filePath); +end + +if in.n_dirs_up ~= 0 + base_path = adi.sl.dir.filepartsx(base_path,in.n_dirs_up); +end + end \ No newline at end of file diff --git a/src/Import/labchart/adi/+adi/+sl/+stack/getPackageRoot.m b/Import/labchart/adi/+adi/+sl/+stack/getPackageRoot.m similarity index 95% rename from src/Import/labchart/adi/+adi/+sl/+stack/getPackageRoot.m rename to Import/labchart/adi/+adi/+sl/+stack/getPackageRoot.m index 61024990..3b5bd5e3 100644 --- a/src/Import/labchart/adi/+adi/+sl/+stack/getPackageRoot.m +++ b/Import/labchart/adi/+adi/+sl/+stack/getPackageRoot.m @@ -1,22 +1,22 @@ -function package_root = getPackageRoot() -% -% package_root = sl.stack.getPackageRoot() -% -% Returns the path of the folder that contains the base package. -% -% Examples: -% Called from: 'C:\repos\matlab_git\my_repo\+package\my_function.m -% Returns: 'C:\repos\matlab_git\my_repo\' -% - -temp_path = adi.sl.stack.getMyBasePath('','n_callers_up',1); - -I = strfind(temp_path,'+'); -if isempty(I) - package_root = temp_path; -else - last_char_I = I(1)-2; - package_root = temp_path(1:last_char_I); -end - -end +function package_root = getPackageRoot() +% +% package_root = sl.stack.getPackageRoot() +% +% Returns the path of the folder that contains the base package. +% +% Examples: +% Called from: 'C:\repos\matlab_git\my_repo\+package\my_function.m +% Returns: 'C:\repos\matlab_git\my_repo\' +% + +temp_path = adi.sl.stack.getMyBasePath('','n_callers_up',1); + +I = strfind(temp_path,'+'); +if isempty(I) + package_root = temp_path; +else + last_char_I = I(1)-2; + package_root = temp_path(1:last_char_I); +end + +end diff --git a/src/Import/labchart/adi/+adi/+sl/+str/contains.m b/Import/labchart/adi/+adi/+sl/+str/contains.m similarity index 96% rename from src/Import/labchart/adi/+adi/+sl/+str/contains.m rename to Import/labchart/adi/+adi/+sl/+str/contains.m index b9b8b859..9c6bb539 100644 --- a/src/Import/labchart/adi/+adi/+sl/+str/contains.m +++ b/Import/labchart/adi/+adi/+sl/+str/contains.m @@ -1,78 +1,78 @@ -function flag = contains(input_string,string_to_match,varargin) -% -% sl.str.contains(s1,str_to_match,varargin) -% -% Checks if one string can be found in another string. -% -% Inputs: -% ------- -% input_string: char -% string_to_match: char -% -% Optional Inputs: -% ---------------- -% location: (default 'anywhere' -% - 'start' -% - 'end' -% - 'anywhere' -% -% Examples: -% ---------- -% >> sl.str.contains('testing','ing','location','end') -% ans = 1 -% -% >> sl.str.contains('testing','est','location','anywhere') - -in.case_sensitive = true; -in.location = 'anywhere'; -in = adi.sl.in.processVarargin(in,varargin); - -switch in.location - case 'start' - if in.case_sensitive - flag = strncmp(input_string,string_to_match,length(string_to_match)); - else - flag = strncmpi(input_string,string_to_match,length(string_to_match)); - end - case 'end' - length_str = length(string_to_match); - if length(input_string) < length_str - flag = false; - else - if in.case_sensitive - flag = strcmp(input_string((end-length_str+1):end),string_to_match); - else - flag = strcmpi(input_string((end-length_str+1):end),string_to_match); - end - end - case 'anywhere' - if in.case_sensitive - flag = any(strfind(input_string,string_to_match)); - else - %I had considered using regexpi but then I need to worry about - %translating the string to match - %flag = any(regexpi(input_string,regexptranslate(string_to_match),'match','once') - flag = any(strfind(lower(input_string),lower(string_to_match))); - end - otherwise - error('Unrecognized option for string match: %s',in.location); -end - -end - -%{ - -%Testing end match -sl.str.contains('testing','ing','location','end') - -%String too long -sl.str.contains('testing','asdfasdfing','location','end') - -%Testing start -sl.str.contains('testing','test','location','start') - -%Middle match -sl.str.contains('testing','est','location','anywhere') - - +function flag = contains(input_string,string_to_match,varargin) +% +% sl.str.contains(s1,str_to_match,varargin) +% +% Checks if one string can be found in another string. +% +% Inputs: +% ------- +% input_string: char +% string_to_match: char +% +% Optional Inputs: +% ---------------- +% location: (default 'anywhere' +% - 'start' +% - 'end' +% - 'anywhere' +% +% Examples: +% ---------- +% >> sl.str.contains('testing','ing','location','end') +% ans = 1 +% +% >> sl.str.contains('testing','est','location','anywhere') + +in.case_sensitive = true; +in.location = 'anywhere'; +in = adi.sl.in.processVarargin(in,varargin); + +switch in.location + case 'start' + if in.case_sensitive + flag = strncmp(input_string,string_to_match,length(string_to_match)); + else + flag = strncmpi(input_string,string_to_match,length(string_to_match)); + end + case 'end' + length_str = length(string_to_match); + if length(input_string) < length_str + flag = false; + else + if in.case_sensitive + flag = strcmp(input_string((end-length_str+1):end),string_to_match); + else + flag = strcmpi(input_string((end-length_str+1):end),string_to_match); + end + end + case 'anywhere' + if in.case_sensitive + flag = any(strfind(input_string,string_to_match)); + else + %I had considered using regexpi but then I need to worry about + %translating the string to match + %flag = any(regexpi(input_string,regexptranslate(string_to_match),'match','once') + flag = any(strfind(lower(input_string),lower(string_to_match))); + end + otherwise + error('Unrecognized option for string match: %s',in.location); +end + +end + +%{ + +%Testing end match +sl.str.contains('testing','ing','location','end') + +%String too long +sl.str.contains('testing','asdfasdfing','location','end') + +%Testing start +sl.str.contains('testing','test','location','start') + +%Middle match +sl.str.contains('testing','est','location','anywhere') + + %} \ No newline at end of file diff --git a/src/Import/labchart/adi/+adi/+tests/t001_speedWritingAndWriting.m b/Import/labchart/adi/+adi/+tests/t001_speedWritingAndWriting.m similarity index 97% rename from src/Import/labchart/adi/+adi/+tests/t001_speedWritingAndWriting.m rename to Import/labchart/adi/+adi/+tests/t001_speedWritingAndWriting.m index 308f530b..885befa4 100644 --- a/src/Import/labchart/adi/+adi/+tests/t001_speedWritingAndWriting.m +++ b/Import/labchart/adi/+adi/+tests/t001_speedWritingAndWriting.m @@ -1,79 +1,79 @@ -function t001_speedWritingAndWriting -% -% adi.tests.t001_speedWritingAndWriting -% -% STATUS: - -FILE_PATH = 'C:\Data\GSK\ChrisRaw\140121 pelvic nerve recordings.adicht'; -SAVE_DIR = 'D:\Data\HDF5_test'; - -%Things to vary: -%- chunk size -%- compression level -%- shuffle or no shuffle - -quick_test = false; -if quick_test - pct_chunk_sizes = 0.5; %0.05:0.05:1; - compression_levels = 1; %0:9; - shuffle_options = false; %[true false]; - n_repeats = 1; -else - pct_chunk_sizes = 0.2:0.2:1; - compression_levels = [0 1:2:9]; - shuffle_options = [true, false]; - n_repeats = 3; -end - -n_chunk_sizes = length(pct_chunk_sizes); -n_compression = length(compression_levels); -n_shuffle = length(shuffle_options); - - - -write_times = zeros(n_chunk_sizes,n_compression,n_shuffle,n_repeats); -file_sizes = write_times; - -[~,file_name] = fileparts(FILE_PATH); -results_path = fullfile(SAVE_DIR,[file_name '_results.mat']); - -for iRepeat = 1:n_repeats - for iChunkPct = 1:n_chunk_sizes - for iCompression = 1:n_compression - for iShuffle = 1:n_shuffle - fprintf('Converting %s, %d, %d, %d, %d\n',datestr(now), iRepeat,iCompression,iChunkPct,iShuffle) - options = adi.h5_conversion_options; - options.chunk_length_pct = pct_chunk_sizes(iChunkPct); - options.use_shuffle = shuffle_options(iShuffle); - options.deflate_value = compression_levels(iCompression); - t = tic; - - - % suffix = sprintf('c%d_len%d_s%d',... - % options.deflate_value,... - % options.chunk_length,... - % options.use_shuffle); - - suffix = sprintf('_c%d_p%d_s%d',iCompression,iChunkPct,iShuffle); - - save_path = fullfile(SAVE_DIR,[file_name suffix '.h5']); - - adi.convert(FILE_PATH,... - 'save_path',save_path,... - 'conversion_options',options); - toc(t) %For display - elapsed_time = toc(t); - write_times(iChunkPct,iCompression,iShuffle,iRepeat) = elapsed_time; - - temp = dir(save_path); - file_sizes(iChunkPct,iCompression,iShuffle,iRepeat) = temp.bytes; - end - end - end - save(results_path,'file_sizes','write_times','pct_chunk_sizes',... - 'compression_levels','shuffle_options'); -end - - - - +function t001_speedWritingAndWriting +% +% adi.tests.t001_speedWritingAndWriting +% +% STATUS: + +FILE_PATH = 'C:\Data\GSK\ChrisRaw\140121 pelvic nerve recordings.adicht'; +SAVE_DIR = 'D:\Data\HDF5_test'; + +%Things to vary: +%- chunk size +%- compression level +%- shuffle or no shuffle + +quick_test = false; +if quick_test + pct_chunk_sizes = 0.5; %0.05:0.05:1; + compression_levels = 1; %0:9; + shuffle_options = false; %[true false]; + n_repeats = 1; +else + pct_chunk_sizes = 0.2:0.2:1; + compression_levels = [0 1:2:9]; + shuffle_options = [true, false]; + n_repeats = 3; +end + +n_chunk_sizes = length(pct_chunk_sizes); +n_compression = length(compression_levels); +n_shuffle = length(shuffle_options); + + + +write_times = zeros(n_chunk_sizes,n_compression,n_shuffle,n_repeats); +file_sizes = write_times; + +[~,file_name] = fileparts(FILE_PATH); +results_path = fullfile(SAVE_DIR,[file_name '_results.mat']); + +for iRepeat = 1:n_repeats + for iChunkPct = 1:n_chunk_sizes + for iCompression = 1:n_compression + for iShuffle = 1:n_shuffle + fprintf('Converting %s, %d, %d, %d, %d\n',datestr(now), iRepeat,iCompression,iChunkPct,iShuffle) + options = adi.h5_conversion_options; + options.chunk_length_pct = pct_chunk_sizes(iChunkPct); + options.use_shuffle = shuffle_options(iShuffle); + options.deflate_value = compression_levels(iCompression); + t = tic; + + + % suffix = sprintf('c%d_len%d_s%d',... + % options.deflate_value,... + % options.chunk_length,... + % options.use_shuffle); + + suffix = sprintf('_c%d_p%d_s%d',iCompression,iChunkPct,iShuffle); + + save_path = fullfile(SAVE_DIR,[file_name suffix '.h5']); + + adi.convert(FILE_PATH,... + 'save_path',save_path,... + 'conversion_options',options); + toc(t) %For display + elapsed_time = toc(t); + write_times(iChunkPct,iCompression,iShuffle,iRepeat) = elapsed_time; + + temp = dir(save_path); + file_sizes(iChunkPct,iCompression,iShuffle,iRepeat) = temp.bytes; + end + end + end + save(results_path,'file_sizes','write_times','pct_chunk_sizes',... + 'compression_levels','shuffle_options'); +end + + + + diff --git a/src/Import/labchart/adi/+adi/@channel/channel.m b/Import/labchart/adi/+adi/@channel/channel.m similarity index 97% rename from src/Import/labchart/adi/+adi/@channel/channel.m rename to Import/labchart/adi/+adi/@channel/channel.m index 53081725..47889cdb 100644 --- a/src/Import/labchart/adi/+adi/@channel/channel.m +++ b/Import/labchart/adi/+adi/@channel/channel.m @@ -1,391 +1,391 @@ -classdef (Hidden) channel < handle - % - % Class: - % adi.channel - % - % This class only holds information regarding the channel. - - properties - id %Internal number (1 based) - name - - %These properties are on a per record basis ... - %----------------------------------------------- - units %cellstr - n_samples %array - # of samples collected on this channel during - %each record - dt %array - time between samples - fs %array - sampling rate (1/dt) - - %????? I'm not sure what the heck this is .... - data_starts %See definition in adi.record - record_starts - end - - properties (Hidden) - n_records - file_h - tick_dt - record_handles - sdk - file_path - end - - properties (Dependent) - downsample_amount %How this channel relates to the fastest sampling - %rate. If this is the fastest sampled channel, the value will be 1. - %If the sampling rate is a tenth of the fastest, the value will be - %10. - end - - methods - function value = get.downsample_amount(obj) - value = obj.dt./obj.tick_dt; - end - end - - methods - function obj = channel(file_h,sdk,channel_id,record_handles,file_path) - %x adi.channel constructor - % - % obj = adi.channel(file_h,sdk,channel_id,record_handles,file_path) - % - % Inputs: - % ------- - % sdk : reference to an sdk object - % - - obj.sdk = sdk; - obj.id = channel_id; - obj.n_records = length(record_handles); - obj.file_h = file_h; - obj.tick_dt = [record_handles.tick_dt]; - obj.data_starts = [record_handles.data_start]; - obj.record_starts = [record_handles.record_start]; - obj.record_handles = record_handles; - obj.file_path = file_path; - - temp_sample_period = zeros(1,obj.n_records); - temp_n_samples = zeros(1,obj.n_records); - temp_units = cell(1,obj.n_records); - - obj.name = sdk.getChannelName(file_h,channel_id); - - for iRecord = 1:obj.n_records - temp_sample_period(iRecord) = sdk.getSamplePeriod(file_h,iRecord,channel_id); - temp_n_samples(iRecord) = sdk.getNSamplesInRecord(file_h,iRecord,channel_id); - temp_units{iRecord} = sdk.getUnits(file_h,iRecord,channel_id); - end - - obj.units = temp_units; - obj.n_samples = temp_n_samples; - obj.dt = temp_sample_period; - obj.fs = 1./(obj.dt); - end - - %I'd like to remove this ... - %------------------------------------------------------ - function comment_objs = getRecordComments(obj,record_id,varargin) - %x Small helper to get the comments for a given record - % - % comment_objs = obj.getRecordComments(record_id,varargin) - - - in.time_range = []; - in.all_channels = true; - in = adi.sl.in.processVarargin(in,varargin); - - comment_objs = obj.record_handles(record_id).comments; - - % - if ~isempty(in.time_range) && ~isempty(comment_objs) - comment_objs = comment_objs.filterByTime(in.time_range); - end - - if ~in.all_channels && ~isempty(comment_objs) - comment_objs = comment_objs.filterByChannel(in.time_range); - end - - - end - %------------------------------------------------------ - function printChannelNames(objs) - %x Prints all channel names to the command window - % - % printChannelNames(objs) - - for iObj = 1:length(objs) - fprintf('%s\n',objs(iObj).name); - end - end - function chan = getChannelByName(objs,name,varargin) - %x Finds and returns a channel object by name - % - % chan = getChannelByName(objs,name) - % - % Inputs: - % ------- - % name: str - % Name of the channel to retrieve. Optional inputs - % dictate how this input is compared to the actual names - % of the channels. - % - % Optional Inputs: - % ---------------- - % case_sensitive: (default false) - % partial_match: (default true) - % If true the input only needs to be a part of the name. - % For example we could get the channel 'Bladder Pressure' - % by using the 'pres' since 'pres' is in the - % string 'Bladder Pressure' - % multiple_channel_rule: {'error','first','last',index #,'shortest'} - % - % See Also: - % adi.file.getChannelByName - - in.case_sensitive = false; - in.partial_match = true; - in.multiple_channel_rule = 'error'; - in = adi.sl.in.processVarargin(in,varargin); - - all_names = {objs.name}; - if ~in.case_sensitive - all_names = lower(all_names); - name = lower(name); - end - - if in.partial_match - I = find(cellfun(@(x) adi.sl.str.contains(x,name),all_names)); - else - %Could also use: sl.str.findSingularMatch - I = find(strcmp(all_names,name)); - end - - if isempty(I) - error('Unable to find channel with name: %s',name) - elseif length(I) > 1 - if isnumeric(in.multiple_channel_rule) - I = I(in.multiple_channel_rule); - else - switch in.multiple_channel_rule - case 'error' - error('Multiple matches for channel name found') - case 'first' - I = I(1); - case 'last' - I = I(end); - case 'shortest' - name_lengths = cellfun('length',all_names(I)); - [~,I2] = min(name_lengths); - I = I(I2); - otherwise - error(['Multiple matches for channel name found and' ... - ' multiple matches option: "%s" not recognized'],... - in.multiple_channel_rule) - end - end - end - - chan = objs(I); - end - function objs_with_data = removeEmptyObjects(objs) - %x Removes channels with no data in them. - % - % This is done by default on loading the channels so that - % empty channels don't clutter things up. - % - % This can be disabled by changing the read options. - % - % See also: - % adi.readFile - - n_objs = length(objs); - keep_mask = false(1,n_objs); - for iObj = 1:n_objs - keep_mask(iObj) = sum(objs(iObj).n_samples) ~= 0; - end - objs_with_data = objs(keep_mask); - end - function varargout = getData(obj,record_id,varargin) - % - % data_object = obj.getData(record_id,varargin) - % - % [data,time] = obj.getData(record_id,'return_object',false,varargin) - % - % Inputs: - % ------- - % record_id: number - % Record # from which to retrieve data. Adinstruments - % stores data in chunks known as records, which can be - % like trials depending on how the user uses them. - % Channel properties can change between records. - % - % Optional Inputs: - % ---------------- - % return_object: (default true) - % If true then a sci.time_series.data object is returned. - % This is made false if the class doesn't exist (such - % as when the adi package is being used on its own) - % data_range: [min max] (default full range) - % Values are in samples. Specifies which samples to get. - % ex. [10 30] specifies to get sample 10 through sample - % 30 - % get_as_samples: (default true) - % If false the channel is upsampled to the highest rate - % using sample and hold. NOTE: This is not very well - % tested and might break things but it is offered in the - % underlying SDK. - % time_range: [min max] - % Often times it is more natural to specify a range of - % time over which to request the data, rather than a - % range of samples. Use this to specify the data that is - % between the specified min and max time values. - % leave_raw: (default false) - % If true the data are not converted to double (most - % likely they will be returned as type 'single'). This is - % mostly used when converting from the adicht format to - % another file format. - % - % Outputs: - % -------- - % data_object : - % - - if record_id < 1 || record_id > obj.n_records - error('Record input: %d, out of range: [1 %d]',record_id,obj.n_records); - end - - in.return_object = true; - in.data_range = [1 obj.n_samples(record_id)]; - in.time_range = []; %Seconds, TODO: Document this ... - in.get_as_samples = true; %Alternatively ... - in.leave_raw = false; - in = adi.sl.in.processVarargin(in,varargin); - - in.return_object = in.return_object && logical(exist('sci.time_series.data','class')); - - %TODO: This is not right if get_as_samples is false - if isempty(in.time_range) - %We populate this for comment retrieval - in.time_range = (in.data_range-1)/obj.fs(record_id); - else - in.data_range(1) = floor(in.time_range(1)*obj.fs(record_id))+1; - in.data_range(2) = ceil(in.time_range(2)*obj.fs(record_id))+1; - end - - if obj.n_samples(record_id) == 0 - data = []; - else - if any(in.data_range > obj.n_samples(record_id)) - %TODO: Make this error more explicit - error('Data requested out of range') - end - - if in.data_range(1) > in.data_range(2) - error('Specified data range must be increasing') - end - - data = obj.sdk.getChannelData(... - obj.file_h,... - record_id,... - obj.id,... - in.data_range(1),... - in.data_range(2)-in.data_range(1)+1,... - in.get_as_samples,... - 'leave_raw',in.leave_raw); - - if isrow(data) - data = data'; - end - end - - if in.return_object - comments = obj.getRecordComments(record_id,'time_range',in.time_range); - - if isempty(comments) - time_events = sci.time_series.discrete_events.empty(); - else - time_events = sci.time_series.discrete_events('comments',... - [comments.time],'values',[comments.id],... - 'msgs',{comments.str}); - end - - %TODO: This is not right if get_as_samples is false - time_object = sci.time_series.time(... - obj.dt(record_id),... - length(data),... - 'sample_offset',in.data_range(1),... - 'start_datetime',obj.data_starts(record_id)); - varargout{1} = sci.time_series.data(data,... - time_object,... - 'units',obj.units{record_id},... - 'channel_labels',obj.name,... - 'y_label',obj.name,... - 'history',sprintf('File: %s\nRecord: %d',obj.file_path,record_id),... - 'events',time_events); - else - varargout{1} = data; - if nargout == 2 - varargout{2} = (0:(length(data)-1)).*obj.dt(record_id); - end - end - end - end - methods (Hidden) - exportToHDF5File(objs,fobj,save_path,conversion_options) - function exportToMatFile(objs,m,conversion_options) - - MAX_SAMPLES_AT_ONCE = 1e7; - - m.channel_version = 1; - - m.channel_meta = struct(... - 'id', {objs.id},... - 'name', {objs.name},... - 'units', {objs.units},... - 'n_samples', {objs.n_samples},... - 'dt', {objs.dt}); - - %NOTE: It would be nice to be able to save the raw data ... - %----------------------------------- - m.data_version = 1; - - %NOTE: We can't go deeper than a single element :/ - - n_objs = length(objs); - n_records = objs(1).n_records; %#ok - for iChan = 1:n_objs - cur_chan = objs(iChan); - for iRecord = 1:n_records %#ok - cur_n_samples = cur_chan.n_samples(iRecord); - chan_name = sprintf('data__chan_%d_rec_%d',iChan,iRecord); - if cur_n_samples < MAX_SAMPLES_AT_ONCE - %(obj,record_id,get_as_samples) - m.(chan_name) = cur_chan.getData(iRecord,'leave_raw',true,'return_object',false); - else - - start_I = 1:MAX_SAMPLES_AT_ONCE:cur_n_samples; - end_I = MAX_SAMPLES_AT_ONCE:MAX_SAMPLES_AT_ONCE:cur_n_samples; - - if length(end_I) < length(start_I) - end_I(end+1) = cur_n_samples; %#ok - end - - %I am assuming that the output is single. - m.(chan_name)(cur_n_samples,1) = single(0); %Initialize output - for iChunk = 1:length(start_I) - cur_start = start_I(iChunk); - cur_end = end_I(iChunk); - %n_samples_get = cur_end-cur_start + 1; - m.(chan_name)(cur_start:cur_end,1) = ... - cur_chan.getData(iRecord,'data_range',[cur_start cur_end],... - 'leave_raw',true,'return_object',false); - end - end - end - end - end - end - -end - +classdef (Hidden) channel < handle + % + % Class: + % adi.channel + % + % This class only holds information regarding the channel. + + properties + id %Internal number (1 based) + name + + %These properties are on a per record basis ... + %----------------------------------------------- + units %cellstr + n_samples %array - # of samples collected on this channel during + %each record + dt %array - time between samples + fs %array - sampling rate (1/dt) + + %????? I'm not sure what the heck this is .... + data_starts %See definition in adi.record + record_starts + end + + properties (Hidden) + n_records + file_h + tick_dt + record_handles + sdk + file_path + end + + properties (Dependent) + downsample_amount %How this channel relates to the fastest sampling + %rate. If this is the fastest sampled channel, the value will be 1. + %If the sampling rate is a tenth of the fastest, the value will be + %10. + end + + methods + function value = get.downsample_amount(obj) + value = obj.dt./obj.tick_dt; + end + end + + methods + function obj = channel(file_h,sdk,channel_id,record_handles,file_path) + %x adi.channel constructor + % + % obj = adi.channel(file_h,sdk,channel_id,record_handles,file_path) + % + % Inputs: + % ------- + % sdk : reference to an sdk object + % + + obj.sdk = sdk; + obj.id = channel_id; + obj.n_records = length(record_handles); + obj.file_h = file_h; + obj.tick_dt = [record_handles.tick_dt]; + obj.data_starts = [record_handles.data_start]; + obj.record_starts = [record_handles.record_start]; + obj.record_handles = record_handles; + obj.file_path = file_path; + + temp_sample_period = zeros(1,obj.n_records); + temp_n_samples = zeros(1,obj.n_records); + temp_units = cell(1,obj.n_records); + + obj.name = sdk.getChannelName(file_h,channel_id); + + for iRecord = 1:obj.n_records + temp_sample_period(iRecord) = sdk.getSamplePeriod(file_h,iRecord,channel_id); + temp_n_samples(iRecord) = sdk.getNSamplesInRecord(file_h,iRecord,channel_id); + temp_units{iRecord} = sdk.getUnits(file_h,iRecord,channel_id); + end + + obj.units = temp_units; + obj.n_samples = temp_n_samples; + obj.dt = temp_sample_period; + obj.fs = 1./(obj.dt); + end + + %I'd like to remove this ... + %------------------------------------------------------ + function comment_objs = getRecordComments(obj,record_id,varargin) + %x Small helper to get the comments for a given record + % + % comment_objs = obj.getRecordComments(record_id,varargin) + + + in.time_range = []; + in.all_channels = true; + in = adi.sl.in.processVarargin(in,varargin); + + comment_objs = obj.record_handles(record_id).comments; + + % + if ~isempty(in.time_range) && ~isempty(comment_objs) + comment_objs = comment_objs.filterByTime(in.time_range); + end + + if ~in.all_channels && ~isempty(comment_objs) + comment_objs = comment_objs.filterByChannel(in.time_range); + end + + + end + %------------------------------------------------------ + function printChannelNames(objs) + %x Prints all channel names to the command window + % + % printChannelNames(objs) + + for iObj = 1:length(objs) + fprintf('%s\n',objs(iObj).name); + end + end + function chan = getChannelByName(objs,name,varargin) + %x Finds and returns a channel object by name + % + % chan = getChannelByName(objs,name) + % + % Inputs: + % ------- + % name: str + % Name of the channel to retrieve. Optional inputs + % dictate how this input is compared to the actual names + % of the channels. + % + % Optional Inputs: + % ---------------- + % case_sensitive: (default false) + % partial_match: (default true) + % If true the input only needs to be a part of the name. + % For example we could get the channel 'Bladder Pressure' + % by using the 'pres' since 'pres' is in the + % string 'Bladder Pressure' + % multiple_channel_rule: {'error','first','last',index #,'shortest'} + % + % See Also: + % adi.file.getChannelByName + + in.case_sensitive = false; + in.partial_match = true; + in.multiple_channel_rule = 'error'; + in = adi.sl.in.processVarargin(in,varargin); + + all_names = {objs.name}; + if ~in.case_sensitive + all_names = lower(all_names); + name = lower(name); + end + + if in.partial_match + I = find(cellfun(@(x) adi.sl.str.contains(x,name),all_names)); + else + %Could also use: sl.str.findSingularMatch + I = find(strcmp(all_names,name)); + end + + if isempty(I) + error('Unable to find channel with name: %s',name) + elseif length(I) > 1 + if isnumeric(in.multiple_channel_rule) + I = I(in.multiple_channel_rule); + else + switch in.multiple_channel_rule + case 'error' + error('Multiple matches for channel name found') + case 'first' + I = I(1); + case 'last' + I = I(end); + case 'shortest' + name_lengths = cellfun('length',all_names(I)); + [~,I2] = min(name_lengths); + I = I(I2); + otherwise + error(['Multiple matches for channel name found and' ... + ' multiple matches option: "%s" not recognized'],... + in.multiple_channel_rule) + end + end + end + + chan = objs(I); + end + function objs_with_data = removeEmptyObjects(objs) + %x Removes channels with no data in them. + % + % This is done by default on loading the channels so that + % empty channels don't clutter things up. + % + % This can be disabled by changing the read options. + % + % See also: + % adi.readFile + + n_objs = length(objs); + keep_mask = false(1,n_objs); + for iObj = 1:n_objs + keep_mask(iObj) = sum(objs(iObj).n_samples) ~= 0; + end + objs_with_data = objs(keep_mask); + end + function varargout = getData(obj,record_id,varargin) + % + % data_object = obj.getData(record_id,varargin) + % + % [data,time] = obj.getData(record_id,'return_object',false,varargin) + % + % Inputs: + % ------- + % record_id: number + % Record # from which to retrieve data. Adinstruments + % stores data in chunks known as records, which can be + % like trials depending on how the user uses them. + % Channel properties can change between records. + % + % Optional Inputs: + % ---------------- + % return_object: (default true) + % If true then a sci.time_series.data object is returned. + % This is made false if the class doesn't exist (such + % as when the adi package is being used on its own) + % data_range: [min max] (default full range) + % Values are in samples. Specifies which samples to get. + % ex. [10 30] specifies to get sample 10 through sample + % 30 + % get_as_samples: (default true) + % If false the channel is upsampled to the highest rate + % using sample and hold. NOTE: This is not very well + % tested and might break things but it is offered in the + % underlying SDK. + % time_range: [min max] + % Often times it is more natural to specify a range of + % time over which to request the data, rather than a + % range of samples. Use this to specify the data that is + % between the specified min and max time values. + % leave_raw: (default false) + % If true the data are not converted to double (most + % likely they will be returned as type 'single'). This is + % mostly used when converting from the adicht format to + % another file format. + % + % Outputs: + % -------- + % data_object : + % + + if record_id < 1 || record_id > obj.n_records + error('Record input: %d, out of range: [1 %d]',record_id,obj.n_records); + end + + in.return_object = true; + in.data_range = [1 obj.n_samples(record_id)]; + in.time_range = []; %Seconds, TODO: Document this ... + in.get_as_samples = true; %Alternatively ... + in.leave_raw = false; + in = adi.sl.in.processVarargin(in,varargin); + + in.return_object = in.return_object && logical(exist('sci.time_series.data','class')); + + %TODO: This is not right if get_as_samples is false + if isempty(in.time_range) + %We populate this for comment retrieval + in.time_range = (in.data_range-1)/obj.fs(record_id); + else + in.data_range(1) = floor(in.time_range(1)*obj.fs(record_id))+1; + in.data_range(2) = ceil(in.time_range(2)*obj.fs(record_id))+1; + end + + if obj.n_samples(record_id) == 0 + data = []; + else + if any(in.data_range > obj.n_samples(record_id)) + %TODO: Make this error more explicit + error('Data requested out of range') + end + + if in.data_range(1) > in.data_range(2) + error('Specified data range must be increasing') + end + + data = obj.sdk.getChannelData(... + obj.file_h,... + record_id,... + obj.id,... + in.data_range(1),... + in.data_range(2)-in.data_range(1)+1,... + in.get_as_samples,... + 'leave_raw',in.leave_raw); + + if isrow(data) + data = data'; + end + end + + if in.return_object + comments = obj.getRecordComments(record_id,'time_range',in.time_range); + + if isempty(comments) + time_events = sci.time_series.discrete_events.empty(); + else + time_events = sci.time_series.discrete_events('comments',... + [comments.time],'values',[comments.id],... + 'msgs',{comments.str}); + end + + %TODO: This is not right if get_as_samples is false + time_object = sci.time_series.time(... + obj.dt(record_id),... + length(data),... + 'sample_offset',in.data_range(1),... + 'start_datetime',obj.data_starts(record_id)); + varargout{1} = sci.time_series.data(data,... + time_object,... + 'units',obj.units{record_id},... + 'channel_labels',obj.name,... + 'y_label',obj.name,... + 'history',sprintf('File: %s\nRecord: %d',obj.file_path,record_id),... + 'events',time_events); + else + varargout{1} = data; + if nargout == 2 + varargout{2} = (0:(length(data)-1)).*obj.dt(record_id); + end + end + end + end + methods (Hidden) + exportToHDF5File(objs,fobj,save_path,conversion_options) + function exportToMatFile(objs,m,conversion_options) + + MAX_SAMPLES_AT_ONCE = 1e7; + + m.channel_version = 1; + + m.channel_meta = struct(... + 'id', {objs.id},... + 'name', {objs.name},... + 'units', {objs.units},... + 'n_samples', {objs.n_samples},... + 'dt', {objs.dt}); + + %NOTE: It would be nice to be able to save the raw data ... + %----------------------------------- + m.data_version = 1; + + %NOTE: We can't go deeper than a single element :/ + + n_objs = length(objs); + n_records = objs(1).n_records; %#ok + for iChan = 1:n_objs + cur_chan = objs(iChan); + for iRecord = 1:n_records %#ok + cur_n_samples = cur_chan.n_samples(iRecord); + chan_name = sprintf('data__chan_%d_rec_%d',iChan,iRecord); + if cur_n_samples < MAX_SAMPLES_AT_ONCE + %(obj,record_id,get_as_samples) + m.(chan_name) = cur_chan.getData(iRecord,'leave_raw',true,'return_object',false); + else + + start_I = 1:MAX_SAMPLES_AT_ONCE:cur_n_samples; + end_I = MAX_SAMPLES_AT_ONCE:MAX_SAMPLES_AT_ONCE:cur_n_samples; + + if length(end_I) < length(start_I) + end_I(end+1) = cur_n_samples; %#ok + end + + %I am assuming that the output is single. + m.(chan_name)(cur_n_samples,1) = single(0); %Initialize output + for iChunk = 1:length(start_I) + cur_start = start_I(iChunk); + cur_end = end_I(iChunk); + %n_samples_get = cur_end-cur_start + 1; + m.(chan_name)(cur_start:cur_end,1) = ... + cur_chan.getData(iRecord,'data_range',[cur_start cur_end],... + 'leave_raw',true,'return_object',false); + end + end + end + end + end + end + +end + diff --git a/src/Import/labchart/adi/+adi/@channel/exportToHDF5File.m b/Import/labchart/adi/+adi/@channel/exportToHDF5File.m similarity index 96% rename from src/Import/labchart/adi/+adi/@channel/exportToHDF5File.m rename to Import/labchart/adi/+adi/@channel/exportToHDF5File.m index 30f2e67c..0a95ebc4 100644 --- a/src/Import/labchart/adi/+adi/@channel/exportToHDF5File.m +++ b/Import/labchart/adi/+adi/@channel/exportToHDF5File.m @@ -1,84 +1,84 @@ -function exportToHDF5File(objs,fobj,save_path,conversion_options) -% -% adi.channel.exportToHDF5File -% -% See Also: -% --------- -% adi.file.exportToHDF5File - - -DEFLATE_VALUE = conversion_options.deflate_value; -MAX_SAMPLES_PER_READ = conversion_options.max_samples_per_read; -CHUNK_LENGTH = conversion_options.chunk_length; -SHUFFLE_FLAG = conversion_options.use_shuffle; - -DATA_TYPE = 'single'; - -group_name = '/channel_meta'; -h5m.group.create(fobj,'channel_version'); -h5writeatt(save_path,'/channel_version','version',1); - -h5m.group.create(fobj,group_name); -%TODO: Rewrite with h5m library - -h5writeatt(save_path,group_name,'name',int16(char({objs.name}))); -h5writeatt(save_path,group_name,'id',[objs.id]); - -temp = vertcat(objs.units); -temp = int16(char(temp(:))); -h5writeatt(save_path,group_name,'units',temp); -h5writeatt(save_path,group_name,'dt',vertcat(objs.dt)); -h5writeatt(save_path,group_name,'n_samples',vertcat(objs.n_samples)); - -h5m.group.create(fobj,'data_version'); -h5writeatt(save_path,'/data_version','version',1); - -%Now onto saving the data -%---------------------------------------------- -n_objs = length(objs); -n_records = objs(1).n_records; -for iChan = 1:n_objs - cur_chan = objs(iChan); - for iRecord = 1:n_records - cur_n_samples = cur_chan.n_samples(iRecord); - chan_name = sprintf('/data__chan_%d_rec_%d',iChan,iRecord); - - h5create(save_path,chan_name,[cur_n_samples 1],... - 'ChunkSize',[min(CHUNK_LENGTH,cur_n_samples) 1],... - 'Datatype',DATA_TYPE,... - 'Deflate',DEFLATE_VALUE,... - 'Shuffle',SHUFFLE_FLAG); - - if cur_n_samples < MAX_SAMPLES_PER_READ - %This is a write sequence - - h5write(save_path, chan_name, ... - cur_chan.getData(iRecord,'leave_raw',true,'return_object',false)); - else - - start_I = 1:MAX_SAMPLES_PER_READ:cur_n_samples; - end_I = MAX_SAMPLES_PER_READ:MAX_SAMPLES_PER_READ:cur_n_samples; - - if length(end_I) < length(start_I) - end_I(end+1) = cur_n_samples; %#ok - end - - for iChunk = 1:length(start_I) - cur_start = start_I(iChunk); - cur_end = end_I(iChunk); - n_samples_get = cur_end-cur_start + 1; - - data = cur_chan.getData(iRecord,'data_range',... - [cur_start,cur_start+n_samples_get-1],'leave_raw',true,... - 'return_object',false); - - - - h5write(save_path,chan_name,data,[cur_start 1],[length(data) 1],[1 1]) - end - end - end -end - - +function exportToHDF5File(objs,fobj,save_path,conversion_options) +% +% adi.channel.exportToHDF5File +% +% See Also: +% --------- +% adi.file.exportToHDF5File + + +DEFLATE_VALUE = conversion_options.deflate_value; +MAX_SAMPLES_PER_READ = conversion_options.max_samples_per_read; +CHUNK_LENGTH = conversion_options.chunk_length; +SHUFFLE_FLAG = conversion_options.use_shuffle; + +DATA_TYPE = 'single'; + +group_name = '/channel_meta'; +h5m.group.create(fobj,'channel_version'); +h5writeatt(save_path,'/channel_version','version',1); + +h5m.group.create(fobj,group_name); +%TODO: Rewrite with h5m library + +h5writeatt(save_path,group_name,'name',int16(char({objs.name}))); +h5writeatt(save_path,group_name,'id',[objs.id]); + +temp = vertcat(objs.units); +temp = int16(char(temp(:))); +h5writeatt(save_path,group_name,'units',temp); +h5writeatt(save_path,group_name,'dt',vertcat(objs.dt)); +h5writeatt(save_path,group_name,'n_samples',vertcat(objs.n_samples)); + +h5m.group.create(fobj,'data_version'); +h5writeatt(save_path,'/data_version','version',1); + +%Now onto saving the data +%---------------------------------------------- +n_objs = length(objs); +n_records = objs(1).n_records; +for iChan = 1:n_objs + cur_chan = objs(iChan); + for iRecord = 1:n_records + cur_n_samples = cur_chan.n_samples(iRecord); + chan_name = sprintf('/data__chan_%d_rec_%d',iChan,iRecord); + + h5create(save_path,chan_name,[cur_n_samples 1],... + 'ChunkSize',[min(CHUNK_LENGTH,cur_n_samples) 1],... + 'Datatype',DATA_TYPE,... + 'Deflate',DEFLATE_VALUE,... + 'Shuffle',SHUFFLE_FLAG); + + if cur_n_samples < MAX_SAMPLES_PER_READ + %This is a write sequence + + h5write(save_path, chan_name, ... + cur_chan.getData(iRecord,'leave_raw',true,'return_object',false)); + else + + start_I = 1:MAX_SAMPLES_PER_READ:cur_n_samples; + end_I = MAX_SAMPLES_PER_READ:MAX_SAMPLES_PER_READ:cur_n_samples; + + if length(end_I) < length(start_I) + end_I(end+1) = cur_n_samples; %#ok + end + + for iChunk = 1:length(start_I) + cur_start = start_I(iChunk); + cur_end = end_I(iChunk); + n_samples_get = cur_end-cur_start + 1; + + data = cur_chan.getData(iRecord,'data_range',... + [cur_start,cur_start+n_samples_get-1],'leave_raw',true,... + 'return_object',false); + + + + h5write(save_path,chan_name,data,[cur_start 1],[length(data) 1],[1 1]) + end + end + end +end + + end \ No newline at end of file diff --git a/src/Import/labchart/adi/+adi/@file_viewer/file_viewer.m b/Import/labchart/adi/+adi/@file_viewer/file_viewer.m similarity index 96% rename from src/Import/labchart/adi/+adi/@file_viewer/file_viewer.m rename to Import/labchart/adi/+adi/@file_viewer/file_viewer.m index 347b232f..9ef01881 100644 --- a/src/Import/labchart/adi/+adi/@file_viewer/file_viewer.m +++ b/Import/labchart/adi/+adi/@file_viewer/file_viewer.m @@ -1,75 +1,75 @@ -classdef file_viewer - % - % Class: - % adi.file_viewer - % - - properties - end - - methods - function obj = file_viewer(file_path) - % - % obj = adi.file_viewer(file_path) - % - % See Also: - % --------- - % adi.view - - %TODO: - %--------------------------- - %- Display comments in panel - % - click on comment to go to comment - %X DONE Add title to figue window - %- manual ylims - create nice interface for this - %- support panning - %- build in processing support - filtering - %- add support for adding a channel - %- reorder channels - %- display comments on figures - %- allow saving viewing settings into a file for - % later retrieval - - f = adi.readFile(file_path); - h_figure = figure; - - for iChannel = 1:f.n_channels - cur_channel_name = f.channel_names{iChannel}; - chan_obj = f.getChannelByName(cur_channel_name,'partial_match',false); - - %TODO: Allow array retrieval of data for multiple records - all_chan_data = cell(1,f.n_records); - %all_chan_data = cell(1,1); - for iRecord = 1:f.n_records - if ~isnan(chan_obj.dt(iRecord)) - all_chan_data{iRecord} = chan_obj.getData(iRecord); - else - error('This causes problems with offsets, need to fix this') - all_chan_data{iRecord} = []; - end - end - - subplot(f.n_channels,1,iChannel); - plot([all_chan_data{:}]) - - end - - set(h_figure,'name',file_path); - sl.plot.postp.linkFigureAxes(h_figure,'x'); - - h_axes = sl.hg.figure.getAxes(h_figure); - - set(h_axes,'YLimMode','manual'); - - scroll = sl.plot.big_data.scrollbar(gca); - - sl.plot.postp.autoscale(h_axes) - - - keyboard - - end - end - -end - +classdef file_viewer + % + % Class: + % adi.file_viewer + % + + properties + end + + methods + function obj = file_viewer(file_path) + % + % obj = adi.file_viewer(file_path) + % + % See Also: + % --------- + % adi.view + + %TODO: + %--------------------------- + %- Display comments in panel + % - click on comment to go to comment + %X DONE Add title to figue window + %- manual ylims - create nice interface for this + %- support panning + %- build in processing support - filtering + %- add support for adding a channel + %- reorder channels + %- display comments on figures + %- allow saving viewing settings into a file for + % later retrieval + + f = adi.readFile(file_path); + h_figure = figure; + + for iChannel = 1:f.n_channels + cur_channel_name = f.channel_names{iChannel}; + chan_obj = f.getChannelByName(cur_channel_name,'partial_match',false); + + %TODO: Allow array retrieval of data for multiple records + all_chan_data = cell(1,f.n_records); + %all_chan_data = cell(1,1); + for iRecord = 1:f.n_records + if ~isnan(chan_obj.dt(iRecord)) + all_chan_data{iRecord} = chan_obj.getData(iRecord); + else + error('This causes problems with offsets, need to fix this') + all_chan_data{iRecord} = []; + end + end + + subplot(f.n_channels,1,iChannel); + plot([all_chan_data{:}]) + + end + + set(h_figure,'name',file_path); + sl.plot.postp.linkFigureAxes(h_figure,'x'); + + h_axes = sl.hg.figure.getAxes(h_figure); + + set(h_axes,'YLimMode','manual'); + + scroll = sl.plot.big_data.scrollbar(gca); + + sl.plot.postp.autoscale(h_axes) + + + keyboard + + end + end + +end + diff --git a/src/Import/labchart/adi/+adi/@file_viewer/private/main.fig b/Import/labchart/adi/+adi/@file_viewer/private/main.fig similarity index 100% rename from src/Import/labchart/adi/+adi/@file_viewer/private/main.fig rename to Import/labchart/adi/+adi/@file_viewer/private/main.fig diff --git a/src/Import/labchart/adi/+adi/channel_writer.m b/Import/labchart/adi/+adi/channel_writer.m similarity index 96% rename from src/Import/labchart/adi/+adi/channel_writer.m rename to Import/labchart/adi/+adi/channel_writer.m index e9b3669b..de2d1f34 100644 --- a/src/Import/labchart/adi/+adi/channel_writer.m +++ b/Import/labchart/adi/+adi/channel_writer.m @@ -1,102 +1,102 @@ -classdef (Hidden) channel_writer < handle - % - % Class: - % adi.channel_writer - % - % This is meant to be an interface - % - % adi.setChannelName(file_h,channel,channel_name) - % adi.sdk.setChannelInfo - % adi.sdk.addChannelSamples - - - properties - id - end - %*** These are currently not write safe - they don't get updated - properties - name - fs - units - enabled = true - samples_per_record - end - - properties (Hidden) - parent %adi.file_writer - end - - properties (Dependent) - duration_per_record - last_record_duration - current_record - end - - methods - function value = get.duration_per_record(obj) - value = obj.samples_per_record./obj.fs; - end - function value = get.current_record(obj) - value = obj.parent.current_record; - end - function value = get.last_record_duration(obj) - all_durations = obj.duration_per_record; - if isempty(all_durations) - value = NaN; - else - value = all_durations(end); - end - end - end - - methods - function obj = channel_writer(file_writer_obj,id,name,fs,units) - % - % - % adi.channel_writer(file_writer_obj,id,name,fs,units) - - obj.parent = file_writer_obj; - obj.id = id; - obj.name = name; - obj.fs = fs; - obj.units = units; - - obj.updateName(); - obj.updateInfo(); - end - function initializeRecord(objs,record_number) - % - % initializeRecord(objs,record_number) - % - for iObj = 1:length(objs) - obj = objs(iObj); - if length(obj.samples_per_record) < record_number - temp = obj.samples_per_record; - obj.samples_per_record = zeros(1,record_number); - obj.samples_per_record(1:length(temp)) = temp; - end - end - end - function updateName(obj) - file_h = obj.parent.file_h; - adi.sdk.setChannelName(file_h,obj.id,obj.name); - end - function updateInfo(obj) - writer_h = obj.parent.data_writer_h; - adi.sdk.setChannelInfo(writer_h,obj.id,1/obj.fs,obj.units,'enabled_for_record',obj.enabled); - end - function addSamples(obj,data) - % - % addSamples(obj,data) - - cur_record_local = obj.current_record; - n_samples = length(data); - obj.samples_per_record(cur_record_local) = obj.samples_per_record(cur_record_local) + n_samples; - - writer_h = obj.parent.data_writer_h; - adi.sdk.addChannelSamples(writer_h,obj.id,data) - end - end - -end - +classdef (Hidden) channel_writer < handle + % + % Class: + % adi.channel_writer + % + % This is meant to be an interface + % + % adi.setChannelName(file_h,channel,channel_name) + % adi.sdk.setChannelInfo + % adi.sdk.addChannelSamples + + + properties + id + end + %*** These are currently not write safe - they don't get updated + properties + name + fs + units + enabled = true + samples_per_record + end + + properties (Hidden) + parent %adi.file_writer + end + + properties (Dependent) + duration_per_record + last_record_duration + current_record + end + + methods + function value = get.duration_per_record(obj) + value = obj.samples_per_record./obj.fs; + end + function value = get.current_record(obj) + value = obj.parent.current_record; + end + function value = get.last_record_duration(obj) + all_durations = obj.duration_per_record; + if isempty(all_durations) + value = NaN; + else + value = all_durations(end); + end + end + end + + methods + function obj = channel_writer(file_writer_obj,id,name,fs,units) + % + % + % adi.channel_writer(file_writer_obj,id,name,fs,units) + + obj.parent = file_writer_obj; + obj.id = id; + obj.name = name; + obj.fs = fs; + obj.units = units; + + obj.updateName(); + obj.updateInfo(); + end + function initializeRecord(objs,record_number) + % + % initializeRecord(objs,record_number) + % + for iObj = 1:length(objs) + obj = objs(iObj); + if length(obj.samples_per_record) < record_number + temp = obj.samples_per_record; + obj.samples_per_record = zeros(1,record_number); + obj.samples_per_record(1:length(temp)) = temp; + end + end + end + function updateName(obj) + file_h = obj.parent.file_h; + adi.sdk.setChannelName(file_h,obj.id,obj.name); + end + function updateInfo(obj) + writer_h = obj.parent.data_writer_h; + adi.sdk.setChannelInfo(writer_h,obj.id,1/obj.fs,obj.units,'enabled_for_record',obj.enabled); + end + function addSamples(obj,data) + % + % addSamples(obj,data) + + cur_record_local = obj.current_record; + n_samples = length(data); + obj.samples_per_record(cur_record_local) = obj.samples_per_record(cur_record_local) + n_samples; + + writer_h = obj.parent.data_writer_h; + adi.sdk.addChannelSamples(writer_h,obj.id,data) + end + end + +end + diff --git a/src/Import/labchart/adi/+adi/comment.m b/Import/labchart/adi/+adi/comment.m similarity index 97% rename from src/Import/labchart/adi/+adi/comment.m rename to Import/labchart/adi/+adi/comment.m index 57942b21..a17224ff 100644 --- a/src/Import/labchart/adi/+adi/comment.m +++ b/Import/labchart/adi/+adi/comment.m @@ -1,169 +1,169 @@ -classdef (Hidden) comment < handle - % - % Class: - % adi.comment - % - % Holds a comment. - % - % NOTE: Comments can be moved after they are placed. I think - % this means that the comments might not be ordered by ID. - % - % Also comments can be deleted, which might cause gaps in the ID - % numbering as well. - - properties - str %The string content of the comment - id %The number associated with the comment, starts at ???? - tick_position %????????? - %TODO: Add time since start of record and experiment ... - channel %-1 indicates all channels - record %(#, not a pointer) - tick_dt - trigger_minus_rec_start %(in seconds) - end - - properties (Dependent) - time %Time in seconds since the start of the record. - end - - properties - d1 = '------ Options -----' - time_relative_to_file = true - end - - methods - function value = get.time(obj) - if obj.time_relative_to_file - value = obj.tick_position*obj.tick_dt; - else - value = obj.tick_position*obj.tick_dt + obj.trigger_minus_rec_start; - end - end - end - - methods - function obj = comment(comment_string,tick_pos,channel,comment_num,record_id,tick_dt,trigger_minus_rec_start) - - obj.str = comment_string; - obj.id = comment_num; - obj.tick_position = tick_pos; - obj.channel = channel; - obj.record = record_id; - obj.tick_dt = tick_dt; - obj.trigger_minus_rec_start = trigger_minus_rec_start; - end - % function objs = sortByID(objs) - % - % end - function changeTimeBasis(objs) - - end - function pretty_print(objs) - % - % - % Example Output: - % - % Format - % ID : time : str - % Record #04 - % 002: 315.85: start pump - % 003: 318.85: 5 ml/hr - % 004: 1624.55: stop pump - % 008: 1952.00: qp 1 - % 005: 2088.35: start pump - % 006: 2782.95: stop pump - % 007: 3011.50: qp 2 - - all_records = [objs.record]; - [u,uI] = adi.sl.array.uniqueWithGroupIndices(all_records); - - n_records = length(u); - - fprintf('Format\n'); - fprintf('ID : time : str\n'); - - for iRecord = 1:n_records - cur_record_indices = uI{iRecord}; - cur_record = u(iRecord); - n_indices = length(cur_record_indices); - - fprintf('Record #%02d\n',cur_record); - for iComment = 1:n_indices - cur_obj = objs(cur_record_indices(iComment)); - fprintf('%03d: %0.2f: %s\n',cur_obj.id,cur_obj.time,cur_obj.str); - end - end - end - function objs_out = filterByIDs(objs_in,ids_to_get,varargin) - % - % - % objs_out = filterByIDs(objs_in,ids_to_get,varargin) - - in.order = 'input_id'; - %Other orders: NYI - % - object order 1st object, 2nd 3rd, etc (based on order of - % objs_in => sort loc before returning ... - in = adi.sl.in.processVarargin(in,varargin); - - all_ids = [objs_in.id]; - - [mask,loc] = ismember(ids_to_get,all_ids); - - if ~all(mask) - error('One of the requested ids is missing') - end - - objs_out = objs_in(loc); - - - end - function objs_out = filterByRecord(objs_in,record_id) - keep_mask = [objs.record] == record_id; - objs_out = objs_in(keep_mask); - end - function objs_out = filterByTime(objs_in,time_range) - times = [objs_in.time]; - keep_mask = times >= time_range(1) & times <= time_range(2); - objs_out = objs_in(keep_mask); - end - function objs_out = filterByChannel(objs_in,channel_id) - channels = [kept_objs.channel]; - keep_mask = channels == -1 | channels == channel_id; - objs_out = objs_in(keep_mask); - end - end - methods - function exportToHDF5File(objs,fobj,save_path,conversion_options) - group_name = '/comments'; - h5m.group.create(fobj,'comment_version'); - h5writeatt(save_path,'/comment_version','version',1); - - h5m.group.create(fobj,group_name); - - %TODO: Rewrite with h5m library - %TODO: This needs to be fixed - h5writeatt(save_path,group_name,'str',int16(char({objs.str}))); - - h5writeatt(save_path,group_name,'id',[objs.id]); - h5writeatt(save_path,group_name,'tick_position',[objs.tick_position]); - h5writeatt(save_path,group_name,'channel',[objs.channel]); - h5writeatt(save_path,group_name,'record',[objs.record]); - h5writeatt(save_path,group_name,'tick_dt',[objs.tick_dt]); - end - function exportToMatFile(objs,m,conversion_options) - - m.comment_version = 1; - - m.comments = struct(... - 'str', {objs.str},... - 'id', {objs.id},... - 'tick_position', {objs.tick_position},... - 'channel', {objs.channel},... - 'record', {objs.record},... - 'tick_dt', {objs.tick_dt}); - - end - end - -end - +classdef (Hidden) comment < handle + % + % Class: + % adi.comment + % + % Holds a comment. + % + % NOTE: Comments can be moved after they are placed. I think + % this means that the comments might not be ordered by ID. + % + % Also comments can be deleted, which might cause gaps in the ID + % numbering as well. + + properties + str %The string content of the comment + id %The number associated with the comment, starts at ???? + tick_position %????????? + %TODO: Add time since start of record and experiment ... + channel %-1 indicates all channels + record %(#, not a pointer) + tick_dt + trigger_minus_rec_start %(in seconds) + end + + properties (Dependent) + time %Time in seconds since the start of the record. + end + + properties + d1 = '------ Options -----' + time_relative_to_file = true + end + + methods + function value = get.time(obj) + if obj.time_relative_to_file + value = obj.tick_position*obj.tick_dt; + else + value = obj.tick_position*obj.tick_dt + obj.trigger_minus_rec_start; + end + end + end + + methods + function obj = comment(comment_string,tick_pos,channel,comment_num,record_id,tick_dt,trigger_minus_rec_start) + + obj.str = comment_string; + obj.id = comment_num; + obj.tick_position = tick_pos; + obj.channel = channel; + obj.record = record_id; + obj.tick_dt = tick_dt; + obj.trigger_minus_rec_start = trigger_minus_rec_start; + end + % function objs = sortByID(objs) + % + % end + function changeTimeBasis(objs) + + end + function pretty_print(objs) + % + % + % Example Output: + % + % Format + % ID : time : str + % Record #04 + % 002: 315.85: start pump + % 003: 318.85: 5 ml/hr + % 004: 1624.55: stop pump + % 008: 1952.00: qp 1 + % 005: 2088.35: start pump + % 006: 2782.95: stop pump + % 007: 3011.50: qp 2 + + all_records = [objs.record]; + [u,uI] = adi.sl.array.uniqueWithGroupIndices(all_records); + + n_records = length(u); + + fprintf('Format\n'); + fprintf('ID : time : str\n'); + + for iRecord = 1:n_records + cur_record_indices = uI{iRecord}; + cur_record = u(iRecord); + n_indices = length(cur_record_indices); + + fprintf('Record #%02d\n',cur_record); + for iComment = 1:n_indices + cur_obj = objs(cur_record_indices(iComment)); + fprintf('%03d: %0.2f: %s\n',cur_obj.id,cur_obj.time,cur_obj.str); + end + end + end + function objs_out = filterByIDs(objs_in,ids_to_get,varargin) + % + % + % objs_out = filterByIDs(objs_in,ids_to_get,varargin) + + in.order = 'input_id'; + %Other orders: NYI + % - object order 1st object, 2nd 3rd, etc (based on order of + % objs_in => sort loc before returning ... + in = adi.sl.in.processVarargin(in,varargin); + + all_ids = [objs_in.id]; + + [mask,loc] = ismember(ids_to_get,all_ids); + + if ~all(mask) + error('One of the requested ids is missing') + end + + objs_out = objs_in(loc); + + + end + function objs_out = filterByRecord(objs_in,record_id) + keep_mask = [objs.record] == record_id; + objs_out = objs_in(keep_mask); + end + function objs_out = filterByTime(objs_in,time_range) + times = [objs_in.time]; + keep_mask = times >= time_range(1) & times <= time_range(2); + objs_out = objs_in(keep_mask); + end + function objs_out = filterByChannel(objs_in,channel_id) + channels = [kept_objs.channel]; + keep_mask = channels == -1 | channels == channel_id; + objs_out = objs_in(keep_mask); + end + end + methods + function exportToHDF5File(objs,fobj,save_path,conversion_options) + group_name = '/comments'; + h5m.group.create(fobj,'comment_version'); + h5writeatt(save_path,'/comment_version','version',1); + + h5m.group.create(fobj,group_name); + + %TODO: Rewrite with h5m library + %TODO: This needs to be fixed + h5writeatt(save_path,group_name,'str',int16(char({objs.str}))); + + h5writeatt(save_path,group_name,'id',[objs.id]); + h5writeatt(save_path,group_name,'tick_position',[objs.tick_position]); + h5writeatt(save_path,group_name,'channel',[objs.channel]); + h5writeatt(save_path,group_name,'record',[objs.record]); + h5writeatt(save_path,group_name,'tick_dt',[objs.tick_dt]); + end + function exportToMatFile(objs,m,conversion_options) + + m.comment_version = 1; + + m.comments = struct(... + 'str', {objs.str},... + 'id', {objs.id},... + 'tick_position', {objs.tick_position},... + 'channel', {objs.channel},... + 'record', {objs.record},... + 'tick_dt', {objs.tick_dt}); + + end + end + +end + diff --git a/src/Import/labchart/adi/+adi/comment_handle.m b/Import/labchart/adi/+adi/comment_handle.m similarity index 97% rename from src/Import/labchart/adi/+adi/comment_handle.m rename to Import/labchart/adi/+adi/comment_handle.m index 18badb01..76713c65 100644 --- a/src/Import/labchart/adi/+adi/comment_handle.m +++ b/Import/labchart/adi/+adi/comment_handle.m @@ -1,61 +1,61 @@ -classdef (Hidden) comment_handle < handle - % - % Class: - % adi.comment_handle - % - % This contains a handle that is needed by the SDK to get comments - % for a particular record. Methods in this class can be used to - % extract actual comments from a record. - % - % See Also: - % adi.comment - - - properties - pointer_value %Pointer to the a commenct accessor object in the mex - %code. This gets cast to ADI_CommentsHandle in the mex code. This - %shouldn't be changed ... - - is_valid = false %A handle may not be valid if there are no comments - %for a given record - record - tick_dt - file_name - trigger_minus_rec_start - end - - methods - function obj = comment_handle(file_name,pointer_value,is_valid,record_id,tick_dt,trigger_minus_rec_start) - % - % obj = adi.comment_handle(pointer_value,is_valid) - - obj.file_name = file_name; - obj.pointer_value = pointer_value; - obj.is_valid = is_valid; - obj.record = record_id; - obj.tick_dt = tick_dt; - obj.trigger_minus_rec_start = trigger_minus_rec_start; - end - function delete(obj) - if ~obj.is_valid - return - end - %fprintf(2,'ADI SDK: Deleting comment: %s\n',obj.file_name); - adi.sdk.closeCommentAccessor(obj.pointer_value); - end - function has_another_comment = advanceCommentPointer(obj) - has_another_comment = adi.sdk.advanceComments(obj); - end - function cur_comment = getCurrentComment(obj) - cur_comment = adi.sdk.getCommentInfo(obj); - end - function close(obj) - %fprintf(2,'ADI SDK: Closing comment: %s\n',obj.file_name); - adi.sdk.closeCommentAccessor(obj.pointer_value); - obj.is_valid = false; - end - end - - -end - +classdef (Hidden) comment_handle < handle + % + % Class: + % adi.comment_handle + % + % This contains a handle that is needed by the SDK to get comments + % for a particular record. Methods in this class can be used to + % extract actual comments from a record. + % + % See Also: + % adi.comment + + + properties + pointer_value %Pointer to the a commenct accessor object in the mex + %code. This gets cast to ADI_CommentsHandle in the mex code. This + %shouldn't be changed ... + + is_valid = false %A handle may not be valid if there are no comments + %for a given record + record + tick_dt + file_name + trigger_minus_rec_start + end + + methods + function obj = comment_handle(file_name,pointer_value,is_valid,record_id,tick_dt,trigger_minus_rec_start) + % + % obj = adi.comment_handle(pointer_value,is_valid) + + obj.file_name = file_name; + obj.pointer_value = pointer_value; + obj.is_valid = is_valid; + obj.record = record_id; + obj.tick_dt = tick_dt; + obj.trigger_minus_rec_start = trigger_minus_rec_start; + end + function delete(obj) + if ~obj.is_valid + return + end + %fprintf(2,'ADI SDK: Deleting comment: %s\n',obj.file_name); + adi.sdk.closeCommentAccessor(obj.pointer_value); + end + function has_another_comment = advanceCommentPointer(obj) + has_another_comment = adi.sdk.advanceComments(obj); + end + function cur_comment = getCurrentComment(obj) + cur_comment = adi.sdk.getCommentInfo(obj); + end + function close(obj) + %fprintf(2,'ADI SDK: Closing comment: %s\n',obj.file_name); + adi.sdk.closeCommentAccessor(obj.pointer_value); + obj.is_valid = false; + end + end + + +end + diff --git a/src/Import/labchart/adi/+adi/convert.m b/Import/labchart/adi/+adi/convert.m similarity index 96% rename from src/Import/labchart/adi/+adi/convert.m rename to Import/labchart/adi/+adi/convert.m index 4ac3729a..04575a2d 100644 --- a/src/Import/labchart/adi/+adi/convert.m +++ b/Import/labchart/adi/+adi/convert.m @@ -1,142 +1,142 @@ -function save_path = convert(file_path_or_paths,varargin) -% -% adi.convert(*file_path,varargin) -% -% This function will save a .adicht file's contents into a .mat file -% (v7.3) or a hdf5 file -% -% The format is a bit awkward since it was originally written using a -% 32bit SDK which meant that partial reads and writes needed to be -% supported. -% -% Once converted, the converted file can be read by this program as well. -% -% Current Status: -% --------------- -% Things are working however the HDF5 format will likely change soon as I -% develop my HDF5 Matlab library: -% https://github.com/JimHokanson/hdf5_matlab -% -% Optional Inputs: -% ---------------- -% file_path_or_paths : str or cellstr (default: prompts user) -% Path to the file or files. If omitted a prompt will ask the user -% to select the file to convert. -% format : {'h5','mat'} (default 'mat') -% The format to convert the file to. H5 (HDF5) requires additional -% code, located at: -% https://github.com/JimHokanson/hdf5_matlab -% conversion_options: {adi.h5_conversion_options OR adi.mat_conversion_options} -% These classes provide access to the conversion options. The main -% point of these options (at least initially) was to have control -% over options that impact how fast the data is written (and then -% subsequently written) -% save_path : -% Final file save path. This is not recommended for multiple files to -% convert -% save_root : -% Folder to save converted files in. See also "root_path" -% root_path : -% If this is specified in addition to save_root then files are saved -% in deeper directories after swapping this value for save_root. In -% other words a file at data/type_1/ coulde be moved to -% new_data/type_1 either via save_root = 'new_data/type_1' or more -% generically for other files in 'data' via: -% save_root = 'new_data' -% root_path = 'data' -% -% Examples: -% --------- -% -% -% -% See Also: -% adi.h5_conversion_options -% adi.h5_mat_conversion_options - -persistent base_path - -in.conversion_options = []; %{adi.mat_conversion_options, adi.h5_conversion_options} -in.format = 'mat'; %or 'h5' -in.save_path = ''; -in.save_root = ''; -in.root_path = ''; %To match for save root -in.no_exist_only = false; -in = adi.sl.in.processVarargin(in,varargin); - -if in.format(1) == '.' - in.format(1) = []; -end - -if nargin == 0 || isempty(file_path_or_paths) - - [file_path_or_paths,file_root] = adi.uiGetChartFile('prompt','Pick a file to convert','start_path',base_path,'multi_select',true); - - if isnumeric(file_path_or_paths) - return - end - - base_path = file_root; - -else - if ischar(file_path_or_paths) - base_path = fileparts(file_path_or_paths); - else - base_path = fileparts(file_path_or_paths{1}); - end -end - -for iFile = 1:length(file_path_or_paths) - - cur_file_path = file_path_or_paths{iFile}; - - save_path = h__getSavePath(in,cur_file_path); - -% % % if ~isempty(save_path) -% % % -% % % end -% % % -% % % if in.no_exist_only && exist( - - file_obj = adi.readFile(cur_file_path); - - %This is a hack ... - - - switch in.format - case 'h5' - %adi.file.exportToMatFile - save_path = file_obj.exportToHDF5File(save_path,in.conversion_options); - case 'mat' - %adi.file.exportToMatFile - save_path = file_obj.exportToMatFile(save_path,in.conversion_options); - otherwise - error('Unrecognized format option: %s',in.format); - end - -end -end - -function save_path = h__getSavePath(in,cur_file_path) -% -%Save to the save_root. Preserve structure if root path is specified. - -[file_root_path,file_name] = fileparts(cur_file_path); - -if isempty(in.save_root) - %If empty the converter will save it next to the original file - save_path = in.save_path; -else - if isempty(in.root_path) - save_path = fullfile(in.save_root,file_name); - else - if strncmp(in.root_path,file_root_path,length(in.root_path)) - start_I = length(in.root_path)+1; - extra_path = file_root_path(start_I:end); - save_path = fullfile(in.save_root,extra_path,file_name); - else - error('root path needs to be in the file path being converted') - end - end -end +function save_path = convert(file_path_or_paths,varargin) +% +% adi.convert(*file_path,varargin) +% +% This function will save a .adicht file's contents into a .mat file +% (v7.3) or a hdf5 file +% +% The format is a bit awkward since it was originally written using a +% 32bit SDK which meant that partial reads and writes needed to be +% supported. +% +% Once converted, the converted file can be read by this program as well. +% +% Current Status: +% --------------- +% Things are working however the HDF5 format will likely change soon as I +% develop my HDF5 Matlab library: +% https://github.com/JimHokanson/hdf5_matlab +% +% Optional Inputs: +% ---------------- +% file_path_or_paths : str or cellstr (default: prompts user) +% Path to the file or files. If omitted a prompt will ask the user +% to select the file to convert. +% format : {'h5','mat'} (default 'mat') +% The format to convert the file to. H5 (HDF5) requires additional +% code, located at: +% https://github.com/JimHokanson/hdf5_matlab +% conversion_options: {adi.h5_conversion_options OR adi.mat_conversion_options} +% These classes provide access to the conversion options. The main +% point of these options (at least initially) was to have control +% over options that impact how fast the data is written (and then +% subsequently written) +% save_path : +% Final file save path. This is not recommended for multiple files to +% convert +% save_root : +% Folder to save converted files in. See also "root_path" +% root_path : +% If this is specified in addition to save_root then files are saved +% in deeper directories after swapping this value for save_root. In +% other words a file at data/type_1/ coulde be moved to +% new_data/type_1 either via save_root = 'new_data/type_1' or more +% generically for other files in 'data' via: +% save_root = 'new_data' +% root_path = 'data' +% +% Examples: +% --------- +% +% +% +% See Also: +% adi.h5_conversion_options +% adi.h5_mat_conversion_options + +persistent base_path + +in.conversion_options = []; %{adi.mat_conversion_options, adi.h5_conversion_options} +in.format = 'mat'; %or 'h5' +in.save_path = ''; +in.save_root = ''; +in.root_path = ''; %To match for save root +in.no_exist_only = false; +in = adi.sl.in.processVarargin(in,varargin); + +if in.format(1) == '.' + in.format(1) = []; +end + +if nargin == 0 || isempty(file_path_or_paths) + + [file_path_or_paths,file_root] = adi.uiGetChartFile('prompt','Pick a file to convert','start_path',base_path,'multi_select',true); + + if isnumeric(file_path_or_paths) + return + end + + base_path = file_root; + +else + if ischar(file_path_or_paths) + base_path = fileparts(file_path_or_paths); + else + base_path = fileparts(file_path_or_paths{1}); + end +end + +for iFile = 1:length(file_path_or_paths) + + cur_file_path = file_path_or_paths{iFile}; + + save_path = h__getSavePath(in,cur_file_path); + +% % % if ~isempty(save_path) +% % % +% % % end +% % % +% % % if in.no_exist_only && exist( + + file_obj = adi.readFile(cur_file_path); + + %This is a hack ... + + + switch in.format + case 'h5' + %adi.file.exportToMatFile + save_path = file_obj.exportToHDF5File(save_path,in.conversion_options); + case 'mat' + %adi.file.exportToMatFile + save_path = file_obj.exportToMatFile(save_path,in.conversion_options); + otherwise + error('Unrecognized format option: %s',in.format); + end + +end +end + +function save_path = h__getSavePath(in,cur_file_path) +% +%Save to the save_root. Preserve structure if root path is specified. + +[file_root_path,file_name] = fileparts(cur_file_path); + +if isempty(in.save_root) + %If empty the converter will save it next to the original file + save_path = in.save_path; +else + if isempty(in.root_path) + save_path = fullfile(in.save_root,file_name); + else + if strncmp(in.root_path,file_root_path,length(in.root_path)) + start_I = length(in.root_path)+1; + extra_path = file_root_path(start_I:end); + save_path = fullfile(in.save_root,extra_path,file_name); + else + error('root path needs to be in the file path being converted') + end + end +end end \ No newline at end of file diff --git a/src/Import/labchart/adi/+adi/createFile.m b/Import/labchart/adi/+adi/createFile.m similarity index 95% rename from src/Import/labchart/adi/+adi/createFile.m rename to Import/labchart/adi/+adi/createFile.m index 8d696cfb..52631608 100644 --- a/src/Import/labchart/adi/+adi/createFile.m +++ b/Import/labchart/adi/+adi/createFile.m @@ -1,35 +1,35 @@ -function file_writer = createFile(file_path,varargin) -% -% file_writer = adi.createFile(file_path) -% -% This is a work in progress -% - -in.copy_blank_when_new = false; -in = adi.sl.in.processVarargin(in,varargin); - -is_new = ~exist(file_path,'file'); - -%Possibilities -%1) create new file de novo -%2) create new file using a copy of a blank file as a starting point -%3) edit a file that already exists - -if is_new - if in.copy_blank_when_new - adi.createBlankFileAtPath(file_path) - file_h = adi.sdk.openFile(file_path,'read_and_write',true); - else - file_h = adi.sdk.createFile(file_path); - end -else - file_h = adi.sdk.openFile(file_path,'read_and_write',true); -end -%file_h : adi.file_handle - -data_writer_h = adi.sdk.createDataWriter(file_h); -%data_writer_h : adi.data_writer_handle - -file_writer = adi.file_writer(file_path, file_h, data_writer_h, is_new); - +function file_writer = createFile(file_path,varargin) +% +% file_writer = adi.createFile(file_path) +% +% This is a work in progress +% + +in.copy_blank_when_new = false; +in = adi.sl.in.processVarargin(in,varargin); + +is_new = ~exist(file_path,'file'); + +%Possibilities +%1) create new file de novo +%2) create new file using a copy of a blank file as a starting point +%3) edit a file that already exists + +if is_new + if in.copy_blank_when_new + adi.createBlankFileAtPath(file_path) + file_h = adi.sdk.openFile(file_path,'read_and_write',true); + else + file_h = adi.sdk.createFile(file_path); + end +else + file_h = adi.sdk.openFile(file_path,'read_and_write',true); +end +%file_h : adi.file_handle + +data_writer_h = adi.sdk.createDataWriter(file_h); +%data_writer_h : adi.data_writer_handle + +file_writer = adi.file_writer(file_path, file_h, data_writer_h, is_new); + end \ No newline at end of file diff --git a/src/Import/labchart/adi/+adi/data_writer_handle.m b/Import/labchart/adi/+adi/data_writer_handle.m similarity index 95% rename from src/Import/labchart/adi/+adi/data_writer_handle.m rename to Import/labchart/adi/+adi/data_writer_handle.m index 4fe57a05..4c25b59a 100644 --- a/src/Import/labchart/adi/+adi/data_writer_handle.m +++ b/Import/labchart/adi/+adi/data_writer_handle.m @@ -1,25 +1,25 @@ -classdef (Hidden) data_writer_handle < handle - % - % Class: - % adi.data_writer_handle - % - % See Also: - % --------- - % adi.createFile - % adi.file_handle - - properties - pointer_value - end - - methods - function obj = data_writer_handle(pointer_value) - obj.pointer_value = pointer_value; - end - function delete(obj) - adi.sdk.closeWriter(obj.pointer_value) - end - end - -end - +classdef (Hidden) data_writer_handle < handle + % + % Class: + % adi.data_writer_handle + % + % See Also: + % --------- + % adi.createFile + % adi.file_handle + + properties + pointer_value + end + + methods + function obj = data_writer_handle(pointer_value) + obj.pointer_value = pointer_value; + end + function delete(obj) + adi.sdk.closeWriter(obj.pointer_value) + end + end + +end + diff --git a/src/Import/labchart/adi/+adi/documentation/FunctionMapping.csv b/Import/labchart/adi/+adi/documentation/FunctionMapping.csv similarity index 96% rename from src/Import/labchart/adi/+adi/documentation/FunctionMapping.csv rename to Import/labchart/adi/+adi/documentation/FunctionMapping.csv index 449cc8d8..623b96a0 100644 --- a/src/Import/labchart/adi/+adi/documentation/FunctionMapping.csv +++ b/Import/labchart/adi/+adi/documentation/FunctionMapping.csv @@ -1,31 +1,31 @@ -Header_Order,DLL Function Name,mex option,Matlab Name,Notes -1,ADI_OpenFile,0,openFile, -2,ADI_CreateFile,NYI,, -3,ADI_GetErrorMessage,14,, -4,ADI_TickToSamplePos,NYI,, -5,ADI_SamplePosToTick,NYI,, -6,ADI_GetNumberOfRecords,1,, -7,ADI_GetNumberOfChannels,2,, -8,ADI_GetNumTicksInRecord,3,, -9,ADI_GetRecordTickPeriod,4,, -10,ADI_GetNumSamplesInRecord,5,, -11,ADI_GetRecordSamplePeriod,15,getSamplePeriod, -12,ADI_GetRecordTime,16,, -13,ADI_CreateCommentsAccessor,6,, -14,ADI_CloseCommentsAccessor,7,, -15,ADI_GetCommentInfo,8,, -16,ADI_NextComment,9,, -17,ADI_GetSamples,10,, -18,ADI_GetUnitsName,11,, -19,ADI_GetChannelName,12,, -20,ADI_SetChannelName,NYI,, -21,ADI_CreateWriter,NYI,, -22,ADI_SetChannelInfo,NYI,, -23,ADI_StartRecord,NYI,, -24,ADI_AddChannelSamples,NYI,, -25,ADI_FinishRecord,NYI,, -26,ADI_CommitFile,NYI,, -27,ADI_CloseWriter,NYI,, -28,ADI_AddComment,NYI,, -29,ADI_DeleteComment,NYI,, -30,ADI_CloseFile,13,closeFile, +Header_Order,DLL Function Name,mex option,Matlab Name,Notes +1,ADI_OpenFile,0,openFile, +2,ADI_CreateFile,NYI,, +3,ADI_GetErrorMessage,14,, +4,ADI_TickToSamplePos,NYI,, +5,ADI_SamplePosToTick,NYI,, +6,ADI_GetNumberOfRecords,1,, +7,ADI_GetNumberOfChannels,2,, +8,ADI_GetNumTicksInRecord,3,, +9,ADI_GetRecordTickPeriod,4,, +10,ADI_GetNumSamplesInRecord,5,, +11,ADI_GetRecordSamplePeriod,15,getSamplePeriod, +12,ADI_GetRecordTime,16,, +13,ADI_CreateCommentsAccessor,6,, +14,ADI_CloseCommentsAccessor,7,, +15,ADI_GetCommentInfo,8,, +16,ADI_NextComment,9,, +17,ADI_GetSamples,10,, +18,ADI_GetUnitsName,11,, +19,ADI_GetChannelName,12,, +20,ADI_SetChannelName,NYI,, +21,ADI_CreateWriter,NYI,, +22,ADI_SetChannelInfo,NYI,, +23,ADI_StartRecord,NYI,, +24,ADI_AddChannelSamples,NYI,, +25,ADI_FinishRecord,NYI,, +26,ADI_CommitFile,NYI,, +27,ADI_CloseWriter,NYI,, +28,ADI_AddComment,NYI,, +29,ADI_DeleteComment,NYI,, +30,ADI_CloseFile,13,closeFile, diff --git a/src/Import/labchart/adi/+adi/documentation/com_interface_notes.m b/Import/labchart/adi/+adi/documentation/com_interface_notes.m similarity index 96% rename from src/Import/labchart/adi/+adi/documentation/com_interface_notes.m rename to Import/labchart/adi/+adi/documentation/com_interface_notes.m index bb4b83d4..20908fb4 100644 --- a/src/Import/labchart/adi/+adi/documentation/com_interface_notes.m +++ b/Import/labchart/adi/+adi/documentation/com_interface_notes.m @@ -1,122 +1,122 @@ -%This file was me messing around with the COM interface via .NET -% -%Due to the interface code I would need to write most of what I need in C# -%and then call my code. -% -%The COM interface exposes the raw data where as the C SDK only exposes -%data as floating point data (single). -% -%For now I'm going to hold off on doing anything with this approach. - - -%wtf = NET.addAssembly('C:\Users\Jim\Documents\ADInstruments\SimpleDataFileSDKCOM\DotNETInterop\bin\Debug\ADIDatIOWInLib.dll'); - - -base_path = 'C:\repos\matlab_git\ad_sdk\+adinstruments\private\interfaceConverterCode'; -adi_asm = NET.addAssembly(fullfile(base_path,'ADIDatIOWinLib.dll')); - -obj = ADIDatIOWinLib.ADIDataObject(); -t = adi_asm.AssemblyHandle.GetType('ADIDatIOWinLib.IADIDataReader'); - -adi_data = t.InvokeMember('GetADIData',System.Reflection.BindingFlags.InvokeMethod,[],obj,[]); - -%Inputs: -%1) function name -%2) System.Reflection.BindingFlags invokeAttr -%3) System.Reflection.Binder binder -%4) System.Object target -% - the created class -%5) Args -% - - -conv_asm = NET.addAssembly(fullfile(base_path,'interfaceConv.dll')); -%clark = ADIDatIOWinLib.ADIDataObject(); - -%wtf.OpenFileForRead('C:\Data\GSK\ChrisRaw\140113 pelvic and hypogastric nerve recordings.adicht') -wtf = interfaceConv.converter.getReader(obj,'C:\Data\GSK\ChrisRaw\140113 pelvic and hypogastric nerve recordings.adicht'); - -file_path = 'C:\Data\GSK\ChrisRaw\140113 pelvic and hypogastric nerve recordings.mat'; -tic; -huh = load(file_path,'data__chan_4_rec_4'); -toc; - -tic; -fid = fopen(file_path,'r'); -arg = fread(fid,[1 Inf],'*uint8'); -fclose(fid); -toc; - - %wtf = c.getReader(clark); - - - - -%% Load Assembly -A = NET.addAssembly([pwd '\ClassLibrary1.dll']); -% Get Type information for the IClass interface -t = A.AssemblyHandle.GetType('ClassLibrary1.IClass'); -%% Create an object instance -obj = ClassLibrary1.Class1; -%% Call the method (through reflection) -% First define an Object[] for the inputs -inputs = NET.createArray('System.Object',1); -% Define the actual inputs -inputs(1) = System.String('World'); -% Call the method -t.InvokeMember('myFunction',System.Reflection.BindingFlags.InvokeMethod,[],obj,inputs) - - -%{ -Structures: - 'ADIDatIOWinLib.ADIChannelId' - 'ADIDatIOWinLib.ADIPosition' - 'ADIDatIOWinLib.ADIRational64' - 'ADIDatIOWinLib.ADIScaling' - 'ADIDatIOWinLib.ADITimeDate' - 'ADIDatIOWinLib.BaseUnitsInfo' - 'ADIDatIOWinLib.ChannelYDataRange' - 'ADIDatIOWinLib.ChartCommentPos' - 'ADIDatIOWinLib.RecordTimeInfo' - 'ADIDatIOWinLib.TTickToSample' - 'ADIDatIOWinLib.UserUnitsInfo' -Enums: - 'ADIDatIOWinLib.ADICommentFlags' - 'ADIDatIOWinLib.ADIDataFlags' - 'ADIDatIOWinLib.ADIDataType' - 'ADIDatIOWinLib.ADIDataValueId' - 'ADIDatIOWinLib.ADIEnumDataType' - 'ADIDatIOWinLib.ADIFileOpenFlags' - 'ADIDatIOWinLib.ADIRecordFlags' - 'ADIDatIOWinLib.ADIReservedFlags' - 'ADIDatIOWinLib.EnumCommentFlags' - 'ADIDatIOWinLib.EventFindTypes' - 'ADIDatIOWinLib.TimeDisplayMode' - 'ADIDatIOWinLib.UnitPrefix' -Interfaces: - 'ADIDatIOWinLib.IADIComment' - 'ADIDatIOWinLib.IADIData' - 'ADIDatIOWinLib.IADIDataReader' - 'ADIDatIOWinLib.IADIDataSink' - 'ADIDatIOWinLib.IADIDataWriter' - 'ADIDatIOWinLib.IAutoADIString' - 'ADIDatIOWinLib.IEnumADIComment' - 'ADIDatIOWinLib.IEnumExBase' - 'ADIDatIOWinLib.IEnumFloatEx' - 'ADIDatIOWinLib.IEnumShortEx' - -%} - -reader = cast(clark,'ADIDatIOWinLib.IADIDataReader') - - -wtf = ADIDatIOWinLib.IADIDataReader(clark) - -%'System.Type requestedType') -%{ - -ADIDatIOWinLib.ADIDataObject dataObject = new ADIDatIOWinLib.ADIDataObject(); -ADIDatIOWinLib.IADIDataReader reader = (ADIDatIOWinLib.IADIDataReader)dataObject; -reader.OpenFileForRead(filePath); -mADIData = reader.GetADIData(); - +%This file was me messing around with the COM interface via .NET +% +%Due to the interface code I would need to write most of what I need in C# +%and then call my code. +% +%The COM interface exposes the raw data where as the C SDK only exposes +%data as floating point data (single). +% +%For now I'm going to hold off on doing anything with this approach. + + +%wtf = NET.addAssembly('C:\Users\Jim\Documents\ADInstruments\SimpleDataFileSDKCOM\DotNETInterop\bin\Debug\ADIDatIOWInLib.dll'); + + +base_path = 'C:\repos\matlab_git\ad_sdk\+adinstruments\private\interfaceConverterCode'; +adi_asm = NET.addAssembly(fullfile(base_path,'ADIDatIOWinLib.dll')); + +obj = ADIDatIOWinLib.ADIDataObject(); +t = adi_asm.AssemblyHandle.GetType('ADIDatIOWinLib.IADIDataReader'); + +adi_data = t.InvokeMember('GetADIData',System.Reflection.BindingFlags.InvokeMethod,[],obj,[]); + +%Inputs: +%1) function name +%2) System.Reflection.BindingFlags invokeAttr +%3) System.Reflection.Binder binder +%4) System.Object target +% - the created class +%5) Args +% - + +conv_asm = NET.addAssembly(fullfile(base_path,'interfaceConv.dll')); +%clark = ADIDatIOWinLib.ADIDataObject(); + +%wtf.OpenFileForRead('C:\Data\GSK\ChrisRaw\140113 pelvic and hypogastric nerve recordings.adicht') +wtf = interfaceConv.converter.getReader(obj,'C:\Data\GSK\ChrisRaw\140113 pelvic and hypogastric nerve recordings.adicht'); + +file_path = 'C:\Data\GSK\ChrisRaw\140113 pelvic and hypogastric nerve recordings.mat'; +tic; +huh = load(file_path,'data__chan_4_rec_4'); +toc; + +tic; +fid = fopen(file_path,'r'); +arg = fread(fid,[1 Inf],'*uint8'); +fclose(fid); +toc; + + %wtf = c.getReader(clark); + + + + +%% Load Assembly +A = NET.addAssembly([pwd '\ClassLibrary1.dll']); +% Get Type information for the IClass interface +t = A.AssemblyHandle.GetType('ClassLibrary1.IClass'); +%% Create an object instance +obj = ClassLibrary1.Class1; +%% Call the method (through reflection) +% First define an Object[] for the inputs +inputs = NET.createArray('System.Object',1); +% Define the actual inputs +inputs(1) = System.String('World'); +% Call the method +t.InvokeMember('myFunction',System.Reflection.BindingFlags.InvokeMethod,[],obj,inputs) + + +%{ +Structures: + 'ADIDatIOWinLib.ADIChannelId' + 'ADIDatIOWinLib.ADIPosition' + 'ADIDatIOWinLib.ADIRational64' + 'ADIDatIOWinLib.ADIScaling' + 'ADIDatIOWinLib.ADITimeDate' + 'ADIDatIOWinLib.BaseUnitsInfo' + 'ADIDatIOWinLib.ChannelYDataRange' + 'ADIDatIOWinLib.ChartCommentPos' + 'ADIDatIOWinLib.RecordTimeInfo' + 'ADIDatIOWinLib.TTickToSample' + 'ADIDatIOWinLib.UserUnitsInfo' +Enums: + 'ADIDatIOWinLib.ADICommentFlags' + 'ADIDatIOWinLib.ADIDataFlags' + 'ADIDatIOWinLib.ADIDataType' + 'ADIDatIOWinLib.ADIDataValueId' + 'ADIDatIOWinLib.ADIEnumDataType' + 'ADIDatIOWinLib.ADIFileOpenFlags' + 'ADIDatIOWinLib.ADIRecordFlags' + 'ADIDatIOWinLib.ADIReservedFlags' + 'ADIDatIOWinLib.EnumCommentFlags' + 'ADIDatIOWinLib.EventFindTypes' + 'ADIDatIOWinLib.TimeDisplayMode' + 'ADIDatIOWinLib.UnitPrefix' +Interfaces: + 'ADIDatIOWinLib.IADIComment' + 'ADIDatIOWinLib.IADIData' + 'ADIDatIOWinLib.IADIDataReader' + 'ADIDatIOWinLib.IADIDataSink' + 'ADIDatIOWinLib.IADIDataWriter' + 'ADIDatIOWinLib.IAutoADIString' + 'ADIDatIOWinLib.IEnumADIComment' + 'ADIDatIOWinLib.IEnumExBase' + 'ADIDatIOWinLib.IEnumFloatEx' + 'ADIDatIOWinLib.IEnumShortEx' + +%} + +reader = cast(clark,'ADIDatIOWinLib.IADIDataReader') + + +wtf = ADIDatIOWinLib.IADIDataReader(clark) + +%'System.Type requestedType') +%{ + +ADIDatIOWinLib.ADIDataObject dataObject = new ADIDatIOWinLib.ADIDataObject(); +ADIDatIOWinLib.IADIDataReader reader = (ADIDatIOWinLib.IADIDataReader)dataObject; +reader.OpenFileForRead(filePath); +mADIData = reader.GetADIData(); + %} \ No newline at end of file diff --git a/src/Import/labchart/adi/+adi/editFile.m b/Import/labchart/adi/+adi/editFile.m similarity index 95% rename from src/Import/labchart/adi/+adi/editFile.m rename to Import/labchart/adi/+adi/editFile.m index 0bf2dcc1..80864d56 100644 --- a/src/Import/labchart/adi/+adi/editFile.m +++ b/Import/labchart/adi/+adi/editFile.m @@ -1,18 +1,18 @@ -function file_writer = editFile(file_path,varargin) -%x Open a file for editing -% -% file_writer = adi.editFile(file_path) -% -% - -if ~exist(file_path,'file') - error('File to edit doesn''t exist:\n%s',file_path) -end - -file_h = adi.sdk.openFile(file_path,'read_and_write',true); - -data_writer_h = adi.sdk.createDataWriter(file_h); - -file_writer = adi.file_writer(file_path, file_h, data_writer_h, false); - +function file_writer = editFile(file_path,varargin) +%x Open a file for editing +% +% file_writer = adi.editFile(file_path) +% +% + +if ~exist(file_path,'file') + error('File to edit doesn''t exist:\n%s',file_path) +end + +file_h = adi.sdk.openFile(file_path,'read_and_write',true); + +data_writer_h = adi.sdk.createDataWriter(file_h); + +file_writer = adi.file_writer(file_path, file_h, data_writer_h, false); + end \ No newline at end of file diff --git a/src/Import/labchart/adi/+adi/extractRecordToNewFile.m b/Import/labchart/adi/+adi/extractRecordToNewFile.m similarity index 96% rename from src/Import/labchart/adi/+adi/extractRecordToNewFile.m rename to Import/labchart/adi/+adi/extractRecordToNewFile.m index f93f34de..0829930d 100644 --- a/src/Import/labchart/adi/+adi/extractRecordToNewFile.m +++ b/Import/labchart/adi/+adi/extractRecordToNewFile.m @@ -1,90 +1,90 @@ -function extractRecordToNewFile(source_file_path,record_id,varargin) -% -% adi.extractRecordToNewFile(source_file_path,record_id,varargin) -% -% -% This is a bit buggy but I think it works ... -% -% Optional Inputs: -% ---------------- -% new_file_path: -% channels : cell array -% Names of channels whose data you would like to replace -% data : cell array -% Each element holds the new data to write to that channel -% - -%{ -%Example code: -%-------------------------------------------------------------------------- -source_file_path = 'F:\GSK\Rat_Expts\2014\edited\140919_J_01_Wistar_PudStim.adicht' -record_id = 7; - -file_h = adi.readFile(source_file_path); - -eus_chan = file_h.getChannelByName('eus'); - -raw_eus_data = eus_chan.getData(record_id,'return_object',false); - -raw_eus_data = 5*raw_eus_data; - -adi.extractRecordToNewFile(file_h,record_id,'channels',{eus_chan.name},'data',{raw_eus_data}) -%-------------------------------------------------------------------------- -%} - -%TODO: Add on ability to not include channels -%TODO: Allow passing in a file reference for the source file path -%TODO: Allow passing in a time limit -%TODO: Allow channel specs objects for channels -%TODO: Allow non-cell array inputs for channels and data - -in.new_file_path = ''; -in.channels = {}; -in.data = {}; -in = adi.sl.in.processVarargin(in,varargin); - -if isobject(source_file_path) - file_h = source_file_path; - source_file_path = file_h.file_path; -else - file_h = adi.readFile(source_file_path); -end - -if isempty(in.new_file_path) - [root_path,file_name] = fileparts(source_file_path); - new_file_name = sprintf('%s_record_%d.adicht',file_name,record_id); - in.new_file_path = fullfile(root_path,new_file_name); -end - -fw = adi.createFile(in.new_file_path,false); - - -chan_writer_handles = cell(1,file_h.n_channels); - -for iChan = 1:file_h.n_channels - cur_chan_info = file_h.channel_specs(iChan); - temp = fw.addChannel(iChan,cur_chan_info.name,... - cur_chan_info.fs(record_id),cur_chan_info.units{record_id}); - chan_writer_handles{iChan} = temp; -end - -fw.startRecord(); - -for iChan = 1:file_h.n_channels - cur_chan_writer = chan_writer_handles{iChan}; - cur_chan_reader = file_h.channel_specs(iChan); - I = find(strcmp(in.channels,cur_chan_reader.name)); - if isempty(I) - temp_data = cur_chan_reader.getData(record_id,'return_object',false,'leave_raw',true); - else - temp_data = single(in.data{I}); - end - cur_chan_writer.addSamples(temp_data); -end - -fw.stopRecord(); - -fw.save(); -fw.close(); - +function extractRecordToNewFile(source_file_path,record_id,varargin) +% +% adi.extractRecordToNewFile(source_file_path,record_id,varargin) +% +% +% This is a bit buggy but I think it works ... +% +% Optional Inputs: +% ---------------- +% new_file_path: +% channels : cell array +% Names of channels whose data you would like to replace +% data : cell array +% Each element holds the new data to write to that channel +% + +%{ +%Example code: +%-------------------------------------------------------------------------- +source_file_path = 'F:\GSK\Rat_Expts\2014\edited\140919_J_01_Wistar_PudStim.adicht' +record_id = 7; + +file_h = adi.readFile(source_file_path); + +eus_chan = file_h.getChannelByName('eus'); + +raw_eus_data = eus_chan.getData(record_id,'return_object',false); + +raw_eus_data = 5*raw_eus_data; + +adi.extractRecordToNewFile(file_h,record_id,'channels',{eus_chan.name},'data',{raw_eus_data}) +%-------------------------------------------------------------------------- +%} + +%TODO: Add on ability to not include channels +%TODO: Allow passing in a file reference for the source file path +%TODO: Allow passing in a time limit +%TODO: Allow channel specs objects for channels +%TODO: Allow non-cell array inputs for channels and data + +in.new_file_path = ''; +in.channels = {}; +in.data = {}; +in = adi.sl.in.processVarargin(in,varargin); + +if isobject(source_file_path) + file_h = source_file_path; + source_file_path = file_h.file_path; +else + file_h = adi.readFile(source_file_path); +end + +if isempty(in.new_file_path) + [root_path,file_name] = fileparts(source_file_path); + new_file_name = sprintf('%s_record_%d.adicht',file_name,record_id); + in.new_file_path = fullfile(root_path,new_file_name); +end + +fw = adi.createFile(in.new_file_path,false); + + +chan_writer_handles = cell(1,file_h.n_channels); + +for iChan = 1:file_h.n_channels + cur_chan_info = file_h.channel_specs(iChan); + temp = fw.addChannel(iChan,cur_chan_info.name,... + cur_chan_info.fs(record_id),cur_chan_info.units{record_id}); + chan_writer_handles{iChan} = temp; +end + +fw.startRecord(); + +for iChan = 1:file_h.n_channels + cur_chan_writer = chan_writer_handles{iChan}; + cur_chan_reader = file_h.channel_specs(iChan); + I = find(strcmp(in.channels,cur_chan_reader.name)); + if isempty(I) + temp_data = cur_chan_reader.getData(record_id,'return_object',false,'leave_raw',true); + else + temp_data = single(in.data{I}); + end + cur_chan_writer.addSamples(temp_data); +end + +fw.stopRecord(); + +fw.save(); +fw.close(); + end \ No newline at end of file diff --git a/src/Import/labchart/adi/+adi/file.m b/Import/labchart/adi/+adi/file.m similarity index 97% rename from src/Import/labchart/adi/+adi/file.m rename to Import/labchart/adi/+adi/file.m index aa3804aa..4ccce3d4 100644 --- a/src/Import/labchart/adi/+adi/file.m +++ b/Import/labchart/adi/+adi/file.m @@ -1,253 +1,253 @@ -classdef (Hidden) file < handle - % - % Class: - % adi.file - % - % ***** This object should be instantiated via adi.readFile ***** - % - % This is the root class for a Labchart file. It holds meta - % data and classes with more meta data. The channel classes can - % be used to actually get data. - % - % See Also: - % adi.readFile - - properties - file_path %Full path to the file from which this class was populated. - end - - properties (Hidden) - file_h - end - - properties - n_records - n_channels %# of channels in the file (across all records). This may - %be reduced if some channels have no data and the input options to - %the constructor specify to remove empty channels. - records %adi.record - channel_specs %adi.channel These classes hold information - %about each of the channels used. - end - - properties (Dependent) - channel_names - end - - methods - function value = get.channel_names(obj) - temp = obj.channel_specs; - if isempty(temp) - value = {}; - else - value = {temp.name}; - end - end - end - - %Constructor - %-------------------------------- - methods - function obj = file(file_path,file_h,sdk,in) - % - % This should be created by adi.readFile - % - % Inputs: - % ------- - % file_path : str - % The path of the file (for reference). - % file_h : adi.file_handle - % A reference to the actual file. - % sdk: {adi.sdk, adi.h5_file_sdk, mat_file_sdk} - % Calls are made to the SDK to interact with the file. - % in : adi.file_read_options - % Options for reading the file. - % - % See Also: - % adi.readFile - - obj.file_path = file_path; - obj.file_h = file_h; - - %Could try switching these to determine what is causing - %the crash. Is it records or the first call to the sdk after - %opening? Currently those 2 are the same. Flipping these 2 - %lines could disambiguate the situation. - obj.n_records = sdk.getNumberOfRecords(file_h); - temp_n_channels = sdk.getNumberOfChannels(file_h); - - - - %Get record objects - %------------------------------------------- - temp = cell(1,obj.n_records); - - for iRec = 1:obj.n_records - temp{iRec} = adi.record(file_h,sdk,iRec); - end - - obj.records = [temp{:}]; - - %Get channel objects - %------------------------------------------- - temp = cell(1,temp_n_channels); - - for iChan = 1:temp_n_channels - temp{iChan} = adi.channel(file_h,sdk,iChan,obj.records,file_path); - end - - obj.channel_specs = [temp{:}]; - - if in.remove_empty_channels - obj.channel_specs = obj.channel_specs.removeEmptyObjects(); - end - - if ~isempty(in.channels_remove) - mask = ismember(in.channels_remove,obj.channel_names); - if ~all(mask) - %Some of the channels that were requested to be removed - %are not in the file - %TODO: Print warning message - end - - mask = ismember(obj.channel_names,in.channels_remove); - obj.channel_specs(mask) = []; - end - obj.n_channels = length(obj.channel_specs); - end - end - methods - function all_comments = getAllComments(obj) - all_records = obj.records; - all_comments = [all_records.comments]; - end - function summarizeRecords(obj) - %x Not Yet Implemented - %For each record: - %# of comments - %which channels contain data - %duration of the record - keyboard - end - function chan = getChannelByName(obj,channel_name,varargin) - %x Returns channel object for a given channel name - % - % chan = ad_sdk.adi.getChannelByName(obj,channel_name,varargin) - % - % See Also: - % adi.channel.getChannelByName() - - in.case_sensitive = false; - in.partial_match = true; - in.multiple_channel_rule = 'error'; - in = adi.sl.in.processVarargin(in,varargin); - - temp = obj.channel_specs; - if isempty(temp) - error('Requested channel: %s, not found',channel_name) - end - - chan = temp.getChannelByName(channel_name,in); - end - end - - %TODO: These should be in their own class - %adi.io.mat.file & - %adi.io.h5.file - % - %Currently the SDK takes care of the loading, which bridges the gap - %of knowledge of the file contents ... i.e. this file knows write - %contents but the SDK needs to know how to read - %File Methods - methods - function save_path = exportToHDF5File(obj,save_path,conversion_options) - %x Exports contents to a HDF5 file. - % - % This is similiar to the v7.3 mat files but by calling the - % HDF5 library functions directly we can control how the data - % are saved. - % - % See Also: - % adi.record.exportToHDF5File - % adi.channel.exportToHDF5File - - if nargin < 3 || isempty(conversion_options) - conversion_options = adi.h5_conversion_options; - end - - if ~exist('save_path','var') || isempty(save_path) - save_path = adi.sl.dir.changeFileExtension(obj.file_path,'h5'); - else - save_path = adi.sl.dir.changeFileExtension(save_path,'h5'); - end - - if strcmp(save_path,obj.file_path) - error('Conversion path and file path are the same') - end - - if exist(save_path,'file') - delete(save_path); - end - - adi.sl.dir.createFolderIfNoExist(fileparts(save_path)); - - %TODO: I'd eventually like to use the h5m library I'm writing. - %This would change the calls to h5writteatt - - fobj = h5m.file.create(save_path); - h5m.group.create(fobj,'file'); - - %TODO: Replace with h5m library when ready - h5writeatt(save_path,'/','version',1); - h5writeatt(save_path,'/file','n_records',obj.n_records) - h5writeatt(save_path,'/file','n_channels',obj.n_channels) - - obj.records.exportToHDF5File(fobj,save_path,conversion_options); - obj.channel_specs.exportToHDF5File(fobj,save_path,conversion_options); - - end - function save_path = exportToMatFile(obj,save_path,conversion_options) - % - % Converts the file to a mat file. - % - % This is rediculously SLOW. Unfortunately we don't have much - % control over how mat files are saved, even though the - % underlying HDF5 format provides tons of flexibility. To - % remedy this problem the HDF5 conversion code was created. - - if nargin < 3 || isempty(conversion_options) - conversion_options = adi.mat_conversion_options; - end - - if ~exist('save_path','var') || isempty(save_path) - save_path = adi.sl.dir.changeFileExtension(obj.file_path,'mat'); - else - save_path = adi.sl.dir.changeFileExtension(save_path,'mat'); - end - - - - if strcmp(save_path,obj.file_path) - error('Conversion path and file path are the same') - end - - adi.sl.dir.createFolderIfNoExist(fileparts(save_path)); - - if exist(save_path,'file') - delete(save_path); - end - - %http://www.mathworks.com/help/matlab/ref/matfile.html - m = matfile(save_path); - - m.file_version = 1; - m.file_meta = struct('n_records',obj.n_records,'n_channels',obj.n_channels); - - obj.records.exportToMatFile(m,conversion_options); - obj.channel_specs.exportToMatFile(m,conversion_options) - - end - end - -end - +classdef (Hidden) file < handle + % + % Class: + % adi.file + % + % ***** This object should be instantiated via adi.readFile ***** + % + % This is the root class for a Labchart file. It holds meta + % data and classes with more meta data. The channel classes can + % be used to actually get data. + % + % See Also: + % adi.readFile + + properties + file_path %Full path to the file from which this class was populated. + end + + properties (Hidden) + file_h + end + + properties + n_records + n_channels %# of channels in the file (across all records). This may + %be reduced if some channels have no data and the input options to + %the constructor specify to remove empty channels. + records %adi.record + channel_specs %adi.channel These classes hold information + %about each of the channels used. + end + + properties (Dependent) + channel_names + end + + methods + function value = get.channel_names(obj) + temp = obj.channel_specs; + if isempty(temp) + value = {}; + else + value = {temp.name}; + end + end + end + + %Constructor + %-------------------------------- + methods + function obj = file(file_path,file_h,sdk,in) + % + % This should be created by adi.readFile + % + % Inputs: + % ------- + % file_path : str + % The path of the file (for reference). + % file_h : adi.file_handle + % A reference to the actual file. + % sdk: {adi.sdk, adi.h5_file_sdk, mat_file_sdk} + % Calls are made to the SDK to interact with the file. + % in : adi.file_read_options + % Options for reading the file. + % + % See Also: + % adi.readFile + + obj.file_path = file_path; + obj.file_h = file_h; + + %Could try switching these to determine what is causing + %the crash. Is it records or the first call to the sdk after + %opening? Currently those 2 are the same. Flipping these 2 + %lines could disambiguate the situation. + obj.n_records = sdk.getNumberOfRecords(file_h); + temp_n_channels = sdk.getNumberOfChannels(file_h); + + + + %Get record objects + %------------------------------------------- + temp = cell(1,obj.n_records); + + for iRec = 1:obj.n_records + temp{iRec} = adi.record(file_h,sdk,iRec); + end + + obj.records = [temp{:}]; + + %Get channel objects + %------------------------------------------- + temp = cell(1,temp_n_channels); + + for iChan = 1:temp_n_channels + temp{iChan} = adi.channel(file_h,sdk,iChan,obj.records,file_path); + end + + obj.channel_specs = [temp{:}]; + + if in.remove_empty_channels + obj.channel_specs = obj.channel_specs.removeEmptyObjects(); + end + + if ~isempty(in.channels_remove) + mask = ismember(in.channels_remove,obj.channel_names); + if ~all(mask) + %Some of the channels that were requested to be removed + %are not in the file + %TODO: Print warning message + end + + mask = ismember(obj.channel_names,in.channels_remove); + obj.channel_specs(mask) = []; + end + obj.n_channels = length(obj.channel_specs); + end + end + methods + function all_comments = getAllComments(obj) + all_records = obj.records; + all_comments = [all_records.comments]; + end + function summarizeRecords(obj) + %x Not Yet Implemented + %For each record: + %# of comments + %which channels contain data + %duration of the record + keyboard + end + function chan = getChannelByName(obj,channel_name,varargin) + %x Returns channel object for a given channel name + % + % chan = ad_sdk.adi.getChannelByName(obj,channel_name,varargin) + % + % See Also: + % adi.channel.getChannelByName() + + in.case_sensitive = false; + in.partial_match = true; + in.multiple_channel_rule = 'error'; + in = adi.sl.in.processVarargin(in,varargin); + + temp = obj.channel_specs; + if isempty(temp) + error('Requested channel: %s, not found',channel_name) + end + + chan = temp.getChannelByName(channel_name,in); + end + end + + %TODO: These should be in their own class + %adi.io.mat.file & + %adi.io.h5.file + % + %Currently the SDK takes care of the loading, which bridges the gap + %of knowledge of the file contents ... i.e. this file knows write + %contents but the SDK needs to know how to read + %File Methods + methods + function save_path = exportToHDF5File(obj,save_path,conversion_options) + %x Exports contents to a HDF5 file. + % + % This is similiar to the v7.3 mat files but by calling the + % HDF5 library functions directly we can control how the data + % are saved. + % + % See Also: + % adi.record.exportToHDF5File + % adi.channel.exportToHDF5File + + if nargin < 3 || isempty(conversion_options) + conversion_options = adi.h5_conversion_options; + end + + if ~exist('save_path','var') || isempty(save_path) + save_path = adi.sl.dir.changeFileExtension(obj.file_path,'h5'); + else + save_path = adi.sl.dir.changeFileExtension(save_path,'h5'); + end + + if strcmp(save_path,obj.file_path) + error('Conversion path and file path are the same') + end + + if exist(save_path,'file') + delete(save_path); + end + + adi.sl.dir.createFolderIfNoExist(fileparts(save_path)); + + %TODO: I'd eventually like to use the h5m library I'm writing. + %This would change the calls to h5writteatt + + fobj = h5m.file.create(save_path); + h5m.group.create(fobj,'file'); + + %TODO: Replace with h5m library when ready + h5writeatt(save_path,'/','version',1); + h5writeatt(save_path,'/file','n_records',obj.n_records) + h5writeatt(save_path,'/file','n_channels',obj.n_channels) + + obj.records.exportToHDF5File(fobj,save_path,conversion_options); + obj.channel_specs.exportToHDF5File(fobj,save_path,conversion_options); + + end + function save_path = exportToMatFile(obj,save_path,conversion_options) + % + % Converts the file to a mat file. + % + % This is rediculously SLOW. Unfortunately we don't have much + % control over how mat files are saved, even though the + % underlying HDF5 format provides tons of flexibility. To + % remedy this problem the HDF5 conversion code was created. + + if nargin < 3 || isempty(conversion_options) + conversion_options = adi.mat_conversion_options; + end + + if ~exist('save_path','var') || isempty(save_path) + save_path = adi.sl.dir.changeFileExtension(obj.file_path,'mat'); + else + save_path = adi.sl.dir.changeFileExtension(save_path,'mat'); + end + + + + if strcmp(save_path,obj.file_path) + error('Conversion path and file path are the same') + end + + adi.sl.dir.createFolderIfNoExist(fileparts(save_path)); + + if exist(save_path,'file') + delete(save_path); + end + + %http://www.mathworks.com/help/matlab/ref/matfile.html + m = matfile(save_path); + + m.file_version = 1; + m.file_meta = struct('n_records',obj.n_records,'n_channels',obj.n_channels); + + obj.records.exportToMatFile(m,conversion_options); + obj.channel_specs.exportToMatFile(m,conversion_options) + + end + end + +end + diff --git a/src/Import/labchart/adi/+adi/file_handle.m b/Import/labchart/adi/+adi/file_handle.m similarity index 96% rename from src/Import/labchart/adi/+adi/file_handle.m rename to Import/labchart/adi/+adi/file_handle.m index 7bfd3022..1deb48b3 100644 --- a/src/Import/labchart/adi/+adi/file_handle.m +++ b/Import/labchart/adi/+adi/file_handle.m @@ -1,37 +1,37 @@ -classdef (Hidden) file_handle < handle - % - % Class: - % adi.file_handle - % - % This class is simply meant to hold the reference to an open file. - % When no one holds it the file will be closed. - - properties - pointer_value %Pointer to the file object in the mex code. This gets - %cast to ADI_FileHandle in the mex code. - file_path - end - - methods - function obj = file_handle(pointer_value,file_path) - % - % Inputs: - % ------- - % pointer_value: - % file_path: - - obj.pointer_value = pointer_value; - obj.file_path = file_path; - end - function delete(obj) - % - % - % fprintf(2,'ADI SDK - Deleting file ref: %s\n',obj.file_name); - - adi.handle_logger.logOperation(obj.file_path,'closeFile',obj.pointer_value) - adi.sdk.closeFile(obj.pointer_value); - end - end - -end - +classdef (Hidden) file_handle < handle + % + % Class: + % adi.file_handle + % + % This class is simply meant to hold the reference to an open file. + % When no one holds it the file will be closed. + + properties + pointer_value %Pointer to the file object in the mex code. This gets + %cast to ADI_FileHandle in the mex code. + file_path + end + + methods + function obj = file_handle(pointer_value,file_path) + % + % Inputs: + % ------- + % pointer_value: + % file_path: + + obj.pointer_value = pointer_value; + obj.file_path = file_path; + end + function delete(obj) + % + % + % fprintf(2,'ADI SDK - Deleting file ref: %s\n',obj.file_name); + + adi.handle_logger.logOperation(obj.file_path,'closeFile',obj.pointer_value) + adi.sdk.closeFile(obj.pointer_value); + end + end + +end + diff --git a/src/Import/labchart/adi/+adi/file_read_options.m b/Import/labchart/adi/+adi/file_read_options.m similarity index 96% rename from src/Import/labchart/adi/+adi/file_read_options.m rename to Import/labchart/adi/+adi/file_read_options.m index a59a7d36..7bcfa61a 100644 --- a/src/Import/labchart/adi/+adi/file_read_options.m +++ b/Import/labchart/adi/+adi/file_read_options.m @@ -1,29 +1,29 @@ -classdef file_read_options < handle - % - % Class: - % adi.file_read_options - % - % Contains reading options. Currently this is for all file formats. - - properties %All file formats: - %adi.file - remove_empty_channels = true; %If true, channels without data for - %all records are removed. - channels_remove = {} %TODO: On setting ensure it is a cell array - % - % This should be a cell array of channels which you wish to not - % include when reading the file. - - %conversion_max_ - end - - properties %Mat file format only - load_all_mat_on_start = true; %Not yet linked to the method - %See: adi.mat_file_h - end - - methods - end - -end - +classdef file_read_options < handle + % + % Class: + % adi.file_read_options + % + % Contains reading options. Currently this is for all file formats. + + properties %All file formats: + %adi.file + remove_empty_channels = true; %If true, channels without data for + %all records are removed. + channels_remove = {} %TODO: On setting ensure it is a cell array + % + % This should be a cell array of channels which you wish to not + % include when reading the file. + + %conversion_max_ + end + + properties %Mat file format only + load_all_mat_on_start = true; %Not yet linked to the method + %See: adi.mat_file_h + end + + methods + end + +end + diff --git a/src/Import/labchart/adi/+adi/file_writer.m b/Import/labchart/adi/+adi/file_writer.m similarity index 97% rename from src/Import/labchart/adi/+adi/file_writer.m rename to Import/labchart/adi/+adi/file_writer.m index 9bc0e885..735f106a 100644 --- a/src/Import/labchart/adi/+adi/file_writer.m +++ b/Import/labchart/adi/+adi/file_writer.m @@ -1,323 +1,323 @@ -classdef (Hidden) file_writer < handle - % - % Class: - % adi.file_writer - % - % See Also: - % --------- - % adi.channel_writer - % - % - % SDK Calls: - % ---------- - % adi.sdk.commitFile - % adi.sdk.closeWriter - % adi.sdk.addComment - % adi.sdk.deleteComment - % adi.createFile - % - % ADI write operations - % -------------------- - % ADI_SetChannelName - % ADI_CreateWriter - % ADI_SetChannelInfo - % ADI_StartRecord - Starts the writer recording a new record, setting the trigger time. - % ADI_AddChannelSamples - Writes new data samples into the specified channel record. - % ADI_FinishRecord - Ends the current record being written by the writer. - % ADI_CommitFile - Ensures all changes to the file made via the writer session are written to the file. - % ADI_CloseWriter - Terminates the writer session and releases resources used by the session. - % ADI_AddComment - - - %{ - Comment editing setup - --------------------- - We'll have an array of comments but we'll need to access the delete and - add comment methods - - %} - - %{ - TODO: I need to determine how this interface should be organized. - I'd like to generate a set of commands that the user would execute then - implement those commands. - - 1) create file - 2) initialize channels - 3) start record - 4) add comments - 5) stop record - 6) repeat steps 2 - 5 - 7) commit and close file - ??? does it help to commit more frequently? - - %} - properties - file_path %Where we are writing to - current_record = NaN %NaN when not recording - last_record = 0 %will always point to last record completed - %0 indicates that no records have been recorded - record_durations %???? We can get this for - record_dts %We'll log this for every record - record_trigger_times %Unix time values (Units: s) - channels = {} %{adi.channel_writer} - - comments - end - - properties (Dependent) - current_channel_names - in_record_mode - end - - methods - function value = get.current_channel_names(obj) - temp = obj.channels; - n_chans = length(temp); - value = cell(1,n_chans); - for iChan = 1:n_chans - cur_chan = temp{iChan}; - if ~isempty(cur_chan) - value{iChan} = cur_chan.name; - end - end - end - function value = get.in_record_mode(obj) - value = ~isnan(obj.current_record); - end - end - - properties (Hidden) - is_new %Whether or not the file existed when created - file_h % - data_writer_h % - end - - methods - function obj = file_writer(file_path,file_h,data_writer_h,is_new) - % - % Call these to initialize this object: - % - adi.createFile() OR - % - adi.editFile - % - % obj = adi.file_writer(file_path,file_h) - % - % Inputs: - % ------- - % file_path : - % file_h : adi.file_handle - % data_writer_h : adi.data_writer_handle - % is_new : logical - % - % - % See Also: - % --------- - % adi.createFile - % adi.editFile - - obj.file_path = file_path; - obj.file_h = file_h; - obj.data_writer_h = data_writer_h; - - %TODO: If the file is not new, read in the channel and record - %specs from the file ... - obj.is_new = is_new; - if ~is_new - temp_file = adi.file(file_path,file_h,adi.sdk,adi.file_read_options); - obj.last_record = temp_file.n_records; - %TODO: Do we want to instantiate writers for all the - %channels ???? - Yes - % - - recorded_chan_specs = temp_file.channel_specs; - if ~isempty(recorded_chan_specs) - max_id = max([recorded_chan_specs.id]); - - chan_ca = cell(1,max_id); - for iChan = 1:length(recorded_chan_specs) - - cur_obj = recorded_chan_specs(iChan); - cur_id = cur_obj.id; - %* fs and units are on a record by record basis so we - %use the last ones - % - %TODO: If a channel was not used, we shouldn't add it - chan_ca{cur_id} = obj.addChannel(cur_id,cur_obj.name,cur_obj.fs(end),cur_obj.units{end}); - end - obj.channels = chan_ca; - end - - records = temp_file.records; - if ~isempty(records) - - obj.comments = [records.comments]; obj.record_durations = [records.duration]; - obj.record_dts = [records.tick_dt]; - % - %Need to add the record times - error('Not yet implemented') - end - end - end - function comment_number = addComment(obj,record,comment_time,comment_string,varargin) - %x Adds a comment to the specified record - % - % comment_number = addComment(obj,tick_position,comment_string,varargin) - % - % Inputs: - % ------- - % record : - % -1 means current record - % comment_time : - % Time is in seconds ... - % TODO: Clarify how this relates to the trigger - % and data start - % comment_string : string - % The actual text of the comment to add - % - % Optional Inputs: - % ---------------- - % channel : - % -1 indicates to add to all channels - % 1 - add to channel 1 - % 2 - add to channel 2 - % - % Outputs: - % -------- - % comment_number : numeric - % The resulting id of the comment. - % - % TODO: We could build in support to adding to channels - % by name - % TODO: Build check on the channel if it is out of range - - in.channel = -1; - in = adi.sl.in.processVarargin(in,varargin); - - %TODO: Check that record makes sense - %If -1, check that we are in a record - %otherwise, make sure record is between 1 and n records - if record == -1 - record = obj.current_record; - end - tick_position = round(comment_time/obj.record_dts(record)); - - comment_number = adi.sdk.addComment(obj.file_h,in.channel,record,tick_position,comment_string); - end - function deleteComment(obj,comment_number) - adi.sdk.deleteComment(obj.file_h,comment_number) - end - function new_chan = addChannel(obj,id,name,fs,units) - %x Add a channel that can be written to - % - % Inputs: - % ------- - % id : - % Channel number, starting at 1. These do not need to be - % continuous. - % name : string - % Name of the channel - % fs : numeric - % Sampling rate - % units : string - % Units of the measurement - % - % Outputs: - % -------- - % new_chan : - % - new_chan = adi.channel_writer(obj,id,name,fs,units); - - %TODO: Do I want to make an explicit delete call to an object - %if it is there - %temp = obj.channels{id}; - %if ~isempty(temp) - % temp.delete() - %end - obj.channels{id} = new_chan; - end - function startRecord(obj,varargin) - % - % Optional Inputs: - % ---------------- - % - % I think 'old_record' was meant to allow instantiating - % things based on the previous record - - in.record_to_copy = []; - %What are the units on trigger time??? - %This should probably be afer the last record, rather than now - in.trigger_time = []; - in.fractional_seconds = 0; - in.trigger_minus_rec_start = 0; - in = adi.sl.in.processVarargin(in,varargin); - - if obj.in_record_mode - error('Unable to start a record when in record mode already') - end - - obj.current_record = obj.last_record + 1; - - if ~isempty(in.record_to_copy) - %TODO: Populate in based on these properties ... - end - in = rmfield(in,'record_to_copy'); - - if isempty(in.trigger_time) - %If record 2, add duration of record 1 to this value - if obj.current_record > 1 - %trigger_times are in Unix time (seconds) - %Do we need to add a slight offset ???? - in.trigger_time = obj.record_trigger_times(end) + obj.record_durations(end)+30; - %Add duration of last record to last record start time - else - in.trigger_time = sl.datetime.matlabToUnix(now); - end - end - - all_chans = [obj.channels{:}]; - - all_chans.initializeRecord(obj.current_record); - - adi.sdk.startRecord(obj.data_writer_h,in); - - %in.trigger_time - - - %TODO: Check if the channel is enabled or not for determining - %which has the highest fs - highest_fs = max([all_chans.fs]); - obj.record_dts = [obj.record_dts 1/highest_fs]; - obj.record_trigger_times = [obj.record_trigger_times in.trigger_time]; - end - function stopRecord(obj) - obj.last_record = obj.current_record; - obj.current_record = NaN; - adi.sdk.finishRecord(obj.data_writer_h) - - channel_objects = [obj.channels{:}]; - channel_durations = [channel_objects.last_record_duration]; - obj.record_durations = [obj.record_durations max(channel_durations)]; - end - function save(obj) - adi.sdk.commitFile(obj.data_writer_h) - end - function delete(obj) - delete(obj.file_h) - %Why is this not working ???? - %Did I not implement it correctly? - % - %I think I might want this as a delete method in - %adi.data_writer_handle - %adi.sdk.closeWriter(obj.data_writer_h.pointer_value) - - %MOVED TO DELETE - end - %addChannel - end - - methods (Hidden) - function updateSampleCount(obj,channel_obj,n_samples) - %We may not need this ... - end - end - -end - +classdef (Hidden) file_writer < handle + % + % Class: + % adi.file_writer + % + % See Also: + % --------- + % adi.channel_writer + % + % + % SDK Calls: + % ---------- + % adi.sdk.commitFile + % adi.sdk.closeWriter + % adi.sdk.addComment + % adi.sdk.deleteComment + % adi.createFile + % + % ADI write operations + % -------------------- + % ADI_SetChannelName + % ADI_CreateWriter + % ADI_SetChannelInfo + % ADI_StartRecord - Starts the writer recording a new record, setting the trigger time. + % ADI_AddChannelSamples - Writes new data samples into the specified channel record. + % ADI_FinishRecord - Ends the current record being written by the writer. + % ADI_CommitFile - Ensures all changes to the file made via the writer session are written to the file. + % ADI_CloseWriter - Terminates the writer session and releases resources used by the session. + % ADI_AddComment - + + %{ + Comment editing setup + --------------------- + We'll have an array of comments but we'll need to access the delete and + add comment methods + + %} + + %{ + TODO: I need to determine how this interface should be organized. + I'd like to generate a set of commands that the user would execute then + implement those commands. + + 1) create file + 2) initialize channels + 3) start record + 4) add comments + 5) stop record + 6) repeat steps 2 - 5 + 7) commit and close file - ??? does it help to commit more frequently? + + %} + properties + file_path %Where we are writing to + current_record = NaN %NaN when not recording + last_record = 0 %will always point to last record completed + %0 indicates that no records have been recorded + record_durations %???? We can get this for + record_dts %We'll log this for every record + record_trigger_times %Unix time values (Units: s) + channels = {} %{adi.channel_writer} + + comments + end + + properties (Dependent) + current_channel_names + in_record_mode + end + + methods + function value = get.current_channel_names(obj) + temp = obj.channels; + n_chans = length(temp); + value = cell(1,n_chans); + for iChan = 1:n_chans + cur_chan = temp{iChan}; + if ~isempty(cur_chan) + value{iChan} = cur_chan.name; + end + end + end + function value = get.in_record_mode(obj) + value = ~isnan(obj.current_record); + end + end + + properties (Hidden) + is_new %Whether or not the file existed when created + file_h % + data_writer_h % + end + + methods + function obj = file_writer(file_path,file_h,data_writer_h,is_new) + % + % Call these to initialize this object: + % - adi.createFile() OR + % - adi.editFile + % + % obj = adi.file_writer(file_path,file_h) + % + % Inputs: + % ------- + % file_path : + % file_h : adi.file_handle + % data_writer_h : adi.data_writer_handle + % is_new : logical + % + % + % See Also: + % --------- + % adi.createFile + % adi.editFile + + obj.file_path = file_path; + obj.file_h = file_h; + obj.data_writer_h = data_writer_h; + + %TODO: If the file is not new, read in the channel and record + %specs from the file ... + obj.is_new = is_new; + if ~is_new + temp_file = adi.file(file_path,file_h,adi.sdk,adi.file_read_options); + obj.last_record = temp_file.n_records; + %TODO: Do we want to instantiate writers for all the + %channels ???? - Yes + % + + recorded_chan_specs = temp_file.channel_specs; + if ~isempty(recorded_chan_specs) + max_id = max([recorded_chan_specs.id]); + + chan_ca = cell(1,max_id); + for iChan = 1:length(recorded_chan_specs) + + cur_obj = recorded_chan_specs(iChan); + cur_id = cur_obj.id; + %* fs and units are on a record by record basis so we + %use the last ones + % + %TODO: If a channel was not used, we shouldn't add it + chan_ca{cur_id} = obj.addChannel(cur_id,cur_obj.name,cur_obj.fs(end),cur_obj.units{end}); + end + obj.channels = chan_ca; + end + + records = temp_file.records; + if ~isempty(records) + + obj.comments = [records.comments]; obj.record_durations = [records.duration]; + obj.record_dts = [records.tick_dt]; + % + %Need to add the record times + error('Not yet implemented') + end + end + end + function comment_number = addComment(obj,record,comment_time,comment_string,varargin) + %x Adds a comment to the specified record + % + % comment_number = addComment(obj,tick_position,comment_string,varargin) + % + % Inputs: + % ------- + % record : + % -1 means current record + % comment_time : + % Time is in seconds ... + % TODO: Clarify how this relates to the trigger + % and data start + % comment_string : string + % The actual text of the comment to add + % + % Optional Inputs: + % ---------------- + % channel : + % -1 indicates to add to all channels + % 1 - add to channel 1 + % 2 - add to channel 2 + % + % Outputs: + % -------- + % comment_number : numeric + % The resulting id of the comment. + % + % TODO: We could build in support to adding to channels + % by name + % TODO: Build check on the channel if it is out of range + + in.channel = -1; + in = adi.sl.in.processVarargin(in,varargin); + + %TODO: Check that record makes sense + %If -1, check that we are in a record + %otherwise, make sure record is between 1 and n records + if record == -1 + record = obj.current_record; + end + tick_position = round(comment_time/obj.record_dts(record)); + + comment_number = adi.sdk.addComment(obj.file_h,in.channel,record,tick_position,comment_string); + end + function deleteComment(obj,comment_number) + adi.sdk.deleteComment(obj.file_h,comment_number) + end + function new_chan = addChannel(obj,id,name,fs,units) + %x Add a channel that can be written to + % + % Inputs: + % ------- + % id : + % Channel number, starting at 1. These do not need to be + % continuous. + % name : string + % Name of the channel + % fs : numeric + % Sampling rate + % units : string + % Units of the measurement + % + % Outputs: + % -------- + % new_chan : + % + new_chan = adi.channel_writer(obj,id,name,fs,units); + + %TODO: Do I want to make an explicit delete call to an object + %if it is there + %temp = obj.channels{id}; + %if ~isempty(temp) + % temp.delete() + %end + obj.channels{id} = new_chan; + end + function startRecord(obj,varargin) + % + % Optional Inputs: + % ---------------- + % + % I think 'old_record' was meant to allow instantiating + % things based on the previous record + + in.record_to_copy = []; + %What are the units on trigger time??? + %This should probably be afer the last record, rather than now + in.trigger_time = []; + in.fractional_seconds = 0; + in.trigger_minus_rec_start = 0; + in = adi.sl.in.processVarargin(in,varargin); + + if obj.in_record_mode + error('Unable to start a record when in record mode already') + end + + obj.current_record = obj.last_record + 1; + + if ~isempty(in.record_to_copy) + %TODO: Populate in based on these properties ... + end + in = rmfield(in,'record_to_copy'); + + if isempty(in.trigger_time) + %If record 2, add duration of record 1 to this value + if obj.current_record > 1 + %trigger_times are in Unix time (seconds) + %Do we need to add a slight offset ???? + in.trigger_time = obj.record_trigger_times(end) + obj.record_durations(end)+30; + %Add duration of last record to last record start time + else + in.trigger_time = sl.datetime.matlabToUnix(now); + end + end + + all_chans = [obj.channels{:}]; + + all_chans.initializeRecord(obj.current_record); + + adi.sdk.startRecord(obj.data_writer_h,in); + + %in.trigger_time + + + %TODO: Check if the channel is enabled or not for determining + %which has the highest fs + highest_fs = max([all_chans.fs]); + obj.record_dts = [obj.record_dts 1/highest_fs]; + obj.record_trigger_times = [obj.record_trigger_times in.trigger_time]; + end + function stopRecord(obj) + obj.last_record = obj.current_record; + obj.current_record = NaN; + adi.sdk.finishRecord(obj.data_writer_h) + + channel_objects = [obj.channels{:}]; + channel_durations = [channel_objects.last_record_duration]; + obj.record_durations = [obj.record_durations max(channel_durations)]; + end + function save(obj) + adi.sdk.commitFile(obj.data_writer_h) + end + function delete(obj) + delete(obj.file_h) + %Why is this not working ???? + %Did I not implement it correctly? + % + %I think I might want this as a delete method in + %adi.data_writer_handle + %adi.sdk.closeWriter(obj.data_writer_h.pointer_value) + + %MOVED TO DELETE + end + %addChannel + end + + methods (Hidden) + function updateSampleCount(obj,channel_obj,n_samples) + %We may not need this ... + end + end + +end + diff --git a/src/Import/labchart/adi/+adi/h5_conversion_options.m b/Import/labchart/adi/+adi/h5_conversion_options.m similarity index 96% rename from src/Import/labchart/adi/+adi/h5_conversion_options.m rename to Import/labchart/adi/+adi/h5_conversion_options.m index a359e481..a528b763 100644 --- a/src/Import/labchart/adi/+adi/h5_conversion_options.m +++ b/Import/labchart/adi/+adi/h5_conversion_options.m @@ -1,33 +1,33 @@ -classdef h5_conversion_options < handle - % - % Class: - % adi.h5_conversion_options - % - % See Also: - % adi.channel.exportToHDF5File - - properties - max_samples_per_read = 1e8 - deflate_value = 3 %(0 - 9 for gzip - %0 - no compression - %9 - most compression - % - % NOTE: At some point with gzip the data fail to compress any - % more. - use_shuffle = false - chunk_length = 1e8 %Ideally this would be linked to - %'max_samples_per_read' but for now this is ok - end - - properties (Dependent) - chunk_length_pct - end - - methods - function set.chunk_length_pct(obj,value) - obj.chunk_length = round(obj.max_samples_per_read*value); - end - end - -end - +classdef h5_conversion_options < handle + % + % Class: + % adi.h5_conversion_options + % + % See Also: + % adi.channel.exportToHDF5File + + properties + max_samples_per_read = 1e8 + deflate_value = 3 %(0 - 9 for gzip + %0 - no compression + %9 - most compression + % + % NOTE: At some point with gzip the data fail to compress any + % more. + use_shuffle = false + chunk_length = 1e8 %Ideally this would be linked to + %'max_samples_per_read' but for now this is ok + end + + properties (Dependent) + chunk_length_pct + end + + methods + function set.chunk_length_pct(obj,value) + obj.chunk_length = round(obj.max_samples_per_read*value); + end + end + +end + diff --git a/src/Import/labchart/adi/+adi/h5_file_h.m b/Import/labchart/adi/+adi/h5_file_h.m similarity index 97% rename from src/Import/labchart/adi/+adi/h5_file_h.m rename to Import/labchart/adi/+adi/h5_file_h.m index 51d72448..0804abbb 100644 --- a/src/Import/labchart/adi/+adi/h5_file_h.m +++ b/Import/labchart/adi/+adi/h5_file_h.m @@ -1,108 +1,108 @@ -classdef (Hidden) h5_file_h < handle - % - % Class: - % adi.h5_file_h - - properties - file_path - m %Structure containing the meta data - end - - methods - function obj = h5_file_h(file_path) - % - % obj = adi.h5_file_h(file_path) - % - % See Also: - % adi.readFile - - %TODO: Since we are not using this right away, we might - %want to try and get the file path if it were evaluated - %currently (in case it is relative) - obj.file_path = file_path; - %obj.m = h5m.file.open(file_path); - - - %The general approach used below is to read all meta - %information into memory now. We attempt to mimic the format - %used when saving to a 'mat' format so that we can use the same - %SDK interface. - % - %In general I really dislike this approach and will eventually - %revert to functions that read and write structs. Also, the - %encapsulation is currently shot and needs to be fixed (writing - %and reading are separated) - %============================================================== - - %File - %------------------------------------- - rf = @(attr)h5readatt(file_path,'/file',attr); - file_struct = struct(... - 'n_records', rf('n_records'),... - 'n_channels', rf('n_channels')); - - %Records - %-------------------------------------- - rr = @(attr)num2cell(h5readatt(file_path,'/record_meta',attr)); - - record_struct = struct(... - 'n_ticks', rr('n_ticks'),... - 'tick_dt', rr('tick_dt'),... - 'record_start', rr('record_start'),... - 'data_start', rr('data_start'),... - 'trigger_minus_rec_start_samples', rr('trigger_minus_rec_start_samples'))'; - - %Comments - rco = @(attr)num2cell(h5readatt(file_path,'/comments',attr)); - - rs = @(attr,group_name)cellstr(char(h5readatt(file_path,group_name,attr))); - - % temp = h5readatt(file_path,'/comments','str'); - % comment_strs = cellstr(char(temp)); - - comment_struct = struct(... - 'str', rs('str','/comments'),... - 'id', rco('id'),... - 'tick_position',rco('tick_position'),... - 'channel', rco('channel'),... - 'record', rco('record'),... - 'tick_dt', rco('tick_dt'))'; - - %Channels - %----------------------------- - rch1 = @(attr)h5readatt(file_path,'/channel_meta',attr); - rch2 = @(attr)num2cell(rch1(attr)); - - id = rch2('id'); - n_rows = length(id); - - dt = num2cell(rch1('dt'),2); - n_samples = num2cell(rch1('n_samples'),2); - - units_temp = cellstr(char(rch1('units'))); - - n_records = length(record_struct); - units_temp2 = reshape(units_temp,[n_rows n_records]); - units = num2cell(units_temp2,2); - - %dt - separate by rows - %n_samples - " " - %units - yikes ... - by rows, but also char - channel_struct = struct(... - 'units', units,... - 'name', rs('name','/channel_meta'),... - 'id', id,... - 'dt', dt,... - 'n_samples',n_samples)'; - - obj.m = struct(... - 'file_meta', file_struct,... - 'record_meta', record_struct,... - 'channel_meta', channel_struct,... - 'comments', comment_struct); - - end - end - -end - +classdef (Hidden) h5_file_h < handle + % + % Class: + % adi.h5_file_h + + properties + file_path + m %Structure containing the meta data + end + + methods + function obj = h5_file_h(file_path) + % + % obj = adi.h5_file_h(file_path) + % + % See Also: + % adi.readFile + + %TODO: Since we are not using this right away, we might + %want to try and get the file path if it were evaluated + %currently (in case it is relative) + obj.file_path = file_path; + %obj.m = h5m.file.open(file_path); + + + %The general approach used below is to read all meta + %information into memory now. We attempt to mimic the format + %used when saving to a 'mat' format so that we can use the same + %SDK interface. + % + %In general I really dislike this approach and will eventually + %revert to functions that read and write structs. Also, the + %encapsulation is currently shot and needs to be fixed (writing + %and reading are separated) + %============================================================== + + %File + %------------------------------------- + rf = @(attr)h5readatt(file_path,'/file',attr); + file_struct = struct(... + 'n_records', rf('n_records'),... + 'n_channels', rf('n_channels')); + + %Records + %-------------------------------------- + rr = @(attr)num2cell(h5readatt(file_path,'/record_meta',attr)); + + record_struct = struct(... + 'n_ticks', rr('n_ticks'),... + 'tick_dt', rr('tick_dt'),... + 'record_start', rr('record_start'),... + 'data_start', rr('data_start'),... + 'trigger_minus_rec_start_samples', rr('trigger_minus_rec_start_samples'))'; + + %Comments + rco = @(attr)num2cell(h5readatt(file_path,'/comments',attr)); + + rs = @(attr,group_name)cellstr(char(h5readatt(file_path,group_name,attr))); + + % temp = h5readatt(file_path,'/comments','str'); + % comment_strs = cellstr(char(temp)); + + comment_struct = struct(... + 'str', rs('str','/comments'),... + 'id', rco('id'),... + 'tick_position',rco('tick_position'),... + 'channel', rco('channel'),... + 'record', rco('record'),... + 'tick_dt', rco('tick_dt'))'; + + %Channels + %----------------------------- + rch1 = @(attr)h5readatt(file_path,'/channel_meta',attr); + rch2 = @(attr)num2cell(rch1(attr)); + + id = rch2('id'); + n_rows = length(id); + + dt = num2cell(rch1('dt'),2); + n_samples = num2cell(rch1('n_samples'),2); + + units_temp = cellstr(char(rch1('units'))); + + n_records = length(record_struct); + units_temp2 = reshape(units_temp,[n_rows n_records]); + units = num2cell(units_temp2,2); + + %dt - separate by rows + %n_samples - " " + %units - yikes ... - by rows, but also char + channel_struct = struct(... + 'units', units,... + 'name', rs('name','/channel_meta'),... + 'id', id,... + 'dt', dt,... + 'n_samples',n_samples)'; + + obj.m = struct(... + 'file_meta', file_struct,... + 'record_meta', record_struct,... + 'channel_meta', channel_struct,... + 'comments', comment_struct); + + end + end + +end + diff --git a/src/Import/labchart/adi/+adi/h5_file_sdk.m b/Import/labchart/adi/+adi/h5_file_sdk.m similarity index 97% rename from src/Import/labchart/adi/+adi/h5_file_sdk.m rename to Import/labchart/adi/+adi/h5_file_sdk.m index b62bb4fe..b9ee8109 100644 --- a/src/Import/labchart/adi/+adi/h5_file_sdk.m +++ b/Import/labchart/adi/+adi/h5_file_sdk.m @@ -1,77 +1,77 @@ -classdef (Hidden) h5_file_sdk < adi.mat_file_sdk - % - % Class: - % adi.h5_file_sdk - % - % This should expose the SDK in a similar manner as the regular SDK - % but it should do it from a h5 file. - % - % JAH 2014-6-15: This code layout will likely change although the - % interface will most likely not. I just don't like the non-obvious - % code layout. - % - % See Also: - % adi.mat_file_sdk - % adi.sdk - - %NOTE: In Matlab the functions can be easily visualized by folding all - %the code and then expanding this methods block - methods (Static) - %File specific functions - %------------------------------------------------------------------ - function file_h = openFile(file_path) - % - % file = adi.h5_file_sdk.openFile(file_path) - % - % NOTE: Only reading is supported. - % - % Inputs: - % ------- - % file_path : char - % Full path to the file. - % - % Outputs: - % -------- - % file : adi.h5_file_h - - file_h = adi.h5_file_h(file_path); - - end - function output_data = getChannelData(file_h,record,channel,start_sample,n_samples_get,get_samples,varargin) - % - % - % output_data = getChannelData(file_h,record,channel,start_sample,n_samples_get,get_samples,varargin) - % - % Inputs: - % -------- - % file_h : adi.h5_file_h - - in.leave_raw = false; - in = adi.sl.in.processVarargin(in,varargin); - - if get_samples == false - %JAH: NYI - error('Sorry, I can''t let you do that ...') - end - - chan_name = sprintf('/data__chan_%d_rec_%d',channel,record); - - output_data = h5read(file_h.file_path,chan_name,[start_sample 1],[n_samples_get 1]); - - if ~in.leave_raw - output_data = double(output_data); - end - end - end - - %Wrapper methods - methods (Static) - function comments = getAllCommentsForRecord(file_h,record_id,tick_dt,trigger_minus_rec_start) - % - - comments = adi.sdk.getAllCommentsForRecord(file_h,record_id,tick_dt,trigger_minus_rec_start,adi.mat_file_sdk); - end - end - -end - +classdef (Hidden) h5_file_sdk < adi.mat_file_sdk + % + % Class: + % adi.h5_file_sdk + % + % This should expose the SDK in a similar manner as the regular SDK + % but it should do it from a h5 file. + % + % JAH 2014-6-15: This code layout will likely change although the + % interface will most likely not. I just don't like the non-obvious + % code layout. + % + % See Also: + % adi.mat_file_sdk + % adi.sdk + + %NOTE: In Matlab the functions can be easily visualized by folding all + %the code and then expanding this methods block + methods (Static) + %File specific functions + %------------------------------------------------------------------ + function file_h = openFile(file_path) + % + % file = adi.h5_file_sdk.openFile(file_path) + % + % NOTE: Only reading is supported. + % + % Inputs: + % ------- + % file_path : char + % Full path to the file. + % + % Outputs: + % -------- + % file : adi.h5_file_h + + file_h = adi.h5_file_h(file_path); + + end + function output_data = getChannelData(file_h,record,channel,start_sample,n_samples_get,get_samples,varargin) + % + % + % output_data = getChannelData(file_h,record,channel,start_sample,n_samples_get,get_samples,varargin) + % + % Inputs: + % -------- + % file_h : adi.h5_file_h + + in.leave_raw = false; + in = adi.sl.in.processVarargin(in,varargin); + + if get_samples == false + %JAH: NYI + error('Sorry, I can''t let you do that ...') + end + + chan_name = sprintf('/data__chan_%d_rec_%d',channel,record); + + output_data = h5read(file_h.file_path,chan_name,[start_sample 1],[n_samples_get 1]); + + if ~in.leave_raw + output_data = double(output_data); + end + end + end + + %Wrapper methods + methods (Static) + function comments = getAllCommentsForRecord(file_h,record_id,tick_dt,trigger_minus_rec_start) + % + + comments = adi.sdk.getAllCommentsForRecord(file_h,record_id,tick_dt,trigger_minus_rec_start,adi.mat_file_sdk); + end + end + +end + diff --git a/src/Import/labchart/adi/+adi/handle_logger.m b/Import/labchart/adi/+adi/handle_logger.m similarity index 96% rename from src/Import/labchart/adi/+adi/handle_logger.m rename to Import/labchart/adi/+adi/handle_logger.m index 8f9a1016..6cf80a9f 100644 --- a/src/Import/labchart/adi/+adi/handle_logger.m +++ b/Import/labchart/adi/+adi/handle_logger.m @@ -1,53 +1,53 @@ -classdef (Hidden) handle_logger < handle - % - % Class: - % adi.handle_logger - % - % This is hopefully a temporary class that logs open and close - % operations. - - properties - fid - end - - methods - %TODO: Make private - function obj = handle_logger() - %Call this via: - % -% % % % % repo_root = adi.sl.stack.getPackageRoot; -% % % % % file_path = fullfile(repo_root,'temp_logger.txt'); -% % % % % obj.fid = fopen(file_path,'a'); - end - function delete(obj) -% % % % fclose(obj.fid); - end - end - - methods (Static) - function logOperation(file_path,handle_type,handle_value) - % - % adi.handle_logger.logOperation(file_path,handle_type,handle_value) - % - % Inputs: - % ------- - % file_path : - % Labchart file that is being referenced (not the save - % path) - % handle_type : string - % Who is calling the logger? - % handle_value : integer - -% % % % persistent obj -% % % % -% % % % if isempty(obj) -% % % % obj = adi.handle_logger; -% % % % end -% % % % -% % % % %write_str = sprintf('%s %s:\t%s:%ld\n',datestr(now),file_path,handle_type,handle_value); -% % % % fwrite(obj.fid,write_str); - end - end - -end - +classdef (Hidden) handle_logger < handle + % + % Class: + % adi.handle_logger + % + % This is hopefully a temporary class that logs open and close + % operations. + + properties + fid + end + + methods + %TODO: Make private + function obj = handle_logger() + %Call this via: + % +% % % % % repo_root = adi.sl.stack.getPackageRoot; +% % % % % file_path = fullfile(repo_root,'temp_logger.txt'); +% % % % % obj.fid = fopen(file_path,'a'); + end + function delete(obj) +% % % % fclose(obj.fid); + end + end + + methods (Static) + function logOperation(file_path,handle_type,handle_value) + % + % adi.handle_logger.logOperation(file_path,handle_type,handle_value) + % + % Inputs: + % ------- + % file_path : + % Labchart file that is being referenced (not the save + % path) + % handle_type : string + % Who is calling the logger? + % handle_value : integer + +% % % % persistent obj +% % % % +% % % % if isempty(obj) +% % % % obj = adi.handle_logger; +% % % % end +% % % % +% % % % %write_str = sprintf('%s %s:\t%s:%ld\n',datestr(now),file_path,handle_type,handle_value); +% % % % fwrite(obj.fid,write_str); + end + end + +end + diff --git a/src/Import/labchart/adi/+adi/handle_manager.m b/Import/labchart/adi/+adi/handle_manager.m similarity index 97% rename from src/Import/labchart/adi/+adi/handle_manager.m rename to Import/labchart/adi/+adi/handle_manager.m index 7dab16ee..4c4c0c07 100644 --- a/src/Import/labchart/adi/+adi/handle_manager.m +++ b/Import/labchart/adi/+adi/handle_manager.m @@ -1,182 +1,182 @@ -classdef (Hidden) handle_manager - % - % Class: - % adi.handle_manager - % - % This class keeps track of open files and attempts to prevent - % closing a file that for some reason is not actually open. - % - % This class is called directly by functions in adi.sdk - % - % It is only used by the ADInstruments SDK since I've had some issues - % with getting - % - % - % See Also: - % adi.sdk - % adi.sdk.openFile - - properties - - %NOTE: This file is locked so to change and rerun this class you - %need: - % - % adi.handle_manager.unlock - % clear classes - - DEBUG = false - %Set this to be true to enable printing of statements in the class - %methods - - USE_FIX = true - %true - single file only ever gets one pointer - %false - single file gets multiple pointers - % - % By default this should be true unless we're inspecting how - % the SDK works when this is not true. - end - - properties - map %containers.Map - % - % key - pointer value of open file - % value - file path - path_key_map - % - % key - file path - % value - count of how many are open - end - - methods - function obj = handle_manager() - obj.map = containers.Map('KeyType','int64','ValueType','char'); - obj.path_key_map = containers.Map('KeyType','char','ValueType','any'); - end - end - - methods (Static) - function pointer_value = checkFilePointer(file_path) - % pointer_value = adi.handle_manager.checkFilePointer(file_path) - % - % This gets called on opening a file using the ADI sdk. If - % a file is already open, we return its pointer, rather - % than creating a new pointer for the file. - % - % If a file is not already open, then we return 0, indicating - % that a new pointer should be requested from the SDK. - % - % Inputs: - % ------- - % file_path : path to the file to open - % - % Outputs: - % -------- - % pointer_value : numeric value acting as c pointer - % If the file is not already open, a value of 0 is - % returned - % - % See Also: - % adi.sdk.openFile - - obj = adi.handle_manager.getReference(); - if obj.USE_FIX - if obj.path_key_map.isKey(file_path) - if obj.DEBUG - fprintf(2,'Pointer found for:\n%s\n',file_path); - end - temp = obj.path_key_map(file_path); - pointer_value = temp(1); - temp(2) = temp(2) + 1; - obj.path_key_map(file_path) = temp; - else - %fprintf(2,'Pointer not found for:\n%s\n',file_path); - pointer_value = 0; - end - - else - pointer_value = 0; - end - end - function openFile(file_path,pointer_value) - % - % adi.handle_manager.openFile(file_path,pointer_value) - % - % See Also: - % adi.sdk.openFile - - obj = adi.handle_manager.getReference(); - %disp(file_path) - %disp(pointer_value) - if obj.map.isKey(pointer_value) - error('Pointer value is redundant, this is not expected') - end - obj.map(pointer_value) = file_path; - - if obj.USE_FIX - % [pointer_value count] - obj.path_key_map(file_path) = [pointer_value 1]; - end - end - function closeFile(pointer_value) - % - % adi.handle_manager.closeFile(pointer_value) - % - % See Also: - % adi.sdk.closeFile - % - % TODO: The encapsulation is a bit lacking here. - - obj = adi.handle_manager.getReference(); - if obj.map.isKey(pointer_value) - file_path = obj.map(pointer_value); - - if ~obj.USE_FIX - %Then just close the file - %TODO: We should return the count to the SDK instead - %here we would return 0 (or 1, depending on the design) - obj.map.remove(pointer_value); - result_code = sdk_mex(13,pointer_value); - adi.sdk.handleErrorCode(result_code); - else - - temp = obj.path_key_map(file_path); - if temp(2) == 1 - %fprintf(2,'Closing reference for:\n%s\n',file_path); - obj.map.remove(pointer_value); - obj.path_key_map.remove(file_path); - result_code = sdk_mex(13,pointer_value); - adi.sdk.handleErrorCode(result_code); - else - %fprintf(2,'Decrementing reference count for:\n%s\n',file_path); - temp(2) = temp(2) - 1; - obj.path_key_map(file_path) = temp; - end - - end - else - %TODO: Move formatted warning into adi.sl - warning('Trying to close a file whose pointer is not logged') - end - end - function output_obj = getReference() - % - % adi.handle_manager.getReference - % - persistent obj - if isempty(obj) - %NOTE: We lock things to try and prevent problems with - %the mex file. I'm not sure if this is really necessary, - %but it makes me sleep better at night :) - mlock(); - obj = adi.handle_manager; - end - output_obj = obj; - end - function unlock() - %adi.handle_manager.unlock - munlock(); - end - end - -end - +classdef (Hidden) handle_manager + % + % Class: + % adi.handle_manager + % + % This class keeps track of open files and attempts to prevent + % closing a file that for some reason is not actually open. + % + % This class is called directly by functions in adi.sdk + % + % It is only used by the ADInstruments SDK since I've had some issues + % with getting + % + % + % See Also: + % adi.sdk + % adi.sdk.openFile + + properties + + %NOTE: This file is locked so to change and rerun this class you + %need: + % + % adi.handle_manager.unlock + % clear classes + + DEBUG = false + %Set this to be true to enable printing of statements in the class + %methods + + USE_FIX = true + %true - single file only ever gets one pointer + %false - single file gets multiple pointers + % + % By default this should be true unless we're inspecting how + % the SDK works when this is not true. + end + + properties + map %containers.Map + % + % key - pointer value of open file + % value - file path + path_key_map + % + % key - file path + % value - count of how many are open + end + + methods + function obj = handle_manager() + obj.map = containers.Map('KeyType','int64','ValueType','char'); + obj.path_key_map = containers.Map('KeyType','char','ValueType','any'); + end + end + + methods (Static) + function pointer_value = checkFilePointer(file_path) + % pointer_value = adi.handle_manager.checkFilePointer(file_path) + % + % This gets called on opening a file using the ADI sdk. If + % a file is already open, we return its pointer, rather + % than creating a new pointer for the file. + % + % If a file is not already open, then we return 0, indicating + % that a new pointer should be requested from the SDK. + % + % Inputs: + % ------- + % file_path : path to the file to open + % + % Outputs: + % -------- + % pointer_value : numeric value acting as c pointer + % If the file is not already open, a value of 0 is + % returned + % + % See Also: + % adi.sdk.openFile + + obj = adi.handle_manager.getReference(); + if obj.USE_FIX + if obj.path_key_map.isKey(file_path) + if obj.DEBUG + fprintf(2,'Pointer found for:\n%s\n',file_path); + end + temp = obj.path_key_map(file_path); + pointer_value = temp(1); + temp(2) = temp(2) + 1; + obj.path_key_map(file_path) = temp; + else + %fprintf(2,'Pointer not found for:\n%s\n',file_path); + pointer_value = 0; + end + + else + pointer_value = 0; + end + end + function openFile(file_path,pointer_value) + % + % adi.handle_manager.openFile(file_path,pointer_value) + % + % See Also: + % adi.sdk.openFile + + obj = adi.handle_manager.getReference(); + %disp(file_path) + %disp(pointer_value) + if obj.map.isKey(pointer_value) + error('Pointer value is redundant, this is not expected') + end + obj.map(pointer_value) = file_path; + + if obj.USE_FIX + % [pointer_value count] + obj.path_key_map(file_path) = [pointer_value 1]; + end + end + function closeFile(pointer_value) + % + % adi.handle_manager.closeFile(pointer_value) + % + % See Also: + % adi.sdk.closeFile + % + % TODO: The encapsulation is a bit lacking here. + + obj = adi.handle_manager.getReference(); + if obj.map.isKey(pointer_value) + file_path = obj.map(pointer_value); + + if ~obj.USE_FIX + %Then just close the file + %TODO: We should return the count to the SDK instead + %here we would return 0 (or 1, depending on the design) + obj.map.remove(pointer_value); + result_code = sdk_mex(13,pointer_value); + adi.sdk.handleErrorCode(result_code); + else + + temp = obj.path_key_map(file_path); + if temp(2) == 1 + %fprintf(2,'Closing reference for:\n%s\n',file_path); + obj.map.remove(pointer_value); + obj.path_key_map.remove(file_path); + result_code = sdk_mex(13,pointer_value); + adi.sdk.handleErrorCode(result_code); + else + %fprintf(2,'Decrementing reference count for:\n%s\n',file_path); + temp(2) = temp(2) - 1; + obj.path_key_map(file_path) = temp; + end + + end + else + %TODO: Move formatted warning into adi.sl + warning('Trying to close a file whose pointer is not logged') + end + end + function output_obj = getReference() + % + % adi.handle_manager.getReference + % + persistent obj + if isempty(obj) + %NOTE: We lock things to try and prevent problems with + %the mex file. I'm not sure if this is really necessary, + %but it makes me sleep better at night :) + mlock(); + obj = adi.handle_manager; + end + output_obj = obj; + end + function unlock() + %adi.handle_manager.unlock + munlock(); + end + end + +end + diff --git a/src/Import/labchart/adi/+adi/mat_comment_handle.m b/Import/labchart/adi/+adi/mat_comment_handle.m similarity index 96% rename from src/Import/labchart/adi/+adi/mat_comment_handle.m rename to Import/labchart/adi/+adi/mat_comment_handle.m index f324c66b..15291931 100644 --- a/src/Import/labchart/adi/+adi/mat_comment_handle.m +++ b/Import/labchart/adi/+adi/mat_comment_handle.m @@ -1,64 +1,64 @@ -classdef (Hidden) mat_comment_handle < handle - % - % Class: - % adi.mat_comment_handle - % - % NOTE: This class is a quick hack to get the mat file sdk working - % - % This contains a handle that is needed by the SDK to get comments - % for a particular record. Methods in this class can be used to - % extract actual comments from a record. - % - % See Also: - % adi.comment - - - properties - is_valid = false %A handle may not be valid if there are no comments - %for a given record - record - tick_dt - - current_index = 1 - trigger_minus_record_start_s - end - - properties (Hidden) - comment_data - n_comments - end - - methods - function obj = mat_comment_handle(comment_data,is_valid,record_id,tick_dt,trigger_minus_record_start_s) - % - % adi.mat_comment_handle(comment_data,is_valid,record_id,tick_dt) - - %NOTE: Only comments for the record are passed in ... - - obj.comment_data = comment_data; - obj.is_valid = is_valid; - obj.record = record_id; - obj.tick_dt = tick_dt; - obj.n_comments = length(comment_data); - obj.trigger_minus_record_start_s = trigger_minus_record_start_s; - end - function delete(~) - end - function has_another_comment = advanceCommentPointer(obj) - obj.current_index = obj.current_index + 1; - has_another_comment = obj.current_index <= obj.n_comments; - end - function cur_comment = getCurrentComment(obj) - if obj.n_comments == 0 - cur_comment = []; - else - cur_comment = adi.mat_file_sdk.getCommentInfo(obj,obj.comment_data(obj.current_index)); - end - end - function close(~) - end - end - - -end - +classdef (Hidden) mat_comment_handle < handle + % + % Class: + % adi.mat_comment_handle + % + % NOTE: This class is a quick hack to get the mat file sdk working + % + % This contains a handle that is needed by the SDK to get comments + % for a particular record. Methods in this class can be used to + % extract actual comments from a record. + % + % See Also: + % adi.comment + + + properties + is_valid = false %A handle may not be valid if there are no comments + %for a given record + record + tick_dt + + current_index = 1 + trigger_minus_record_start_s + end + + properties (Hidden) + comment_data + n_comments + end + + methods + function obj = mat_comment_handle(comment_data,is_valid,record_id,tick_dt,trigger_minus_record_start_s) + % + % adi.mat_comment_handle(comment_data,is_valid,record_id,tick_dt) + + %NOTE: Only comments for the record are passed in ... + + obj.comment_data = comment_data; + obj.is_valid = is_valid; + obj.record = record_id; + obj.tick_dt = tick_dt; + obj.n_comments = length(comment_data); + obj.trigger_minus_record_start_s = trigger_minus_record_start_s; + end + function delete(~) + end + function has_another_comment = advanceCommentPointer(obj) + obj.current_index = obj.current_index + 1; + has_another_comment = obj.current_index <= obj.n_comments; + end + function cur_comment = getCurrentComment(obj) + if obj.n_comments == 0 + cur_comment = []; + else + cur_comment = adi.mat_file_sdk.getCommentInfo(obj,obj.comment_data(obj.current_index)); + end + end + function close(~) + end + end + + +end + diff --git a/src/Import/labchart/adi/+adi/mat_conversion_options.m b/Import/labchart/adi/+adi/mat_conversion_options.m similarity index 92% rename from src/Import/labchart/adi/+adi/mat_conversion_options.m rename to Import/labchart/adi/+adi/mat_conversion_options.m index f8da9dc1..d3065531 100644 --- a/src/Import/labchart/adi/+adi/mat_conversion_options.m +++ b/Import/labchart/adi/+adi/mat_conversion_options.m @@ -1,15 +1,15 @@ -classdef mat_conversion_options - % - % Class: - % adi.mat_conversion_options - % - % Nothing needed yet! - - properties - end - - methods - end - -end - +classdef mat_conversion_options + % + % Class: + % adi.mat_conversion_options + % + % Nothing needed yet! + + properties + end + + methods + end + +end + diff --git a/src/Import/labchart/adi/+adi/mat_file_h.m b/Import/labchart/adi/+adi/mat_file_h.m similarity index 96% rename from src/Import/labchart/adi/+adi/mat_file_h.m rename to Import/labchart/adi/+adi/mat_file_h.m index 2e42ff7c..9f8e443e 100644 --- a/src/Import/labchart/adi/+adi/mat_file_h.m +++ b/Import/labchart/adi/+adi/mat_file_h.m @@ -1,44 +1,44 @@ -classdef (Hidden) mat_file_h < handle - % - % Class: - % adi.mat_file_h - - properties - m %Handle to the file. - end - - methods - function obj = mat_file_h(file_path,varargin) - % - % obj = adi.mat_file_h(file_path,varargin) - % - % Optional Inputs: - % ---------------- - % load_all : logical (default false) - % If true the entire file is loaded into memory at once, - % otherwise the 'matfile' commend and the subsequent - % 'matlab.io.MatFile' class are used. Loading everything - % might makes things slightly faster but it also might be - % a lot slower if only analyzing a portion of the file. - % It might also cause an "out of memory" error. - % - % See Also: - % adi.readFile - - %TODO: Link this to input options in read file - - in.load_all = false; - in = adi.sl.in.processVarargin(in,varargin); - if in.load_all - obj.m = load(file_path); - else - obj.m = matfile(file_path,'Writable',false); - end - end - function delete(obj) - %TODO: Delete - end - end - -end - +classdef (Hidden) mat_file_h < handle + % + % Class: + % adi.mat_file_h + + properties + m %Handle to the file. + end + + methods + function obj = mat_file_h(file_path,varargin) + % + % obj = adi.mat_file_h(file_path,varargin) + % + % Optional Inputs: + % ---------------- + % load_all : logical (default false) + % If true the entire file is loaded into memory at once, + % otherwise the 'matfile' commend and the subsequent + % 'matlab.io.MatFile' class are used. Loading everything + % might makes things slightly faster but it also might be + % a lot slower if only analyzing a portion of the file. + % It might also cause an "out of memory" error. + % + % See Also: + % adi.readFile + + %TODO: Link this to input options in read file + + in.load_all = false; + in = adi.sl.in.processVarargin(in,varargin); + if in.load_all + obj.m = load(file_path); + else + obj.m = matfile(file_path,'Writable',false); + end + end + function delete(obj) + %TODO: Delete + end + end + +end + diff --git a/src/Import/labchart/adi/+adi/mat_file_sdk.m b/Import/labchart/adi/+adi/mat_file_sdk.m similarity index 97% rename from src/Import/labchart/adi/+adi/mat_file_sdk.m rename to Import/labchart/adi/+adi/mat_file_sdk.m index 51be1985..911529b2 100644 --- a/src/Import/labchart/adi/+adi/mat_file_sdk.m +++ b/Import/labchart/adi/+adi/mat_file_sdk.m @@ -1,166 +1,166 @@ -classdef (Hidden) mat_file_sdk < handle - % - % Class: - % adi.mat_file_sdk - % - % This should expose the SDK in a similar manner as the regular SDK - % but it should do it from a mat file. - % - % The h5_file_sdk borrows implementations from this class and then - % changes some of the methods. I think I would rather they both - % inherit from a file sdk. - % - % JAH 2014-6-15: This code layout will likely change although the - % interface will most likely not. I just don't like the non-obvious - % code layout. - - %NOTE: In Matlab the functions can be easily visualized by folding all - %the code and then expanding this methods block - methods (Static) - %File specific functions - %------------------------------------------------------------------ - function file_h = openFile(file_path) - % - % file = adi.mat_file_sdk.openFile(file_path) - % - % NOTE: Only reading is supported. - % - % Inputs: - % ------- - % file_path : char - % Full path to the file. - % - % Outputs: - % -------- - % file : adi.mat_file_h - - file_h = adi.mat_file_h(file_path); - - end - function n_records = getNumberOfRecords(file_h) - %getNumberOfRecords Get the number of records for a file. - % - % n_records = adi.mat_file_sdk.getNumberOfRecords(file_h) - % - % See definition of the "records" in the definition section. - - file_meta = file_h.m.file_meta; - n_records = file_meta.n_records; - end - function n_channels = getNumberOfChannels(file_h) - %getNumberOfChannels Get # of channels for a file. - % - % n_channels = adi.mat_file_sdk.getNumberOfChannels(file_h) - - - file_meta = file_h.m.file_meta; - n_channels = file_meta.n_channels; - end - %Record specific functions - %------------------------------------------------------------------ - function n_ticks_in_record = getNTicksInRecord(file_h,record) - % - - record_meta = file_h.m.record_meta(1,record); - n_ticks_in_record = record_meta.n_ticks; - - end - function dt_tick = getTickPeriod(file_h,record,~) - % - - record_meta = file_h.m.record_meta(1,record); - dt_tick = record_meta.tick_dt; - end - function [record_start,data_start,trigger_minus_rec_start_samples] = getRecordStartTime(file_h,record,tick_dt) - % - record_meta = file_h.m.record_meta(1,record); - record_start = record_meta.record_start; - data_start = record_meta.data_start; - trigger_minus_rec_start_samples = record_meta.trigger_minus_rec_start_samples; - end - %Comment specific functions - %------------------------------------------------------------------ - function comments_h = getCommentAccessor(file_h,record,tick_dt,trigger_minus_record_start_s) - % - - comments = file_h.m.comments; - comments_for_record = comments([comments.record] == record); - comments_h = adi.mat_comment_handle(comments_for_record,... - ~isempty(comments_for_record),record,tick_dt,trigger_minus_record_start_s); - end -% function closeCommentAccessor(pointer_value) -% end -% function has_another_comment = advanceComments(comments_h) -% end - function comment_info = getCommentInfo(comments_h,data) - % - % - % comment_info = adi.sdk.getCommentInfo(comments_h) - - comment_info = adi.comment(data.str,... - data.tick_position,... - data.channel,... - data.id,... - comments_h.record,... - comments_h.tick_dt,... - comments_h.trigger_minus_record_start_s); - end - %Channel specific functions - %------------------------------------------------------------------ - function n_samples = getNSamplesInRecord(file_h,record,channel) - % - cm = file_h.m.channel_meta; - n_samples = cm(channel).n_samples(record); - - end - function output_data = getChannelData(file_h,record,channel,start_sample,n_samples_get,get_samples,varargin) - % - %(file_h,record,channel,start_sample,n_samples_get,get_samples,varargin) - - in.leave_raw = false; - in = adi.sl.in.processVarargin(in,varargin); - - if get_samples == false - %JAH: NYI - error('Sorry, I can''t let you do that ...') - end - - chan_name = sprintf('data__chan_%d_rec_%d',channel,record); - output_data = file_h.m.(chan_name)(start_sample:(start_sample+n_samples_get-1),1); - - if in.leave_raw - %output_data = output_data; - else - output_data = double(output_data); %Matlab can get finicky working with singles - end - - end - function units = getUnits(file_h,record,channel) - %getUnits - cm = file_h.m.channel_meta(1,channel); - units = cm.units{record}; - end - function channel_name = getChannelName(file_h,channel) - % - cm = file_h.m.channel_meta(1,channel); - channel_name = cm.name; - end - function dt_channel = getSamplePeriod(file_h,record,channel) - % - cm = file_h.m.channel_meta(1,channel); - dt_channel = cm.dt(record); - end - end - - %Wrapper methods - methods (Static) - function comments = getAllCommentsForRecord(file_h,record_id,tick_dt,trigger_minus_rec_start_samples) - % - %TODO: This isn't right - - comments = adi.sdk.getAllCommentsForRecord(file_h,record_id,tick_dt,trigger_minus_rec_start_samples,adi.mat_file_sdk); - end - end - -end - +classdef (Hidden) mat_file_sdk < handle + % + % Class: + % adi.mat_file_sdk + % + % This should expose the SDK in a similar manner as the regular SDK + % but it should do it from a mat file. + % + % The h5_file_sdk borrows implementations from this class and then + % changes some of the methods. I think I would rather they both + % inherit from a file sdk. + % + % JAH 2014-6-15: This code layout will likely change although the + % interface will most likely not. I just don't like the non-obvious + % code layout. + + %NOTE: In Matlab the functions can be easily visualized by folding all + %the code and then expanding this methods block + methods (Static) + %File specific functions + %------------------------------------------------------------------ + function file_h = openFile(file_path) + % + % file = adi.mat_file_sdk.openFile(file_path) + % + % NOTE: Only reading is supported. + % + % Inputs: + % ------- + % file_path : char + % Full path to the file. + % + % Outputs: + % -------- + % file : adi.mat_file_h + + file_h = adi.mat_file_h(file_path); + + end + function n_records = getNumberOfRecords(file_h) + %getNumberOfRecords Get the number of records for a file. + % + % n_records = adi.mat_file_sdk.getNumberOfRecords(file_h) + % + % See definition of the "records" in the definition section. + + file_meta = file_h.m.file_meta; + n_records = file_meta.n_records; + end + function n_channels = getNumberOfChannels(file_h) + %getNumberOfChannels Get # of channels for a file. + % + % n_channels = adi.mat_file_sdk.getNumberOfChannels(file_h) + + + file_meta = file_h.m.file_meta; + n_channels = file_meta.n_channels; + end + %Record specific functions + %------------------------------------------------------------------ + function n_ticks_in_record = getNTicksInRecord(file_h,record) + % + + record_meta = file_h.m.record_meta(1,record); + n_ticks_in_record = record_meta.n_ticks; + + end + function dt_tick = getTickPeriod(file_h,record,~) + % + + record_meta = file_h.m.record_meta(1,record); + dt_tick = record_meta.tick_dt; + end + function [record_start,data_start,trigger_minus_rec_start_samples] = getRecordStartTime(file_h,record,tick_dt) + % + record_meta = file_h.m.record_meta(1,record); + record_start = record_meta.record_start; + data_start = record_meta.data_start; + trigger_minus_rec_start_samples = record_meta.trigger_minus_rec_start_samples; + end + %Comment specific functions + %------------------------------------------------------------------ + function comments_h = getCommentAccessor(file_h,record,tick_dt,trigger_minus_record_start_s) + % + + comments = file_h.m.comments; + comments_for_record = comments([comments.record] == record); + comments_h = adi.mat_comment_handle(comments_for_record,... + ~isempty(comments_for_record),record,tick_dt,trigger_minus_record_start_s); + end +% function closeCommentAccessor(pointer_value) +% end +% function has_another_comment = advanceComments(comments_h) +% end + function comment_info = getCommentInfo(comments_h,data) + % + % + % comment_info = adi.sdk.getCommentInfo(comments_h) + + comment_info = adi.comment(data.str,... + data.tick_position,... + data.channel,... + data.id,... + comments_h.record,... + comments_h.tick_dt,... + comments_h.trigger_minus_record_start_s); + end + %Channel specific functions + %------------------------------------------------------------------ + function n_samples = getNSamplesInRecord(file_h,record,channel) + % + cm = file_h.m.channel_meta; + n_samples = cm(channel).n_samples(record); + + end + function output_data = getChannelData(file_h,record,channel,start_sample,n_samples_get,get_samples,varargin) + % + %(file_h,record,channel,start_sample,n_samples_get,get_samples,varargin) + + in.leave_raw = false; + in = adi.sl.in.processVarargin(in,varargin); + + if get_samples == false + %JAH: NYI + error('Sorry, I can''t let you do that ...') + end + + chan_name = sprintf('data__chan_%d_rec_%d',channel,record); + output_data = file_h.m.(chan_name)(start_sample:(start_sample+n_samples_get-1),1); + + if in.leave_raw + %output_data = output_data; + else + output_data = double(output_data); %Matlab can get finicky working with singles + end + + end + function units = getUnits(file_h,record,channel) + %getUnits + cm = file_h.m.channel_meta(1,channel); + units = cm.units{record}; + end + function channel_name = getChannelName(file_h,channel) + % + cm = file_h.m.channel_meta(1,channel); + channel_name = cm.name; + end + function dt_channel = getSamplePeriod(file_h,record,channel) + % + cm = file_h.m.channel_meta(1,channel); + dt_channel = cm.dt(record); + end + end + + %Wrapper methods + methods (Static) + function comments = getAllCommentsForRecord(file_h,record_id,tick_dt,trigger_minus_rec_start_samples) + % + %TODO: This isn't right + + comments = adi.sdk.getAllCommentsForRecord(file_h,record_id,tick_dt,trigger_minus_rec_start_samples,adi.mat_file_sdk); + end + end + +end + diff --git a/src/Import/labchart/adi/+adi/private/ADIDatCAPI_mex.h b/Import/labchart/adi/+adi/private/ADIDatCAPI_mex.h similarity index 98% rename from src/Import/labchart/adi/+adi/private/ADIDatCAPI_mex.h rename to Import/labchart/adi/+adi/private/ADIDatCAPI_mex.h index 1ac5b305..d7706661 100644 --- a/src/Import/labchart/adi/+adi/private/ADIDatCAPI_mex.h +++ b/Import/labchart/adi/+adi/private/ADIDatCAPI_mex.h @@ -1,455 +1,455 @@ -/** -* Copyright (c) 2011-2012 ADInstruments. All rights reserved. -* -* \ADIDatFileSDK_license_start -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, this -* list of conditions and the following disclaimer. -* -* 2. The name of ADInstruments may not be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* 3. This is an unsupported product which you use at your own risk. For unofficial -* technical support, please use http://www.adinstruments.com/forum . -* -* THIS SOFTWARE IS PROVIDED BY ADINSTRUMENTS "AS IS" AND ANY EXPRESS OR IMPLIED -* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE -* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ADINSTRUMENTS BE LIABLE FOR -* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -* \ADIDatFileSDK_license_end -*/ - -//JAH Modifications -//==================================================== -//- removed trailing comma in enumerations -//- made enumerations typedef and added explicit alias - - -#ifndef ADIDatCAPI_H__ -#define ADIDatCAPI_H__ - - -#ifdef ADIDATIOWIN_EXPORTS -#define DLLEXPORT __declspec(dllexport) -#else -#define DLLEXPORT -#endif - - -#ifdef __cplusplus -extern "C" { -#endif - - - // Result code values - typedef enum ADIResultCode - { - //Win32 error codes (HRESULTs) - kResultSuccess = 0, // operation succeeded - kResultErrorFlagBit = 0x80000000L, // high bit set if operation failed - kResultInvalidArg = 0x80070057L, // invalid argument. One (or more) of the arguments is invalid - kResultFail = 0x80004005L, // Unspecified error - kResultFileNotFound = 0x80030002L, // failure to find the specified file (check the path) - - - //Start of error codes specific to this API - kResultADICAPIMsgBase = 0xA0049000L, - - kResultFileIOError = kResultADICAPIMsgBase, // file IO error - could not read/write file - kResultFileOpenFail, // file failed to open - kResultInvalidFileHandle, // file handle is invalid - kResultInvalidPosition, // pos specified is outside the bounds of the record or file - kResultInvalidCommentNum, // invalid commentNum. Comment could not be found - kResultNoData, // the data requested was not present (e.g. no more comments in the record). - kResultBufferTooSmall // the buffer passed to a function to receive data (e.g. comment text) was not big enough to receive all the data. - - // new result codes must be added at the end - } ADIResultCode; - - - // File open modes - typedef enum ADIFileOpenMode - { - kOpenFileForReadOnly = 0, // opens the file as read-only, so data cannot be written - kOpenFileForReadAndWrite // opens the file as read/write - } ADIFileOpenMode; - - - // Data Types : ADICDataFlags - typedef enum ADICDataFlags - { - kADICDataAtSampleRate = 0, // specifies that the function uses samples - kADICDataAtTickRate = 0x80000000 // specifies that the function uses ticks - } ADICDataFlags; - - - //Struct holding maximum and minimum values between which valid - //data values in a channel fall. - typedef struct ADIDataLimits - { - float mMaxLimit; - float mMinLimit; - } ADIDataLimits; - - // Handles - essentially void* with a little added type safety. - struct ADI_FileHandle__ { int unused; }; typedef struct ADI_FileHandle__ *ADI_FileHandle; - struct ADI_WriterHandle__ { int unused; }; typedef struct ADI_WriterHandle__ *ADI_WriterHandle; - struct ADI_CommentsHandle__ { int unused; }; typedef struct ADI_CommentsHandle__ *ADI_CommentsHandle; - -// Define ADI_USELOADIDATDLL to link explicitly to the ADIDatDll. To link implicitly using the -// import library leave this undefined. -#ifndef ADI_USELOADIDATDLL - - - //-------------------- - // General Operations: - // - - - // Opens an existing *.adidat file for read and write operations and returns a pointer - // to it. - // If operation is successful, 'fileH' param will be be a handle to the file, else 0. - // Params: path - absolute, delimited path to the file, - // e.g. "C:\\MyData\\TestFile.adidat" - // fileH - pointer to an ADI_FileHandle object [outparam] - // mode - ADIFileOpenMode option for controlling the how the file is to be opened - // Return: a ADIResultCode for result of the operation - DLLEXPORT ADIResultCode ADI_OpenFile(const wchar_t* path, ADI_FileHandle* fileH, ADIFileOpenMode mode); - - - // Creates a new *.adidat file for write operations at the specified location and - // returns a pointer to it. - // If operation is successful, 'file' param will be be a handle to the file, else 0. - // Params: path - absolute, delimited path to the file, - // e.g. "C:\\MyData\\NewFile.adidat" - // fileH - pointer to an ADI_FileHandle object [outparam] - // Return: a ADIResultCode for result of the operation - DLLEXPORT ADIResultCode ADI_CreateFile(const wchar_t* path, ADI_FileHandle* fileH); - - - // Retrieves a text description of a result code returned from an API call. - // Params: code - an ADIResultCode value - // message - null-terminated text for the error message [outparam] - // maxChars - the size used for the buffer. Must not exceed this when copying - // text into the buffer - // textLen - receives the number of characters needed to hold the full comment text, - // even if parameter text is NULL (optional, may be NULL) [outparam] - // Return: returns kResultBufferTooSmall if maxChars was too small to receive the full title text. - // Return: a ADIResultCode for result of the operation - DLLEXPORT ADIResultCode ADI_GetErrorMessage(ADIResultCode code, wchar_t* messageOut, - long maxChars, long *textLen); - - - // Converts a tick position to a sample position for a given channel. - // Params: fileH - ADI_FileHandle for the open file - // channel - the channel index (starting from 0) - // record - the record index (starting from 0) - // tickInRecord - the tick position to be converted - // samplePosInRecord - the converted sample position [outparam] - // Return: a ADIResultCode for result of the operation - DLLEXPORT ADIResultCode ADI_TickToSamplePos(ADI_FileHandle fileH, long channel, long record, - long tickInRecord, double* samplePosInRecord); - - - // Converts a sample position to a tick position for a given channel. - // Params: fileH - ADI_FileHandle for the open file - // channel - the channel index (starting from 0) - // record - the record index (starting from 0) - // samplePosInRecord - the tick position to be converted - // tickInRecord - the converted sample position [outparam] - // Return: a ADIResultCode for result of the operation - DLLEXPORT ADIResultCode ADI_SamplePosToTick(ADI_FileHandle fileH, long channel, long record, - double samplePosInRecord, double* tickInRecord); - - - //----------------- - // Read Operations: - // - - - // Retrieves the number of records in the file. - // Params: fileH - ADI_FileHandle for the open file - // nRecords - the number of records in the file [outparam] - // Return: a ADIResultCode for result of the operation - DLLEXPORT ADIResultCode ADI_GetNumberOfRecords(ADI_FileHandle fileH, long* nRecords); - - - // Retrieves the number of channels in the file. - // Params: fileH - ADI_FileHandle for the open file - // nChannels - the number of channels in the file [outparam] - // Return: a ADIResultCode for result of the operation - DLLEXPORT ADIResultCode ADI_GetNumberOfChannels(ADI_FileHandle fileH, long* nChannels); - - - // Retrieves the number of ticks in the specified record. - // Params: fileH - ADI_FileHandle for the open file - // record - the record index (starting from 0) - // nTicks - the number of ticks in the record [outparam] - // Return: a ADIResultCode for result of the operation - DLLEXPORT ADIResultCode ADI_GetNumTicksInRecord(ADI_FileHandle fileH, long record, long* nTicks); - - - // Retrieves the tick period for the specified record and channel. - // Params: fileH - ADI_FileHandle for the open file - // channel - the channel in the record (starting from 0) - // record - the record index (starting from 0) - // secsPerTick - the tick period for the record [outparam] - // Return: a ADIResultCode for result of the operation - DLLEXPORT ADIResultCode ADI_GetRecordTickPeriod(ADI_FileHandle fileH, long channel, long record, - double* secsPerTick); - - - // Retrieves the number of samples in the specified record. - // Params: fileH - ADI_FileHandle for the open file - // channel - the channel in the record (starting from 0) - // record - the record index (starting from 0) - // nSamples - the number of samples in the record [outparam] - // Return: a ADIResultCode for result of the operation - DLLEXPORT ADIResultCode ADI_GetNumSamplesInRecord(ADI_FileHandle fileH, long channel, long record, - long* nSamples); - - - // Retrieves the sample period for the specified record. - // Params: fileH - ADI_FileHandle for the open file - // channel - the channel in the record (starting from 0) - // record - the record index (starting from 0) - // secsPerSample - the sample period for the record [outparam] - // Return: a ADIResultCode for result of the operation - DLLEXPORT ADIResultCode ADI_GetRecordSamplePeriod(ADI_FileHandle fileH, long channel, long record, - double* secsPerSample); - - - //Retrieves time information about the specified record. - //The trigger time is the time origin of the record and may differ from the start time if - //there is a pre or post trigger delay, as specified by the trigMinusRecStart parameter. - // Params: fileH - ADI_FileHandle for the open file - // record - the record index (starting from 0) - // triggerTime - time_t receives the date and time of the trigger - // position for the new record. Measured as number of - // seconds from 1 Jan 1970 - // fracSecs - receives the fractional seconds part of - // the record trigger time ('triggerTime' parameter) - // trigMinusRecStart - trigger-time-minus-record-start-ticks. Receives the - // difference between the time of trigger tick and the first - // tick in the record. This +ve for pre-trigger delay and - // -ve for post-trigger delay. - // Return: a ADIResultCode for result of the operation - DLLEXPORT ADIResultCode ADI_GetRecordTime(ADI_FileHandle fileH, long record, time_t *triggerTime, - double *fracSecs, long *triggerMinusStartTicks); - - - // Creates a comments accessor handle for the specified record. - // Params: fileH - ADI_FileHandle for the open file - // record - the record index (starting from 0) - // commentsH - handle to the new comments accessor for the record [outparam] - // Return: a ADIResultCode for result of the operation - DLLEXPORT ADIResultCode ADI_CreateCommentsAccessor(ADI_FileHandle fileH, long record, - ADI_CommentsHandle* commentsH); - - - // Closes the comments accessor, releasing the memory it used. - // Sets the ADI_CommentsHandle to 0. - // Params: ADI_CommentsHandle - handle to a comments accessor - // Return: a ADIResultCode for result of the operation - DLLEXPORT ADIResultCode ADI_CloseCommentsAccessor(ADI_CommentsHandle *commentsH); - - - // Retrieves information from the comment currently referenced by the comments accessor. - // Params: ADI_CommentsHandle - handle to a comments accessor - // tickPos - receives the tick position of the comment in the record [outparam] - // commentNum - receives the number of the comment [outparam] - // channel - receives the channel of the comment (-1 for all channel comments) [outparam] - // text - buffer to receive null terminated text for the comment (optional, may be NULL) [outparam] - // maxChars - the size of the text buffer in wchar_t s. The text will be truncated to fit in this size - // textLen - receives the number of characters needed to hold the full comment text, - // even if parameter text is NULL (optional, may be NULL) [outparam] - // Return: returns kResultBufferTooSmall if maxChars was too small to receive the full comment text. - // Returns kResultNoData if this accessor has reached the end of the comments in the record. - DLLEXPORT ADIResultCode ADI_GetCommentInfo(ADI_CommentsHandle commentsH, long *tickPos, long *channel, long *commentNum, wchar_t* text, - long maxChars, long *textLen); - - - // Advances the comments accessor to the next comment in the record - // Params: ADI_CommentsHandle - handle to a comments accessor - // Returns kResultNoData if this accessor has reached the end of the comments in the record. - DLLEXPORT ADIResultCode ADI_NextComment(ADI_CommentsHandle commentsH); - - - // Retrieves a block of sample data from the file into a buffer. Samples are in physical - // prefixed units. - // Params: fileH - ADI_FileHandle for the open file - // channel - the channel containing the desired data (starting from 0) - // record - the record containing the start position of the desired data - // (starting from 0) - // startPos - the start position as an offset from the start of the record (0) - // nLength - number of elements (ticks/samples) to retrieve - // dataType - specifies the type of data (ticks or samples) to retrieve - // data - pointer to a float array of 'nLength' in size - // e.g. float* data=(float*)malloc(sizeof(float*kDataSize)); [outparam] - // returned - the number of samples actually returned by the function (may be less - // than the amount requested) [outparam] - // Return: a ADIResultCode for result of the operation - DLLEXPORT ADIResultCode ADI_GetSamples(ADI_FileHandle fileH, long channel, long record, long startPos, - ADICDataFlags dataType, long nLength, float* data, long* returned); - - - // Retrieves the prefixed units of a channel, as a string. - // Params: fileH - ADI_FileHandle for the open file - // channel - the unit's channel (starting from 0) - // record - the unit's record (starting from 0) - // units - buffer to receive null terminated text for the units name (optional, may be NULL) [outparam] - // maxChars - the size of the text buffer in wchar_t s. The text will be truncated to fit in this size - // textLen - receives the number of characters needed to hold the full comment text, - // even if parameter text is NULL (optional, may be NULL) [outparam] - // Return: returns kResultBufferTooSmall if maxChars was too small to receive the full comment text. - // Return: a ADIResultCode for result of the operation - DLLEXPORT ADIResultCode ADI_GetUnitsName(ADI_FileHandle fileH, long channel, long record, wchar_t* units, - long maxChars, long *textLen); - - - // Retrieves the name of a channel, as a string. - // Params: fileH - ADI_FileHandle for the open file - // channel - the channel index (starting from 0) - // name - null-terminated text for the name [outparam] - // maxChars - the size used for the buffer. Must not exceed this when copying - // text into the buffer - // textLen - receives the number of characters needed to hold the full comment text, - // even if parameter text is NULL (optional, may be NULL) [outparam] - // Return: returns kResultBufferTooSmall if maxChars was too small to receive the full title text. - // Return: a ADIResultCode for result of the operation - DLLEXPORT ADIResultCode ADI_GetChannelName(ADI_FileHandle fileH, long channel, wchar_t* name, - long maxChars, long *textLen); - - - //------------------ - // Write Operations: - // - - // Sets the name of the specified channel. - // Params: file - ADI_FileHandle for the open file - // channel - the channel to set the name (starting from 0) - // name - null-terminated text string with the channel name - // Return: a ADIResultCode for result of the operation - DLLEXPORT ADIResultCode ADI_SetChannelName(ADI_FileHandle fileH, long channel, const wchar_t* name); - - - // Creates a new writer session for writing new data and returns a handle to that open writer for use in - // other related functions. - // Params: fileH - ADI_FileHandle for the open file - // writerH - ADI_WriterHandle for the new writing session [outparam] - // Return: a ADIResultCode for result of the operation - DLLEXPORT ADIResultCode ADI_CreateWriter(ADI_FileHandle fileH, ADI_WriterHandle* writerH); - - - // Sets the channel information for the specified channel in a new record to be written by the writer session. - // Params: writerH - ADI_WriterHandle for the writing session - // channel - the channel to receive the new info (starting from 0) - // enabled - boolean value set true (1) if data is to be added to this channel in the new record - // secondsPerSample - new sample period for this channel in the new record - // unitsName - null-terminated text string units for the channel record - // limits - Optional pointer to a struct holding maximum and minimum values between which valid - // data values in the channel fall. - // If NULL, the limits are +ve and -ve infinity. - // - // Return: a ADIResultCode for result of the operation - DLLEXPORT ADIResultCode ADI_SetChannelInfo(ADI_WriterHandle writerH, long channel, int enabled, - double secondsPerSample, const wchar_t* units, const ADIDataLimits *limits); - - - //Starts the writer recording a new record, setting the trigger time. - //The trigger time is the time origin of the record and may differ from the start time if - //there is a pre or post trigger delay, as specified by the trigMinusRecStart parameter. - // writerH - ADI_WriterHandle for the writing session - // triggerTime - time_t specifying the date and time of the trigger - // position for the new record. Measured as number of - // seconds from 1 Jan 1970 - // fracSecs - Provides fraction-resolution to the start position of - // the record ('triggerTime' parameter) - // trigMinusRecStart - trigger-time-minus-record-start-ticks. Specifies the - // difference between the time of trigger tick and the first - // tick in the record. This +ve for pre-trigger delay and - // -ve for post-trigger delay. - // Return: a ADIResultCode for result of the operation - DLLEXPORT ADIResultCode ADI_StartRecord(ADI_WriterHandle writerH, time_t triggerTime, - double fracSecs, long triggerMinusStartTicks); - - - // Writes new data samples into the specified channel record. - // Params: writerH - ADI_WriterHandle for the writing session - // channel - the channel to receive the new data (starting from 0) - // data - an array of new float data - // e.g. float* data = (float*)malloc(sizeof(float * numSamples)); - // dataType - specifies the type of data (ticks or samples) being added - // nSamples - number of samples in the array - // newTicksAdded - number of ticks by which the record increased as a result of adding these samples. - // This will usually be 0 for channels other than the first to which samples are added. - // In the multi-rate case, this can be greater than the number of samples added if - // the channel has a sample rate lower than the tick rate. - // Return: a ADIResultCode for result of the operation - DLLEXPORT ADIResultCode ADI_AddChannelSamples(ADI_WriterHandle writerH, long channel, - float* data, long nSamples, long *newTicksAdded); - - - // Ends the current record being written by the writer. - // Params: writerH - ADI_WriterHandle for the writer session - // Return: a ADIResultCode for result of the operation - DLLEXPORT ADIResultCode ADI_FinishRecord(ADI_WriterHandle writerH); - - // Ensures all changes to the file made via the writer session are written to the file. - // Params: writerH - ADI_WriterHandle for the writer session - // Return: a ADIResultCode for result of the operation - DLLEXPORT ADIResultCode ADI_CommitFile(ADI_WriterHandle writerH, long flags); - - // Terminates the writer session and releases resources used by the session. - // Sets the ADI_WriterHandle to 0. - // Also calls ADI_CommitFile() to ensure all changes to the file made via the - //writer session are written to the file. - // Params: writerH - ADI_WriterHandle for the writer session - // Return: a ADIResultCode for result of the operation - DLLEXPORT ADIResultCode ADI_CloseWriter(ADI_WriterHandle *writerH); - - - // Adds a new comment at the specified position in the existing data. - // Params: file - ADI_FileHandle for the open file - // channel - the channel to add the comment into, or -1 for all-channel comment - // record - the record containing the desired position of the new comment - // (starting from 0) - // tickPos - the tick position of the comment as an offset from the start of - // the record (0) - // text - the null-terminated text string for the new comment - // commentNum - the number of the newly added comment (optional, may be NULL) [outparam] - // Return: a ADIResultCode for result of the operation - DLLEXPORT ADIResultCode ADI_AddComment(ADI_FileHandle fileH, long channel, long record, long tickPos, - const wchar_t* text, long* commentNum); - - - // Deletes a comment from the specified position in the existing data. - // Params: file - ADI_FileHandle for the open file - // commentNum - the number of the comment to delete - // Return: a ADIResultCode for result of the operation - DLLEXPORT ADIResultCode ADI_DeleteComment(ADI_FileHandle fileH, long commentNum); - - - // Closes the open file and releases memory. - // If operation is successful, 'fileH' param will be be 0. - // Params: fileH - pointer to an ADI_FileHandle object [in/outparam] - // Return: a ADIResultCode for result of the operation - DLLEXPORT ADIResultCode ADI_CloseFile(ADI_FileHandle* fileH); - -#endif //ADI_USELOADIDATDLL - -#ifdef __cplusplus -} -#endif - +/** +* Copyright (c) 2011-2012 ADInstruments. All rights reserved. +* +* \ADIDatFileSDK_license_start +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* 2. The name of ADInstruments may not be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* 3. This is an unsupported product which you use at your own risk. For unofficial +* technical support, please use http://www.adinstruments.com/forum . +* +* THIS SOFTWARE IS PROVIDED BY ADINSTRUMENTS "AS IS" AND ANY EXPRESS OR IMPLIED +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE +* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ADINSTRUMENTS BE LIABLE FOR +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +* \ADIDatFileSDK_license_end +*/ + +//JAH Modifications +//==================================================== +//- removed trailing comma in enumerations +//- made enumerations typedef and added explicit alias + + +#ifndef ADIDatCAPI_H__ +#define ADIDatCAPI_H__ + + +#ifdef ADIDATIOWIN_EXPORTS +#define DLLEXPORT __declspec(dllexport) +#else +#define DLLEXPORT +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + + + // Result code values + typedef enum ADIResultCode + { + //Win32 error codes (HRESULTs) + kResultSuccess = 0, // operation succeeded + kResultErrorFlagBit = 0x80000000L, // high bit set if operation failed + kResultInvalidArg = 0x80070057L, // invalid argument. One (or more) of the arguments is invalid + kResultFail = 0x80004005L, // Unspecified error + kResultFileNotFound = 0x80030002L, // failure to find the specified file (check the path) + + + //Start of error codes specific to this API + kResultADICAPIMsgBase = 0xA0049000L, + + kResultFileIOError = kResultADICAPIMsgBase, // file IO error - could not read/write file + kResultFileOpenFail, // file failed to open + kResultInvalidFileHandle, // file handle is invalid + kResultInvalidPosition, // pos specified is outside the bounds of the record or file + kResultInvalidCommentNum, // invalid commentNum. Comment could not be found + kResultNoData, // the data requested was not present (e.g. no more comments in the record). + kResultBufferTooSmall // the buffer passed to a function to receive data (e.g. comment text) was not big enough to receive all the data. + + // new result codes must be added at the end + } ADIResultCode; + + + // File open modes + typedef enum ADIFileOpenMode + { + kOpenFileForReadOnly = 0, // opens the file as read-only, so data cannot be written + kOpenFileForReadAndWrite // opens the file as read/write + } ADIFileOpenMode; + + + // Data Types : ADICDataFlags + typedef enum ADICDataFlags + { + kADICDataAtSampleRate = 0, // specifies that the function uses samples + kADICDataAtTickRate = 0x80000000 // specifies that the function uses ticks + } ADICDataFlags; + + + //Struct holding maximum and minimum values between which valid + //data values in a channel fall. + typedef struct ADIDataLimits + { + float mMaxLimit; + float mMinLimit; + } ADIDataLimits; + + // Handles - essentially void* with a little added type safety. + struct ADI_FileHandle__ { int unused; }; typedef struct ADI_FileHandle__ *ADI_FileHandle; + struct ADI_WriterHandle__ { int unused; }; typedef struct ADI_WriterHandle__ *ADI_WriterHandle; + struct ADI_CommentsHandle__ { int unused; }; typedef struct ADI_CommentsHandle__ *ADI_CommentsHandle; + +// Define ADI_USELOADIDATDLL to link explicitly to the ADIDatDll. To link implicitly using the +// import library leave this undefined. +#ifndef ADI_USELOADIDATDLL + + + //-------------------- + // General Operations: + // + + + // Opens an existing *.adidat file for read and write operations and returns a pointer + // to it. + // If operation is successful, 'fileH' param will be be a handle to the file, else 0. + // Params: path - absolute, delimited path to the file, + // e.g. "C:\\MyData\\TestFile.adidat" + // fileH - pointer to an ADI_FileHandle object [outparam] + // mode - ADIFileOpenMode option for controlling the how the file is to be opened + // Return: a ADIResultCode for result of the operation + DLLEXPORT ADIResultCode ADI_OpenFile(const wchar_t* path, ADI_FileHandle* fileH, ADIFileOpenMode mode); + + + // Creates a new *.adidat file for write operations at the specified location and + // returns a pointer to it. + // If operation is successful, 'file' param will be be a handle to the file, else 0. + // Params: path - absolute, delimited path to the file, + // e.g. "C:\\MyData\\NewFile.adidat" + // fileH - pointer to an ADI_FileHandle object [outparam] + // Return: a ADIResultCode for result of the operation + DLLEXPORT ADIResultCode ADI_CreateFile(const wchar_t* path, ADI_FileHandle* fileH); + + + // Retrieves a text description of a result code returned from an API call. + // Params: code - an ADIResultCode value + // message - null-terminated text for the error message [outparam] + // maxChars - the size used for the buffer. Must not exceed this when copying + // text into the buffer + // textLen - receives the number of characters needed to hold the full comment text, + // even if parameter text is NULL (optional, may be NULL) [outparam] + // Return: returns kResultBufferTooSmall if maxChars was too small to receive the full title text. + // Return: a ADIResultCode for result of the operation + DLLEXPORT ADIResultCode ADI_GetErrorMessage(ADIResultCode code, wchar_t* messageOut, + long maxChars, long *textLen); + + + // Converts a tick position to a sample position for a given channel. + // Params: fileH - ADI_FileHandle for the open file + // channel - the channel index (starting from 0) + // record - the record index (starting from 0) + // tickInRecord - the tick position to be converted + // samplePosInRecord - the converted sample position [outparam] + // Return: a ADIResultCode for result of the operation + DLLEXPORT ADIResultCode ADI_TickToSamplePos(ADI_FileHandle fileH, long channel, long record, + long tickInRecord, double* samplePosInRecord); + + + // Converts a sample position to a tick position for a given channel. + // Params: fileH - ADI_FileHandle for the open file + // channel - the channel index (starting from 0) + // record - the record index (starting from 0) + // samplePosInRecord - the tick position to be converted + // tickInRecord - the converted sample position [outparam] + // Return: a ADIResultCode for result of the operation + DLLEXPORT ADIResultCode ADI_SamplePosToTick(ADI_FileHandle fileH, long channel, long record, + double samplePosInRecord, double* tickInRecord); + + + //----------------- + // Read Operations: + // + + + // Retrieves the number of records in the file. + // Params: fileH - ADI_FileHandle for the open file + // nRecords - the number of records in the file [outparam] + // Return: a ADIResultCode for result of the operation + DLLEXPORT ADIResultCode ADI_GetNumberOfRecords(ADI_FileHandle fileH, long* nRecords); + + + // Retrieves the number of channels in the file. + // Params: fileH - ADI_FileHandle for the open file + // nChannels - the number of channels in the file [outparam] + // Return: a ADIResultCode for result of the operation + DLLEXPORT ADIResultCode ADI_GetNumberOfChannels(ADI_FileHandle fileH, long* nChannels); + + + // Retrieves the number of ticks in the specified record. + // Params: fileH - ADI_FileHandle for the open file + // record - the record index (starting from 0) + // nTicks - the number of ticks in the record [outparam] + // Return: a ADIResultCode for result of the operation + DLLEXPORT ADIResultCode ADI_GetNumTicksInRecord(ADI_FileHandle fileH, long record, long* nTicks); + + + // Retrieves the tick period for the specified record and channel. + // Params: fileH - ADI_FileHandle for the open file + // channel - the channel in the record (starting from 0) + // record - the record index (starting from 0) + // secsPerTick - the tick period for the record [outparam] + // Return: a ADIResultCode for result of the operation + DLLEXPORT ADIResultCode ADI_GetRecordTickPeriod(ADI_FileHandle fileH, long channel, long record, + double* secsPerTick); + + + // Retrieves the number of samples in the specified record. + // Params: fileH - ADI_FileHandle for the open file + // channel - the channel in the record (starting from 0) + // record - the record index (starting from 0) + // nSamples - the number of samples in the record [outparam] + // Return: a ADIResultCode for result of the operation + DLLEXPORT ADIResultCode ADI_GetNumSamplesInRecord(ADI_FileHandle fileH, long channel, long record, + long* nSamples); + + + // Retrieves the sample period for the specified record. + // Params: fileH - ADI_FileHandle for the open file + // channel - the channel in the record (starting from 0) + // record - the record index (starting from 0) + // secsPerSample - the sample period for the record [outparam] + // Return: a ADIResultCode for result of the operation + DLLEXPORT ADIResultCode ADI_GetRecordSamplePeriod(ADI_FileHandle fileH, long channel, long record, + double* secsPerSample); + + + //Retrieves time information about the specified record. + //The trigger time is the time origin of the record and may differ from the start time if + //there is a pre or post trigger delay, as specified by the trigMinusRecStart parameter. + // Params: fileH - ADI_FileHandle for the open file + // record - the record index (starting from 0) + // triggerTime - time_t receives the date and time of the trigger + // position for the new record. Measured as number of + // seconds from 1 Jan 1970 + // fracSecs - receives the fractional seconds part of + // the record trigger time ('triggerTime' parameter) + // trigMinusRecStart - trigger-time-minus-record-start-ticks. Receives the + // difference between the time of trigger tick and the first + // tick in the record. This +ve for pre-trigger delay and + // -ve for post-trigger delay. + // Return: a ADIResultCode for result of the operation + DLLEXPORT ADIResultCode ADI_GetRecordTime(ADI_FileHandle fileH, long record, time_t *triggerTime, + double *fracSecs, long *triggerMinusStartTicks); + + + // Creates a comments accessor handle for the specified record. + // Params: fileH - ADI_FileHandle for the open file + // record - the record index (starting from 0) + // commentsH - handle to the new comments accessor for the record [outparam] + // Return: a ADIResultCode for result of the operation + DLLEXPORT ADIResultCode ADI_CreateCommentsAccessor(ADI_FileHandle fileH, long record, + ADI_CommentsHandle* commentsH); + + + // Closes the comments accessor, releasing the memory it used. + // Sets the ADI_CommentsHandle to 0. + // Params: ADI_CommentsHandle - handle to a comments accessor + // Return: a ADIResultCode for result of the operation + DLLEXPORT ADIResultCode ADI_CloseCommentsAccessor(ADI_CommentsHandle *commentsH); + + + // Retrieves information from the comment currently referenced by the comments accessor. + // Params: ADI_CommentsHandle - handle to a comments accessor + // tickPos - receives the tick position of the comment in the record [outparam] + // commentNum - receives the number of the comment [outparam] + // channel - receives the channel of the comment (-1 for all channel comments) [outparam] + // text - buffer to receive null terminated text for the comment (optional, may be NULL) [outparam] + // maxChars - the size of the text buffer in wchar_t s. The text will be truncated to fit in this size + // textLen - receives the number of characters needed to hold the full comment text, + // even if parameter text is NULL (optional, may be NULL) [outparam] + // Return: returns kResultBufferTooSmall if maxChars was too small to receive the full comment text. + // Returns kResultNoData if this accessor has reached the end of the comments in the record. + DLLEXPORT ADIResultCode ADI_GetCommentInfo(ADI_CommentsHandle commentsH, long *tickPos, long *channel, long *commentNum, wchar_t* text, + long maxChars, long *textLen); + + + // Advances the comments accessor to the next comment in the record + // Params: ADI_CommentsHandle - handle to a comments accessor + // Returns kResultNoData if this accessor has reached the end of the comments in the record. + DLLEXPORT ADIResultCode ADI_NextComment(ADI_CommentsHandle commentsH); + + + // Retrieves a block of sample data from the file into a buffer. Samples are in physical + // prefixed units. + // Params: fileH - ADI_FileHandle for the open file + // channel - the channel containing the desired data (starting from 0) + // record - the record containing the start position of the desired data + // (starting from 0) + // startPos - the start position as an offset from the start of the record (0) + // nLength - number of elements (ticks/samples) to retrieve + // dataType - specifies the type of data (ticks or samples) to retrieve + // data - pointer to a float array of 'nLength' in size + // e.g. float* data=(float*)malloc(sizeof(float*kDataSize)); [outparam] + // returned - the number of samples actually returned by the function (may be less + // than the amount requested) [outparam] + // Return: a ADIResultCode for result of the operation + DLLEXPORT ADIResultCode ADI_GetSamples(ADI_FileHandle fileH, long channel, long record, long startPos, + ADICDataFlags dataType, long nLength, float* data, long* returned); + + + // Retrieves the prefixed units of a channel, as a string. + // Params: fileH - ADI_FileHandle for the open file + // channel - the unit's channel (starting from 0) + // record - the unit's record (starting from 0) + // units - buffer to receive null terminated text for the units name (optional, may be NULL) [outparam] + // maxChars - the size of the text buffer in wchar_t s. The text will be truncated to fit in this size + // textLen - receives the number of characters needed to hold the full comment text, + // even if parameter text is NULL (optional, may be NULL) [outparam] + // Return: returns kResultBufferTooSmall if maxChars was too small to receive the full comment text. + // Return: a ADIResultCode for result of the operation + DLLEXPORT ADIResultCode ADI_GetUnitsName(ADI_FileHandle fileH, long channel, long record, wchar_t* units, + long maxChars, long *textLen); + + + // Retrieves the name of a channel, as a string. + // Params: fileH - ADI_FileHandle for the open file + // channel - the channel index (starting from 0) + // name - null-terminated text for the name [outparam] + // maxChars - the size used for the buffer. Must not exceed this when copying + // text into the buffer + // textLen - receives the number of characters needed to hold the full comment text, + // even if parameter text is NULL (optional, may be NULL) [outparam] + // Return: returns kResultBufferTooSmall if maxChars was too small to receive the full title text. + // Return: a ADIResultCode for result of the operation + DLLEXPORT ADIResultCode ADI_GetChannelName(ADI_FileHandle fileH, long channel, wchar_t* name, + long maxChars, long *textLen); + + + //------------------ + // Write Operations: + // + + // Sets the name of the specified channel. + // Params: file - ADI_FileHandle for the open file + // channel - the channel to set the name (starting from 0) + // name - null-terminated text string with the channel name + // Return: a ADIResultCode for result of the operation + DLLEXPORT ADIResultCode ADI_SetChannelName(ADI_FileHandle fileH, long channel, const wchar_t* name); + + + // Creates a new writer session for writing new data and returns a handle to that open writer for use in + // other related functions. + // Params: fileH - ADI_FileHandle for the open file + // writerH - ADI_WriterHandle for the new writing session [outparam] + // Return: a ADIResultCode for result of the operation + DLLEXPORT ADIResultCode ADI_CreateWriter(ADI_FileHandle fileH, ADI_WriterHandle* writerH); + + + // Sets the channel information for the specified channel in a new record to be written by the writer session. + // Params: writerH - ADI_WriterHandle for the writing session + // channel - the channel to receive the new info (starting from 0) + // enabled - boolean value set true (1) if data is to be added to this channel in the new record + // secondsPerSample - new sample period for this channel in the new record + // unitsName - null-terminated text string units for the channel record + // limits - Optional pointer to a struct holding maximum and minimum values between which valid + // data values in the channel fall. + // If NULL, the limits are +ve and -ve infinity. + // + // Return: a ADIResultCode for result of the operation + DLLEXPORT ADIResultCode ADI_SetChannelInfo(ADI_WriterHandle writerH, long channel, int enabled, + double secondsPerSample, const wchar_t* units, const ADIDataLimits *limits); + + + //Starts the writer recording a new record, setting the trigger time. + //The trigger time is the time origin of the record and may differ from the start time if + //there is a pre or post trigger delay, as specified by the trigMinusRecStart parameter. + // writerH - ADI_WriterHandle for the writing session + // triggerTime - time_t specifying the date and time of the trigger + // position for the new record. Measured as number of + // seconds from 1 Jan 1970 + // fracSecs - Provides fraction-resolution to the start position of + // the record ('triggerTime' parameter) + // trigMinusRecStart - trigger-time-minus-record-start-ticks. Specifies the + // difference between the time of trigger tick and the first + // tick in the record. This +ve for pre-trigger delay and + // -ve for post-trigger delay. + // Return: a ADIResultCode for result of the operation + DLLEXPORT ADIResultCode ADI_StartRecord(ADI_WriterHandle writerH, time_t triggerTime, + double fracSecs, long triggerMinusStartTicks); + + + // Writes new data samples into the specified channel record. + // Params: writerH - ADI_WriterHandle for the writing session + // channel - the channel to receive the new data (starting from 0) + // data - an array of new float data + // e.g. float* data = (float*)malloc(sizeof(float * numSamples)); + // dataType - specifies the type of data (ticks or samples) being added + // nSamples - number of samples in the array + // newTicksAdded - number of ticks by which the record increased as a result of adding these samples. + // This will usually be 0 for channels other than the first to which samples are added. + // In the multi-rate case, this can be greater than the number of samples added if + // the channel has a sample rate lower than the tick rate. + // Return: a ADIResultCode for result of the operation + DLLEXPORT ADIResultCode ADI_AddChannelSamples(ADI_WriterHandle writerH, long channel, + float* data, long nSamples, long *newTicksAdded); + + + // Ends the current record being written by the writer. + // Params: writerH - ADI_WriterHandle for the writer session + // Return: a ADIResultCode for result of the operation + DLLEXPORT ADIResultCode ADI_FinishRecord(ADI_WriterHandle writerH); + + // Ensures all changes to the file made via the writer session are written to the file. + // Params: writerH - ADI_WriterHandle for the writer session + // Return: a ADIResultCode for result of the operation + DLLEXPORT ADIResultCode ADI_CommitFile(ADI_WriterHandle writerH, long flags); + + // Terminates the writer session and releases resources used by the session. + // Sets the ADI_WriterHandle to 0. + // Also calls ADI_CommitFile() to ensure all changes to the file made via the + //writer session are written to the file. + // Params: writerH - ADI_WriterHandle for the writer session + // Return: a ADIResultCode for result of the operation + DLLEXPORT ADIResultCode ADI_CloseWriter(ADI_WriterHandle *writerH); + + + // Adds a new comment at the specified position in the existing data. + // Params: file - ADI_FileHandle for the open file + // channel - the channel to add the comment into, or -1 for all-channel comment + // record - the record containing the desired position of the new comment + // (starting from 0) + // tickPos - the tick position of the comment as an offset from the start of + // the record (0) + // text - the null-terminated text string for the new comment + // commentNum - the number of the newly added comment (optional, may be NULL) [outparam] + // Return: a ADIResultCode for result of the operation + DLLEXPORT ADIResultCode ADI_AddComment(ADI_FileHandle fileH, long channel, long record, long tickPos, + const wchar_t* text, long* commentNum); + + + // Deletes a comment from the specified position in the existing data. + // Params: file - ADI_FileHandle for the open file + // commentNum - the number of the comment to delete + // Return: a ADIResultCode for result of the operation + DLLEXPORT ADIResultCode ADI_DeleteComment(ADI_FileHandle fileH, long commentNum); + + + // Closes the open file and releases memory. + // If operation is successful, 'fileH' param will be be 0. + // Params: fileH - pointer to an ADI_FileHandle object [in/outparam] + // Return: a ADIResultCode for result of the operation + DLLEXPORT ADIResultCode ADI_CloseFile(ADI_FileHandle* fileH); + +#endif //ADI_USELOADIDATDLL + +#ifdef __cplusplus +} +#endif + #endif \ No newline at end of file diff --git a/src/Import/labchart/adi/+adi/private/ADIDatIOWin64.dll b/Import/labchart/adi/+adi/private/ADIDatIOWin64.dll similarity index 100% rename from src/Import/labchart/adi/+adi/private/ADIDatIOWin64.dll rename to Import/labchart/adi/+adi/private/ADIDatIOWin64.dll diff --git a/src/Import/labchart/adi/+adi/private/ADIDatIOWin64.lib b/Import/labchart/adi/+adi/private/ADIDatIOWin64.lib similarity index 100% rename from src/Import/labchart/adi/+adi/private/ADIDatIOWin64.lib rename to Import/labchart/adi/+adi/private/ADIDatIOWin64.lib diff --git a/src/Import/labchart/adi/+adi/private/c.m b/Import/labchart/adi/+adi/private/c.m similarity index 89% rename from src/Import/labchart/adi/+adi/private/c.m rename to Import/labchart/adi/+adi/private/c.m index 321ede26..a82871f9 100644 --- a/src/Import/labchart/adi/+adi/private/c.m +++ b/Import/labchart/adi/+adi/private/c.m @@ -1,4 +1,4 @@ -function output = c(input) - -output = int32(input); +function output = c(input) + +output = int32(input); end \ No newline at end of file diff --git a/src/Import/labchart/adi/+adi/private/c0.m b/Import/labchart/adi/+adi/private/c0.m similarity index 76% rename from src/Import/labchart/adi/+adi/private/c0.m rename to Import/labchart/adi/+adi/private/c0.m index d6445316..4468380c 100644 --- a/src/Import/labchart/adi/+adi/private/c0.m +++ b/Import/labchart/adi/+adi/private/c0.m @@ -1,5 +1,5 @@ -function output = c0(input) -% -% Helper function for correcting inputs to the mex function - +function output = c0(input) +% +% Helper function for correcting inputs to the mex function + output = int32(input-1); \ No newline at end of file diff --git a/src/Import/labchart/adi/+adi/private/clong.m b/Import/labchart/adi/+adi/private/clong.m similarity index 94% rename from src/Import/labchart/adi/+adi/private/clong.m rename to Import/labchart/adi/+adi/private/clong.m index 7764c8ca..8ec23904 100644 --- a/src/Import/labchart/adi/+adi/private/clong.m +++ b/Import/labchart/adi/+adi/private/clong.m @@ -1,8 +1,8 @@ -function num_out = clong(num_in) -% -% Convert to long type -% -% For right now I'm using int32, might need an 'if' statement at some -% point - num_out = int32(num_in); +function num_out = clong(num_in) +% +% Convert to long type +% +% For right now I'm using int32, might need an 'if' statement at some +% point + num_out = int32(num_in); end \ No newline at end of file diff --git a/src/Import/labchart/adi/+adi/private/sdk_mex.cpp b/Import/labchart/adi/+adi/private/sdk_mex.cpp similarity index 97% rename from src/Import/labchart/adi/+adi/private/sdk_mex.cpp rename to Import/labchart/adi/+adi/private/sdk_mex.cpp index 16eb7ff1..f61f0e6e 100644 --- a/src/Import/labchart/adi/+adi/private/sdk_mex.cpp +++ b/Import/labchart/adi/+adi/private/sdk_mex.cpp @@ -1,808 +1,808 @@ -/* - * - * Old compiling notes: - * -------------------- - * mex sdk_mex.cpp ADIDatIOWin.lib - * mex -v sdk_mex.cpp LoadADIDatDll.cpp ADIDatIOWin64.lib - * - * Compiling should be done via: - * adi.sdk.makeMex() - * - * http://www.mathworks.com/help/matlab/matlab_external/passing-arguments-to-shared-library-functions.html - * - */ - -#define MAX_STRING_LENGTH 500 //I decided to avoid trying to deal with any -//sort of dynamic allocation. Since strings aren't that long, I'm fine -//hardcoding this value for now, assuming that this value is plenty large - -#include -#include -#include -#include -#include -#include "mex.h" -#include "ADIDatCAPI_mex.h" -#include -//#include "LoadADIDatDll.h" - -int ref_count = 0; //NYI -int locked = 0; - -void setDoubleOutput(mxArray *plhs[],int index, double value) -{ - - //Sets a single scalar value at the output location specified - // - // Inputs: - // ------------------------------------ - // plhs : The output data - // index : which index to set the data for (0 based) - // value : The value to assign to that particular output - // - // Example: (In Matlab) - // [a,b] = testFunction() - // - // Let's say we are trying to set b to 5 - // - // setLongOutput(plhs,1,5) - - //NOTE: We've hardcoded the output to be a scalar - plhs[index] = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL); - double *p_value; - p_value = (double *)mxGetData(plhs[index]); - p_value[0] = value; -} - -void setInt64Output(mxArray *plhs[],int index, int64_t value) -{ - plhs[index] = mxCreateNumericMatrix(1,1,mxINT64_CLASS,mxREAL); - - - int64_t *p_value; - p_value = (int64_t *)mxGetData(plhs[index]); - p_value[0] = value; -} - -//TODO: It would be nice to template these ... -void setLongOutput(mxArray *plhs[],int index, long value) -{ - - //Sets a single scalar value at the output location specified - // - // Inputs: - // ------- - // plhs : The output data - // index : which index to set the data for (0 based) - // value : The value to assign to that particular output - // - // Example: (In Matlab) - // [a,b] = testFunction() - // - // Let's say we are trying to set b to 5 - // - // setLongOutput(plhs,1,5) - - //NOTE: We've hardcoded the output to be a scalar - - //TODO: Is this correct with a 64 bit system ????? - plhs[index] = mxCreateNumericMatrix(1,1,mxINT32_CLASS,mxREAL); - - - long *p_value; - p_value = (long *)mxGetData(plhs[index]); - p_value[0] = value; -} - -double getDoubleInput(const mxArray *prhs[], int index){ - - double *p_value; - p_value = (double *)mxGetData(prhs[index]); - - //Compare start time - - //Return only first value (assume only 1 value) - return p_value[0]; - -} - -int getIntInput(const mxArray *prhs[], int index){ - - int *p_value; - p_value = (int *)mxGetData(prhs[index]); - return p_value[0]; - -} - -long getLongInput(const mxArray *prhs[], int index){ - - long *p_value; - p_value = (long *)mxGetData(prhs[index]); - return p_value[0]; -} - -int64_t getInt64Input(const mxArray *prhs[], int index){ - - int64_t *p_value; - p_value = (int64_t *)mxGetData(prhs[index]); - return p_value[0]; -} - -//=================================================================== - -ADI_FileHandle getFileHandle(const mxArray *prhs[]) -{ - - //ASSUMPTION: We currently assume the file handle will be the second - //input to the function, after the function option (i.e. index 1) - - return ADI_FileHandle(getInt64Input(prhs,1)); -} - -ADI_CommentsHandle getCommentsHandle(const mxArray *prhs[]) -{ - - //TODO: I can replace this now with a call to getLongInput ... -// int *input_file_handle; -// input_file_handle = (int *)mxGetData(prhs[1]); -// return ADI_CommentsHandle(input_file_handle[0]); -// - return ADI_CommentsHandle(getInt64Input(prhs,1)); -} - -ADI_WriterHandle getWriterHandle(const mxArray *prhs[]){ - return ADI_WriterHandle(getLongInput(prhs,1)); -} - -wchar_t *getStringOutputPointer(mxArray *plhs[],int index) -{ - plhs[index] = mxCreateNumericMatrix(1,MAX_STRING_LENGTH,mxINT16_CLASS,mxREAL); - return (wchar_t *)mxGetData(plhs[index]); -} - -void setFileHandle(mxArray *plhs[], ADIResultCode result, ADI_FileHandle fileH){ - - //Used by openFile and createFile - - int64_t *fh_pointer; - //Assign to 2nd value, first is the status code ... - plhs[1] = mxCreateNumericMatrix(1,1,mxINT64_CLASS,mxREAL); - fh_pointer = (int64_t *) mxGetData(plhs[1]); - if (result == 0) - { - fh_pointer[0] = (int64_t)fileH; - } - else - { - fh_pointer[0] = 0; - } -} - -void setWriterHandle(mxArray *plhs[], ADIResultCode result, ADI_WriterHandle writerH){ - - int64_t *wh_pointer; - //Assign to 2nd value, first is the status code ... - plhs[1] = mxCreateNumericMatrix(1,1,mxINT64_CLASS,mxREAL); - wh_pointer = (int64_t *) mxGetData(plhs[1]); - if (result == 0) - { - wh_pointer[0] = (int64_t)writerH; - } - else - { - wh_pointer[0] = 0; - } -} - - -//========================================================================= -void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) -{ - //Documentation of the calling forms is given within each if clause - - if (!locked) - { - - - - //NOTE: If we run clear all this will clear the definition of - //this file and depending on whether or not we had open references - //could cause Matlab to crash. By locking this file we prevent - //clearing the file (which means we can't recompile it unless we - //close Matlab) but we also prevent Matlab from crashing. - // - //TODO: Implement allowing unlock by reference counting - //TODO: Alternatively we could pass in a command to unlock - mexLock(); - locked = 1; - } - - - ADI_FileHandle fileH(0); - - - //Setup output result code - //----------------------------------------------- - //Each function returns a result code, indicating if the function call - //worked or not. - ADIResultCode result; - int *out_result; //Each function will return a result code as well as - //possibly other values .. - plhs[0] = mxCreateNumericMatrix(1,1,mxINT32_CLASS,mxREAL); - out_result = (int *) mxGetData(plhs[0]); - - - //Which function to call - double function_option = mxGetScalar(prhs[0]); - - //Function list - //-------------------------------------- - // 0 ADI_OpenFile - // 1 ADI_GetNumberOfRecords - // 2 ADI_GetNumberOfChannels - // 3 ADI_GetNumTicksInRecord - // 4 ADI_GetRecordTickPeriod - // 5 ADI_GetNumSamplesInRecord - // 6 ADI_CreateCommentsAccessor - // 7 ADI_CloseCommentsAccessor - // 8 ADI_GetCommentInfo - // 9 ADI_NextComment - // 10 ADI_GetSamples - // 11 ADI_GetUnitsName - // 12 ADI_GetChannelName - // 13 ADI_CloseFile - // 14 ADI_GetErrorMessage - // 15 ADI_GetRecordSamplePeriod - // 16 ADI_GetRecordTime - // 17 ADI_CreateFile - - - if (function_option == 0) - { - // ADI_OpenFile <> openFile - // =================================================== - // [result_code,file_h] = sdk_mex(0,file_path) - - wchar_t *w_file_path = (wchar_t *)mxGetData(prhs[1]); - - //long openMode = getLongInput(prhs,2); - - result = ADI_OpenFile(w_file_path, &fileH, kOpenFileForReadOnly); - out_result[0] = result; - - setFileHandle(plhs,result,fileH); - } - else if (function_option == 0.5) - { - //This is a call to open the file for reading and writing - // - //TODO: Replace this with an input to function 0 - - wchar_t *w_file_path = (wchar_t *)mxGetData(prhs[1]); - - result = ADI_OpenFile(w_file_path, &fileH, kOpenFileForReadAndWrite); - out_result[0] = result; - - setFileHandle(plhs,result,fileH); - } - else if (function_option == 1) - { - // ADI_GetNumberOfRecords <> getNumberOfRecords - // ====================================================== - // [result_code,n_records] = sdk_mex(1,file_handle) - - long nRecords = 0; - fileH = getFileHandle(prhs); - - //ADIResultCode ADI_GetNumberOfRecords(ADI_FileHandle fileH, long* nRecords); - result = ADI_GetNumberOfRecords(fileH,&nRecords); - out_result[0] = result; - setLongOutput(plhs,1,nRecords); - - } - else if (function_option == 2) - { - // ADI_GetNumberOfChannels <> getNumberOfChannels - // ======================================================== - // [result_code,n_channels] = sdk_mex(2,file_handle) - - long nChannels = 0; - fileH = getFileHandle(prhs); - - //ADIResultCode ADI_GetNumberOfChannels(ADI_FileHandle fileH, long* nChannels); - result = ADI_GetNumberOfChannels(fileH,&nChannels); - out_result[0] = result; - setLongOutput(plhs,1,nChannels); - } - else if (function_option == 3) - { - // ADI_GetNumTicksInRecord <> getNTicksInRecord - // ====================================================== - // [result,n_ticks] = sdk_mex(3,file_handle,record_idx_0b) - - fileH = getFileHandle(prhs); - - //0 or 1 based ... - long record = getLongInput(prhs,2); - long nTicks = 0; - - //ADIResultCode ADI_GetNumTicksInRecord(ADI_FileHandle fileH, long record, long* nTicks); - result = ADI_GetNumTicksInRecord(fileH,record,&nTicks); - out_result[0] = result; - setLongOutput(plhs,1,nTicks); - } - else if (function_option == 4) - { - // ADI_GetRecordTickPeriod <> getTickPeriod - // ========================================================= - // [result,s_per_tick] = sdk_mex(4,file_handle,record_idx_0b,channel_idx_0b) - - fileH = getFileHandle(prhs); - - long record = getLongInput(prhs,2); - long channel = getLongInput(prhs,3); - double secsPerTick = 0; - - //ADIResultCode ADI_GetRecordTickPeriod(ADI_FileHandle fileH, long channel, long record, double* secsPerTick); - out_result[0] = ADI_GetRecordTickPeriod(fileH,channel,record,&secsPerTick); - setDoubleOutput(plhs,1,secsPerTick); - - } - else if (function_option == 5) - { - // ADI_GetNumSamplesInRecord <> getNSamplesInRecord - // ======================================================== - // [result_code,n_samples] = sdk_mex(5,file_handle,record_idx_0b,channel_idx_0b); - - fileH = getFileHandle(prhs); - - long record = getLongInput(prhs,2); - long channel = getLongInput(prhs,3); - long nSamples = 0; - - //ADIResultCode ADI_GetNumSamplesInRecord(ADI_FileHandle fileH, long channel, long record, long* nSamples); - out_result[0] = ADI_GetNumSamplesInRecord(fileH,channel,record,&nSamples); - setLongOutput(plhs,1,nSamples); - } - else if (function_option == 6) - { - // ADI_CreateCommentsAccessor <> getCommentAccessor - // ======================================================== - // [result_code,comments_h] = sdk_mex(6,file_handle,record_idx_0b); - - ADI_CommentsHandle commentsH(0); - fileH = getFileHandle(prhs); - long record = getLongInput(prhs,2); - - //ADIResultCode ADI_CreateCommentsAccessor(ADI_FileHandle fileH, long record, ADI_CommentsHandle* commentsH); - result = ADI_CreateCommentsAccessor(fileH,record,&commentsH); - out_result[0] = result; - - int64_t *p_c; - plhs[1] = mxCreateNumericMatrix(1,1,mxINT64_CLASS,mxREAL); - p_c = (int64_t *) mxGetData(plhs[1]); - if (result == 0) - p_c[0] = (int64_t)commentsH; - else - p_c[0] = 0; - } - else if (function_option == 7) - { - // ADI_CloseCommentsAccessor <> closeCommentAccessor - // ======================================================== - // result_code = sdk_mex(7,comments_h); - - ADI_CommentsHandle commentsH = getCommentsHandle(prhs); - - //ADIResultCode ADI_CloseCommentsAccessor(ADI_CommentsHandle *commentsH); - out_result[0] = ADI_CloseCommentsAccessor(&commentsH); - } - else if (function_option == 8) - { - // ADI_GetCommentInfo <> getCommentInfo - // ==================================================== - // [result_code,comment_string,comment_length,tick_pos,channel,comment_num] = sdk_mex(8,comment_h) - // - // Status: Done - - ADI_CommentsHandle commentsH = getCommentsHandle(prhs); - - wchar_t *messageOut = getStringOutputPointer(plhs,1); - long tickPos = 0; - long channel = 0; - long commentNum = 0; - long textLen = 0; - - - //ADIResultCode ADI_GetCommentInfo(ADI_CommentsHandle commentsH, long *tickPos, long *channel, long *commentNum, wchar_t* text,long maxChars, long *textLen); - // tickPos - receives the tick position of the comment in the record [outparam] - // commentNum - receives the number of the comment [outparam] - // channel - receives the channel of the comment (-1 for all channel comments) [outparam] - // text - buffer to receive null terminated text for the comment (optional, may be NULL) [outparam] - // maxChars - the size of the text buffer in wchar_t s. The text will be truncated to fit in this size - // textLen - receives the number of characters needed to hold the full comment text, - // even if parameter text is NULL (optional, may be NULL) [outparam] - - out_result[0] = ADI_GetCommentInfo(commentsH,&tickPos,&channel,&commentNum,messageOut,MAX_STRING_LENGTH,&textLen); - - setLongOutput(plhs,2,textLen); - setLongOutput(plhs,3,tickPos); - setLongOutput(plhs,4,channel); - setLongOutput(plhs,5,commentNum); - - } - else if (function_option == 9) - { - - // ADI_NextComment <> advanceComments - // ================================================== - // result_code = adi.sdk_mex(9,comments_h); - // - // Returns kResultNoData if there are no more comments ... - // - // Status: Done - - ADI_CommentsHandle commentsH = getCommentsHandle(prhs); - - //ADIResultCode ADI_NextComment(ADI_CommentsHandle commentsH); - out_result[0] = ADI_NextComment(commentsH); - } - else if (function_option == 10) - { - // ADI_GetSamples <> getChannelData - // =========================================================== - // [result,data,n_returned] = sdk_mex(10,file_h,channel_0b,record_0b,startPos,nLength,dataType) - - fileH = getFileHandle(prhs); - - long channel = getLongInput(prhs,2); - long record = getLongInput(prhs,3); - long startPos = getLongInput(prhs,4); - long nLength = getLongInput(prhs,5); - - ADICDataFlags dataType = static_cast(getLongInput(prhs,6)); - - plhs[1] = mxCreateNumericMatrix(1,(mwSize)nLength,mxSINGLE_CLASS,mxREAL); - float *data = (float *)mxGetData(plhs[1]); - - long returned = 0; - // Retrieves a block of sample data from the file into a buffer. Samples are in physical - // prefixed units. - //DLLEXPORT ADIResultCode ADI_GetSamples(ADI_FileHandle fileH, long channel, long record, long startPos, - // ADICDataFlags dataType, long nLength, float* data, long* returned); - out_result[0] = ADI_GetSamples(fileH,channel,record,startPos,dataType,nLength,data,&returned); - //out_result[0] = ADI_GetSamples(fileH,channel,record,startPos,kADICDataAtSampleRate,nLength,data,&returned); - - setLongOutput(plhs,2,returned); - - //out_result[0] = 4; - } - else if (function_option == 11) - { - // ADI_GetUnitsName <> getUnits - // ======================================= - // [result_code,str_data,str_length] = sdk_mex(11,file_h,record,channel); - - //Inputs - fileH = getFileHandle(prhs); - long record = getLongInput(prhs,2); - long channel = getLongInput(prhs,3); - - //Outputs - long textLen = 0; - wchar_t *unitsOut = getStringOutputPointer(plhs,1); - - - // Retrieves the prefixed units of a channel, as a string. - // - //ADIResultCode ADI_GetUnitsName(ADI_FileHandle fileH, long channel, long record, wchar_t* units, long maxChars, long *textLen); - out_result[0] = ADI_GetUnitsName(fileH, channel, record, unitsOut, MAX_STRING_LENGTH, &textLen); - setLongOutput(plhs,2,textLen); - } - else if (function_option == 12) - { - // ADI_GetChannelName <> getChannelName - // ============================================= - // [result_code,str_data,str_length] = sdk_mex(12,file_h,channel); - - - //Inputs - fileH = getFileHandle(prhs); - long channel = getLongInput(prhs,2); - - //Outputs - long textLen = 0; - wchar_t *nameOut = getStringOutputPointer(plhs,1); - - // Retrieves the name of a channel, as a string. - - //ADIResultCode ADI_GetChannelName(ADI_FileHandle fileH, long channel, wchar_t* name, long maxChars, long *textLen); - out_result[0] = ADI_GetChannelName(fileH, channel, nameOut, MAX_STRING_LENGTH, &textLen); - setLongOutput(plhs,2,textLen); - } - else if (function_option == 13) - { - // ADI_CloseFile <> closeFile - // ============================================================== - // - - fileH = getFileHandle(prhs); - result = ADI_CloseFile(&fileH); - out_result[0] = result; - } - else if (function_option == 14) - { - // ADI_GetErrorMessage <> getErrorMessage - // ============================================================== - // err_msg = sdk_mex(14,error_code) - - long textLen = 0; - - wchar_t *messageOut = getStringOutputPointer(plhs,1); - - ADIResultCode code = (ADIResultCode)getLongInput(prhs,1); - - //ADIResultCode ADI_GetErrorMessage(ADIResultCode code, wchar_t* messageOut, long maxChars, long *textLen); - out_result[0] = ADI_GetErrorMessage(code, messageOut, MAX_STRING_LENGTH, &textLen); - setLongOutput(plhs,2,textLen); - - } - else if (function_option == 15) - { - // ADI_GetRecordSamplePeriod <> getSamplePeriod - // ============================================================== - // [result_code,dt_channel] = sdk_mex(15,file_h,record,channel) - - fileH = getFileHandle(prhs); - long record = getLongInput(prhs,2); - long channel = getLongInput(prhs,3); - double secsPerSample = 0; - - out_result[0] = ADI_GetRecordSamplePeriod(fileH, channel, record, &secsPerSample); - setDoubleOutput(plhs,1,secsPerSample); - } - else if (function_option == 16) - { - // ADI_GetRecordTime <> getRecordStartTime - // ============================================================== - // [result_code,trigger_time,frac_secs,trigger_minus_rec_start] = sdk_mex(16,file_h,record) - - fileH = getFileHandle(prhs); - long record = getLongInput(prhs,2); - - time_t triggerTime = 0; - double fracSecs = 0; - long triggerMinusStartTicks = 0; - - //Retrieves time information about the specified record. - //The trigger time is the time origin of the record and may differ from the start time if - //there is a pre or post trigger delay, as specified by the trigMinusRecStart parameter. - // Params: fileH - ADI_FileHandle for the open file - // record - the record index (starting from 0) - // triggerTime - time_t receives the date and time of the trigger - // position for the new record. Measured as number of - // seconds from 1 Jan 1970 - // fracSecs - receives the fractional seconds part of - // the record trigger time ('triggerTime' parameter) - // trigMinusRecStart - trigger-time-minus-record-start-ticks. Receives the - // difference between the time of trigger tick and the first - // tick in the record. This +ve for pre-trigger delay and - // -ve for post-trigger delay. - // Return: a ADIResultCode for result of the operation - - //DLLEXPORT ADIResultCode ADI_GetRecordTime(ADI_FileHandle fileH, long record, time_t *triggerTime, - //double *fracSecs, long *triggerMinusStartTicks); - - out_result[0] = ADI_GetRecordTime(fileH, record, &triggerTime, &fracSecs, &triggerMinusStartTicks); - - setDoubleOutput(plhs,1,(double)triggerTime); - setDoubleOutput(plhs,2,fracSecs); - setLongOutput(plhs,3,triggerMinusStartTicks); - - } - else if (function_option == 17){ - // - // ADI_CreateFile <> createFile - // ============================================================== - // [result_code,file_h] = sdk_mex(17,file_path) - // - // Implemented via sdk.createFile - - wchar_t *w_file_path = (wchar_t *)mxGetData(prhs[1]); - - result = ADI_CreateFile(w_file_path, &fileH); - out_result[0] = result; - - setFileHandle(plhs,result,fileH); - } - else if (function_option == 18){ - // - // ADI_SetChannelName <> setChannelName - // ============================================================== - // [result_code,file_h] = sdk_mex(18,file_h,channel,name) - // - // Implemented via sdk.setChannelName - - fileH = getFileHandle(prhs); - long channel = getLongInput(prhs,2); - wchar_t *channel_name = (wchar_t *)mxGetData(prhs[3]); - - out_result[0] = ADI_SetChannelName(fileH, channel, channel_name); - } - else if (function_option == 19){ - // - // ADI_CreateWriter <> createDataWriter - // =========================================== - // [result_code,writer_h] = sdk_mex(19,file_h) - // - // Implemented via sdk.createDataWriter - - ADI_WriterHandle writerH(0); - - fileH = getFileHandle(prhs); - - result = ADI_CreateWriter(fileH,&writerH); - out_result[0] = result; - - setWriterHandle(plhs,result,writerH); - } - else if (function_option == 20){ - // - // ADI_SetChannelInfo <> setChannelInfo - // =========================================== - // [result_code] = sdk_mex(20,writer_h,channel,enabled,seconds_per_sample,units,limits) - // - // implemented via adi.sdk.setChannelInfo - - ADI_WriterHandle writerH = getWriterHandle(prhs); - - long channel = getLongInput(prhs,2); - int enabled = getIntInput(prhs,3); - double seconds_per_sample = getDoubleInput(prhs,4); - wchar_t *units = (wchar_t *)mxGetData(prhs[5]); - float *temp_limits = (float *)mxGetData(prhs[5]); - ADIDataLimits limits; - limits.mMaxLimit = temp_limits[1]; - limits.mMinLimit = temp_limits[0]; - - out_result[0] = ADI_SetChannelInfo(writerH, channel, enabled, seconds_per_sample, units, &limits); - -// DLLEXPORT ADIResultCode ADI_SetChannelInfo(ADI_WriterHandle writerH, long channel, int enabled, -// double secondsPerSample, const wchar_t* units, const ADIDataLimits *limits); - - } - else if (function_option == 21){ - // - // ADI_StartRecord <> startRecord - // =========================================== - // result_code = sdk_mex(21, writerH, trigger_time, fractional_seconds, trigger_minus_rec_start) - // - // implemented via adi.sdk.startRecord - - ADI_WriterHandle writerH = getWriterHandle(prhs); - time_t trigger_time = (time_t)getDoubleInput(prhs,2); - double fractional_seconds = getDoubleInput(prhs,3); - long trigger_minus_rec_start = getLongInput(prhs,4); - - out_result[0] = ADI_StartRecord(writerH, trigger_time, fractional_seconds, trigger_minus_rec_start); - -// DLLEXPORT ADIResultCode ADI_StartRecord(ADI_WriterHandle writerH, time_t triggerTime, -// double fracSecs, long triggerMinusStartTicks); - } - else if (function_option == 22){ - // - // ADI_AddChannelSamples <> addChannelSamples - // =========================================== - // [result_code,new_ticks_added] = sdk_mex(22, writerH, channel, data, n_samples) - // - // adi.sdk.addChannelSamples - - ADI_WriterHandle writerH = getWriterHandle(prhs); - long channel = getLongInput(prhs,2); - float *data = (float *)mxGetData(prhs[3]); - long n_samples = (long)mxGetNumberOfElements(prhs[3]); - long new_ticks_added = 0; - - out_result[0] = ADI_AddChannelSamples(writerH, channel, data, n_samples, &new_ticks_added); - - setLongOutput(plhs,1,new_ticks_added); - -// DLLEXPORT ADIResultCode ADI_AddChannelSamples(ADI_WriterHandle writerH, long channel, -// float* data, long nSamples, long *newTicksAdded); - } - else if (function_option == 23){ - // - // ADI_FinishRecord <> finishRecord - // =========================================== - // [result_code] = sdk_mex(23, writerH) - // - // Implemented via adi.sdk.finishRecord - - ADI_WriterHandle writerH = getWriterHandle(prhs); - - out_result[0] = ADI_FinishRecord(writerH); - -// DLLEXPORT ADIResultCode ADI_FinishRecord(ADI_WriterHandle writerH); - } - else if (function_option == 24){ - // - // ADI_CommitFile <> commitFile - // =========================================== - // [result_code] = sdk_mex(24, writerH, flags) - // - // Implemented via adi.sdk.commitFile - - ADI_WriterHandle writerH = getWriterHandle(prhs); - - //TODO: What are the flags?????? - - out_result[0] = ADI_CommitFile(writerH, 0); - -// DLLEXPORT ADIResultCode ADI_CommitFile(ADI_WriterHandle writerH, long flags); - } - else if (function_option == 25){ - // - // ADI_CloseWriter <> closeWriter - // =========================================== - // [result_code] = sdk_mex(25, writerH) - // - // Implemented via adi.sdk.closeWriter - - ADI_WriterHandle writerH = getWriterHandle(prhs); - - out_result[0] = ADI_CloseWriter(&writerH); - -// DLLEXPORT ADIResultCode ADI_CloseWriter(ADI_WriterHandle *writerH); - } - else if (function_option == 26){ - // - // ADI_AddComment <> addComment - // =========================================== - // [result_code, comment_number] = - // sdk_mex(26, file_h, channel, record, tick_position, text) - // - // Implemented via adi.sdk.addComment - - fileH = getFileHandle(prhs); - long channel = getLongInput(prhs,2); - long record = getLongInput(prhs,3); - long tick_position = getLongInput(prhs,4); - wchar_t *text = (wchar_t *)mxGetData(prhs[5]); - long comment_number = 0; - //long comment_number = getLongInput(prhs,6); - - out_result[0] = ADI_AddComment(fileH, channel, record, tick_position, text, &comment_number); - - setLongOutput(plhs,1,comment_number); - -// DLLEXPORT ADIResultCode ADI_AddComment(ADI_FileHandle fileH, long channel, long record, long tickPos, -// const wchar_t* text, long* commentNum); - } - else if (function_option == 27){ - // - // ADI_DeleteComment <> deleteComment - // =========================================== - // result_code = sdk_mex(27,file_h,comment_number) - // - // Implemented via adi.sdk.deleteComment - - fileH = getFileHandle(prhs); - long comment_number = getLongInput(prhs,2); - - out_result[0] = ADI_DeleteComment(fileH,comment_number); - -// DLLEXPORT ADIResultCode ADI_DeleteComment(ADI_FileHandle fileH, long commentNum); - } - else if (function_option == 100){ - mexUnlock(); - locked = 0; - } - else - { - mexErrMsgIdAndTxt("adinstruments:sdk_mex", - "Invalid function option"); - } - - //ADI_GetRecordSamplePeriod - //ADI_GetRecordTime +/* + * + * Old compiling notes: + * -------------------- + * mex sdk_mex.cpp ADIDatIOWin.lib + * mex -v sdk_mex.cpp LoadADIDatDll.cpp ADIDatIOWin64.lib + * + * Compiling should be done via: + * adi.sdk.makeMex() + * + * http://www.mathworks.com/help/matlab/matlab_external/passing-arguments-to-shared-library-functions.html + * + */ + +#define MAX_STRING_LENGTH 500 //I decided to avoid trying to deal with any +//sort of dynamic allocation. Since strings aren't that long, I'm fine +//hardcoding this value for now, assuming that this value is plenty large + +#include +#include +#include +#include +#include +#include "mex.h" +#include "ADIDatCAPI_mex.h" +#include +//#include "LoadADIDatDll.h" + +int ref_count = 0; //NYI +int locked = 0; + +void setDoubleOutput(mxArray *plhs[],int index, double value) +{ + + //Sets a single scalar value at the output location specified + // + // Inputs: + // ------------------------------------ + // plhs : The output data + // index : which index to set the data for (0 based) + // value : The value to assign to that particular output + // + // Example: (In Matlab) + // [a,b] = testFunction() + // + // Let's say we are trying to set b to 5 + // + // setLongOutput(plhs,1,5) + + //NOTE: We've hardcoded the output to be a scalar + plhs[index] = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL); + double *p_value; + p_value = (double *)mxGetData(plhs[index]); + p_value[0] = value; +} + +void setInt64Output(mxArray *plhs[],int index, int64_t value) +{ + plhs[index] = mxCreateNumericMatrix(1,1,mxINT64_CLASS,mxREAL); + + + int64_t *p_value; + p_value = (int64_t *)mxGetData(plhs[index]); + p_value[0] = value; +} + +//TODO: It would be nice to template these ... +void setLongOutput(mxArray *plhs[],int index, long value) +{ + + //Sets a single scalar value at the output location specified + // + // Inputs: + // ------- + // plhs : The output data + // index : which index to set the data for (0 based) + // value : The value to assign to that particular output + // + // Example: (In Matlab) + // [a,b] = testFunction() + // + // Let's say we are trying to set b to 5 + // + // setLongOutput(plhs,1,5) + + //NOTE: We've hardcoded the output to be a scalar + + //TODO: Is this correct with a 64 bit system ????? + plhs[index] = mxCreateNumericMatrix(1,1,mxINT32_CLASS,mxREAL); + + + long *p_value; + p_value = (long *)mxGetData(plhs[index]); + p_value[0] = value; +} + +double getDoubleInput(const mxArray *prhs[], int index){ + + double *p_value; + p_value = (double *)mxGetData(prhs[index]); + + //Compare start time + + //Return only first value (assume only 1 value) + return p_value[0]; + +} + +int getIntInput(const mxArray *prhs[], int index){ + + int *p_value; + p_value = (int *)mxGetData(prhs[index]); + return p_value[0]; + +} + +long getLongInput(const mxArray *prhs[], int index){ + + long *p_value; + p_value = (long *)mxGetData(prhs[index]); + return p_value[0]; +} + +int64_t getInt64Input(const mxArray *prhs[], int index){ + + int64_t *p_value; + p_value = (int64_t *)mxGetData(prhs[index]); + return p_value[0]; +} + +//=================================================================== + +ADI_FileHandle getFileHandle(const mxArray *prhs[]) +{ + + //ASSUMPTION: We currently assume the file handle will be the second + //input to the function, after the function option (i.e. index 1) + + return ADI_FileHandle(getInt64Input(prhs,1)); +} + +ADI_CommentsHandle getCommentsHandle(const mxArray *prhs[]) +{ + + //TODO: I can replace this now with a call to getLongInput ... +// int *input_file_handle; +// input_file_handle = (int *)mxGetData(prhs[1]); +// return ADI_CommentsHandle(input_file_handle[0]); +// + return ADI_CommentsHandle(getInt64Input(prhs,1)); +} + +ADI_WriterHandle getWriterHandle(const mxArray *prhs[]){ + return ADI_WriterHandle(getLongInput(prhs,1)); +} + +wchar_t *getStringOutputPointer(mxArray *plhs[],int index) +{ + plhs[index] = mxCreateNumericMatrix(1,MAX_STRING_LENGTH,mxINT16_CLASS,mxREAL); + return (wchar_t *)mxGetData(plhs[index]); +} + +void setFileHandle(mxArray *plhs[], ADIResultCode result, ADI_FileHandle fileH){ + + //Used by openFile and createFile + + int64_t *fh_pointer; + //Assign to 2nd value, first is the status code ... + plhs[1] = mxCreateNumericMatrix(1,1,mxINT64_CLASS,mxREAL); + fh_pointer = (int64_t *) mxGetData(plhs[1]); + if (result == 0) + { + fh_pointer[0] = (int64_t)fileH; + } + else + { + fh_pointer[0] = 0; + } +} + +void setWriterHandle(mxArray *plhs[], ADIResultCode result, ADI_WriterHandle writerH){ + + int64_t *wh_pointer; + //Assign to 2nd value, first is the status code ... + plhs[1] = mxCreateNumericMatrix(1,1,mxINT64_CLASS,mxREAL); + wh_pointer = (int64_t *) mxGetData(plhs[1]); + if (result == 0) + { + wh_pointer[0] = (int64_t)writerH; + } + else + { + wh_pointer[0] = 0; + } +} + + +//========================================================================= +void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) +{ + //Documentation of the calling forms is given within each if clause + + if (!locked) + { + + + + //NOTE: If we run clear all this will clear the definition of + //this file and depending on whether or not we had open references + //could cause Matlab to crash. By locking this file we prevent + //clearing the file (which means we can't recompile it unless we + //close Matlab) but we also prevent Matlab from crashing. + // + //TODO: Implement allowing unlock by reference counting + //TODO: Alternatively we could pass in a command to unlock + mexLock(); + locked = 1; + } + + + ADI_FileHandle fileH(0); + + + //Setup output result code + //----------------------------------------------- + //Each function returns a result code, indicating if the function call + //worked or not. + ADIResultCode result; + int *out_result; //Each function will return a result code as well as + //possibly other values .. + plhs[0] = mxCreateNumericMatrix(1,1,mxINT32_CLASS,mxREAL); + out_result = (int *) mxGetData(plhs[0]); + + + //Which function to call + double function_option = mxGetScalar(prhs[0]); + + //Function list + //-------------------------------------- + // 0 ADI_OpenFile + // 1 ADI_GetNumberOfRecords + // 2 ADI_GetNumberOfChannels + // 3 ADI_GetNumTicksInRecord + // 4 ADI_GetRecordTickPeriod + // 5 ADI_GetNumSamplesInRecord + // 6 ADI_CreateCommentsAccessor + // 7 ADI_CloseCommentsAccessor + // 8 ADI_GetCommentInfo + // 9 ADI_NextComment + // 10 ADI_GetSamples + // 11 ADI_GetUnitsName + // 12 ADI_GetChannelName + // 13 ADI_CloseFile + // 14 ADI_GetErrorMessage + // 15 ADI_GetRecordSamplePeriod + // 16 ADI_GetRecordTime + // 17 ADI_CreateFile + + + if (function_option == 0) + { + // ADI_OpenFile <> openFile + // =================================================== + // [result_code,file_h] = sdk_mex(0,file_path) + + wchar_t *w_file_path = (wchar_t *)mxGetData(prhs[1]); + + //long openMode = getLongInput(prhs,2); + + result = ADI_OpenFile(w_file_path, &fileH, kOpenFileForReadOnly); + out_result[0] = result; + + setFileHandle(plhs,result,fileH); + } + else if (function_option == 0.5) + { + //This is a call to open the file for reading and writing + // + //TODO: Replace this with an input to function 0 + + wchar_t *w_file_path = (wchar_t *)mxGetData(prhs[1]); + + result = ADI_OpenFile(w_file_path, &fileH, kOpenFileForReadAndWrite); + out_result[0] = result; + + setFileHandle(plhs,result,fileH); + } + else if (function_option == 1) + { + // ADI_GetNumberOfRecords <> getNumberOfRecords + // ====================================================== + // [result_code,n_records] = sdk_mex(1,file_handle) + + long nRecords = 0; + fileH = getFileHandle(prhs); + + //ADIResultCode ADI_GetNumberOfRecords(ADI_FileHandle fileH, long* nRecords); + result = ADI_GetNumberOfRecords(fileH,&nRecords); + out_result[0] = result; + setLongOutput(plhs,1,nRecords); + + } + else if (function_option == 2) + { + // ADI_GetNumberOfChannels <> getNumberOfChannels + // ======================================================== + // [result_code,n_channels] = sdk_mex(2,file_handle) + + long nChannels = 0; + fileH = getFileHandle(prhs); + + //ADIResultCode ADI_GetNumberOfChannels(ADI_FileHandle fileH, long* nChannels); + result = ADI_GetNumberOfChannels(fileH,&nChannels); + out_result[0] = result; + setLongOutput(plhs,1,nChannels); + } + else if (function_option == 3) + { + // ADI_GetNumTicksInRecord <> getNTicksInRecord + // ====================================================== + // [result,n_ticks] = sdk_mex(3,file_handle,record_idx_0b) + + fileH = getFileHandle(prhs); + + //0 or 1 based ... + long record = getLongInput(prhs,2); + long nTicks = 0; + + //ADIResultCode ADI_GetNumTicksInRecord(ADI_FileHandle fileH, long record, long* nTicks); + result = ADI_GetNumTicksInRecord(fileH,record,&nTicks); + out_result[0] = result; + setLongOutput(plhs,1,nTicks); + } + else if (function_option == 4) + { + // ADI_GetRecordTickPeriod <> getTickPeriod + // ========================================================= + // [result,s_per_tick] = sdk_mex(4,file_handle,record_idx_0b,channel_idx_0b) + + fileH = getFileHandle(prhs); + + long record = getLongInput(prhs,2); + long channel = getLongInput(prhs,3); + double secsPerTick = 0; + + //ADIResultCode ADI_GetRecordTickPeriod(ADI_FileHandle fileH, long channel, long record, double* secsPerTick); + out_result[0] = ADI_GetRecordTickPeriod(fileH,channel,record,&secsPerTick); + setDoubleOutput(plhs,1,secsPerTick); + + } + else if (function_option == 5) + { + // ADI_GetNumSamplesInRecord <> getNSamplesInRecord + // ======================================================== + // [result_code,n_samples] = sdk_mex(5,file_handle,record_idx_0b,channel_idx_0b); + + fileH = getFileHandle(prhs); + + long record = getLongInput(prhs,2); + long channel = getLongInput(prhs,3); + long nSamples = 0; + + //ADIResultCode ADI_GetNumSamplesInRecord(ADI_FileHandle fileH, long channel, long record, long* nSamples); + out_result[0] = ADI_GetNumSamplesInRecord(fileH,channel,record,&nSamples); + setLongOutput(plhs,1,nSamples); + } + else if (function_option == 6) + { + // ADI_CreateCommentsAccessor <> getCommentAccessor + // ======================================================== + // [result_code,comments_h] = sdk_mex(6,file_handle,record_idx_0b); + + ADI_CommentsHandle commentsH(0); + fileH = getFileHandle(prhs); + long record = getLongInput(prhs,2); + + //ADIResultCode ADI_CreateCommentsAccessor(ADI_FileHandle fileH, long record, ADI_CommentsHandle* commentsH); + result = ADI_CreateCommentsAccessor(fileH,record,&commentsH); + out_result[0] = result; + + int64_t *p_c; + plhs[1] = mxCreateNumericMatrix(1,1,mxINT64_CLASS,mxREAL); + p_c = (int64_t *) mxGetData(plhs[1]); + if (result == 0) + p_c[0] = (int64_t)commentsH; + else + p_c[0] = 0; + } + else if (function_option == 7) + { + // ADI_CloseCommentsAccessor <> closeCommentAccessor + // ======================================================== + // result_code = sdk_mex(7,comments_h); + + ADI_CommentsHandle commentsH = getCommentsHandle(prhs); + + //ADIResultCode ADI_CloseCommentsAccessor(ADI_CommentsHandle *commentsH); + out_result[0] = ADI_CloseCommentsAccessor(&commentsH); + } + else if (function_option == 8) + { + // ADI_GetCommentInfo <> getCommentInfo + // ==================================================== + // [result_code,comment_string,comment_length,tick_pos,channel,comment_num] = sdk_mex(8,comment_h) + // + // Status: Done + + ADI_CommentsHandle commentsH = getCommentsHandle(prhs); + + wchar_t *messageOut = getStringOutputPointer(plhs,1); + long tickPos = 0; + long channel = 0; + long commentNum = 0; + long textLen = 0; + + + //ADIResultCode ADI_GetCommentInfo(ADI_CommentsHandle commentsH, long *tickPos, long *channel, long *commentNum, wchar_t* text,long maxChars, long *textLen); + // tickPos - receives the tick position of the comment in the record [outparam] + // commentNum - receives the number of the comment [outparam] + // channel - receives the channel of the comment (-1 for all channel comments) [outparam] + // text - buffer to receive null terminated text for the comment (optional, may be NULL) [outparam] + // maxChars - the size of the text buffer in wchar_t s. The text will be truncated to fit in this size + // textLen - receives the number of characters needed to hold the full comment text, + // even if parameter text is NULL (optional, may be NULL) [outparam] + + out_result[0] = ADI_GetCommentInfo(commentsH,&tickPos,&channel,&commentNum,messageOut,MAX_STRING_LENGTH,&textLen); + + setLongOutput(plhs,2,textLen); + setLongOutput(plhs,3,tickPos); + setLongOutput(plhs,4,channel); + setLongOutput(plhs,5,commentNum); + + } + else if (function_option == 9) + { + + // ADI_NextComment <> advanceComments + // ================================================== + // result_code = adi.sdk_mex(9,comments_h); + // + // Returns kResultNoData if there are no more comments ... + // + // Status: Done + + ADI_CommentsHandle commentsH = getCommentsHandle(prhs); + + //ADIResultCode ADI_NextComment(ADI_CommentsHandle commentsH); + out_result[0] = ADI_NextComment(commentsH); + } + else if (function_option == 10) + { + // ADI_GetSamples <> getChannelData + // =========================================================== + // [result,data,n_returned] = sdk_mex(10,file_h,channel_0b,record_0b,startPos,nLength,dataType) + + fileH = getFileHandle(prhs); + + long channel = getLongInput(prhs,2); + long record = getLongInput(prhs,3); + long startPos = getLongInput(prhs,4); + long nLength = getLongInput(prhs,5); + + ADICDataFlags dataType = static_cast(getLongInput(prhs,6)); + + plhs[1] = mxCreateNumericMatrix(1,(mwSize)nLength,mxSINGLE_CLASS,mxREAL); + float *data = (float *)mxGetData(plhs[1]); + + long returned = 0; + // Retrieves a block of sample data from the file into a buffer. Samples are in physical + // prefixed units. + //DLLEXPORT ADIResultCode ADI_GetSamples(ADI_FileHandle fileH, long channel, long record, long startPos, + // ADICDataFlags dataType, long nLength, float* data, long* returned); + out_result[0] = ADI_GetSamples(fileH,channel,record,startPos,dataType,nLength,data,&returned); + //out_result[0] = ADI_GetSamples(fileH,channel,record,startPos,kADICDataAtSampleRate,nLength,data,&returned); + + setLongOutput(plhs,2,returned); + + //out_result[0] = 4; + } + else if (function_option == 11) + { + // ADI_GetUnitsName <> getUnits + // ======================================= + // [result_code,str_data,str_length] = sdk_mex(11,file_h,record,channel); + + //Inputs + fileH = getFileHandle(prhs); + long record = getLongInput(prhs,2); + long channel = getLongInput(prhs,3); + + //Outputs + long textLen = 0; + wchar_t *unitsOut = getStringOutputPointer(plhs,1); + + + // Retrieves the prefixed units of a channel, as a string. + // + //ADIResultCode ADI_GetUnitsName(ADI_FileHandle fileH, long channel, long record, wchar_t* units, long maxChars, long *textLen); + out_result[0] = ADI_GetUnitsName(fileH, channel, record, unitsOut, MAX_STRING_LENGTH, &textLen); + setLongOutput(plhs,2,textLen); + } + else if (function_option == 12) + { + // ADI_GetChannelName <> getChannelName + // ============================================= + // [result_code,str_data,str_length] = sdk_mex(12,file_h,channel); + + + //Inputs + fileH = getFileHandle(prhs); + long channel = getLongInput(prhs,2); + + //Outputs + long textLen = 0; + wchar_t *nameOut = getStringOutputPointer(plhs,1); + + // Retrieves the name of a channel, as a string. + + //ADIResultCode ADI_GetChannelName(ADI_FileHandle fileH, long channel, wchar_t* name, long maxChars, long *textLen); + out_result[0] = ADI_GetChannelName(fileH, channel, nameOut, MAX_STRING_LENGTH, &textLen); + setLongOutput(plhs,2,textLen); + } + else if (function_option == 13) + { + // ADI_CloseFile <> closeFile + // ============================================================== + // + + fileH = getFileHandle(prhs); + result = ADI_CloseFile(&fileH); + out_result[0] = result; + } + else if (function_option == 14) + { + // ADI_GetErrorMessage <> getErrorMessage + // ============================================================== + // err_msg = sdk_mex(14,error_code) + + long textLen = 0; + + wchar_t *messageOut = getStringOutputPointer(plhs,1); + + ADIResultCode code = (ADIResultCode)getLongInput(prhs,1); + + //ADIResultCode ADI_GetErrorMessage(ADIResultCode code, wchar_t* messageOut, long maxChars, long *textLen); + out_result[0] = ADI_GetErrorMessage(code, messageOut, MAX_STRING_LENGTH, &textLen); + setLongOutput(plhs,2,textLen); + + } + else if (function_option == 15) + { + // ADI_GetRecordSamplePeriod <> getSamplePeriod + // ============================================================== + // [result_code,dt_channel] = sdk_mex(15,file_h,record,channel) + + fileH = getFileHandle(prhs); + long record = getLongInput(prhs,2); + long channel = getLongInput(prhs,3); + double secsPerSample = 0; + + out_result[0] = ADI_GetRecordSamplePeriod(fileH, channel, record, &secsPerSample); + setDoubleOutput(plhs,1,secsPerSample); + } + else if (function_option == 16) + { + // ADI_GetRecordTime <> getRecordStartTime + // ============================================================== + // [result_code,trigger_time,frac_secs,trigger_minus_rec_start] = sdk_mex(16,file_h,record) + + fileH = getFileHandle(prhs); + long record = getLongInput(prhs,2); + + time_t triggerTime = 0; + double fracSecs = 0; + long triggerMinusStartTicks = 0; + + //Retrieves time information about the specified record. + //The trigger time is the time origin of the record and may differ from the start time if + //there is a pre or post trigger delay, as specified by the trigMinusRecStart parameter. + // Params: fileH - ADI_FileHandle for the open file + // record - the record index (starting from 0) + // triggerTime - time_t receives the date and time of the trigger + // position for the new record. Measured as number of + // seconds from 1 Jan 1970 + // fracSecs - receives the fractional seconds part of + // the record trigger time ('triggerTime' parameter) + // trigMinusRecStart - trigger-time-minus-record-start-ticks. Receives the + // difference between the time of trigger tick and the first + // tick in the record. This +ve for pre-trigger delay and + // -ve for post-trigger delay. + // Return: a ADIResultCode for result of the operation + + //DLLEXPORT ADIResultCode ADI_GetRecordTime(ADI_FileHandle fileH, long record, time_t *triggerTime, + //double *fracSecs, long *triggerMinusStartTicks); + + out_result[0] = ADI_GetRecordTime(fileH, record, &triggerTime, &fracSecs, &triggerMinusStartTicks); + + setDoubleOutput(plhs,1,(double)triggerTime); + setDoubleOutput(plhs,2,fracSecs); + setLongOutput(plhs,3,triggerMinusStartTicks); + + } + else if (function_option == 17){ + // + // ADI_CreateFile <> createFile + // ============================================================== + // [result_code,file_h] = sdk_mex(17,file_path) + // + // Implemented via sdk.createFile + + wchar_t *w_file_path = (wchar_t *)mxGetData(prhs[1]); + + result = ADI_CreateFile(w_file_path, &fileH); + out_result[0] = result; + + setFileHandle(plhs,result,fileH); + } + else if (function_option == 18){ + // + // ADI_SetChannelName <> setChannelName + // ============================================================== + // [result_code,file_h] = sdk_mex(18,file_h,channel,name) + // + // Implemented via sdk.setChannelName + + fileH = getFileHandle(prhs); + long channel = getLongInput(prhs,2); + wchar_t *channel_name = (wchar_t *)mxGetData(prhs[3]); + + out_result[0] = ADI_SetChannelName(fileH, channel, channel_name); + } + else if (function_option == 19){ + // + // ADI_CreateWriter <> createDataWriter + // =========================================== + // [result_code,writer_h] = sdk_mex(19,file_h) + // + // Implemented via sdk.createDataWriter + + ADI_WriterHandle writerH(0); + + fileH = getFileHandle(prhs); + + result = ADI_CreateWriter(fileH,&writerH); + out_result[0] = result; + + setWriterHandle(plhs,result,writerH); + } + else if (function_option == 20){ + // + // ADI_SetChannelInfo <> setChannelInfo + // =========================================== + // [result_code] = sdk_mex(20,writer_h,channel,enabled,seconds_per_sample,units,limits) + // + // implemented via adi.sdk.setChannelInfo + + ADI_WriterHandle writerH = getWriterHandle(prhs); + + long channel = getLongInput(prhs,2); + int enabled = getIntInput(prhs,3); + double seconds_per_sample = getDoubleInput(prhs,4); + wchar_t *units = (wchar_t *)mxGetData(prhs[5]); + float *temp_limits = (float *)mxGetData(prhs[5]); + ADIDataLimits limits; + limits.mMaxLimit = temp_limits[1]; + limits.mMinLimit = temp_limits[0]; + + out_result[0] = ADI_SetChannelInfo(writerH, channel, enabled, seconds_per_sample, units, &limits); + +// DLLEXPORT ADIResultCode ADI_SetChannelInfo(ADI_WriterHandle writerH, long channel, int enabled, +// double secondsPerSample, const wchar_t* units, const ADIDataLimits *limits); + + } + else if (function_option == 21){ + // + // ADI_StartRecord <> startRecord + // =========================================== + // result_code = sdk_mex(21, writerH, trigger_time, fractional_seconds, trigger_minus_rec_start) + // + // implemented via adi.sdk.startRecord + + ADI_WriterHandle writerH = getWriterHandle(prhs); + time_t trigger_time = (time_t)getDoubleInput(prhs,2); + double fractional_seconds = getDoubleInput(prhs,3); + long trigger_minus_rec_start = getLongInput(prhs,4); + + out_result[0] = ADI_StartRecord(writerH, trigger_time, fractional_seconds, trigger_minus_rec_start); + +// DLLEXPORT ADIResultCode ADI_StartRecord(ADI_WriterHandle writerH, time_t triggerTime, +// double fracSecs, long triggerMinusStartTicks); + } + else if (function_option == 22){ + // + // ADI_AddChannelSamples <> addChannelSamples + // =========================================== + // [result_code,new_ticks_added] = sdk_mex(22, writerH, channel, data, n_samples) + // + // adi.sdk.addChannelSamples + + ADI_WriterHandle writerH = getWriterHandle(prhs); + long channel = getLongInput(prhs,2); + float *data = (float *)mxGetData(prhs[3]); + long n_samples = (long)mxGetNumberOfElements(prhs[3]); + long new_ticks_added = 0; + + out_result[0] = ADI_AddChannelSamples(writerH, channel, data, n_samples, &new_ticks_added); + + setLongOutput(plhs,1,new_ticks_added); + +// DLLEXPORT ADIResultCode ADI_AddChannelSamples(ADI_WriterHandle writerH, long channel, +// float* data, long nSamples, long *newTicksAdded); + } + else if (function_option == 23){ + // + // ADI_FinishRecord <> finishRecord + // =========================================== + // [result_code] = sdk_mex(23, writerH) + // + // Implemented via adi.sdk.finishRecord + + ADI_WriterHandle writerH = getWriterHandle(prhs); + + out_result[0] = ADI_FinishRecord(writerH); + +// DLLEXPORT ADIResultCode ADI_FinishRecord(ADI_WriterHandle writerH); + } + else if (function_option == 24){ + // + // ADI_CommitFile <> commitFile + // =========================================== + // [result_code] = sdk_mex(24, writerH, flags) + // + // Implemented via adi.sdk.commitFile + + ADI_WriterHandle writerH = getWriterHandle(prhs); + + //TODO: What are the flags?????? + + out_result[0] = ADI_CommitFile(writerH, 0); + +// DLLEXPORT ADIResultCode ADI_CommitFile(ADI_WriterHandle writerH, long flags); + } + else if (function_option == 25){ + // + // ADI_CloseWriter <> closeWriter + // =========================================== + // [result_code] = sdk_mex(25, writerH) + // + // Implemented via adi.sdk.closeWriter + + ADI_WriterHandle writerH = getWriterHandle(prhs); + + out_result[0] = ADI_CloseWriter(&writerH); + +// DLLEXPORT ADIResultCode ADI_CloseWriter(ADI_WriterHandle *writerH); + } + else if (function_option == 26){ + // + // ADI_AddComment <> addComment + // =========================================== + // [result_code, comment_number] = + // sdk_mex(26, file_h, channel, record, tick_position, text) + // + // Implemented via adi.sdk.addComment + + fileH = getFileHandle(prhs); + long channel = getLongInput(prhs,2); + long record = getLongInput(prhs,3); + long tick_position = getLongInput(prhs,4); + wchar_t *text = (wchar_t *)mxGetData(prhs[5]); + long comment_number = 0; + //long comment_number = getLongInput(prhs,6); + + out_result[0] = ADI_AddComment(fileH, channel, record, tick_position, text, &comment_number); + + setLongOutput(plhs,1,comment_number); + +// DLLEXPORT ADIResultCode ADI_AddComment(ADI_FileHandle fileH, long channel, long record, long tickPos, +// const wchar_t* text, long* commentNum); + } + else if (function_option == 27){ + // + // ADI_DeleteComment <> deleteComment + // =========================================== + // result_code = sdk_mex(27,file_h,comment_number) + // + // Implemented via adi.sdk.deleteComment + + fileH = getFileHandle(prhs); + long comment_number = getLongInput(prhs,2); + + out_result[0] = ADI_DeleteComment(fileH,comment_number); + +// DLLEXPORT ADIResultCode ADI_DeleteComment(ADI_FileHandle fileH, long commentNum); + } + else if (function_option == 100){ + mexUnlock(); + locked = 0; + } + else + { + mexErrMsgIdAndTxt("adinstruments:sdk_mex", + "Invalid function option"); + } + + //ADI_GetRecordSamplePeriod + //ADI_GetRecordTime } \ No newline at end of file diff --git a/src/Import/labchart/adi/+adi/private/sdk_mex.mexw64 b/Import/labchart/adi/+adi/private/sdk_mex.mexw64 similarity index 100% rename from src/Import/labchart/adi/+adi/private/sdk_mex.mexw64 rename to Import/labchart/adi/+adi/private/sdk_mex.mexw64 diff --git a/src/Import/labchart/adi/+adi/readFile.m b/Import/labchart/adi/+adi/readFile.m similarity index 96% rename from src/Import/labchart/adi/+adi/readFile.m rename to Import/labchart/adi/+adi/readFile.m index d72714ac..cc69a256 100644 --- a/src/Import/labchart/adi/+adi/readFile.m +++ b/Import/labchart/adi/+adi/readFile.m @@ -1,70 +1,70 @@ -function file_obj = readFile(file_path,varargin) -%x Opens up a LabChart file and extracts meta data. -% -% file_obj = adi.readFile(*file_path,varargin) -% -% file_obj = adi.readFile(*file_path,options) -% -% This function reads some preliminary data from the specified LabChart -% or simple data file and exposes access to further commands for reading -% data. -% -% ********************************************************** -% This is THE gateway function for working with these files. -% ********************************************************** -% -% Optional Inputs: -% ---------------- -% file_path : str -% Path of the file to read. An empty or missing input prompts the -% user. -% -% See adi.file_read_options for additional option details. -% You can pass in specific properties to this function to change: -% -% e.g. adi.readFile(file_path,'remove_empty_channels',false) -% -% OR you can pass in the options object: -% -% options = adi.file_read_options; -% %Change some options ... -% -% adi.readFile(file_path,options) -% -% Outputs: -% -------- -% file_obj : adi.file -% -% See Also: -% adi.file -% adi.convert - -if length(varargin) == 1 && strcmp(class(varargin{1}),adi.file_read_options) - in = varargin{1}; -else - in = adi.file_read_options; - in = adi.sl.in.processVarargin(in,varargin); -end - -if nargin == 0 || isempty(file_path) - file_path = adi.uiGetChartFile(); - if isnumeric(file_path) - return - end -end - -[~,~,file_extension] = fileparts(file_path); - -%Choose SDK based on file extension -%---------------------------------- -if strcmp(file_extension,'.mat') - sdk = adi.mat_file_sdk; -elseif strcmp(file_extension,'.h5') - sdk = adi.h5_file_sdk; -else - sdk = adi.sdk; -end - -file_h = sdk.openFile(file_path); -file_obj = adi.file(file_path,file_h,sdk,in); +function file_obj = readFile(file_path,varargin) +%x Opens up a LabChart file and extracts meta data. +% +% file_obj = adi.readFile(*file_path,varargin) +% +% file_obj = adi.readFile(*file_path,options) +% +% This function reads some preliminary data from the specified LabChart +% or simple data file and exposes access to further commands for reading +% data. +% +% ********************************************************** +% This is THE gateway function for working with these files. +% ********************************************************** +% +% Optional Inputs: +% ---------------- +% file_path : str +% Path of the file to read. An empty or missing input prompts the +% user. +% +% See adi.file_read_options for additional option details. +% You can pass in specific properties to this function to change: +% +% e.g. adi.readFile(file_path,'remove_empty_channels',false) +% +% OR you can pass in the options object: +% +% options = adi.file_read_options; +% %Change some options ... +% +% adi.readFile(file_path,options) +% +% Outputs: +% -------- +% file_obj : adi.file +% +% See Also: +% adi.file +% adi.convert + +if length(varargin) == 1 && strcmp(class(varargin{1}),adi.file_read_options) + in = varargin{1}; +else + in = adi.file_read_options; + in = adi.sl.in.processVarargin(in,varargin); +end + +if nargin == 0 || isempty(file_path) + file_path = adi.uiGetChartFile(); + if isnumeric(file_path) + return + end +end + +[~,~,file_extension] = fileparts(file_path); + +%Choose SDK based on file extension +%---------------------------------- +if strcmp(file_extension,'.mat') + sdk = adi.mat_file_sdk; +elseif strcmp(file_extension,'.h5') + sdk = adi.h5_file_sdk; +else + sdk = adi.sdk; +end + +file_h = sdk.openFile(file_path); +file_obj = adi.file(file_path,file_h,sdk,in); end \ No newline at end of file diff --git a/src/Import/labchart/adi/+adi/record.m b/Import/labchart/adi/+adi/record.m similarity index 97% rename from src/Import/labchart/adi/+adi/record.m rename to Import/labchart/adi/+adi/record.m index 951b67f1..984021f6 100644 --- a/src/Import/labchart/adi/+adi/record.m +++ b/Import/labchart/adi/+adi/record.m @@ -1,115 +1,115 @@ -classdef (Hidden) record < handle - % - % Class: - % adi.record - % - % Labchart Record - % - % A new record is created in a file whenever settings are changed, or - % whenever the users stops (then starts) a recording. - - properties - id %record number (1 based) - n_ticks %# of samples of highest sampling rate channel - comments %adi.comment - tick_dt %The highest sampling rate of any channel in this record. - tick_fs %Sampling frequency, computed for convenience from tick_dt - duration - record_start %(Matlab time) Time in which the record started according - %to Labchart. This is not always the time in which data collection - %for that record started. - - data_start %(Matlab time) Time at which the data that was collected - %during the record was collected. This may not correspond to the - %record_start if a trigger delay was involved. This also apparently - %changes when data are extracted from a file into another file - - data_start_str - - trigger_minus_rec_start %(seconds) How long after the record - %started did the data start - end - - properties (Hidden) - file_h %adi.file_handle - trigger_minus_rec_start_samples - end - - methods - function obj = record(file_h,sdk,record_id) - % - % - % Inputs: - % ------- - % file_h : .file_handle, .h5_file_h, .mat_file_h - - - obj.file_h = file_h; - obj.id = record_id; - - obj.n_ticks = sdk.getNTicksInRecord(file_h,record_id); - - %This is not channel specific, the channel input is not actually - %used according to: - % http://forum.adi.com/viewtopic.php?f=7&t=563 - obj.tick_dt = sdk.getTickPeriod(file_h,record_id,1); - obj.tick_fs = 1./obj.tick_dt; - - obj.duration = obj.n_ticks*obj.tick_dt; - - [obj.record_start,obj.data_start,obj.trigger_minus_rec_start_samples] = ... - sdk.getRecordStartTime(file_h,record_id,obj.tick_dt); - - obj.trigger_minus_rec_start = -1*obj.trigger_minus_rec_start_samples*obj.tick_dt; - - obj.data_start_str = datestr(obj.data_start); - - - - obj.comments = sdk.getAllCommentsForRecord(file_h,obj.id,obj.tick_dt,obj.trigger_minus_rec_start); - end - end - - %These conversion calls should be initiated by the file object - methods (Hidden) - function exportToHDF5File(objs,fobj,save_path,conversion_options) - % - % - % Make sure to also update: - % adi.h5_file_h - group_name = '/record_meta'; - h5m.group.create(fobj,'record_version'); - h5writeatt(save_path,'/record_version','version',1); - - h5m.group.create(fobj,group_name); - %TODO: Rewrite with h5m library - h5writeatt(save_path,group_name,'n_ticks',[objs.n_ticks]); - h5writeatt(save_path,group_name,'tick_dt',[objs.tick_dt]); - h5writeatt(save_path,group_name,'record_start',[objs.record_start]); - h5writeatt(save_path,group_name,'data_start',[objs.data_start]); - h5writeatt(save_path,group_name,'trigger_minus_rec_start_samples',[objs.trigger_minus_rec_start_samples]); - - all_comments = [objs.comments]; - if ~isempty(all_comments) - exportToHDF5File(all_comments,fobj,save_path,conversion_options) - end - end - function exportToMatFile(objs,m,conversion_options) - - m.record_version = 1; - m.record_meta = struct(... - 'n_ticks', {objs.n_ticks}, ... - 'tick_dt', {objs.tick_dt},... - 'record_start', {objs.record_start},... - 'data_start', {objs.data_start},... - 'trigger_minus_rec_start_samples',{objs.trigger_minus_rec_start_samples}); - - all_comments = [objs.comments]; - if ~isempty(all_comments) - exportToMatFile(all_comments,m,conversion_options) - end - end - end - -end - +classdef (Hidden) record < handle + % + % Class: + % adi.record + % + % Labchart Record + % + % A new record is created in a file whenever settings are changed, or + % whenever the users stops (then starts) a recording. + + properties + id %record number (1 based) + n_ticks %# of samples of highest sampling rate channel + comments %adi.comment + tick_dt %The highest sampling rate of any channel in this record. + tick_fs %Sampling frequency, computed for convenience from tick_dt + duration + record_start %(Matlab time) Time in which the record started according + %to Labchart. This is not always the time in which data collection + %for that record started. + + data_start %(Matlab time) Time at which the data that was collected + %during the record was collected. This may not correspond to the + %record_start if a trigger delay was involved. This also apparently + %changes when data are extracted from a file into another file + + data_start_str + + trigger_minus_rec_start %(seconds) How long after the record + %started did the data start + end + + properties (Hidden) + file_h %adi.file_handle + trigger_minus_rec_start_samples + end + + methods + function obj = record(file_h,sdk,record_id) + % + % + % Inputs: + % ------- + % file_h : .file_handle, .h5_file_h, .mat_file_h + + + obj.file_h = file_h; + obj.id = record_id; + + obj.n_ticks = sdk.getNTicksInRecord(file_h,record_id); + + %This is not channel specific, the channel input is not actually + %used according to: + % http://forum.adi.com/viewtopic.php?f=7&t=563 + obj.tick_dt = sdk.getTickPeriod(file_h,record_id,1); + obj.tick_fs = 1./obj.tick_dt; + + obj.duration = obj.n_ticks*obj.tick_dt; + + [obj.record_start,obj.data_start,obj.trigger_minus_rec_start_samples] = ... + sdk.getRecordStartTime(file_h,record_id,obj.tick_dt); + + obj.trigger_minus_rec_start = -1*obj.trigger_minus_rec_start_samples*obj.tick_dt; + + obj.data_start_str = datestr(obj.data_start); + + + + obj.comments = sdk.getAllCommentsForRecord(file_h,obj.id,obj.tick_dt,obj.trigger_minus_rec_start); + end + end + + %These conversion calls should be initiated by the file object + methods (Hidden) + function exportToHDF5File(objs,fobj,save_path,conversion_options) + % + % + % Make sure to also update: + % adi.h5_file_h + group_name = '/record_meta'; + h5m.group.create(fobj,'record_version'); + h5writeatt(save_path,'/record_version','version',1); + + h5m.group.create(fobj,group_name); + %TODO: Rewrite with h5m library + h5writeatt(save_path,group_name,'n_ticks',[objs.n_ticks]); + h5writeatt(save_path,group_name,'tick_dt',[objs.tick_dt]); + h5writeatt(save_path,group_name,'record_start',[objs.record_start]); + h5writeatt(save_path,group_name,'data_start',[objs.data_start]); + h5writeatt(save_path,group_name,'trigger_minus_rec_start_samples',[objs.trigger_minus_rec_start_samples]); + + all_comments = [objs.comments]; + if ~isempty(all_comments) + exportToHDF5File(all_comments,fobj,save_path,conversion_options) + end + end + function exportToMatFile(objs,m,conversion_options) + + m.record_version = 1; + m.record_meta = struct(... + 'n_ticks', {objs.n_ticks}, ... + 'tick_dt', {objs.tick_dt},... + 'record_start', {objs.record_start},... + 'data_start', {objs.data_start},... + 'trigger_minus_rec_start_samples',{objs.trigger_minus_rec_start_samples}); + + all_comments = [objs.comments]; + if ~isempty(all_comments) + exportToMatFile(all_comments,m,conversion_options) + end + end + end + +end + diff --git a/src/Import/labchart/adi/+adi/sdk.m b/Import/labchart/adi/+adi/sdk.m similarity index 97% rename from src/Import/labchart/adi/+adi/sdk.m rename to Import/labchart/adi/+adi/sdk.m index 037d85f2..c70f3994 100644 --- a/src/Import/labchart/adi/+adi/sdk.m +++ b/Import/labchart/adi/+adi/sdk.m @@ -1,833 +1,833 @@ -classdef (Hidden) sdk - % - % Class: - % adi.sdk - % - % This class is meant to be the singular access point for getting - % data from a LabChart file. Methods in this class call a mex - % interface which makes calls to the C API provided by ADInstruments. - % - % Function Definitions: - % --------------------- - % Function definitions for the SDK can be found in the header file. - % - % See: - % /private/ADIDatCAPI_mex.h - % - % They are also defined in the calling function. - % - % - % Some definitions: - % ----------------- - % tick : sampling rate of fastest channel - % record : Records can be somewhat equivalent to trials or blocks - % in other experimental setups. Each file can consist of 1 or - % more records. Each time the start/stop button is pressed a new - % record is created. Additionally, changes to the channel setup - % warrant creation of a new record (such as a change in the - % sampling rate) - % - % Usage Notes: - % ------------ - % NOTE: For the typical user, this SDK doesn't need to be called - % directly. You can access most of the needed functionality by using - % adi.readFile - % - % NOTE: - % Since Matlab's importing is subpar, but since it allows calling - % static methods from an instance of a class, one can instiate this - % class to allow shorter calling of the static methods of the class. - % - % e.g. - % sdk = adi.sdk - % sdk.getNumberOfChannels(file_h) - % - % See Also: - % adi.readFile - - methods (Static) - %adi.sdk.makeMex - %This should only be called with everything closed and cleared to - %avoid crashing Matlab - %{ - %TODO: Can we move all of this into the function itself ... - clear all - close all - adi.sdk.unlockMex - clear all - %} - - function unlockMex() - sdk_mex(100); - end - %adi.sdk.makeMex - function makeMex() - % - % adi.sdk.makeMex - % - % This function compiles the necessary mex code. - - %TODO: allow unlocking - this would require reference counting. - % - %Currently we lock the mex file when it is run. If we didn't - %and we were to clear the mex file and then try to delete a - %file handle Matlab would crash. Reference counting would - %involve incrementing for every opened handle, then - %decrementing every time handles are destroyed. If this count - %is zero, then we could safely clear the mex dll from memory. - - base_path = adi.sl.stack.getMyBasePath; - mex_path = fullfile(base_path,'private'); - - wd = cd; %wd - working directory - cd(mex_path) - try - - if strcmp(computer,'PCWIN64') - mex('sdk_mex.cpp','-v','ADIDatIOWin64.lib') - else - mex('sdk_mex.cpp','ADIDatIOWin.lib') - end - - %Extra files: - %------------------------ - - file_names = cell(1,3); - file_names{1} = 'ADIDatIOWin_thunk_pcwin64.exp'; - file_names{2} = 'ADIDatIOWin_thunk_pcwin64.lib'; - file_names{3} = 'ADIDatIOWin_thunk_pcwin64.obj'; - - for iFile = 1:3 - cur_file_path = fullfile(base_path,file_names{iFile}); - %Let's avoid a warning by checking first (delete throws - %a warning when the file is not present) - if exist(cur_file_path,'file') - delete(cur_file_path) - end - end - - %Go back to where we started. - cd(wd) - catch ME - cd(wd) - fprintf(2,'%s',ME.message); - end - - end - end - - %NOTE: In Matlab the functions can be easily visualized by folding all - %the code and then expanding this methods block - methods (Static) - %File specific functions - %------------------------------------------------------------------ - function file_h = openFile(file_path,varargin) - % - % file = adi.sdk.openFile(file_path) - % - % NOTE: This function allows for reading or writing but - % I've only implemented reading. - % - % Inputs: - % ------- - % file_path : char - % Full path to the file. - % - % Outputs: - % -------- - % file : adi.file_handle - - in.read_and_write = false; - in = adi.sl.in.processVarargin(in,varargin); - - %If the pointer value is already valid - i.e. already open - - %then we just use the current pointer value rather than - %requesting a second - pointer_value = adi.handle_manager.checkFilePointer(file_path); - - if (pointer_value == 0) - adi.handle_logger.logOperation(file_path,'openFile',-1) - %fprintf(2,'ADI SDK - Opening: %s\n',file_path); - %TODO: Change this so we can call the same function but with - %an additional input that specifies reading or writing - if in.read_and_write - [result_code,pointer_value] = sdk_mex(0.5,h__toWChar(file_path)); - else - [result_code,pointer_value] = sdk_mex(0,h__toWChar(file_path)); - end - - adi.sdk.handleErrorCode(result_code) - - adi.handle_manager.openFile(file_path,pointer_value) - - adi.handle_logger.logOperation(file_path,'openFile',pointer_value) - end - - file_h = adi.file_handle(pointer_value,file_path); - - - - end - function file_h = createFile(file_path) - - pointer_value = adi.handle_manager.checkFilePointer(file_path); - if pointer_value == 0 - [result_code,pointer_value] = sdk_mex(17,h__toWChar(file_path)); - adi.sdk.handleErrorCode(result_code) - adi.handle_manager.openFile(file_path,pointer_value) - adi.handle_logger.logOperation(file_path,'createFile',pointer_value) - end - - file_h = adi.file_handle(pointer_value,file_path); - end - function closeFile(pointer_value) - % - % adi.sdk.closeFile(pointer_value) - % - % Since this method should only be called by: - % adi.file_handle.delete() - % - % and since that is the deconstructor method of that object - % it seemed weird to pass in that object ot this method, so - % instead the pointer value is passed in directly. - - adi.handle_manager.closeFile(pointer_value) - - end - function n_records = getNumberOfRecords(file_h) - %getNumberOfRecords Get the number of records for a file. - % - % n_records = adi.sdk.getNumberOfRecords(file_h) - % - % See definition of the "records" in the definition section. - - [result_code,n_records] = sdk_mex(1,file_h.pointer_value); - adi.sdk.handleErrorCode(result_code) - n_records = double(n_records); - end - function n_channels = getNumberOfChannels(file_h) - %getNumberOfChannels Get # of channels for a file. - % - % n_channels = adi.sdk.getNumberOfChannels(file_h) - % - % Outputs: - % =========================================================== - % n_channels : The # of physical channels of recorded data - % across all records. For some records some channels may not - % have any data. A channel is identified by (??? name ??, - % hardware id????, i.e. what makes channel unique?) - % - % Status: DONE - - [result_code,n_channels] = sdk_mex(2,file_h.pointer_value); - adi.sdk.handleErrorCode(result_code) - n_channels = double(n_channels); - end - function writer_h = createDataWriter(file_h) - % - %Creates a new writer session for writing new data and - %returns a handle to that open writer for use in other - %related functions. - - [result_code,writer_pointer] = sdk_mex(19,file_h.pointer_value); - writer_h = adi.data_writer_handle(writer_pointer); - adi.sdk.handleErrorCode(result_code) - end - function commitFile(writer_h) - % - % adi.sdk.commitFile(writer_h) - - result_code = sdk_mex(24,writer_h.pointer_value); - adi.sdk.handleErrorCode(result_code) - end - function closeWriter(pointer_value) - % - % adi.sdk.closeWriter(pointer_value) - - result_code = sdk_mex(25,pointer_value); - adi.sdk.handleErrorCode(result_code) - end - %Record specific functions - %------------------------------------------------------------------ - function n_ticks_in_record = getNTicksInRecord(file_h,record) - % - % - % n_ticks_in_record = adi.sdk.getNTicksInRecord(file_h,record) - % - % Returns the # of samples of channels with the highest data - % rate. - % - % Inputs: - % ===================================== - % record : double - % Record #, 1 based. - % - % Outputs: - % =========================================================== - % n_ticks_in_record : This is equivalent to asking how many - % samples were obtained from the channels with the highest - % sampling rate - % - % Status: DONE - - [result_code,n_ticks_in_record] = sdk_mex(3,file_h.pointer_value,c0(record)); - adi.sdk.handleErrorCode(result_code) - n_ticks_in_record = double(n_ticks_in_record); - - end - function dt_tick = getTickPeriod(file_h,record,channel) - % - % - % dt_tick = adi.sdk.getTickPeriod(file_handle,record,channel) - % - % Outputs: - % =========================================================== - % dt_tick : - % - % STATUS: DONE - - [result_code,dt_tick] = sdk_mex(4,file_h.pointer_value,c0(record),c0(channel)); - adi.sdk.handleErrorCode(result_code) - end - function [record_start,data_start,trigger_minus_rec_start_samples] = getRecordStartTime(file_h,record,tick_dt) - % - % [record_start,data_start] = getRecordStartTime(file_h,record,tick_dt) - % - % Outputs: - % ------------ - % record_start : Matlab datenum - % Time of record start. If triggered, this is the time of - % the trigger. - % data_start : Matlab datenum - % Time at which the first data point was collected. If a - % trigger was used this may be before of after the trigger. - % - % For easier viewing you can use datestr(record_start) or - % datestr(data_start). - - [result_code,trigger_time,fractional_seconds,trigger_minus_rec_start_samples] = sdk_mex(16,file_h.pointer_value,c0(record)); - - trigger_minus_rec_start_samples = double(trigger_minus_rec_start_samples); - - adi.sdk.handleErrorCode(result_code); - - record_start_unix = trigger_time + fractional_seconds; - - %+ trigger_minus_rec_start => data starts before trigger - %- trigger_minus_rec_start => data starts after trigger - % - %Units are in ticks and needs to be converted to seconds - data_start_unix = record_start_unix - trigger_minus_rec_start_samples*tick_dt; - - %NOTE: Times are local, not in GMT - record_start = adi.sl.datetime.unixToMatlab(record_start_unix,0); - data_start = adi.sl.datetime.unixToMatlab(data_start_unix,0); - - end - function startRecord(writer_h,varargin) - % - % - % Optional Inputs: - % ---------------- - % trigger_time: - % fractional_seconds: - % trigger_minus_rec_start: - - %JAH TODO: At this point - in.trigger_time = now; - in.fractional_seconds = 0; - in.trigger_minus_rec_start = 0; - in = adi.sl.in.processVarargin(in,varargin); - - result_code = sdk_mex(21, writer_h.pointer_value, ... - double(in.trigger_time), ... - double(in.fractional_seconds), ... - clong(in.trigger_minus_rec_start)); - adi.sdk.handleErrorCode(result_code) - end - function finishRecord(writer_h) - % - % adi.sdk.finishRecord(writer_h) - - result_code = sdk_mex(23, writer_h.pointer_value); - adi.sdk.handleErrorCode(result_code) - end - %Comment specific functions - %------------------------------------------------------------------ - function comments_h = getCommentAccessor(file_h,record,tick_dt,trigger_minus_record_start_s) - % - % - % comments_h = adi.sdk.getCommentAccessor(file_handle,record_idx_0b) - % - % comments_h :adi.comment_handle - - [result_code,comment_pointer] = sdk_mex(6,file_h.pointer_value,c0(record)); - if adi.sdk.isMissingCommentError(result_code) - comments_h = adi.comment_handle(file_h.file_path,0,false,record,tick_dt,trigger_minus_record_start_s); - else - adi.sdk.handleErrorCode(result_code) - comments_h = adi.comment_handle(file_h.file_path,comment_pointer,true,record,tick_dt,trigger_minus_record_start_s); - end - end - function closeCommentAccessor(pointer_value) - % - % - % adi.sdk.closeCommentAccessor(pointer_value); - % - % This should only be called by: - % adi.comment_handle - - result_code = sdk_mex(7,pointer_value); - adi.sdk.handleErrorCode(result_code); - end - function has_another_comment = advanceComments(comments_h) - % - % - % has_another_comment = adi.sdk.advanceComments(comments_h); - - result_code = sdk_mex(9,comments_h.pointer_value); - - if adi.sdk.isMissingCommentError(result_code) - has_another_comment = false; - else - adi.sdk.handleErrorCode(result_code); - has_another_comment = true; - end - - end - function comment_info = getCommentInfo(comments_h) - % - % - % comment_info = adi.sdk.getCommentInfo(comments_h) - % - % Inputs: - % ------- - % adi.comment_handle - - [result_code,comment_string_data,comment_length,tick_pos,channel,comment_num] = sdk_mex(8,comments_h.pointer_value); - - d = @double; - - if result_code == 0 - comment_string = adi.sdk.getStringFromOutput(comment_string_data,comment_length); - comment_info = adi.comment(comment_string,d(tick_pos),... - d(channel),d(comment_num),comments_h.record,... - comments_h.tick_dt,comments_h.trigger_minus_rec_start); - else - adi.sdk.handleErrorCode(result_code); - comment_info = []; - end - end - function comment_number = addComment(file_h,channel,record,tick_position,comment_string) - % - % comment_number = adi.sdk.addComment(channel,record,tick_position,comment_string) - - [result_code,comment_number] = sdk_mex(26,file_h.pointer_value,... - clong(channel), c0(record), clong(tick_position), h__toWChar(comment_string)); - adi.sdk.handleErrorCode(result_code); - end - function deleteComment(file_h,comment_number) - % - % adi.sdk.deleteComment(file_h,comment_number) - - result_code = sdk_mex(27,file_h.pointer_value,clong(comment_number)); - adi.sdk.handleErrorCode(result_code); - end - %Channel specific functions - %------------------------------------------------------------------ - function n_samples = getNSamplesInRecord(file_h,record,channel) - % - % - % n_samples = adi.sdk.getNSamplesInRecord(file_h,record,channel) - % - % INPUTS - % =========================================== - % record : (0 based) - % channel : (0 based) - % - % Status: DONE - - [result_code,n_samples] = sdk_mex(5,file_h.pointer_value,c0(record),c0(channel)); - adi.sdk.handleErrorCode(result_code) - n_samples = double(n_samples); - end - function output_data = getChannelData(file_h,record,channel,start_sample,n_samples_get,get_samples,varargin) - % - % - % output_data = adi.sdk.getChannelData(... - % file_h,record,channel,start_sample,n_samples_get,get_samples) - % - % Inputs: - % ------- - % channel: - % Channel to get the data from, 1 based. - % record: - % Record to get the data from, 1 based. - % start_sample: first sample to get - % n_samples: - % get_samples: - % If true data is returned as samples, if false, the data - % are upsampled (sample & hold) to the highest rate ... - % - % Optional Inputs: - % ---------------- - % leave_raw: (default false) - % If false, the output is cast to a double. If true, the - % cast does not occur and the output is of type 'single' - % - % See Also: - % adi.channel.getAllData - - in.leave_raw = false; - in = adi.sl.in.processVarargin(in,varargin); - - data_type = c(0); - if ~get_samples - %get in tick units - data_type = bitset(data_type,32); - end - - [result_code,data,n_returned] = sdk_mex(10,... - file_h.pointer_value,c0(channel),... - c0(record),c0(start_sample),... - c(n_samples_get),data_type); - - adi.sdk.handleErrorCode(result_code) - - if n_returned ~= n_samples_get - error('Why was this truncated???') - end - - if in.leave_raw - output_data = data; - else - output_data = double(data); %Matlab can get finicky working with singles - end - end - function units = getUnits(file_h,record,channel) - %getUnits - % - % units = adi.sdk.getUnits(file_h,record,channel) - - - [result_code,str_data,str_length] = sdk_mex(11,... - file_h.pointer_value,c0(record),c0(channel)); - - %TODO: Replace with function call to isGoodResultCode - if result_code == 0 || result_code == 1 - units = adi.sdk.getStringFromOutput(str_data,str_length); - else - adi.sdk.handleErrorCode(result_code); - units = ''; - end - - end - function channel_name = getChannelName(file_h,channel) - % - % - % channel_name = adi.sdk.getChannelName(file_h,channel) - % - % Status: DONE - - [result_code,str_data,str_length] = sdk_mex(12,... - file_h.pointer_value,c0(channel)); - - if result_code == 0 - channel_name = adi.sdk.getStringFromOutput(str_data,str_length); - else - adi.sdk.handleErrorCode(result_code); - channel_name = ''; - end - - end - function dt_channel = getSamplePeriod(file_h,record,channel) - % - % - % dt_channel = getSamplePeriod(file_h,channel,record) - % - % This should return the sample period, the inverse of the - % sampling rate, for a single channel. - % - % For channels with NO SAMPLES, the dt returned is NaN - % - % Alternatively, I can ask: - % A) # of ticks in record - % B) tick period - % C) # of samples in record - % - % sample period = - - n_samples_in_record = adi.sdk.getNSamplesInRecord(file_h,record,channel); - if n_samples_in_record == 0 - dt_channel = NaN; - return - end - - % n_ticks_in_record = adi.sdk.getNTicksInRecord(file_h,record); - % tick_dt = adi.sdk.getTickPeriod(file_h,record,channel); - % dt_channel_temp = tick_dt * n_ticks_in_record/n_samples_in_record; - - [result_code,dt_channel] = sdk_mex(15,... - file_h.pointer_value,c0(record),c0(channel)); - - adi.sdk.handleErrorCode(result_code) - end - function setChannelName(file_h,channel,channel_name) - % - % adi.sdk.setChannelName(file_h,channel,channel_name) - % - % Inputs: - % ------- - % file_h: adi.file_handle - % channel: channel index, starting from zero - % channel_name: - - %??? - Does this create a new channel if it doesn't exist yet? - - result_code = sdk_mex(18,file_h.pointer_value,.... - c0(channel),h__toWChar(channel_name)); - - adi.sdk.handleErrorCode(result_code) - - end - function setChannelInfo(writer_h,channel,seconds_per_sample,units,varargin) - % - % Sets channel information for the specific record. - % - % TODO: Make it so that we can have everything be optional - % ... - % - % Inputs: - % ------- - % channel : - % seconds_per_sample : - % - % Optional Inputs: - % ---------------- - % enabled_for_record : (default true) - % limits : - % ???? Why do we care what the limits are???? - % - % ??? - when is this done relative to a new record? Does - % this need to be done every time or does a default carry - % over? Does setting this create a new record or only get - % updated when a new record is started? - - in.enabled_for_record = true; - in.limits = [-Inf Inf]; - in = adi.sl.in.processVarargin(in,varargin); - - result_code = sdk_mex(20,... - writer_h.pointer_value,... - c0(channel),... - h__toInt(in.enabled_for_record),... - double(seconds_per_sample),... - h__toWChar(units),... - single(in.limits)); - adi.sdk.handleErrorCode(result_code) - end - function addChannelSamples(writer_h,channel,data) - % - % adi.sdk.addChannelSamples(writer_h,channel,data) - % - % Inputs: - % ------- - % writer_h: - % channel: - % data: - % - % DLLEXPORT ADIResultCode ADI_AddChannelSamples(ADI_WriterHandle writerH, long channel, - % float* data, long nSamples, long *newTicksAdded); - - [result_code,new_ticks_added] = sdk_mex(22,writer_h.pointer_value,c0(channel),single(data)); - adi.sdk.handleErrorCode(result_code) - end - %Helper functions - %------------------------------------------------------------------ - function is_ok = checkNullChannelErrorCodes(result_code) - % - % - % is_ok = adi.sdk.checkNullChannelErrorCodes(result_code) - % - % For some reason there is a non-zero error code when - % retrieving information about a channel during a record in - % which there is no data for that channel. The error message - % is: "the operation completed successfully" - - is_ok = result_code == 0 || result_code == 1; - %result_code == 1 - %"the operation completed successfully" - end - function hex_value = resultCodeToHex(result_code) - % - % hex_value = adi.sdk.handleErrorCode(result_code) - % - % Returns the hex_value of the result code for comparision - % with the values in the C header. - - temp = typecast(result_code,'uint32'); - hex_value = dec2hex(temp); - end - function is_missing_comment_code = isMissingCommentError(result_code) - % - % - % is_missing_comment_code = adi.sdk.isMissingCommentError(result_code) - - - %TODO: Do I want to do the literal error check here instead - %of the mod???? - - %Relevant Link: - %http://forum.adi.com/viewtopic.php?f=7&t=551 - - %If there are no comments, the result_code is: - %-1610313723 - data requested not present => xA0049005 - - is_missing_comment_code = mod(result_code,16) == 5; - - end - function handleErrorCode(result_code) - % - % - % adi.sdk.handleErrorCode(result_code) - % - % If there is an error this function will throw an error - % and display the relevant error string given the error code - - %Relevant forum post: - %http://forum.adi.com/viewtopic.php?f=7&t=551 - - if ~adi.sdk.checkNullChannelErrorCodes(result_code) - %if result_code ~= 0 - temp = adi.sl.stack.calling_function_info; - errorID = sprintf('ADINSTRUMENTS:SDK:%s',temp.name); - error_msg = adi.sdk.getErrorMessage(result_code); - - - %TODO: Create a clean id - move to a function - %The ID is not allowed to have periods in it - %Also, the calling function info isn't a clean name - %(I think it includes SDK, but what if I only wanted the - %name, not the full path ...???) - % - errorID = regexprep(errorID,'\.',':'); - - error(errorID,[errorID ' ' error_msg]); - end - - %Copied from ADIDatCAPI_mex.h 5/6/2014 - % % % typedef enum ADIResultCode - % % % { - % % % //Win32 error codes (HRESULTs) - % % % kResultSuccess = 0, // operation succeeded - % % % kResultErrorFlagBit = 0x80000000L, // high bit set if operation failed - % % % kResultInvalidArg = 0x80070057L, // invalid argument. One (or more) of the arguments is invalid - % % % kResultFail = 0x80004005L, // Unspecified error - % % % kResultFileNotFound = 0x80030002L, // failure to find the specified file (check the path) - % % % - % % % - % % % //Start of error codes specific to this API - % % % kResultADICAPIMsgBase = 0xA0049000L, - % % % - % % % kResultFileIOError = kResultADICAPIMsgBase, // file IO error - could not read/write file - % % % kResultFileOpenFail, // file failed to open - % % % kResultInvalidFileHandle, // file handle is invalid - % % % kResultInvalidPosition, // pos specified is outside the bounds of the record or file - % % % kResultInvalidCommentNum, // invalid commentNum. Comment could not be found - % % % kResultNoData, // the data requested was not present (e.g. no more comments in the record). - % % % kResultBufferTooSmall // the buffer passed to a function to receive data (e.g. comment text) was not big enough to receive all the data. - % % % - % % % // new result codes must be added at the end - % % % } ADIResultCode; - - end - function error_msg = getErrorMessage(result_code) - % - % - % error_msg = adi.sdk.getErrorMessage(result_code) - - [~,err_msg_data,err_msg_len] = sdk_mex(14,int32(result_code)); - error_msg = adi.sdk.getStringFromOutput(err_msg_data,err_msg_len); - end - function str = getStringFromOutput(int16_data,str_length) - % - % This is a helper function for whenever we get a string out. - % - % str = adi.sdk.getStringFromOutput(int16_data,str_length) - % - % TODO: Make hidden - % - - %str_length - apparently contains the null character, we'll - %ignore the null character here ... - str = char(int16_data(1:str_length-1)); - end - end - - %Wrapper methods ------------------------------------------------------ - methods (Static) - function comments = getAllCommentsForRecord(file_h,record_id,tick_dt,trigger_minus_record_start_s,sdk) - % - % - % DOCUMENTATION: Out of date - % - % comments = adi.sdk.getAllCommentsForRecord(file_handle,record_obj) - % - % Parameters - % ---------- - % file_handle : adi.file_handle - % - % record_id : double - % - % tick_dt : double - % - % See Also: - % adi.record - - %NOTE: These comments seem to be returned ordered by time, not - %by ID. - - MAX_NUMBER_COMMENTS = 1000; %NOTE: Overflow of this value - %just causes things to slow down, it is not a critical error. - - if ~exist('sdk','var') - sdk = adi.sdk; - end - - temp_comments_ca = cell(1,MAX_NUMBER_COMMENTS); - comments_h = sdk.getCommentAccessor(file_h,record_id,tick_dt,trigger_minus_record_start_s); - - if ~comments_h.is_valid - comments = []; - return - end - - %Once the accessor is retrieved, the first comment can be accessed. - temp_comments_ca{1} = comments_h.getCurrentComment(); - - cur_comment_index = 1; - while comments_h.advanceCommentPointer() - cur_comment_index = cur_comment_index + 1; - temp_comments_ca{cur_comment_index} = comments_h.getCurrentComment(); - end - - comments = [temp_comments_ca{1:cur_comment_index}]; - - comments_h.close(); - end - end - - -end - -function int_out = h__toInt(value_in) - int_out = int32(value_in); -end - -function str_out = h__toWChar(str_in) -%NOTE: I had trouble with the unicode string conversion so per -%some Mathworks forum post I am just using a null terminated -%array of int16s -str_out = [int16(str_in) 0]; -end - +classdef (Hidden) sdk + % + % Class: + % adi.sdk + % + % This class is meant to be the singular access point for getting + % data from a LabChart file. Methods in this class call a mex + % interface which makes calls to the C API provided by ADInstruments. + % + % Function Definitions: + % --------------------- + % Function definitions for the SDK can be found in the header file. + % + % See: + % /private/ADIDatCAPI_mex.h + % + % They are also defined in the calling function. + % + % + % Some definitions: + % ----------------- + % tick : sampling rate of fastest channel + % record : Records can be somewhat equivalent to trials or blocks + % in other experimental setups. Each file can consist of 1 or + % more records. Each time the start/stop button is pressed a new + % record is created. Additionally, changes to the channel setup + % warrant creation of a new record (such as a change in the + % sampling rate) + % + % Usage Notes: + % ------------ + % NOTE: For the typical user, this SDK doesn't need to be called + % directly. You can access most of the needed functionality by using + % adi.readFile + % + % NOTE: + % Since Matlab's importing is subpar, but since it allows calling + % static methods from an instance of a class, one can instiate this + % class to allow shorter calling of the static methods of the class. + % + % e.g. + % sdk = adi.sdk + % sdk.getNumberOfChannels(file_h) + % + % See Also: + % adi.readFile + + methods (Static) + %adi.sdk.makeMex + %This should only be called with everything closed and cleared to + %avoid crashing Matlab + %{ + %TODO: Can we move all of this into the function itself ... + clear all + close all + adi.sdk.unlockMex + clear all + %} + + function unlockMex() + sdk_mex(100); + end + %adi.sdk.makeMex + function makeMex() + % + % adi.sdk.makeMex + % + % This function compiles the necessary mex code. + + %TODO: allow unlocking - this would require reference counting. + % + %Currently we lock the mex file when it is run. If we didn't + %and we were to clear the mex file and then try to delete a + %file handle Matlab would crash. Reference counting would + %involve incrementing for every opened handle, then + %decrementing every time handles are destroyed. If this count + %is zero, then we could safely clear the mex dll from memory. + + base_path = adi.sl.stack.getMyBasePath; + mex_path = fullfile(base_path,'private'); + + wd = cd; %wd - working directory + cd(mex_path) + try + + if strcmp(computer,'PCWIN64') + mex('sdk_mex.cpp','-v','ADIDatIOWin64.lib') + else + mex('sdk_mex.cpp','ADIDatIOWin.lib') + end + + %Extra files: + %------------------------ + + file_names = cell(1,3); + file_names{1} = 'ADIDatIOWin_thunk_pcwin64.exp'; + file_names{2} = 'ADIDatIOWin_thunk_pcwin64.lib'; + file_names{3} = 'ADIDatIOWin_thunk_pcwin64.obj'; + + for iFile = 1:3 + cur_file_path = fullfile(base_path,file_names{iFile}); + %Let's avoid a warning by checking first (delete throws + %a warning when the file is not present) + if exist(cur_file_path,'file') + delete(cur_file_path) + end + end + + %Go back to where we started. + cd(wd) + catch ME + cd(wd) + fprintf(2,'%s',ME.message); + end + + end + end + + %NOTE: In Matlab the functions can be easily visualized by folding all + %the code and then expanding this methods block + methods (Static) + %File specific functions + %------------------------------------------------------------------ + function file_h = openFile(file_path,varargin) + % + % file = adi.sdk.openFile(file_path) + % + % NOTE: This function allows for reading or writing but + % I've only implemented reading. + % + % Inputs: + % ------- + % file_path : char + % Full path to the file. + % + % Outputs: + % -------- + % file : adi.file_handle + + in.read_and_write = false; + in = adi.sl.in.processVarargin(in,varargin); + + %If the pointer value is already valid - i.e. already open - + %then we just use the current pointer value rather than + %requesting a second + pointer_value = adi.handle_manager.checkFilePointer(file_path); + + if (pointer_value == 0) + adi.handle_logger.logOperation(file_path,'openFile',-1) + %fprintf(2,'ADI SDK - Opening: %s\n',file_path); + %TODO: Change this so we can call the same function but with + %an additional input that specifies reading or writing + if in.read_and_write + [result_code,pointer_value] = sdk_mex(0.5,h__toWChar(file_path)); + else + [result_code,pointer_value] = sdk_mex(0,h__toWChar(file_path)); + end + + adi.sdk.handleErrorCode(result_code) + + adi.handle_manager.openFile(file_path,pointer_value) + + adi.handle_logger.logOperation(file_path,'openFile',pointer_value) + end + + file_h = adi.file_handle(pointer_value,file_path); + + + + end + function file_h = createFile(file_path) + + pointer_value = adi.handle_manager.checkFilePointer(file_path); + if pointer_value == 0 + [result_code,pointer_value] = sdk_mex(17,h__toWChar(file_path)); + adi.sdk.handleErrorCode(result_code) + adi.handle_manager.openFile(file_path,pointer_value) + adi.handle_logger.logOperation(file_path,'createFile',pointer_value) + end + + file_h = adi.file_handle(pointer_value,file_path); + end + function closeFile(pointer_value) + % + % adi.sdk.closeFile(pointer_value) + % + % Since this method should only be called by: + % adi.file_handle.delete() + % + % and since that is the deconstructor method of that object + % it seemed weird to pass in that object ot this method, so + % instead the pointer value is passed in directly. + + adi.handle_manager.closeFile(pointer_value) + + end + function n_records = getNumberOfRecords(file_h) + %getNumberOfRecords Get the number of records for a file. + % + % n_records = adi.sdk.getNumberOfRecords(file_h) + % + % See definition of the "records" in the definition section. + + [result_code,n_records] = sdk_mex(1,file_h.pointer_value); + adi.sdk.handleErrorCode(result_code) + n_records = double(n_records); + end + function n_channels = getNumberOfChannels(file_h) + %getNumberOfChannels Get # of channels for a file. + % + % n_channels = adi.sdk.getNumberOfChannels(file_h) + % + % Outputs: + % =========================================================== + % n_channels : The # of physical channels of recorded data + % across all records. For some records some channels may not + % have any data. A channel is identified by (??? name ??, + % hardware id????, i.e. what makes channel unique?) + % + % Status: DONE + + [result_code,n_channels] = sdk_mex(2,file_h.pointer_value); + adi.sdk.handleErrorCode(result_code) + n_channels = double(n_channels); + end + function writer_h = createDataWriter(file_h) + % + %Creates a new writer session for writing new data and + %returns a handle to that open writer for use in other + %related functions. + + [result_code,writer_pointer] = sdk_mex(19,file_h.pointer_value); + writer_h = adi.data_writer_handle(writer_pointer); + adi.sdk.handleErrorCode(result_code) + end + function commitFile(writer_h) + % + % adi.sdk.commitFile(writer_h) + + result_code = sdk_mex(24,writer_h.pointer_value); + adi.sdk.handleErrorCode(result_code) + end + function closeWriter(pointer_value) + % + % adi.sdk.closeWriter(pointer_value) + + result_code = sdk_mex(25,pointer_value); + adi.sdk.handleErrorCode(result_code) + end + %Record specific functions + %------------------------------------------------------------------ + function n_ticks_in_record = getNTicksInRecord(file_h,record) + % + % + % n_ticks_in_record = adi.sdk.getNTicksInRecord(file_h,record) + % + % Returns the # of samples of channels with the highest data + % rate. + % + % Inputs: + % ===================================== + % record : double + % Record #, 1 based. + % + % Outputs: + % =========================================================== + % n_ticks_in_record : This is equivalent to asking how many + % samples were obtained from the channels with the highest + % sampling rate + % + % Status: DONE + + [result_code,n_ticks_in_record] = sdk_mex(3,file_h.pointer_value,c0(record)); + adi.sdk.handleErrorCode(result_code) + n_ticks_in_record = double(n_ticks_in_record); + + end + function dt_tick = getTickPeriod(file_h,record,channel) + % + % + % dt_tick = adi.sdk.getTickPeriod(file_handle,record,channel) + % + % Outputs: + % =========================================================== + % dt_tick : + % + % STATUS: DONE + + [result_code,dt_tick] = sdk_mex(4,file_h.pointer_value,c0(record),c0(channel)); + adi.sdk.handleErrorCode(result_code) + end + function [record_start,data_start,trigger_minus_rec_start_samples] = getRecordStartTime(file_h,record,tick_dt) + % + % [record_start,data_start] = getRecordStartTime(file_h,record,tick_dt) + % + % Outputs: + % ------------ + % record_start : Matlab datenum + % Time of record start. If triggered, this is the time of + % the trigger. + % data_start : Matlab datenum + % Time at which the first data point was collected. If a + % trigger was used this may be before of after the trigger. + % + % For easier viewing you can use datestr(record_start) or + % datestr(data_start). + + [result_code,trigger_time,fractional_seconds,trigger_minus_rec_start_samples] = sdk_mex(16,file_h.pointer_value,c0(record)); + + trigger_minus_rec_start_samples = double(trigger_minus_rec_start_samples); + + adi.sdk.handleErrorCode(result_code); + + record_start_unix = trigger_time + fractional_seconds; + + %+ trigger_minus_rec_start => data starts before trigger + %- trigger_minus_rec_start => data starts after trigger + % + %Units are in ticks and needs to be converted to seconds + data_start_unix = record_start_unix - trigger_minus_rec_start_samples*tick_dt; + + %NOTE: Times are local, not in GMT + record_start = adi.sl.datetime.unixToMatlab(record_start_unix,0); + data_start = adi.sl.datetime.unixToMatlab(data_start_unix,0); + + end + function startRecord(writer_h,varargin) + % + % + % Optional Inputs: + % ---------------- + % trigger_time: + % fractional_seconds: + % trigger_minus_rec_start: + + %JAH TODO: At this point + in.trigger_time = now; + in.fractional_seconds = 0; + in.trigger_minus_rec_start = 0; + in = adi.sl.in.processVarargin(in,varargin); + + result_code = sdk_mex(21, writer_h.pointer_value, ... + double(in.trigger_time), ... + double(in.fractional_seconds), ... + clong(in.trigger_minus_rec_start)); + adi.sdk.handleErrorCode(result_code) + end + function finishRecord(writer_h) + % + % adi.sdk.finishRecord(writer_h) + + result_code = sdk_mex(23, writer_h.pointer_value); + adi.sdk.handleErrorCode(result_code) + end + %Comment specific functions + %------------------------------------------------------------------ + function comments_h = getCommentAccessor(file_h,record,tick_dt,trigger_minus_record_start_s) + % + % + % comments_h = adi.sdk.getCommentAccessor(file_handle,record_idx_0b) + % + % comments_h :adi.comment_handle + + [result_code,comment_pointer] = sdk_mex(6,file_h.pointer_value,c0(record)); + if adi.sdk.isMissingCommentError(result_code) + comments_h = adi.comment_handle(file_h.file_path,0,false,record,tick_dt,trigger_minus_record_start_s); + else + adi.sdk.handleErrorCode(result_code) + comments_h = adi.comment_handle(file_h.file_path,comment_pointer,true,record,tick_dt,trigger_minus_record_start_s); + end + end + function closeCommentAccessor(pointer_value) + % + % + % adi.sdk.closeCommentAccessor(pointer_value); + % + % This should only be called by: + % adi.comment_handle + + result_code = sdk_mex(7,pointer_value); + adi.sdk.handleErrorCode(result_code); + end + function has_another_comment = advanceComments(comments_h) + % + % + % has_another_comment = adi.sdk.advanceComments(comments_h); + + result_code = sdk_mex(9,comments_h.pointer_value); + + if adi.sdk.isMissingCommentError(result_code) + has_another_comment = false; + else + adi.sdk.handleErrorCode(result_code); + has_another_comment = true; + end + + end + function comment_info = getCommentInfo(comments_h) + % + % + % comment_info = adi.sdk.getCommentInfo(comments_h) + % + % Inputs: + % ------- + % adi.comment_handle + + [result_code,comment_string_data,comment_length,tick_pos,channel,comment_num] = sdk_mex(8,comments_h.pointer_value); + + d = @double; + + if result_code == 0 + comment_string = adi.sdk.getStringFromOutput(comment_string_data,comment_length); + comment_info = adi.comment(comment_string,d(tick_pos),... + d(channel),d(comment_num),comments_h.record,... + comments_h.tick_dt,comments_h.trigger_minus_rec_start); + else + adi.sdk.handleErrorCode(result_code); + comment_info = []; + end + end + function comment_number = addComment(file_h,channel,record,tick_position,comment_string) + % + % comment_number = adi.sdk.addComment(channel,record,tick_position,comment_string) + + [result_code,comment_number] = sdk_mex(26,file_h.pointer_value,... + clong(channel), c0(record), clong(tick_position), h__toWChar(comment_string)); + adi.sdk.handleErrorCode(result_code); + end + function deleteComment(file_h,comment_number) + % + % adi.sdk.deleteComment(file_h,comment_number) + + result_code = sdk_mex(27,file_h.pointer_value,clong(comment_number)); + adi.sdk.handleErrorCode(result_code); + end + %Channel specific functions + %------------------------------------------------------------------ + function n_samples = getNSamplesInRecord(file_h,record,channel) + % + % + % n_samples = adi.sdk.getNSamplesInRecord(file_h,record,channel) + % + % INPUTS + % =========================================== + % record : (0 based) + % channel : (0 based) + % + % Status: DONE + + [result_code,n_samples] = sdk_mex(5,file_h.pointer_value,c0(record),c0(channel)); + adi.sdk.handleErrorCode(result_code) + n_samples = double(n_samples); + end + function output_data = getChannelData(file_h,record,channel,start_sample,n_samples_get,get_samples,varargin) + % + % + % output_data = adi.sdk.getChannelData(... + % file_h,record,channel,start_sample,n_samples_get,get_samples) + % + % Inputs: + % ------- + % channel: + % Channel to get the data from, 1 based. + % record: + % Record to get the data from, 1 based. + % start_sample: first sample to get + % n_samples: + % get_samples: + % If true data is returned as samples, if false, the data + % are upsampled (sample & hold) to the highest rate ... + % + % Optional Inputs: + % ---------------- + % leave_raw: (default false) + % If false, the output is cast to a double. If true, the + % cast does not occur and the output is of type 'single' + % + % See Also: + % adi.channel.getAllData + + in.leave_raw = false; + in = adi.sl.in.processVarargin(in,varargin); + + data_type = c(0); + if ~get_samples + %get in tick units + data_type = bitset(data_type,32); + end + + [result_code,data,n_returned] = sdk_mex(10,... + file_h.pointer_value,c0(channel),... + c0(record),c0(start_sample),... + c(n_samples_get),data_type); + + adi.sdk.handleErrorCode(result_code) + + if n_returned ~= n_samples_get + error('Why was this truncated???') + end + + if in.leave_raw + output_data = data; + else + output_data = double(data); %Matlab can get finicky working with singles + end + end + function units = getUnits(file_h,record,channel) + %getUnits + % + % units = adi.sdk.getUnits(file_h,record,channel) + + + [result_code,str_data,str_length] = sdk_mex(11,... + file_h.pointer_value,c0(record),c0(channel)); + + %TODO: Replace with function call to isGoodResultCode + if result_code == 0 || result_code == 1 + units = adi.sdk.getStringFromOutput(str_data,str_length); + else + adi.sdk.handleErrorCode(result_code); + units = ''; + end + + end + function channel_name = getChannelName(file_h,channel) + % + % + % channel_name = adi.sdk.getChannelName(file_h,channel) + % + % Status: DONE + + [result_code,str_data,str_length] = sdk_mex(12,... + file_h.pointer_value,c0(channel)); + + if result_code == 0 + channel_name = adi.sdk.getStringFromOutput(str_data,str_length); + else + adi.sdk.handleErrorCode(result_code); + channel_name = ''; + end + + end + function dt_channel = getSamplePeriod(file_h,record,channel) + % + % + % dt_channel = getSamplePeriod(file_h,channel,record) + % + % This should return the sample period, the inverse of the + % sampling rate, for a single channel. + % + % For channels with NO SAMPLES, the dt returned is NaN + % + % Alternatively, I can ask: + % A) # of ticks in record + % B) tick period + % C) # of samples in record + % + % sample period = + + n_samples_in_record = adi.sdk.getNSamplesInRecord(file_h,record,channel); + if n_samples_in_record == 0 + dt_channel = NaN; + return + end + + % n_ticks_in_record = adi.sdk.getNTicksInRecord(file_h,record); + % tick_dt = adi.sdk.getTickPeriod(file_h,record,channel); + % dt_channel_temp = tick_dt * n_ticks_in_record/n_samples_in_record; + + [result_code,dt_channel] = sdk_mex(15,... + file_h.pointer_value,c0(record),c0(channel)); + + adi.sdk.handleErrorCode(result_code) + end + function setChannelName(file_h,channel,channel_name) + % + % adi.sdk.setChannelName(file_h,channel,channel_name) + % + % Inputs: + % ------- + % file_h: adi.file_handle + % channel: channel index, starting from zero + % channel_name: + + %??? - Does this create a new channel if it doesn't exist yet? + + result_code = sdk_mex(18,file_h.pointer_value,.... + c0(channel),h__toWChar(channel_name)); + + adi.sdk.handleErrorCode(result_code) + + end + function setChannelInfo(writer_h,channel,seconds_per_sample,units,varargin) + % + % Sets channel information for the specific record. + % + % TODO: Make it so that we can have everything be optional + % ... + % + % Inputs: + % ------- + % channel : + % seconds_per_sample : + % + % Optional Inputs: + % ---------------- + % enabled_for_record : (default true) + % limits : + % ???? Why do we care what the limits are???? + % + % ??? - when is this done relative to a new record? Does + % this need to be done every time or does a default carry + % over? Does setting this create a new record or only get + % updated when a new record is started? + + in.enabled_for_record = true; + in.limits = [-Inf Inf]; + in = adi.sl.in.processVarargin(in,varargin); + + result_code = sdk_mex(20,... + writer_h.pointer_value,... + c0(channel),... + h__toInt(in.enabled_for_record),... + double(seconds_per_sample),... + h__toWChar(units),... + single(in.limits)); + adi.sdk.handleErrorCode(result_code) + end + function addChannelSamples(writer_h,channel,data) + % + % adi.sdk.addChannelSamples(writer_h,channel,data) + % + % Inputs: + % ------- + % writer_h: + % channel: + % data: + % + % DLLEXPORT ADIResultCode ADI_AddChannelSamples(ADI_WriterHandle writerH, long channel, + % float* data, long nSamples, long *newTicksAdded); + + [result_code,new_ticks_added] = sdk_mex(22,writer_h.pointer_value,c0(channel),single(data)); + adi.sdk.handleErrorCode(result_code) + end + %Helper functions + %------------------------------------------------------------------ + function is_ok = checkNullChannelErrorCodes(result_code) + % + % + % is_ok = adi.sdk.checkNullChannelErrorCodes(result_code) + % + % For some reason there is a non-zero error code when + % retrieving information about a channel during a record in + % which there is no data for that channel. The error message + % is: "the operation completed successfully" + + is_ok = result_code == 0 || result_code == 1; + %result_code == 1 + %"the operation completed successfully" + end + function hex_value = resultCodeToHex(result_code) + % + % hex_value = adi.sdk.handleErrorCode(result_code) + % + % Returns the hex_value of the result code for comparision + % with the values in the C header. + + temp = typecast(result_code,'uint32'); + hex_value = dec2hex(temp); + end + function is_missing_comment_code = isMissingCommentError(result_code) + % + % + % is_missing_comment_code = adi.sdk.isMissingCommentError(result_code) + + + %TODO: Do I want to do the literal error check here instead + %of the mod???? + + %Relevant Link: + %http://forum.adi.com/viewtopic.php?f=7&t=551 + + %If there are no comments, the result_code is: + %-1610313723 - data requested not present => xA0049005 + + is_missing_comment_code = mod(result_code,16) == 5; + + end + function handleErrorCode(result_code) + % + % + % adi.sdk.handleErrorCode(result_code) + % + % If there is an error this function will throw an error + % and display the relevant error string given the error code + + %Relevant forum post: + %http://forum.adi.com/viewtopic.php?f=7&t=551 + + if ~adi.sdk.checkNullChannelErrorCodes(result_code) + %if result_code ~= 0 + temp = adi.sl.stack.calling_function_info; + errorID = sprintf('ADINSTRUMENTS:SDK:%s',temp.name); + error_msg = adi.sdk.getErrorMessage(result_code); + + + %TODO: Create a clean id - move to a function + %The ID is not allowed to have periods in it + %Also, the calling function info isn't a clean name + %(I think it includes SDK, but what if I only wanted the + %name, not the full path ...???) + % + errorID = regexprep(errorID,'\.',':'); + + error(errorID,[errorID ' ' error_msg]); + end + + %Copied from ADIDatCAPI_mex.h 5/6/2014 + % % % typedef enum ADIResultCode + % % % { + % % % //Win32 error codes (HRESULTs) + % % % kResultSuccess = 0, // operation succeeded + % % % kResultErrorFlagBit = 0x80000000L, // high bit set if operation failed + % % % kResultInvalidArg = 0x80070057L, // invalid argument. One (or more) of the arguments is invalid + % % % kResultFail = 0x80004005L, // Unspecified error + % % % kResultFileNotFound = 0x80030002L, // failure to find the specified file (check the path) + % % % + % % % + % % % //Start of error codes specific to this API + % % % kResultADICAPIMsgBase = 0xA0049000L, + % % % + % % % kResultFileIOError = kResultADICAPIMsgBase, // file IO error - could not read/write file + % % % kResultFileOpenFail, // file failed to open + % % % kResultInvalidFileHandle, // file handle is invalid + % % % kResultInvalidPosition, // pos specified is outside the bounds of the record or file + % % % kResultInvalidCommentNum, // invalid commentNum. Comment could not be found + % % % kResultNoData, // the data requested was not present (e.g. no more comments in the record). + % % % kResultBufferTooSmall // the buffer passed to a function to receive data (e.g. comment text) was not big enough to receive all the data. + % % % + % % % // new result codes must be added at the end + % % % } ADIResultCode; + + end + function error_msg = getErrorMessage(result_code) + % + % + % error_msg = adi.sdk.getErrorMessage(result_code) + + [~,err_msg_data,err_msg_len] = sdk_mex(14,int32(result_code)); + error_msg = adi.sdk.getStringFromOutput(err_msg_data,err_msg_len); + end + function str = getStringFromOutput(int16_data,str_length) + % + % This is a helper function for whenever we get a string out. + % + % str = adi.sdk.getStringFromOutput(int16_data,str_length) + % + % TODO: Make hidden + % + + %str_length - apparently contains the null character, we'll + %ignore the null character here ... + str = char(int16_data(1:str_length-1)); + end + end + + %Wrapper methods ------------------------------------------------------ + methods (Static) + function comments = getAllCommentsForRecord(file_h,record_id,tick_dt,trigger_minus_record_start_s,sdk) + % + % + % DOCUMENTATION: Out of date + % + % comments = adi.sdk.getAllCommentsForRecord(file_handle,record_obj) + % + % Parameters + % ---------- + % file_handle : adi.file_handle + % + % record_id : double + % + % tick_dt : double + % + % See Also: + % adi.record + + %NOTE: These comments seem to be returned ordered by time, not + %by ID. + + MAX_NUMBER_COMMENTS = 1000; %NOTE: Overflow of this value + %just causes things to slow down, it is not a critical error. + + if ~exist('sdk','var') + sdk = adi.sdk; + end + + temp_comments_ca = cell(1,MAX_NUMBER_COMMENTS); + comments_h = sdk.getCommentAccessor(file_h,record_id,tick_dt,trigger_minus_record_start_s); + + if ~comments_h.is_valid + comments = []; + return + end + + %Once the accessor is retrieved, the first comment can be accessed. + temp_comments_ca{1} = comments_h.getCurrentComment(); + + cur_comment_index = 1; + while comments_h.advanceCommentPointer() + cur_comment_index = cur_comment_index + 1; + temp_comments_ca{cur_comment_index} = comments_h.getCurrentComment(); + end + + comments = [temp_comments_ca{1:cur_comment_index}]; + + comments_h.close(); + end + end + + +end + +function int_out = h__toInt(value_in) + int_out = int32(value_in); +end + +function str_out = h__toWChar(str_in) +%NOTE: I had trouble with the unicode string conversion so per +%some Mathworks forum post I am just using a null terminated +%array of int16s +str_out = [int16(str_in) 0]; +end + diff --git a/src/Import/labchart/adi/+adi/test_SDK.m b/Import/labchart/adi/+adi/test_SDK.m similarity index 96% rename from src/Import/labchart/adi/+adi/test_SDK.m rename to Import/labchart/adi/+adi/test_SDK.m index e09dbc8a..5738afc7 100644 --- a/src/Import/labchart/adi/+adi/test_SDK.m +++ b/Import/labchart/adi/+adi/test_SDK.m @@ -1,62 +1,62 @@ -classdef (Hidden) test_SDK - % - % Class: - % adi.test_SDK - % - % Run as: - % adi.test_SDK.run_tests - - properties - end - - methods (Static) - function run_tests() - % - % - % adi.test_SDK.run_tests - % - % See Also: - - %This is a simple write test which eventually should be moved to - %its own function ... - - - - end - function writeChannelTest() - - - COPY_BLANK = false; - %This option is temporary as I was having problems getting - %things to work. - - %If true a blank Labchart file - created in Labchart 8 - is - %copied from this repo to the destination location and a - %openFile with read/write support is called. - %If false then a create_file command is issued instead. - - %This code might move or the function might be renamed ... - temp_file_path = [tempname() '.adicht']; - fprintf(2,'Temporary file being created at:\n%s',temp_file_path) - - file_writer = adi.createFile(temp_file_path,'copy_blank_when_new',COPY_BLANK); - - fw = file_writer; %Let's shorten things - - pres_chan = fw.addChannel(1,'pressure',1000,'cmH20'); - - fw.startRecord(); - - pres_chan.addSamples(1:1000); - - fw.stopRecord(); - - fw.save(); - fw.close(); - - %TODO: I think I need to delete the temp file from the disk - end - end - -end - +classdef (Hidden) test_SDK + % + % Class: + % adi.test_SDK + % + % Run as: + % adi.test_SDK.run_tests + + properties + end + + methods (Static) + function run_tests() + % + % + % adi.test_SDK.run_tests + % + % See Also: + + %This is a simple write test which eventually should be moved to + %its own function ... + + + + end + function writeChannelTest() + + + COPY_BLANK = false; + %This option is temporary as I was having problems getting + %things to work. + + %If true a blank Labchart file - created in Labchart 8 - is + %copied from this repo to the destination location and a + %openFile with read/write support is called. + %If false then a create_file command is issued instead. + + %This code might move or the function might be renamed ... + temp_file_path = [tempname() '.adicht']; + fprintf(2,'Temporary file being created at:\n%s',temp_file_path) + + file_writer = adi.createFile(temp_file_path,'copy_blank_when_new',COPY_BLANK); + + fw = file_writer; %Let's shorten things + + pres_chan = fw.addChannel(1,'pressure',1000,'cmH20'); + + fw.startRecord(); + + pres_chan.addSamples(1:1000); + + fw.stopRecord(); + + fw.save(); + fw.close(); + + %TODO: I think I need to delete the temp file from the disk + end + end + +end + diff --git a/src/Import/labchart/adi/LICENSE b/Import/labchart/adi/LICENSE similarity index 97% rename from src/Import/labchart/adi/LICENSE rename to Import/labchart/adi/LICENSE index e0e693c2..89c88d63 100644 --- a/src/Import/labchart/adi/LICENSE +++ b/Import/labchart/adi/LICENSE @@ -1,21 +1,21 @@ -The MIT License (MIT) - -Copyright (c) 2014 Jim Hokanson - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +The MIT License (MIT) + +Copyright (c) 2014 Jim Hokanson + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/src/Import/labchart/adi/README.rst b/Import/labchart/adi/README.rst similarity index 97% rename from src/Import/labchart/adi/README.rst rename to Import/labchart/adi/README.rst index b7ab3fcf..d7dcbf32 100644 --- a/src/Import/labchart/adi/README.rst +++ b/Import/labchart/adi/README.rst @@ -1,58 +1,58 @@ -======== -Overview -======== - -This code base exposes the C SDK by `ADInstruments `_ -to Matlab. - -General parts include: - -- sdk class/package (see adi.sdk) - this is the Matlab code that directly interfaces with the mex code -- sdk_mex (see +adi/private directory) - this is the actual mex code which calls the ADInstruments dll - -========== -Motivation -========== - -LabChart provides functionality for exporting data to a '.mat' file, although I have yet to get it to work. I also prefer not having files that are simply copies of an original file but in a different format. This code allows reading data directly from LabChart data files. - - -=================== -Top Level Functions -=================== -- adi.readFile : Reads a file -- adi.convert : Converts the a given file to another format (e.g. from .adicht to .mat) - -=================== -File Reading Notes -=================== - -Like most of my more recent readers, the raw channel data are not returned unless specifically requested. Instead a lightweight (low memory) handle is returned with relevant meta data and the raw channel data can be requested via subsequent method calls. - -.. code-block:: matlab - - f = adi.readFile; - pres_chan = f.getChannelByName('pressure'); - raw_pres_data = pres_chan.getData(1); %Get data from the first record - -At some point a function could be written that reads everything and reads it into a structure but this is really really low priority for me. - -To read these files on a Mac first requires converting the 'adicht' format into a 'mat' format. Unfortunately, the way in which these files needs to be created leaves the mat file looking a bit ugly. Once however it is in the 'mat' format, it can be read via the code in the same way that the original 'adicht' file could. - -.. code-block:: matlab - - f = adi.readFile('/Users/Jim/Work/example_file.mat'); - -============== -Current Status -============== - -I've fully implemented the reading portion. I've started the writing portion but I haven't finished it. I have no plans to finish the writing portion at this point in time. - -=========================== -Requirements & Installation -=========================== - -Requires 64bit Matlab on Windows. 32bit Matlab could be supported but some of the mex code would need to be rewritten. - -To install the package ('+adi') needs to be on the Matlab path. Sub-folders of the package should not be added to the path. +======== +Overview +======== + +This code base exposes the C SDK by `ADInstruments `_ +to Matlab. + +General parts include: + +- sdk class/package (see adi.sdk) - this is the Matlab code that directly interfaces with the mex code +- sdk_mex (see +adi/private directory) - this is the actual mex code which calls the ADInstruments dll + +========== +Motivation +========== + +LabChart provides functionality for exporting data to a '.mat' file, although I have yet to get it to work. I also prefer not having files that are simply copies of an original file but in a different format. This code allows reading data directly from LabChart data files. + + +=================== +Top Level Functions +=================== +- adi.readFile : Reads a file +- adi.convert : Converts the a given file to another format (e.g. from .adicht to .mat) + +=================== +File Reading Notes +=================== + +Like most of my more recent readers, the raw channel data are not returned unless specifically requested. Instead a lightweight (low memory) handle is returned with relevant meta data and the raw channel data can be requested via subsequent method calls. + +.. code-block:: matlab + + f = adi.readFile; + pres_chan = f.getChannelByName('pressure'); + raw_pres_data = pres_chan.getData(1); %Get data from the first record + +At some point a function could be written that reads everything and reads it into a structure but this is really really low priority for me. + +To read these files on a Mac first requires converting the 'adicht' format into a 'mat' format. Unfortunately, the way in which these files needs to be created leaves the mat file looking a bit ugly. Once however it is in the 'mat' format, it can be read via the code in the same way that the original 'adicht' file could. + +.. code-block:: matlab + + f = adi.readFile('/Users/Jim/Work/example_file.mat'); + +============== +Current Status +============== + +I've fully implemented the reading portion. I've started the writing portion but I haven't finished it. I have no plans to finish the writing portion at this point in time. + +=========================== +Requirements & Installation +=========================== + +Requires 64bit Matlab on Windows. 32bit Matlab could be supported but some of the mex code would need to be rewritten. + +To install the package ('+adi') needs to be on the Matlab path. Sub-folders of the package should not be added to the path. diff --git a/src/Import/labchart/adi/adi.m b/Import/labchart/adi/adi.m similarity index 97% rename from src/Import/labchart/adi/adi.m rename to Import/labchart/adi/adi.m index 9c104702..27830e8b 100644 --- a/src/Import/labchart/adi/adi.m +++ b/Import/labchart/adi/adi.m @@ -1,119 +1,119 @@ -classdef adi - % - % Class: - % adi - % - % This class is meant to hold simple helpers for the package. - - methods (Static) - function view() - % - % adi.view(*file_path) - % - % This is - %TODO: Run the viewer - file_path = adi.uiGetChartFile(); - adi.file_viewer(file_path); - end - end - - methods (Hidden,Static) - function createBlankFileAtPath(file_path) - % - % adi.createBlankFileAtPath(file_path) - % - % This function was written to try and test out the - % importance of creating a new file, from scratch, versus - % just copying a new file that I had previously created using - % LabChart 8. - % - % I was having trouble with the writing aspect of the SDK. It - % turns out there were bugs in the code that had yet to be - % finished. - % - % I'm not sure if this function is necessary anymore, but - % I'll leave it here for now. - - repo_path = adi.sl.stack.getPackageRoot(); - blank_file_path = fullfile(repo_path,'files','blank_labchart_8_file.adicht'); - copyfile(blank_file_path,file_path) - end - end - methods (Static) - function [file_path, file_root] = uiGetChartFile(varargin) - %x Show user selection window to select Labchart files - % - % [file_path, file_root] = adi.uiGetChartFile(varargin) - % - % This function can be used to select a particular LabChart - % file. - % - % Optional Inputs: - % ---------------- - % multi_select : logical (default: false) - % If true multiple files can be selected. - % prompt : string (default: 'Pick a file to read' - % start_path : string (default: '') - % If not empty the selection will start in the specified - % folder. If empty AND the function was previously used - % the previously selected path will be used. - % - % Output: - % ------- - % file_path : str, 0, or cellstr - % If the user cancels the output is 0. Otherwise this is - % the full path to the file. - % file_root : str or 0 - % Path to the folder that contains the file. - - persistent last_file_root - - in.multi_select = false; - in.prompt = 'Pick a file to read'; - in.start_path = ''; - in = adi.sl.in.processVarargin(in,varargin); - - filter_specifications = ... - {'*.adicht','Labchart Files (*.adicht)'; ... - '*.h5','HDF5 Files (*.h5)';... - '*.mat','Matlab Files (*.mat)'}; - - if in.multi_select - multi_select_value = 'on'; - else - multi_select_value = 'off'; - end - - if isempty(in.start_path) && ~isempty(last_file_root) - in.start_path = last_file_root; - end - - if isempty(in.start_path) - [file_name_or_names,file_root] = uigetfile(filter_specifications,in.prompt,'MultiSelect',multi_select_value); - else - [file_name_or_names,file_root] = uigetfile(filter_specifications,in.prompt,in.start_path,'MultiSelect',multi_select_value); - end - - if isnumeric(file_name_or_names) - file_path = 0; - file_root = 0; - else - last_file_root = file_root; - if ischar(file_name_or_names) - file_path = fullfile(file_root,file_name_or_names); - if in.multi_select - file_path = {file_path}; - end - else - n_files = length(file_name_or_names); - file_path = cell(1,n_files); - for iFile = 1:n_files - file_path{iFile} = fullfile(file_root,file_name_or_names{iFile}); - end - end - end - end - end - -end - +classdef adi + % + % Class: + % adi + % + % This class is meant to hold simple helpers for the package. + + methods (Static) + function view() + % + % adi.view(*file_path) + % + % This is + %TODO: Run the viewer + file_path = adi.uiGetChartFile(); + adi.file_viewer(file_path); + end + end + + methods (Hidden,Static) + function createBlankFileAtPath(file_path) + % + % adi.createBlankFileAtPath(file_path) + % + % This function was written to try and test out the + % importance of creating a new file, from scratch, versus + % just copying a new file that I had previously created using + % LabChart 8. + % + % I was having trouble with the writing aspect of the SDK. It + % turns out there were bugs in the code that had yet to be + % finished. + % + % I'm not sure if this function is necessary anymore, but + % I'll leave it here for now. + + repo_path = adi.sl.stack.getPackageRoot(); + blank_file_path = fullfile(repo_path,'files','blank_labchart_8_file.adicht'); + copyfile(blank_file_path,file_path) + end + end + methods (Static) + function [file_path, file_root] = uiGetChartFile(varargin) + %x Show user selection window to select Labchart files + % + % [file_path, file_root] = adi.uiGetChartFile(varargin) + % + % This function can be used to select a particular LabChart + % file. + % + % Optional Inputs: + % ---------------- + % multi_select : logical (default: false) + % If true multiple files can be selected. + % prompt : string (default: 'Pick a file to read' + % start_path : string (default: '') + % If not empty the selection will start in the specified + % folder. If empty AND the function was previously used + % the previously selected path will be used. + % + % Output: + % ------- + % file_path : str, 0, or cellstr + % If the user cancels the output is 0. Otherwise this is + % the full path to the file. + % file_root : str or 0 + % Path to the folder that contains the file. + + persistent last_file_root + + in.multi_select = false; + in.prompt = 'Pick a file to read'; + in.start_path = ''; + in = adi.sl.in.processVarargin(in,varargin); + + filter_specifications = ... + {'*.adicht','Labchart Files (*.adicht)'; ... + '*.h5','HDF5 Files (*.h5)';... + '*.mat','Matlab Files (*.mat)'}; + + if in.multi_select + multi_select_value = 'on'; + else + multi_select_value = 'off'; + end + + if isempty(in.start_path) && ~isempty(last_file_root) + in.start_path = last_file_root; + end + + if isempty(in.start_path) + [file_name_or_names,file_root] = uigetfile(filter_specifications,in.prompt,'MultiSelect',multi_select_value); + else + [file_name_or_names,file_root] = uigetfile(filter_specifications,in.prompt,in.start_path,'MultiSelect',multi_select_value); + end + + if isnumeric(file_name_or_names) + file_path = 0; + file_root = 0; + else + last_file_root = file_root; + if ischar(file_name_or_names) + file_path = fullfile(file_root,file_name_or_names); + if in.multi_select + file_path = {file_path}; + end + else + n_files = length(file_name_or_names); + file_path = cell(1,n_files); + for iFile = 1:n_files + file_path{iFile} = fullfile(file_root,file_name_or_names{iFile}); + end + end + end + end + end + +end + diff --git a/src/Import/labchart/adi/documentation/ReadMe.md b/Import/labchart/adi/documentation/ReadMe.md similarity index 100% rename from src/Import/labchart/adi/documentation/ReadMe.md rename to Import/labchart/adi/documentation/ReadMe.md diff --git a/src/Import/labchart/adi/documentation/organization.md b/Import/labchart/adi/documentation/organization.md similarity index 96% rename from src/Import/labchart/adi/documentation/organization.md rename to Import/labchart/adi/documentation/organization.md index 6a96f2a1..62afe481 100644 --- a/src/Import/labchart/adi/documentation/organization.md +++ b/Import/labchart/adi/documentation/organization.md @@ -1,31 +1,31 @@ ----------------- -The Labchart SDK ----------------- -This file is meant to briefly discuss how this repo came about and how the code is organized. - -This code is based on the Labchart SDK provided by ADInstruments. An installer for -the SDK can be found in the Labchart folder following installation of Labchart. -The SDK provides a Windows dll and information on what functions are available -in the dll. - -A mex file has been written that calls these dll functions from Matlab. -A separate set of Matlab functions exist that expose this mex file to Matlab. -These functions are currently located in adi.sdk (although I plan on moving this). - -On top of these functions I've written classes that make it slightly easier -to work with the SDK. - -------------------- -Code in the Library -------------------- - -The adi package contains all relevant code. - -Within the adi package are meant to be relevant entry points. -Ideally I want to move most of the non-entry functions outside of the base package but this is a very low priority - -Entry functions include: (may be outdated) -- adi.readFile -- adi.createFile -- adi.editFile +---------------- +The Labchart SDK +---------------- +This file is meant to briefly discuss how this repo came about and how the code is organized. + +This code is based on the Labchart SDK provided by ADInstruments. An installer for +the SDK can be found in the Labchart folder following installation of Labchart. +The SDK provides a Windows dll and information on what functions are available +in the dll. + +A mex file has been written that calls these dll functions from Matlab. +A separate set of Matlab functions exist that expose this mex file to Matlab. +These functions are currently located in adi.sdk (although I plan on moving this). + +On top of these functions I've written classes that make it slightly easier +to work with the SDK. + +------------------- +Code in the Library +------------------- + +The adi package contains all relevant code. + +Within the adi package are meant to be relevant entry points. +Ideally I want to move most of the non-entry functions outside of the base package but this is a very low priority + +Entry functions include: (may be outdated) +- adi.readFile +- adi.createFile +- adi.editFile - adi.convert \ No newline at end of file diff --git a/src/Import/labchart/adi/documentation/updating_mex_code.txt b/Import/labchart/adi/documentation/updating_mex_code.txt similarity index 91% rename from src/Import/labchart/adi/documentation/updating_mex_code.txt rename to Import/labchart/adi/documentation/updating_mex_code.txt index 1cabd241..960f743d 100644 --- a/src/Import/labchart/adi/documentation/updating_mex_code.txt +++ b/Import/labchart/adi/documentation/updating_mex_code.txt @@ -1,16 +1,16 @@ -Upgrading the mex code - -1) Run the ADISimpleDataFileSDK64.msi located at: -C:\Program Files (x86)\ADInstruments\LabChart8\Extras - -2) Copy: -- ADIDatIOWin64.dll -- ADIDatIOWin64.lib - -Over from: (path will be different by user) -C:\Users\Jim\Documents\ADInstruments\SimpleDataFileSDK - -3) Check and see if the header file has changed and move it over if it has. -This however will most likely require some code changes ... - +Upgrading the mex code + +1) Run the ADISimpleDataFileSDK64.msi located at: +C:\Program Files (x86)\ADInstruments\LabChart8\Extras + +2) Copy: +- ADIDatIOWin64.dll +- ADIDatIOWin64.lib + +Over from: (path will be different by user) +C:\Users\Jim\Documents\ADInstruments\SimpleDataFileSDK + +3) Check and see if the header file has changed and move it over if it has. +This however will most likely require some code changes ... + 4) Run adi.sdk.makeMex \ No newline at end of file diff --git a/src/Import/labchart/adi/files/LabChartBinaryFormat.pdf b/Import/labchart/adi/files/LabChartBinaryFormat.pdf similarity index 100% rename from src/Import/labchart/adi/files/LabChartBinaryFormat.pdf rename to Import/labchart/adi/files/LabChartBinaryFormat.pdf diff --git a/src/Import/labchart/adi/files/blank_labchart_8_file.adicht b/Import/labchart/adi/files/blank_labchart_8_file.adicht similarity index 100% rename from src/Import/labchart/adi/files/blank_labchart_8_file.adicht rename to Import/labchart/adi/files/blank_labchart_8_file.adicht diff --git a/src/Import/labchart/adi/files/crash_testing.m b/Import/labchart/adi/files/crash_testing.m similarity index 96% rename from src/Import/labchart/adi/files/crash_testing.m rename to Import/labchart/adi/files/crash_testing.m index f9ccfde7..b8e64a9f 100644 --- a/src/Import/labchart/adi/files/crash_testing.m +++ b/Import/labchart/adi/files/crash_testing.m @@ -1,28 +1,28 @@ -%Running this code enough will cause the program to crash -% -% I think this suggests that if the file is somehow open in on place that -% it shouldn't be opened again in another. -% -% Suggested fix: When trying to open a file, see if it is in memory. -% Problem: I'm not sure how to hold onto the file and yet not allow the -% object to be destroyed. - -%EXPT_ID = '141010_J'; %crashes on Palidin -%EXPT_ID = '140414_C'; %might crash, needs more testing -%EXPT_ID = ''140724_C'; %can crash, takes some work - -for i = 1:100 -EXPT_ID = '141010_J'; -c = dba.GSK.cmg_expt(EXPT_ID); -pres_data = c.getData('pres'); -c2 = dba.GSK.cmg_expt(EXPT_ID); -pres_data2 = c2.getData('pres'); - -clear c -clear c2 -clear pres_data -clear pres_data2 - -c = dba.GSK.cmg_expt(EXPT_ID); -pres_data = c.getData('pres'); +%Running this code enough will cause the program to crash +% +% I think this suggests that if the file is somehow open in on place that +% it shouldn't be opened again in another. +% +% Suggested fix: When trying to open a file, see if it is in memory. +% Problem: I'm not sure how to hold onto the file and yet not allow the +% object to be destroyed. + +%EXPT_ID = '141010_J'; %crashes on Palidin +%EXPT_ID = '140414_C'; %might crash, needs more testing +%EXPT_ID = ''140724_C'; %can crash, takes some work + +for i = 1:100 +EXPT_ID = '141010_J'; +c = dba.GSK.cmg_expt(EXPT_ID); +pres_data = c.getData('pres'); +c2 = dba.GSK.cmg_expt(EXPT_ID); +pres_data2 = c2.getData('pres'); + +clear c +clear c2 +clear pres_data +clear pres_data2 + +c = dba.GSK.cmg_expt(EXPT_ID); +pres_data = c.getData('pres'); end \ No newline at end of file diff --git a/src/Import/nwdq/nReadDataq.m b/Import/nwdq/nReadDataq.m similarity index 97% rename from src/Import/nwdq/nReadDataq.m rename to Import/nwdq/nReadDataq.m index aec720a2..20fa4137 100644 --- a/src/Import/nwdq/nReadDataq.m +++ b/Import/nwdq/nReadDataq.m @@ -1,313 +1,313 @@ -function [info, data] = nReadDataq(filename) -% Read a DATAQ .wdq file according to the documentation published by -% on http://www.dataq.com/resources/techinfo/ff.htm -% -% According to the documentation a .wdq-file consists of three sections -% the header section, the data section and the trailer section. This -% function does only read the header and the data section and thus it only -% returns two structures (info for the header information and data for the -% actual data records). The file trailer has been omitted so far. -% -% In the header section there are some elements which are read but not -% inerpreted. E.g. Element 33 consists of multiple bitwise fields which are -% in this case only read into info.otherSettings. It is up to the user to -% split the data up accordingly to his needs. -% -% Each element in the header section is commented with -% '% Element nr - description' so it should simplify the process of -% searching for an according field name. -% -% The data structure contains an array per channel with the -% recorded data samples. -% -% Things the function hasn't been tested yet (because lack of test-data): -% - packed an unpacked files -% - hiRes and non-hiRes files -% - differential and non differential channel-configuration -% -% Things the function does not do: -% - it does not read the file trailer -% -% Author: Tobias Moser (University of Zurich) in Feb. 2015 - -% initialize info -info = struct(); - -%% Opening file... -[fid] = fopen(filename,'r'); - -% start reading the file - -%% Header section - -% skip element 1 since it depends on element 5 - -fseek(fid, 2, -1); -% Element 2 - sample rate numerator and sample rate formation -info.adReadingsPerSample = fread(fid,1,'*uint16'); - -% Element 3 - Offset in bytes from BOF to header channel info tables -info.headerChannelTablePos = fread(fid,1,'*uint8'); - -% Element 4 - Number of bytes in each channel info entry -info.channelInfoEntrySize = fread(fid,1,'*uint8'); - -% Element 5 - Number of bytes in data file header -info.bytesInDataFileHeader = fread(fid,1,'*int16'); - -if info.bytesInDataFileHeader == 1156 - info.maxChannels = 29; - lLength = 5; -else - info.maxChannels = 144; - lLength = 8; -end - -% jump back to read element 1 -fseek(fid, 0, -1); - -lTmp = fread(fid, 1, '*uint16'); -lAcquired = uint8(0); -for i=1:lLength - lBit = bitget(lTmp, i); - lAcquired = bitset(lAcquired, i, lBit); -end - -info.totalChannelsAcquired = lAcquired; - -% correct Element 5 if it is larger than 144 -if lAcquired > 144 - info.maxChannels = lAcquired + 1; -end - -% go to position for element 6 -fseek(fid, 8, -1); - -% Element 6 - Number of ADC data bytes in file excluding header. -info.adcDataBytes = fread(fid,1,'*uint32'); - -% Element 7 - Total number of event marker, time and date stamp, and event marker comment pointer bytes in trailer -info.eventMarkerInfoPointerBytes = fread(fid, 1, '*uint32'); - -% Element 8 - Total number of user annotation bytes including 1 null per channel -info.totalUserAnnotationBytes = fread(fid, 1, '*uint16'); - -% Element 9 - Height of graphics area in pixels -info.graphicsHeight = fread(fid, 1, '*int16'); - -% Element 10 - Width of graphics area in pixels -info.graphicsWidth = fread(fid, 1, '*int16'); - -% Element 11 - Cursor position relative to screen center: far left = (element 10)/2; center = 0; far right = (element 10)2-1 -info.cursorPosition = fread(fid, 1, '*int16'); - -% Element 12 -> some maximum values -%{ -Byte #24: Max number of overlapping waveforms per window -Byte #25: Max number of horizontally adjacent waveform windows -The high order 6 bits specify the spacing between vertical grid lines. Default = 0 = 20 pixels of space. -The least significant 2 bits contain 01 - the number of horizontally adjacent windows. -Byte #26: Max number of vertically adjacent waveform windows. -Byte #27: Reserved - --> Notice: read it at the moment as uint32 to keep the fread order; if it should be -used later, split it up into a struct-form -%} - -info.maxDesignValues = fread(fid, 1, '*uint32'); - -% Element 13 - Time between channel samples: 1/(sample rate throughput / total number of acquired channels) -info.timeBetweenChannelSamples = fread(fid, 1, '*double'); - -% with this determine the Sample Rate for WinDaq-Files only -info.sampleThroughputRate = int16(info.totalChannelsAcquired) / info.timeBetweenChannelSamples; -info.sampleRatePerChannel = 1 / info.timeBetweenChannelSamples; - -% Element 14 - Time file was opened by acquisition: total number of seconds since Jan. 1, 1970 -info.timeFileOpened = fread(fid, 1, '*int32'); - -% Element 15 - Time file trailer was written by acquisition: total number of seconds since Jan. 1, 1970 -info.timeFileTrailerWritten = fread(fid, 1, '*int32'); - -% Element 16 - Waveform compression factor Relative to start of data section -info.waveformCompressionFactor = fread(fid,1,'*int32'); - -% Element 17 - Position of cursor in waveform file -info.waveformFileCursorPosition = fread(fid, 1, '*int32'); - -% Element 18 - Position of time marker in waveform file -info.waveformFileTimeMarkerPosition = fread(fid, 1, '*int32'); - -% Element 19 - Number of Pre- and Posttrigger data points -info.preTriggerDataPointsCount = fread(fid, 1, '*int16'); -info.postTriggerDataPointsCount = fread(fid, 1, '*int16'); - -% Element 20 - Position of left limit cursor from screen-center in pixels -info.leftLimitCursorPos = fread(fid, 1, '*int16'); - -% Element 21 - Position of right limit cursor from screen-center in pixels -info.rightLimitCursorPos = fread(fid, 1, '*int16'); - -% Element 22 - Playback state memory -info.playbackStateMemroy = fread(fid, 1, '*uint8'); - -% Element 23 - Grid, annotation, compression mode -info.gridAnnotationCompressionMode = fread(fid, 1, '*uint8'); - -% Element 24 - Channel number enabled for adjustments -info.adjustmentsforChannelNumber = fread(fid, 1, '*uint8'); - -% Element 25 - Scroll, "T" key, "P" key, and "W" key states (WinDaq differs from AT-Codas) -info.scrollKeyStates = fread(fid, 1, '*uint8'); - -% Element 26 - Array of 32 elements describing the channels assigned to each waveform window -% not 100% sure -info.channelsToWaveformWindow = fread(fid, 32, '*uint8'); - -% Element 27 - various bits, see documentation -info.hiResFile = fread(fid, 1, '*ubit1'); -info.thermocoupleType = fread(fid, 1, '*ubit2'); -info.mostSignificatn4Bits = fread(fid, 1, '*ubit4'); -info.oscFreeRun = fread(fid, 1, '*ubit1'); -info.lowestPhysicalChannel = fread(fid, 1, '*ubit1'); - -% Bit 9 = 1 if lowest physical channel number is 0 instead of 1 -if info.lowestPhysicalChannel == 1 - info.lowestPhysicalChannel = 0; -else - info.lowestPhysicalChannel = 1; -end; - -info.f3KeySelection = fread(fid, 1, '*ubit2'); -info.f4KeySelection = fread(fid, 1, '*ubit2'); -info.packedFile = fread(fid, 1, '*ubit1'); -info.fft.display = fread(fid, 1, '*ubit1'); - -% Element 28 - Bits 14 and 15 define FFT window. Bit 13 defines FFT type. -info.fft.typeAndWindow = fread(fid, 1, '*uint16'); - -% Element 29 - Bits 0 thru 3 define magnification factor applied to spectrum; -% Bits 4 thru 7 define the spectrum moving average factor -info.spectrum = fread(fid, 1, '*uint8'); - -% Element 30 - Bits 5 and 6 define the display mode; -% bit 7 trig sweep slope; -% Bit 4 = 1/0, erase bar on/off -% Bits 0 thru 3 define the trigger channel source -info.variousDisplaySettings = fread(fid, 1, '*uint8'); - -% Element 31 - MS 14 bits describe the Triggered sweep level -% Data bit 0 is set to indicate Triggered Mode or -% data bit 1 is set to indicate Triggered Storage Mode. -info.triggeredSettings = fread(fid, 1, '*int16'); - -% Element 32 - Bits 7 & 6 describe the active XY cursor. -% Bits 4 - 0 describe the number of 1/16th XY screen stripes enabled (0 - 16). -info.xySettings = fread(fid, 1, '*uint8'); - -% Element 33 - see documentation -info.otherSettings = fread(fid, 1, '*uint8'); - -% Element 34 - Channel information -% go to headerChannelTablePos and start with the iteration through each channel -% until the number fo info.maxChannels is reached - -%% Header Channel Section - -% only read if the header channel size is equal to 36 bytes -% because the documentation only describes elements with -% 36 bytes size (when this was written) -if info.channelInfoEntrySize == 36 - for i = 1:info.totalChannelsAcquired - offsetFactor = uint16(i-1); - headerpos = uint16(info.headerChannelTablePos) + offsetFactor*uint16(info.channelInfoEntrySize); - fseek(fid, headerpos, -1); - % go to position of entry - % Item 1 - Scaling Slope (m) applied to the waveform to scale it within the display window - info.scalingSlope(i) = fread(fid, 1, '*single'); - % Item 2 - Scaling intercept value (b) to Item 1 - info.scalingIntercept(i) = fread(fid, 1, '*single'); - % Item 3 - Calibration scaling factor (m) for waveform value display - info.calibrationScalingFactor(i) = fread(fid, 1, '*double'); - % Item 4 - Calibration Intercept factor (b) for waveform value display - info.calibrationInterceptFactor(i) = fread(fid, 1, '*double'); - % Item 5 - Engineering units tag for calibrated waveform* - info.engineeringUnitsTag(i, 1:6) = deblank(fread(fid, 6, '*char')); - - % Item 6 - Reserved -> skip element - fseek(fid, 1, 0); - % Item 7 - % Unpacked files: Reserved - % Packed files: Sample rate divisor for the channel - info.sampleRateDivisor(i) = fread(fid, 1, '*uint8'); % only if packed Element27 bi 14 = 1 - % Item 8 - 6 bits (Standard version) or 8 bits (Multiplexer versions) used to - % describe the physical channel number - info.physicalChannelNumber(i) = fread(fid, 1, '*uint8'); - % Item 9 - Specifies Gain, mV Full Scale, and Unipolar/Bipolar - info.channelGain(i) = fread(fid, 1, 'bit4=>uint8'); - info.channelMvFullScale(i) = fread(fid, 1, 'bit4=>uint8'); - % Item 10 - see documentation - info.channelSpecificSettings = fread(fid, 1, '*uint16'); - - % calculate (according to Element 6 in File-Header) - % numer of channel samples - info.numberOfChannelSamples(i) = ... - (((info.adcDataBytes/uint32(2*info.totalChannelsAcquired)) - 1) ... - / uint32(info.sampleRateDivisor(i))) + 1; - - end -end - -%% Conclusion - -% warn if file has some special properties -if info.packedFile - warning('Importing from a packed file. Support has not been tested yet.'); -end - -if info.hiResFile - warning('Importing from a hiRes file. Support has not been tested yet.'); -end - -if info.maxChannels >= 144 - warning('Importing from a Multiplexer file. Support has not been tested yet.'); -end - -% prepare -if info.packedFile - info.adcDataBytes = 2*sum(info.numberOfChannelSamples(:)); -end -info.numberOfSamplesWritten = info.adcDataBytes / 2 / uint32(info.totalChannelsAcquired); - -%% DATA section - -% after the fileheader is where to find the acquired data -data = cell(1,info.totalChannelsAcquired); -for i=1:info.totalChannelsAcquired, - fseek(fid, info.bytesInDataFileHeader + int16(2*(i-1)), -1); - % read data - if info.packedFile - % does this make sense, because reading - nSamples = info.numberOfChannelSamples(i); - else - nSamples = info.numberOfSamplesWritten; - end - data{i} = fread(fid, nSamples, '*int16', 2*(info.totalChannelsAcquired -1)); - % convert data to an equivalent engineering unit - % - shift 16bit number to the right by two bits - % - multiply by slope m - % - add the intercept b - if info.hiResFile - data{i} = double(data{i}*0.25)*info.calibrationScalingFactor(i)+info.calibrationInterceptFactor(i); - else - data{i} = double(bitshift(data{i}, -2))*info.calibrationScalingFactor(i)+info.calibrationInterceptFactor(i); - end; -end; - -fclose(fid); - -datacheck = cellfun(@(x) numel(x), data); -if sum(datacheck) == 0 - warning(['Data seems to be empty. Has the file been closed properly? ', ... - 'Maybe try to open, save and import the file again.']); +function [info, data] = nReadDataq(filename) +% Read a DATAQ .wdq file according to the documentation published by +% on http://www.dataq.com/resources/techinfo/ff.htm +% +% According to the documentation a .wdq-file consists of three sections +% the header section, the data section and the trailer section. This +% function does only read the header and the data section and thus it only +% returns two structures (info for the header information and data for the +% actual data records). The file trailer has been omitted so far. +% +% In the header section there are some elements which are read but not +% inerpreted. E.g. Element 33 consists of multiple bitwise fields which are +% in this case only read into info.otherSettings. It is up to the user to +% split the data up accordingly to his needs. +% +% Each element in the header section is commented with +% '% Element nr - description' so it should simplify the process of +% searching for an according field name. +% +% The data structure contains an array per channel with the +% recorded data samples. +% +% Things the function hasn't been tested yet (because lack of test-data): +% - packed an unpacked files +% - hiRes and non-hiRes files +% - differential and non differential channel-configuration +% +% Things the function does not do: +% - it does not read the file trailer +% +% Author: Tobias Moser (University of Zurich) in Feb. 2015 + +% initialize info +info = struct(); + +%% Opening file... +[fid] = fopen(filename,'r'); + +% start reading the file + +%% Header section + +% skip element 1 since it depends on element 5 + +fseek(fid, 2, -1); +% Element 2 - sample rate numerator and sample rate formation +info.adReadingsPerSample = fread(fid,1,'*uint16'); + +% Element 3 - Offset in bytes from BOF to header channel info tables +info.headerChannelTablePos = fread(fid,1,'*uint8'); + +% Element 4 - Number of bytes in each channel info entry +info.channelInfoEntrySize = fread(fid,1,'*uint8'); + +% Element 5 - Number of bytes in data file header +info.bytesInDataFileHeader = fread(fid,1,'*int16'); + +if info.bytesInDataFileHeader == 1156 + info.maxChannels = 29; + lLength = 5; +else + info.maxChannels = 144; + lLength = 8; +end + +% jump back to read element 1 +fseek(fid, 0, -1); + +lTmp = fread(fid, 1, '*uint16'); +lAcquired = uint8(0); +for i=1:lLength + lBit = bitget(lTmp, i); + lAcquired = bitset(lAcquired, i, lBit); +end + +info.totalChannelsAcquired = lAcquired; + +% correct Element 5 if it is larger than 144 +if lAcquired > 144 + info.maxChannels = lAcquired + 1; +end + +% go to position for element 6 +fseek(fid, 8, -1); + +% Element 6 - Number of ADC data bytes in file excluding header. +info.adcDataBytes = fread(fid,1,'*uint32'); + +% Element 7 - Total number of event marker, time and date stamp, and event marker comment pointer bytes in trailer +info.eventMarkerInfoPointerBytes = fread(fid, 1, '*uint32'); + +% Element 8 - Total number of user annotation bytes including 1 null per channel +info.totalUserAnnotationBytes = fread(fid, 1, '*uint16'); + +% Element 9 - Height of graphics area in pixels +info.graphicsHeight = fread(fid, 1, '*int16'); + +% Element 10 - Width of graphics area in pixels +info.graphicsWidth = fread(fid, 1, '*int16'); + +% Element 11 - Cursor position relative to screen center: far left = (element 10)/2; center = 0; far right = (element 10)2-1 +info.cursorPosition = fread(fid, 1, '*int16'); + +% Element 12 -> some maximum values +%{ +Byte #24: Max number of overlapping waveforms per window +Byte #25: Max number of horizontally adjacent waveform windows +The high order 6 bits specify the spacing between vertical grid lines. Default = 0 = 20 pixels of space. +The least significant 2 bits contain 01 - the number of horizontally adjacent windows. +Byte #26: Max number of vertically adjacent waveform windows. +Byte #27: Reserved + +-> Notice: read it at the moment as uint32 to keep the fread order; if it should be +used later, split it up into a struct-form +%} + +info.maxDesignValues = fread(fid, 1, '*uint32'); + +% Element 13 - Time between channel samples: 1/(sample rate throughput / total number of acquired channels) +info.timeBetweenChannelSamples = fread(fid, 1, '*double'); + +% with this determine the Sample Rate for WinDaq-Files only +info.sampleThroughputRate = int16(info.totalChannelsAcquired) / info.timeBetweenChannelSamples; +info.sampleRatePerChannel = 1 / info.timeBetweenChannelSamples; + +% Element 14 - Time file was opened by acquisition: total number of seconds since Jan. 1, 1970 +info.timeFileOpened = fread(fid, 1, '*int32'); + +% Element 15 - Time file trailer was written by acquisition: total number of seconds since Jan. 1, 1970 +info.timeFileTrailerWritten = fread(fid, 1, '*int32'); + +% Element 16 - Waveform compression factor Relative to start of data section +info.waveformCompressionFactor = fread(fid,1,'*int32'); + +% Element 17 - Position of cursor in waveform file +info.waveformFileCursorPosition = fread(fid, 1, '*int32'); + +% Element 18 - Position of time marker in waveform file +info.waveformFileTimeMarkerPosition = fread(fid, 1, '*int32'); + +% Element 19 - Number of Pre- and Posttrigger data points +info.preTriggerDataPointsCount = fread(fid, 1, '*int16'); +info.postTriggerDataPointsCount = fread(fid, 1, '*int16'); + +% Element 20 - Position of left limit cursor from screen-center in pixels +info.leftLimitCursorPos = fread(fid, 1, '*int16'); + +% Element 21 - Position of right limit cursor from screen-center in pixels +info.rightLimitCursorPos = fread(fid, 1, '*int16'); + +% Element 22 - Playback state memory +info.playbackStateMemroy = fread(fid, 1, '*uint8'); + +% Element 23 - Grid, annotation, compression mode +info.gridAnnotationCompressionMode = fread(fid, 1, '*uint8'); + +% Element 24 - Channel number enabled for adjustments +info.adjustmentsforChannelNumber = fread(fid, 1, '*uint8'); + +% Element 25 - Scroll, "T" key, "P" key, and "W" key states (WinDaq differs from AT-Codas) +info.scrollKeyStates = fread(fid, 1, '*uint8'); + +% Element 26 - Array of 32 elements describing the channels assigned to each waveform window +% not 100% sure +info.channelsToWaveformWindow = fread(fid, 32, '*uint8'); + +% Element 27 - various bits, see documentation +info.hiResFile = fread(fid, 1, '*ubit1'); +info.thermocoupleType = fread(fid, 1, '*ubit2'); +info.mostSignificatn4Bits = fread(fid, 1, '*ubit4'); +info.oscFreeRun = fread(fid, 1, '*ubit1'); +info.lowestPhysicalChannel = fread(fid, 1, '*ubit1'); + +% Bit 9 = 1 if lowest physical channel number is 0 instead of 1 +if info.lowestPhysicalChannel == 1 + info.lowestPhysicalChannel = 0; +else + info.lowestPhysicalChannel = 1; +end; + +info.f3KeySelection = fread(fid, 1, '*ubit2'); +info.f4KeySelection = fread(fid, 1, '*ubit2'); +info.packedFile = fread(fid, 1, '*ubit1'); +info.fft.display = fread(fid, 1, '*ubit1'); + +% Element 28 - Bits 14 and 15 define FFT window. Bit 13 defines FFT type. +info.fft.typeAndWindow = fread(fid, 1, '*uint16'); + +% Element 29 - Bits 0 thru 3 define magnification factor applied to spectrum; +% Bits 4 thru 7 define the spectrum moving average factor +info.spectrum = fread(fid, 1, '*uint8'); + +% Element 30 - Bits 5 and 6 define the display mode; +% bit 7 trig sweep slope; +% Bit 4 = 1/0, erase bar on/off +% Bits 0 thru 3 define the trigger channel source +info.variousDisplaySettings = fread(fid, 1, '*uint8'); + +% Element 31 - MS 14 bits describe the Triggered sweep level +% Data bit 0 is set to indicate Triggered Mode or +% data bit 1 is set to indicate Triggered Storage Mode. +info.triggeredSettings = fread(fid, 1, '*int16'); + +% Element 32 - Bits 7 & 6 describe the active XY cursor. +% Bits 4 - 0 describe the number of 1/16th XY screen stripes enabled (0 - 16). +info.xySettings = fread(fid, 1, '*uint8'); + +% Element 33 - see documentation +info.otherSettings = fread(fid, 1, '*uint8'); + +% Element 34 - Channel information +% go to headerChannelTablePos and start with the iteration through each channel +% until the number fo info.maxChannels is reached + +%% Header Channel Section + +% only read if the header channel size is equal to 36 bytes +% because the documentation only describes elements with +% 36 bytes size (when this was written) +if info.channelInfoEntrySize == 36 + for i = 1:info.totalChannelsAcquired + offsetFactor = uint16(i-1); + headerpos = uint16(info.headerChannelTablePos) + offsetFactor*uint16(info.channelInfoEntrySize); + fseek(fid, headerpos, -1); + % go to position of entry + % Item 1 - Scaling Slope (m) applied to the waveform to scale it within the display window + info.scalingSlope(i) = fread(fid, 1, '*single'); + % Item 2 - Scaling intercept value (b) to Item 1 + info.scalingIntercept(i) = fread(fid, 1, '*single'); + % Item 3 - Calibration scaling factor (m) for waveform value display + info.calibrationScalingFactor(i) = fread(fid, 1, '*double'); + % Item 4 - Calibration Intercept factor (b) for waveform value display + info.calibrationInterceptFactor(i) = fread(fid, 1, '*double'); + % Item 5 - Engineering units tag for calibrated waveform* + info.engineeringUnitsTag(i, 1:6) = deblank(fread(fid, 6, '*char')); + + % Item 6 - Reserved -> skip element + fseek(fid, 1, 0); + % Item 7 + % Unpacked files: Reserved + % Packed files: Sample rate divisor for the channel + info.sampleRateDivisor(i) = fread(fid, 1, '*uint8'); % only if packed Element27 bi 14 = 1 + % Item 8 - 6 bits (Standard version) or 8 bits (Multiplexer versions) used to + % describe the physical channel number + info.physicalChannelNumber(i) = fread(fid, 1, '*uint8'); + % Item 9 - Specifies Gain, mV Full Scale, and Unipolar/Bipolar + info.channelGain(i) = fread(fid, 1, 'bit4=>uint8'); + info.channelMvFullScale(i) = fread(fid, 1, 'bit4=>uint8'); + % Item 10 - see documentation + info.channelSpecificSettings = fread(fid, 1, '*uint16'); + + % calculate (according to Element 6 in File-Header) + % numer of channel samples + info.numberOfChannelSamples(i) = ... + (((info.adcDataBytes/uint32(2*info.totalChannelsAcquired)) - 1) ... + / uint32(info.sampleRateDivisor(i))) + 1; + + end +end + +%% Conclusion + +% warn if file has some special properties +if info.packedFile + warning('Importing from a packed file. Support has not been tested yet.'); +end + +if info.hiResFile + warning('Importing from a hiRes file. Support has not been tested yet.'); +end + +if info.maxChannels >= 144 + warning('Importing from a Multiplexer file. Support has not been tested yet.'); +end + +% prepare +if info.packedFile + info.adcDataBytes = 2*sum(info.numberOfChannelSamples(:)); +end +info.numberOfSamplesWritten = info.adcDataBytes / 2 / uint32(info.totalChannelsAcquired); + +%% DATA section + +% after the fileheader is where to find the acquired data +data = cell(1,info.totalChannelsAcquired); +for i=1:info.totalChannelsAcquired, + fseek(fid, info.bytesInDataFileHeader + int16(2*(i-1)), -1); + % read data + if info.packedFile + % does this make sense, because reading + nSamples = info.numberOfChannelSamples(i); + else + nSamples = info.numberOfSamplesWritten; + end + data{i} = fread(fid, nSamples, '*int16', 2*(info.totalChannelsAcquired -1)); + % convert data to an equivalent engineering unit + % - shift 16bit number to the right by two bits + % - multiply by slope m + % - add the intercept b + if info.hiResFile + data{i} = double(data{i}*0.25)*info.calibrationScalingFactor(i)+info.calibrationInterceptFactor(i); + else + data{i} = double(bitshift(data{i}, -2))*info.calibrationScalingFactor(i)+info.calibrationInterceptFactor(i); + end; +end; + +fclose(fid); + +datacheck = cellfun(@(x) numel(x), data); +if sum(datacheck) == 0 + warning(['Data seems to be empty. Has the file been closed properly? ', ... + 'Maybe try to open, save and import the file again.']); end; \ No newline at end of file diff --git a/src/Import/physlog/import_physlog.m b/Import/physlog/import_physlog.m similarity index 97% rename from src/Import/physlog/import_physlog.m rename to Import/physlog/import_physlog.m index 63db8c22..d261edbe 100644 --- a/src/Import/physlog/import_physlog.m +++ b/Import/physlog/import_physlog.m @@ -1,171 +1,171 @@ -function [sts, out] = import_physlog(fn) -% DESCRIPTION: -% This function was written in order to provide a scanphyslog import -% function in the PsPM environment. The function is kept very slim and -% some ideas were taken from other functions (such as the event handling -% bitand() from [1]). This function should be called by pspm_get_physlog. -% -% [1] http://www.mathworks.com/matlabcentral/fileexchange/ -% 42100-readphilipsscanphyslog-filename--channels--skipprep- -% -% FORMAT: [sts, out] = import_physlog(fn) -% -% INPUT: -% fn: (=Filename) Is the path to the according -% scanphyslog file. -% -% OUTPUT: -% sts: Defines whether the function went through without -% any problems or not. If sts == 1 there were no -% errors. If sts ~= 1 there have been errors. -% -% out: Is a struct() with 4 fields (record_date, -% record_time, trigger, data) -% record_date: Contains the record date of the corresponding file. -% This value is read from the file header. -% -% record_time: Contains the record time of the corresponding file. -% As record_date, this value is also read out of the -% file header. -% -% trigger: Is a struct() with three fields: -% val: Contains the event column converted from -% hex to dec. -% sr: Defines the sample rate of the data contained in -% .trigger. -% t: Contains for each trigger one continuous channel -% with the corresponding event. The channels are: -% (according to philips event settings) -% -% .t{:,1} = Trigger ECG -% .t{:,2} = Trigger PPG -% .t{:,3} = Trigger Respiration -% .t{:,4} = Measurement ('slice onset') -% .t{:,5} = start of scan sequence (decimal 16) -% .t{:,6} = end of scan sequence (decimal 32) -% .t{:,7} = Trigger external -% .t{:,8} = Calibration -% .t{:,9} = Manual start -% .t{:,10} = Reference ECG Trigger -% -% Channel 4 apparently is only set when the scan -% software is patched accordingly. -% -% data: Is 6x1 cell structure in PsPM data like fashion. It -% contains: -% -% - again a data field with all the data -% values of the corresponding channel in -% nx1 double format. -% - a header field which sepecifies sr, chantype -% and units of the corresponding data channel. -% -%__________________________________________________________________________ -% PsPM 3.1 -% (C) 2008-2015 Tobias Moser (University of Zurich) - -% $Id$ -% $Rev$ - -% set output -sts = -1; -out = struct(); - -% read header -if exist(fn, 'file') - fileID = fopen(fn,'rt'); -else - warning('ID:invalid_input', 'File ''%s'' not found.', fn); - return; -end - -end_hdr = false; - -out.record_date = date; -out.record_time = datestr(now, 'HH:MM:SS'); - -while ~end_hdr && ~feof(fileID) - l = fgets(fileID); - % still header? - if isempty(regexpi(l, '^##')) - end_hdr = true; - else - expr = '^##\s*\w*\s+(\d\d-\d\d-\d\d\d\d)\s+(\d\d:\d\d:\d\d)\s*$'; - [tokens] = regexp(l, expr, 'tokens'); - % is date time - if ~isempty(tokens) - out.record_date = datestr(datenum(tokens{1}{1},'dd-mm-yyyy'), 'dd-mmm-yyyy'); - out.record_time = tokens{1}{2}; - end - end -end - -fseek(fileID, 0, 'bof'); - -% specify read-in -delimiter = ' '; -formatSpec = '%s%s%s%s%s%s%s%s%s%s%s%s%s%s%[^\n\r]'; -sr = 500; - -% read actual data -fileID = fopen(fn,'r'); -try -dataArray = textscan(fileID, formatSpec, 'Delimiter', delimiter, ... - 'ReturnOnError', false, 'commentstyle', '#', 'MultipleDelimsAsOne',1); -catch - fclose('all'); - warning('ID:invalid_input', 'Cannot read file ''%s''.', fn); return; -end -fclose('all'); - -% handle triggers -% 0x0001 = 0000.0000.0000.0001 = Trigger ECG -% 0x0002 = 0000.0000.0000.0010 = Trigger PPG -% 0x0004 = 0000.0000.0000.0100 = Trigger Respiration -% 0x0008 = 0000.0000.0000.1000 = Measurement ('slice onset') -% 0x0010 = 0000.0000.0001.0000 = start of scan sequence (decimal 16) -% 0x0020 = 0000.0000.0010.0000 = end of scan sequence (decimal 32) -% 0x0040 = 0000.0000.0100.0000 = Trigger external -% 0x0080 = 0000.0000.1000.0000 = Calibration -% 0x0100 = 0000.0001.0000.0000 = Manual start -% 0x8000 = 1000.0000.0000.0000 = Reference ECG Trigger - -trig = struct(); -trig.val = int16(hex2dec(dataArray{:,10})); -trig.t{:,1} = double(bitand(trig.val, 1) ~= 0); % ECG -trig.t{:,2} = double(bitand(trig.val, 2) ~= 0); % PPG -trig.t{:,3} = double(bitand(trig.val, 4) ~= 0); % Respiration -trig.t{:,4} = double(bitand(trig.val, 8) ~= 0); % Measurement -trig.t{:,5} = double(bitand(trig.val, 16) ~= 0); % start of scan sequence -trig.t{:,6} = double(bitand(trig.val, 32) ~= 0); % end of scan sequence -trig.t{:,7} = double(bitand(trig.val, 64) ~= 0); % external -trig.t{:,8} = double(bitand(trig.val, 128) ~= 0); % calibration -trig.t{:,9} = double(bitand(trig.val, 512) ~= 0); % manual start -trig.t{:,10} = double(bitand(trig.val, int16(32768)) ~= 0); % reference ecg trigger - -out.trigger = trig; -out.trigger.sr = sr; - -% convert data into double values -for j = 1:numel(dataArray) - dataArrayDouble(:,j) = str2double(dataArray{j}); -end - -dataArrayDouble(:,sum(~isnan(dataArrayDouble))==0) = []; - -% set data, unit & samplerate -for j = 1:6 - out.data{j,1}.data = dataArrayDouble(:,j); - out.data{j,1}.header.sr = sr; -end -for j = 1:4 - out.data{j,1}.header.chantype = 'ecg'; - out.data{j,1}.header.units = 'volt'; -end -out.data{5,1}.header.chantype = 'ppg'; -out.data{5,1}.header.units = 'volt'; -out.data{6,1}.header.chantype = 'resp'; -out.data{6,1}.header.units = 'PSI'; - -sts = 1; - +function [sts, out] = import_physlog(fn) +% DESCRIPTION: +% This function was written in order to provide a scanphyslog import +% function in the PsPM environment. The function is kept very slim and +% some ideas were taken from other functions (such as the event handling +% bitand() from [1]). This function should be called by pspm_get_physlog. +% +% [1] http://www.mathworks.com/matlabcentral/fileexchange/ +% 42100-readphilipsscanphyslog-filename--channels--skipprep- +% +% FORMAT: [sts, out] = import_physlog(fn) +% +% INPUT: +% fn: (=Filename) Is the path to the according +% scanphyslog file. +% +% OUTPUT: +% sts: Defines whether the function went through without +% any problems or not. If sts == 1 there were no +% errors. If sts ~= 1 there have been errors. +% +% out: Is a struct() with 4 fields (record_date, +% record_time, trigger, data) +% record_date: Contains the record date of the corresponding file. +% This value is read from the file header. +% +% record_time: Contains the record time of the corresponding file. +% As record_date, this value is also read out of the +% file header. +% +% trigger: Is a struct() with three fields: +% val: Contains the event column converted from +% hex to dec. +% sr: Defines the sample rate of the data contained in +% .trigger. +% t: Contains for each trigger one continuous channel +% with the corresponding event. The channels are: +% (according to philips event settings) +% +% .t{:,1} = Trigger ECG +% .t{:,2} = Trigger PPG +% .t{:,3} = Trigger Respiration +% .t{:,4} = Measurement ('slice onset') +% .t{:,5} = start of scan sequence (decimal 16) +% .t{:,6} = end of scan sequence (decimal 32) +% .t{:,7} = Trigger external +% .t{:,8} = Calibration +% .t{:,9} = Manual start +% .t{:,10} = Reference ECG Trigger +% +% Channel 4 apparently is only set when the scan +% software is patched accordingly. +% +% data: Is 6x1 cell structure in PsPM data like fashion. It +% contains: +% +% - again a data field with all the data +% values of the corresponding channel in +% nx1 double format. +% - a header field which sepecifies sr, chantype +% and units of the corresponding data channel. +% +%__________________________________________________________________________ +% PsPM 3.1 +% (C) 2008-2015 Tobias Moser (University of Zurich) + +% $Id$ +% $Rev$ + +% set output +sts = -1; +out = struct(); + +% read header +if exist(fn, 'file') + fileID = fopen(fn,'rt'); +else + warning('ID:invalid_input', 'File ''%s'' not found.', fn); + return; +end + +end_hdr = false; + +out.record_date = date; +out.record_time = datestr(now, 'HH:MM:SS'); + +while ~end_hdr && ~feof(fileID) + l = fgets(fileID); + % still header? + if isempty(regexpi(l, '^##')) + end_hdr = true; + else + expr = '^##\s*\w*\s+(\d\d-\d\d-\d\d\d\d)\s+(\d\d:\d\d:\d\d)\s*$'; + [tokens] = regexp(l, expr, 'tokens'); + % is date time + if ~isempty(tokens) + out.record_date = datestr(datenum(tokens{1}{1},'dd-mm-yyyy'), 'dd-mmm-yyyy'); + out.record_time = tokens{1}{2}; + end + end +end + +fseek(fileID, 0, 'bof'); + +% specify read-in +delimiter = ' '; +formatSpec = '%s%s%s%s%s%s%s%s%s%s%s%s%s%s%[^\n\r]'; +sr = 500; + +% read actual data +fileID = fopen(fn,'r'); +try +dataArray = textscan(fileID, formatSpec, 'Delimiter', delimiter, ... + 'ReturnOnError', false, 'commentstyle', '#', 'MultipleDelimsAsOne',1); +catch + fclose('all'); + warning('ID:invalid_input', 'Cannot read file ''%s''.', fn); return; +end +fclose('all'); + +% handle triggers +% 0x0001 = 0000.0000.0000.0001 = Trigger ECG +% 0x0002 = 0000.0000.0000.0010 = Trigger PPG +% 0x0004 = 0000.0000.0000.0100 = Trigger Respiration +% 0x0008 = 0000.0000.0000.1000 = Measurement ('slice onset') +% 0x0010 = 0000.0000.0001.0000 = start of scan sequence (decimal 16) +% 0x0020 = 0000.0000.0010.0000 = end of scan sequence (decimal 32) +% 0x0040 = 0000.0000.0100.0000 = Trigger external +% 0x0080 = 0000.0000.1000.0000 = Calibration +% 0x0100 = 0000.0001.0000.0000 = Manual start +% 0x8000 = 1000.0000.0000.0000 = Reference ECG Trigger + +trig = struct(); +trig.val = int16(hex2dec(dataArray{:,10})); +trig.t{:,1} = double(bitand(trig.val, 1) ~= 0); % ECG +trig.t{:,2} = double(bitand(trig.val, 2) ~= 0); % PPG +trig.t{:,3} = double(bitand(trig.val, 4) ~= 0); % Respiration +trig.t{:,4} = double(bitand(trig.val, 8) ~= 0); % Measurement +trig.t{:,5} = double(bitand(trig.val, 16) ~= 0); % start of scan sequence +trig.t{:,6} = double(bitand(trig.val, 32) ~= 0); % end of scan sequence +trig.t{:,7} = double(bitand(trig.val, 64) ~= 0); % external +trig.t{:,8} = double(bitand(trig.val, 128) ~= 0); % calibration +trig.t{:,9} = double(bitand(trig.val, 512) ~= 0); % manual start +trig.t{:,10} = double(bitand(trig.val, int16(32768)) ~= 0); % reference ecg trigger + +out.trigger = trig; +out.trigger.sr = sr; + +% convert data into double values +for j = 1:numel(dataArray) + dataArrayDouble(:,j) = str2double(dataArray{j}); +end + +dataArrayDouble(:,sum(~isnan(dataArrayDouble))==0) = []; + +% set data, unit & samplerate +for j = 1:6 + out.data{j,1}.data = dataArrayDouble(:,j); + out.data{j,1}.header.sr = sr; +end +for j = 1:4 + out.data{j,1}.header.chantype = 'ecg'; + out.data{j,1}.header.units = 'volt'; +end +out.data{5,1}.header.chantype = 'ppg'; +out.data{5,1}.header.units = 'volt'; +out.data{6,1}.header.chantype = 'resp'; +out.data{6,1}.header.units = 'PSI'; + +sts = 1; + diff --git a/src/Import/smi/GazeVisToolbox/LICENSE.md b/Import/smi/GazeVisToolbox/LICENSE.md similarity index 100% rename from src/Import/smi/GazeVisToolbox/LICENSE.md rename to Import/smi/GazeVisToolbox/LICENSE.md diff --git a/src/Import/smi/GazeVisToolbox/README.md b/Import/smi/GazeVisToolbox/README.md similarity index 100% rename from src/Import/smi/GazeVisToolbox/README.md rename to Import/smi/GazeVisToolbox/README.md diff --git a/src/Import/smi/GazeVisToolbox/ReadSmiEventHeader.m b/Import/smi/GazeVisToolbox/ReadSmiEventHeader.m similarity index 100% rename from src/Import/smi/GazeVisToolbox/ReadSmiEventHeader.m rename to Import/smi/GazeVisToolbox/ReadSmiEventHeader.m diff --git a/src/Import/smi/GazeVisToolbox/ReadSmiEvents_custom.m b/Import/smi/GazeVisToolbox/ReadSmiEvents_custom.m similarity index 100% rename from src/Import/smi/GazeVisToolbox/ReadSmiEvents_custom.m rename to Import/smi/GazeVisToolbox/ReadSmiEvents_custom.m diff --git a/src/Import/smi/import_smi.m b/Import/smi/import_smi.m similarity index 100% rename from src/Import/smi/import_smi.m rename to Import/smi/import_smi.m diff --git a/src/Import/smi/read_smi_events.m b/Import/smi/read_smi_events.m similarity index 100% rename from src/Import/smi/read_smi_events.m rename to Import/smi/read_smi_events.m diff --git a/src/Import/vario/getVarioport_allChannels.m b/Import/vario/getVarioport_allChannels.m similarity index 95% rename from src/Import/vario/getVarioport_allChannels.m rename to Import/vario/getVarioport_allChannels.m index dbbbf248..b0727540 100644 --- a/src/Import/vario/getVarioport_allChannels.m +++ b/Import/vario/getVarioport_allChannels.m @@ -1,112 +1,112 @@ -function [vario, event] = getVarioport_allChannels(filename) -%Import Varioport data - -% Usage: -% >> vario = getVarioport_allChannels(filename); -% >> [vario, event] = getVarioport_allChannels(filename); -% -% Outputs: -% vario - Varioport data structure -% event - marker channel infos as event structure - -%2009 by Christoph Berger, Rostock University -% - -vario=[]; -if nargout == 2 - event=[]; -end; -%open file -fid = fopen(filename,'r','b'); %big-endian byte ordering - -%channel count -fseek(fid, 7, 'bof'); -vario.head.channel_count = fread(fid, 1); - -%scanrate in Hertz -fseek(fid, 20, 'bof'); -vario.head.ScanRate = fread(fid, 1, 'uint16'); -%scaled scanrate -%SCAN_CONST divided by weighted global scanrate = scaled global scanrate in Hertz . -vario.head.SCAN_CONST = 76800; -vario.head.Scaled_Scan_Rate = vario.head.SCAN_CONST / vario.head.ScanRate; -%date of measure -fseek(fid, 16, 'bof'); -vario.head.measure_date = fread(fid, 3); -%time of measure -fseek(fid, 12, 'bof'); -vario.head.measure_time = fread(fid, 3); -%file header length -fseek(fid, 2, 'bof'); -vario.head.length = fread(fid, 1, 'uint16'); -% get channel info -for i=1:vario.head.channel_count - vario.channel(i) = vario_channel_read(i,fid,vario.head.Scaled_Scan_Rate,vario.head.channel_count); - %write correct channel data - vario.channel(i).data = (vario.channel(i).data - vario.channel(i).offset) .* (vario.channel(i).mul / vario.channel(i).div); -end; -fclose(fid); - -if nargout==2 - markIX = find(strcmpi({vario.channel.name},'marker')); - vario.channel(markIX).time = (1:length(vario.channel(markIX).data)) / vario.channel(markIX).scaled_scan_fac; - %marker value > 0, marker channel shows difference, new marker value is - %kept in next sample - eventIdx = find(vario.channel(markIX).data > 0 & diff([0;vario.channel(markIX).data]) & diff([vario.channel(markIX).data;0]) == 0); - %allocating - event= struct('time', {}, 'nid', {},'name', {}); - if ~isempty(eventIdx) - event(length(eventIdx)).nid=0; - %events - for iEvent = 1:length(eventIdx) - iEventIdx = eventIdx(iEvent); - event(iEvent).time = vario.channel(markIX).time(iEventIdx); - event(iEvent).nid = vario.channel(markIX).data(iEventIdx); - event(iEvent).name = num2str(vario.channel(markIX).data(iEventIdx)); - end - end -end; - -function out = vario_channel_read(chnr,fid,scnrate, chncnt) - -%channel name -fseek(fid, (chnr - 1) * 40 + 36, 'bof'); -out.name = strtrim(fread(fid, 6,'*char')'); -%channel info -%mul -fseek(fid, (chnr - 1) * 40 + 52, 'bof'); -out.mul = fread(fid, 1, 'uint16'); -%div -fseek(fid, (chnr - 1) * 40 + 56, 'bof'); -out.div = fread(fid, 1, 'uint16'); -%offset -fseek(fid, (chnr - 1) * 40 + 54, 'bof'); -out.offset = fread(fid, 1, 'uint16'); -%channel resolution. 1: 2 byte(WORD), 0: 1 byte(BYTE) -fseek(fid, (chnr - 1) * 40 + 47, 'bof'); -out.res = fread(fid, 1); -if out.res && 1 - out.sres = 'uint16'; -else - out.sres = 'uint8'; -end; -%channel unit -fseek(fid, (chnr - 1) * 40 + 42, 'bof'); -out.unit = strtrim((fread(fid, 4,'*char'))'); -%store_rate in Hertz -fseek(fid, (chnr - 1) * 40 + 48, 'bof'); -out.scan_fac = fread(fid, 1); -fseek(fid, (chnr - 1) * 40 + 50, 'bof'); -out.store_fac = fread(fid, 1); -out.scaled_scan_fac = scnrate/(out.scan_fac * out.store_fac); - -%file offset: begin of channel data -fseek(fid, (chnr - 1) * 40 + 60, 'bof'); -%origin=after cheksum header incl. channeldef -out.doffs = fread(fid, 1,'uint32') + 38 + chncnt* 40; -%channel length in byte -fseek(fid, (chnr - 1) * 40 + 64, 'bof'); -out.dlen = fread(fid, 1,'uint32'); -%channel data -fseek(fid, out.doffs, 'bof'); +function [vario, event] = getVarioport_allChannels(filename) +%Import Varioport data + +% Usage: +% >> vario = getVarioport_allChannels(filename); +% >> [vario, event] = getVarioport_allChannels(filename); +% +% Outputs: +% vario - Varioport data structure +% event - marker channel infos as event structure + +%2009 by Christoph Berger, Rostock University +% + +vario=[]; +if nargout == 2 + event=[]; +end; +%open file +fid = fopen(filename,'r','b'); %big-endian byte ordering + +%channel count +fseek(fid, 7, 'bof'); +vario.head.channel_count = fread(fid, 1); + +%scanrate in Hertz +fseek(fid, 20, 'bof'); +vario.head.ScanRate = fread(fid, 1, 'uint16'); +%scaled scanrate +%SCAN_CONST divided by weighted global scanrate = scaled global scanrate in Hertz . +vario.head.SCAN_CONST = 76800; +vario.head.Scaled_Scan_Rate = vario.head.SCAN_CONST / vario.head.ScanRate; +%date of measure +fseek(fid, 16, 'bof'); +vario.head.measure_date = fread(fid, 3); +%time of measure +fseek(fid, 12, 'bof'); +vario.head.measure_time = fread(fid, 3); +%file header length +fseek(fid, 2, 'bof'); +vario.head.length = fread(fid, 1, 'uint16'); +% get channel info +for i=1:vario.head.channel_count + vario.channel(i) = vario_channel_read(i,fid,vario.head.Scaled_Scan_Rate,vario.head.channel_count); + %write correct channel data + vario.channel(i).data = (vario.channel(i).data - vario.channel(i).offset) .* (vario.channel(i).mul / vario.channel(i).div); +end; +fclose(fid); + +if nargout==2 + markIX = find(strcmpi({vario.channel.name},'marker')); + vario.channel(markIX).time = (1:length(vario.channel(markIX).data)) / vario.channel(markIX).scaled_scan_fac; + %marker value > 0, marker channel shows difference, new marker value is + %kept in next sample + eventIdx = find(vario.channel(markIX).data > 0 & diff([0;vario.channel(markIX).data]) & diff([vario.channel(markIX).data;0]) == 0); + %allocating + event= struct('time', {}, 'nid', {},'name', {}); + if ~isempty(eventIdx) + event(length(eventIdx)).nid=0; + %events + for iEvent = 1:length(eventIdx) + iEventIdx = eventIdx(iEvent); + event(iEvent).time = vario.channel(markIX).time(iEventIdx); + event(iEvent).nid = vario.channel(markIX).data(iEventIdx); + event(iEvent).name = num2str(vario.channel(markIX).data(iEventIdx)); + end + end +end; + +function out = vario_channel_read(chnr,fid,scnrate, chncnt) + +%channel name +fseek(fid, (chnr - 1) * 40 + 36, 'bof'); +out.name = strtrim(fread(fid, 6,'*char')'); +%channel info +%mul +fseek(fid, (chnr - 1) * 40 + 52, 'bof'); +out.mul = fread(fid, 1, 'uint16'); +%div +fseek(fid, (chnr - 1) * 40 + 56, 'bof'); +out.div = fread(fid, 1, 'uint16'); +%offset +fseek(fid, (chnr - 1) * 40 + 54, 'bof'); +out.offset = fread(fid, 1, 'uint16'); +%channel resolution. 1: 2 byte(WORD), 0: 1 byte(BYTE) +fseek(fid, (chnr - 1) * 40 + 47, 'bof'); +out.res = fread(fid, 1); +if out.res && 1 + out.sres = 'uint16'; +else + out.sres = 'uint8'; +end; +%channel unit +fseek(fid, (chnr - 1) * 40 + 42, 'bof'); +out.unit = strtrim((fread(fid, 4,'*char'))'); +%store_rate in Hertz +fseek(fid, (chnr - 1) * 40 + 48, 'bof'); +out.scan_fac = fread(fid, 1); +fseek(fid, (chnr - 1) * 40 + 50, 'bof'); +out.store_fac = fread(fid, 1); +out.scaled_scan_fac = scnrate/(out.scan_fac * out.store_fac); + +%file offset: begin of channel data +fseek(fid, (chnr - 1) * 40 + 60, 'bof'); +%origin=after cheksum header incl. channeldef +out.doffs = fread(fid, 1,'uint32') + 38 + chncnt* 40; +%channel length in byte +fseek(fid, (chnr - 1) * 40 + 64, 'bof'); +out.dlen = fread(fid, 1,'uint32'); +%channel data +fseek(fid, out.doffs, 'bof'); out.data = fread(fid, out.dlen / (out.res + 1), out.sres); \ No newline at end of file diff --git a/src/Import/viewpoint/import_viewpoint.m b/Import/viewpoint/import_viewpoint.m similarity index 100% rename from src/Import/viewpoint/import_viewpoint.m rename to Import/viewpoint/import_viewpoint.m diff --git a/src/Import/wdq/ReadDataq.m b/Import/wdq/ReadDataq.m similarity index 97% rename from src/Import/wdq/ReadDataq.m rename to Import/wdq/ReadDataq.m index 4bd8db65..3feb58fa 100644 --- a/src/Import/wdq/ReadDataq.m +++ b/Import/wdq/ReadDataq.m @@ -1,78 +1,78 @@ -function Ch=readdataq(fname) -% Read a DATAQ .wdq or .wdc file into variable "Ch" -% Ch = ReadDataq('junk.wdq') -% fname is the path and filename of the Dataq file -% Returns structure aray: -% Ch = -% SR: sample rate, Hz -% Npt: No points per channel -% Nch: No. channels -% Units: EUTag - units description eg {'kN' 'V'} -% Data: Matrix of the time history data, each channel in a column -% Fname: File path & name -% -% by Steve Grobler, Sinclair Knight Merz, Perth, Australia -% sgrobler@skm.com.au September 2005 -% Based on ReadDataqFile.m from www.dataq.com -% Tested on .wdc files with 2-5 channels, 4.5-2.2 million data points -% each channel. Use at your own risk! -% -% You must have the DATAQ ActiveX controls installed on your machine to use this program. -% You can download the ActiveX control for free at http://www.dataq.com/develop/ -% It may also call the files dataqfileerror.m endoffile.m controlerror.m which -% are available with ReadDataqFile.m from www.dataq.com - -% check that 1 argument is supplied -error(nargchk(1, 1, nargin)) - -figure %this line is optional but it ensures the control is created ina new figure that can be closed later - -%Create the dataqsdk object in a figure window -readdataqfile = actxcontrol('DATAQFILE.ReadDataqFileCtrl.1'); - -%Register the ReadDataqFile Events -readdataqfile.registerevent({'FileError','dataqfileerror';'EndofFile','endoffile';'ControlError','controlerror'}) - -%Select the WinDaq file to read -set(readdataqfile, 'FileName',fname); - -%Open the WinDaq file -readdataqfile.Open - -%Get the sample rate -Ch.SR=readdataqfile.SampleRate; -% Get No. channels, No. Points, EU tags, file name -Ch.Npt=readdataqfile.TotalDataPoints; -Ch.Nch=readdataqfile.ChannelCount; -Ch.Fname=fname; -for i=1:Ch.Nch - Ch.Units(i)=cellstr(readdataqfile.EUTag(i-1)); -end - -% Get the data -blok=32767; % No. of points to read at a time - maximum is 32767 -Ch.Data=NaN(Ch.Nch,Ch.Npt); % Initialise and pre-size the variable to hold the data - -if Ch.Npt<=blok % if No. points is less than 32767, read the whole lot - Ch.Data=readdataqfile.GetData(Ch.Npt, 1); - -else %if No. points is more than 32767, read in blocks of 32767 at a time - for i=1:floor(Ch.Npt/blok) - Ch.Data(:,(i-1)*blok+1:i*blok)=readdataqfile.GetData(blok, 1); - readdataqfile.MoveTo(blok,1); - end - - if rem(Ch.Npt,blok)>0 % read in whatever is left that does not form a full block of 32767 points - Ch.Data(:,(i)*blok+1:end)=readdataqfile.GetData(rem(Ch.Npt,blok), 1); - end -end - -% Close the dataq file and the figure window -readdataqfile.Close -close; - -% Re-shape so that each column represents a channel (instead of each row) -Ch.Data=Ch.Data'; - - - +function Ch=readdataq(fname) +% Read a DATAQ .wdq or .wdc file into variable "Ch" +% Ch = ReadDataq('junk.wdq') +% fname is the path and filename of the Dataq file +% Returns structure aray: +% Ch = +% SR: sample rate, Hz +% Npt: No points per channel +% Nch: No. channels +% Units: EUTag - units description eg {'kN' 'V'} +% Data: Matrix of the time history data, each channel in a column +% Fname: File path & name +% +% by Steve Grobler, Sinclair Knight Merz, Perth, Australia +% sgrobler@skm.com.au September 2005 +% Based on ReadDataqFile.m from www.dataq.com +% Tested on .wdc files with 2-5 channels, 4.5-2.2 million data points +% each channel. Use at your own risk! +% +% You must have the DATAQ ActiveX controls installed on your machine to use this program. +% You can download the ActiveX control for free at http://www.dataq.com/develop/ +% It may also call the files dataqfileerror.m endoffile.m controlerror.m which +% are available with ReadDataqFile.m from www.dataq.com + +% check that 1 argument is supplied +error(nargchk(1, 1, nargin)) + +figure %this line is optional but it ensures the control is created ina new figure that can be closed later + +%Create the dataqsdk object in a figure window +readdataqfile = actxcontrol('DATAQFILE.ReadDataqFileCtrl.1'); + +%Register the ReadDataqFile Events +readdataqfile.registerevent({'FileError','dataqfileerror';'EndofFile','endoffile';'ControlError','controlerror'}) + +%Select the WinDaq file to read +set(readdataqfile, 'FileName',fname); + +%Open the WinDaq file +readdataqfile.Open + +%Get the sample rate +Ch.SR=readdataqfile.SampleRate; +% Get No. channels, No. Points, EU tags, file name +Ch.Npt=readdataqfile.TotalDataPoints; +Ch.Nch=readdataqfile.ChannelCount; +Ch.Fname=fname; +for i=1:Ch.Nch + Ch.Units(i)=cellstr(readdataqfile.EUTag(i-1)); +end + +% Get the data +blok=32767; % No. of points to read at a time - maximum is 32767 +Ch.Data=NaN(Ch.Nch,Ch.Npt); % Initialise and pre-size the variable to hold the data + +if Ch.Npt<=blok % if No. points is less than 32767, read the whole lot + Ch.Data=readdataqfile.GetData(Ch.Npt, 1); + +else %if No. points is more than 32767, read in blocks of 32767 at a time + for i=1:floor(Ch.Npt/blok) + Ch.Data(:,(i-1)*blok+1:i*blok)=readdataqfile.GetData(blok, 1); + readdataqfile.MoveTo(blok,1); + end + + if rem(Ch.Npt,blok)>0 % read in whatever is left that does not form a full block of 32767 points + Ch.Data(:,(i)*blok+1:end)=readdataqfile.GetData(rem(Ch.Npt,blok), 1); + end +end + +% Close the dataq file and the figure window +readdataqfile.Close +close; + +% Re-shape so that each column represents a channel (instead of each row) +Ch.Data=Ch.Data'; + + + diff --git a/src/Import/wdq/activex.exe b/Import/wdq/activex.exe similarity index 100% rename from src/Import/wdq/activex.exe rename to Import/wdq/activex.exe diff --git a/src/Import/wdq/controlerror.m b/Import/wdq/controlerror.m similarity index 83% rename from src/Import/wdq/controlerror.m rename to Import/wdq/controlerror.m index 6898b187..847b6094 100644 --- a/src/Import/wdq/controlerror.m +++ b/Import/wdq/controlerror.m @@ -1,5 +1,5 @@ -%This function is triggered by the event ControlError for the ReadDataqFile -%control. You must register the event ControlError as controlerror so that it will -%call controlerror.m when the event fires. -function controlerror(varargin) %varargin holds a variable number of arguments +%This function is triggered by the event ControlError for the ReadDataqFile +%control. You must register the event ControlError as controlerror so that it will +%call controlerror.m when the event fires. +function controlerror(varargin) %varargin holds a variable number of arguments disp(varargin) %display the error \ No newline at end of file diff --git a/src/Import/wdq/dataqfileerror.m b/Import/wdq/dataqfileerror.m similarity index 82% rename from src/Import/wdq/dataqfileerror.m rename to Import/wdq/dataqfileerror.m index 7f8ca4a2..0a8b4562 100644 --- a/src/Import/wdq/dataqfileerror.m +++ b/Import/wdq/dataqfileerror.m @@ -1,5 +1,5 @@ -%This function is triggered by the event FileError for the ReadDataqFile -%control. You must register the event FileError as newdata so that it will -%call newdata.m when the event fires. -function dataqfileerror(varargin) %varargin holds a variable number of arguments +%This function is triggered by the event FileError for the ReadDataqFile +%control. You must register the event FileError as newdata so that it will +%call newdata.m when the event fires. +function dataqfileerror(varargin) %varargin holds a variable number of arguments disp(varargin) %display the error \ No newline at end of file diff --git a/src/Import/wdq/endoffile.m b/Import/wdq/endoffile.m similarity index 97% rename from src/Import/wdq/endoffile.m rename to Import/wdq/endoffile.m index e438b66d..473a1b03 100644 --- a/src/Import/wdq/endoffile.m +++ b/Import/wdq/endoffile.m @@ -1,5 +1,5 @@ -%This function is triggered by the event EndofFile for the ReadDataqFile -%control. You must register the event EndofFile as endoffile so that it will -%call endoffile.m when the event fires. -function endoffile(varargin) %varargin holds a variable number of arguments +%This function is triggered by the event EndofFile for the ReadDataqFile +%control. You must register the event EndofFile as endoffile so that it will +%call endoffile.m when the event fires. +function endoffile(varargin) %varargin holds a variable number of arguments disp('End of file has been reached!') %display end of file message \ No newline at end of file diff --git a/doc/PsPM_Manual.pdf b/Manual/PsPM_Manual.pdf similarity index 100% rename from doc/PsPM_Manual.pdf rename to Manual/PsPM_Manual.pdf diff --git a/doc/PsPM_References.pdf b/Manual/PsPM_References.pdf similarity index 100% rename from doc/PsPM_References.pdf rename to Manual/PsPM_References.pdf diff --git a/src/backroom/SCR_f_amplitude_check.m b/backroom/SCR_f_amplitude_check.m similarity index 100% rename from src/backroom/SCR_f_amplitude_check.m rename to backroom/SCR_f_amplitude_check.m diff --git a/src/backroom/blink_saccade_filtering.m b/backroom/blink_saccade_filtering.m similarity index 100% rename from src/backroom/blink_saccade_filtering.m rename to backroom/blink_saccade_filtering.m diff --git a/src/backroom/pspm_axpos.m b/backroom/pspm_axpos.m similarity index 95% rename from src/backroom/pspm_axpos.m rename to backroom/pspm_axpos.m index 90a60e07..34a8056a 100644 --- a/src/backroom/pspm_axpos.m +++ b/backroom/pspm_axpos.m @@ -1,30 +1,30 @@ -function pos = axpos (rownum, colnum, leftmarg, rightmarg, upmarg, downmarg, inmarg) -% FORMAT -% pos = axpos (rownum, colnum, leftmarg, rightmarg, upmarg,downmarg, inmarg) -% gets an axes number x 2 (x, y) matrix to be used in axes commands -%__________________________________________________________________________ -% PsPM 3.0 -% (C) 2008-2015 Dominik R Bach (Wellcome Trust Centre for Neuroimaging) - -% $Id$ -% $Rev$ - -% initialise -% ------------------------------------------------------------------------- -global settings; -if isempty(settings), pspm_init; end; -% ------------------------------------------------------------------------- - -height=(1-(upmarg+downmarg+(rownum-1)*inmarg))/rownum; -width=(1-(leftmarg+rightmarg+(colnum-1)*inmarg))/colnum; -ax=1; -for row=1:rownum - for col=1:colnum - pos(ax,1)=leftmarg+(col-1)*(width+inmarg); - pos(ax,2)=downmarg+(rownum-row)*(height+inmarg); - pos(ax,3)=width; - pos(ax,4)=height; - ax=ax+1; - end; -end; +function pos = axpos (rownum, colnum, leftmarg, rightmarg, upmarg, downmarg, inmarg) +% FORMAT +% pos = axpos (rownum, colnum, leftmarg, rightmarg, upmarg,downmarg, inmarg) +% gets an axes number x 2 (x, y) matrix to be used in axes commands +%__________________________________________________________________________ +% PsPM 3.0 +% (C) 2008-2015 Dominik R Bach (Wellcome Trust Centre for Neuroimaging) + +% $Id$ +% $Rev$ + +% initialise +% ------------------------------------------------------------------------- +global settings; +if isempty(settings), pspm_init; end; +% ------------------------------------------------------------------------- + +height=(1-(upmarg+downmarg+(rownum-1)*inmarg))/rownum; +width=(1-(leftmarg+rightmarg+(colnum-1)*inmarg))/colnum; +ax=1; +for row=1:rownum + for col=1:colnum + pos(ax,1)=leftmarg+(col-1)*(width+inmarg); + pos(ax,2)=downmarg+(rownum-row)*(height+inmarg); + pos(ax,3)=width; + pos(ax,4)=height; + ax=ax+1; + end; +end; clear ax width height; \ No newline at end of file diff --git a/src/backroom/pspm_bf_Fourier.m b/backroom/pspm_bf_Fourier.m similarity index 96% rename from src/backroom/pspm_bf_Fourier.m rename to backroom/pspm_bf_Fourier.m index 55cd47b7..09dcd6b3 100644 --- a/src/backroom/pspm_bf_Fourier.m +++ b/backroom/pspm_bf_Fourier.m @@ -1,80 +1,80 @@ -function [bf, x] = pspm_bf_Fourier(varargin) - -% SCR_BF_Fourier provides a sine/cosine set of basis functions with or without -% Hanning window, of specified lenght and order -% -% FORMAT: -% [bf, x] = pspm_bf_Fourier(td, n, order, window) or -% pspm_bf_Fourier([td, n, order, window]) -% with -% td: sampling interval in seconds -% n: window length in seconds (default: 30) -% order: 1/2 * number of basis functions (default: 8) -% window: Hanning window (default: 1) -% -%__________________________________________________________________________ -% PsPM 3.0 -% (C) 2008-2015 Dominik R Bach (Wellcome Trust Centre for Neuroimaging) - -% v001 drb 03.08.3012 - -% $Id$ -% $Rev$ - -% initialise -% ------------------------------------------------------------------------- -global settings; -if isempty(settings), pspm_init; end; -% ------------------------------------------------------------------------- - -% set defaults -%---------------------------------------------------------------------- -n = 30; order = 8; window = 1; - -% get sampling interval -%---------------------------------------------------------------------- -if nargin == 0 - errmsg = 'No sampling interval stated'; warning('ID:invalid_input', errmsg); return; -end; -td = varargin{1}(1); - -% get input arguments -if nargin == 1 - if numel(varargin{1}) > 1, n = varargin{1}(2); end; - if numel(varargin{1}) > 2, order = varargin{1}(3); end; - if numel(varargin{1}) > 3, window = varargin{1}(4); end; -else - n = varargin{2}; - if nargin > 2, order = varargin{3}; end; - if nargin > 3, window = varargin{4}; end; -end; - -if td > n - warning('ID:invalid_input', 'Time resolution is larger than duration of the function.'); return; -elseif td == 0 - warning('ID:invalid_input', 'Time resolution must be larger than 0.'); return; -end; - - -% construct basis set -%---------------------------------------------------------------------- -pst = 0:td:n-td'; -x = pst; -pst = pst/max(pst); - -if window - g = (1 - cos(2*pi*pst))/2; -else - g = ones(size(pst)); -end - -bf = g; - -for i = 1:order - bf = [bf g.*sin(i*2*pi*pst)]; - bf = [bf g.*cos(i*2*pi*pst)]; -end - -return; - - +function [bf, x] = pspm_bf_Fourier(varargin) + +% SCR_BF_Fourier provides a sine/cosine set of basis functions with or without +% Hanning window, of specified lenght and order +% +% FORMAT: +% [bf, x] = pspm_bf_Fourier(td, n, order, window) or +% pspm_bf_Fourier([td, n, order, window]) +% with +% td: sampling interval in seconds +% n: window length in seconds (default: 30) +% order: 1/2 * number of basis functions (default: 8) +% window: Hanning window (default: 1) +% +%__________________________________________________________________________ +% PsPM 3.0 +% (C) 2008-2015 Dominik R Bach (Wellcome Trust Centre for Neuroimaging) + +% v001 drb 03.08.3012 + +% $Id$ +% $Rev$ + +% initialise +% ------------------------------------------------------------------------- +global settings; +if isempty(settings), pspm_init; end; +% ------------------------------------------------------------------------- + +% set defaults +%---------------------------------------------------------------------- +n = 30; order = 8; window = 1; + +% get sampling interval +%---------------------------------------------------------------------- +if nargin == 0 + errmsg = 'No sampling interval stated'; warning('ID:invalid_input', errmsg); return; +end; +td = varargin{1}(1); + +% get input arguments +if nargin == 1 + if numel(varargin{1}) > 1, n = varargin{1}(2); end; + if numel(varargin{1}) > 2, order = varargin{1}(3); end; + if numel(varargin{1}) > 3, window = varargin{1}(4); end; +else + n = varargin{2}; + if nargin > 2, order = varargin{3}; end; + if nargin > 3, window = varargin{4}; end; +end; + +if td > n + warning('ID:invalid_input', 'Time resolution is larger than duration of the function.'); return; +elseif td == 0 + warning('ID:invalid_input', 'Time resolution must be larger than 0.'); return; +end; + + +% construct basis set +%---------------------------------------------------------------------- +pst = 0:td:n-td'; +x = pst; +pst = pst/max(pst); + +if window + g = (1 - cos(2*pi*pst))/2; +else + g = ones(size(pst)); +end + +bf = g; + +for i = 1:order + bf = [bf g.*sin(i*2*pi*pst)]; + bf = [bf g.*cos(i*2*pi*pst)]; +end + +return; + + diff --git a/src/backroom/pspm_combine_markers.m b/backroom/pspm_combine_markers.m similarity index 100% rename from src/backroom/pspm_combine_markers.m rename to backroom/pspm_combine_markers.m diff --git a/src/backroom/pspm_convert_illum2lum.m b/backroom/pspm_convert_illum2lum.m similarity index 97% rename from src/backroom/pspm_convert_illum2lum.m rename to backroom/pspm_convert_illum2lum.m index 2da34905..2be90202 100644 --- a/src/backroom/pspm_convert_illum2lum.m +++ b/backroom/pspm_convert_illum2lum.m @@ -1,48 +1,48 @@ -function [luminance] = pspm_convert_illum2lum(illuminance, distance, display_size, aspect) -% SCR_CONVERT_ILLUM2LUM converts illuminance values into luminance values -% -% FORMAT: [luminance] = pspm_convert_illum2lum(illuminance, distance, display_size, aspect) -% -% ARGUMENTS: -% -% illuminance: The measured illuminance value in lux. -% distance: Distance between eye and screen in m. -% display_size: Size of the display in Inch -% aspect: Struct containing two aspect ratios of the -% screen. -% actual: States the actual aspect ratio of the screen. -% Default is [16 9]. -% used: States the aspect ratio which was set on the -% screen. If is not set, is automatically set to -% the value of aspect.actual. -%__________________________________________________________________________ -% PsPM 3.0 -% (C) 2008-2015 Tobias Moser (University of Zurich) - -% $Id$ -% $Rev$ - -% initialise -% ------------------------------------------------------------------------- -global settings; -if isempty(settings), pspm_init; end; - - -if nargin < 4 || isempty(aspect) || ~isstruct(aspect) - aspect = struct(); -end; - -if ~isfield(aspect, 'actual') - aspect.actual = [16 9]; -end; - -if ~isfield(aspect, 'used') - aspect.used = aspect.actual; -end; - -d_size_m = display_size*2.54/100; - -h = d_size_m/sqrt((aspect.actual(1)/aspect.actual(2))^2 + 1); -w = (aspect.used(1)/aspect.used(2))*h; - -luminance = ( illuminance*(distance^2) ) / ( h * w ); +function [luminance] = pspm_convert_illum2lum(illuminance, distance, display_size, aspect) +% SCR_CONVERT_ILLUM2LUM converts illuminance values into luminance values +% +% FORMAT: [luminance] = pspm_convert_illum2lum(illuminance, distance, display_size, aspect) +% +% ARGUMENTS: +% +% illuminance: The measured illuminance value in lux. +% distance: Distance between eye and screen in m. +% display_size: Size of the display in Inch +% aspect: Struct containing two aspect ratios of the +% screen. +% actual: States the actual aspect ratio of the screen. +% Default is [16 9]. +% used: States the aspect ratio which was set on the +% screen. If is not set, is automatically set to +% the value of aspect.actual. +%__________________________________________________________________________ +% PsPM 3.0 +% (C) 2008-2015 Tobias Moser (University of Zurich) + +% $Id$ +% $Rev$ + +% initialise +% ------------------------------------------------------------------------- +global settings; +if isempty(settings), pspm_init; end; + + +if nargin < 4 || isempty(aspect) || ~isstruct(aspect) + aspect = struct(); +end; + +if ~isfield(aspect, 'actual') + aspect.actual = [16 9]; +end; + +if ~isfield(aspect, 'used') + aspect.used = aspect.actual; +end; + +d_size_m = display_size*2.54/100; + +h = d_size_m/sqrt((aspect.actual(1)/aspect.actual(2))^2 + 1); +w = (aspect.used(1)/aspect.used(2))*h; + +luminance = ( illuminance*(distance^2) ) / ( h * w ); diff --git a/src/backroom/pspm_convert_lux2cdm2.m b/backroom/pspm_convert_lux2cdm2.m similarity index 97% rename from src/backroom/pspm_convert_lux2cdm2.m rename to backroom/pspm_convert_lux2cdm2.m index 806c64e3..655f832e 100644 --- a/src/backroom/pspm_convert_lux2cdm2.m +++ b/backroom/pspm_convert_lux2cdm2.m @@ -1,67 +1,67 @@ -function [sts, cd] = pspm_convert_lux2cdm2(lux, screen) -% SCR_CONVERT_LUX2CDM2 converts lux values to cd/m^2 values. In other words -% a conversion from illuminance (what we measure with the light meter) to -% luminance -% -% It can work on PsPM files or on numeric vectors. -% -% -% FORMAT: -% [sts, cd] = pspm_convert_lux2cdm2(lux, screen) -% -% ARGUMENTS: -% lux: a numeric vector of lux values -% screen: a struct with the following fields -% diameter: screen diameter in inches -% distance: distance between screen and eyes in meter -% aspect_actual: actual aspect ratio of the screen (property -% of the hardware). a 1x2 vector is espected -% e.g. [16 9] -% aspect_used: used aspect ratio of the screen (set in the -% software) (optional). a 1x2 vector is -% expected e.g. [5 4] -%__________________________________________________________________________ -% PsPM 3.1 -% (C) 2016 Tobias Moser (University of Zurich) -% -% $Id$ -% $Rev$ -% -% initialise -% ------------------------------------------------------------------------- -global settings; -if isempty(settings), pspm_init; end; -sts = -1; - - -if ~isnumeric(lux) - warning('ID:invalid_input', 'Lux is not numeric.'); return; -elseif ~isstruct(screen) - warning('ID:invalid_input', 'Screen is not a struct.'); return; -elseif ~isfield(screen, 'diameter') || ~isnumeric(screen.diameter) - warning('ID:invalid_input', 'screen.diameter does not exist or is not numeric.'); -elseif ~isfield(screen, 'distance') || ~isnumeric(screen.distance) - warning('ID:invalid_input', 'screen.distance does not exist or is not numeric.'); -elseif ~isfield(screen, 'aspect_actual') || ~isnumeric(screen.aspect_actual) - warning('ID:invalid_input', 'screen.aspect_actual does not exist or is not numeric.'); return; -elseif isfield(screen, 'aspect_used') && ~isnumeric(screen.aspect_used) - warning('ID:invalid_input', 'screen.aspect_used is not numeric.'); return; -end; - -% default value from aspect_actual -if ~isfield(screen, 'aspect_used') - screen.aspect_used = screen.aspect_actual; -end; - -% do conversion -dia_cm = screen.diameter*2.54; -h = sqrt((screen.aspect_actual(2)*dia_cm)^2 / (sum(screen.aspect_actual.^2)))/100; -w = h*screen.aspect_used(1)/screen.aspect_used(2)/100; - -cd = (lux.*screen.distance^2)/(h*w); -sts = 1; - - - - - +function [sts, cd] = pspm_convert_lux2cdm2(lux, screen) +% SCR_CONVERT_LUX2CDM2 converts lux values to cd/m^2 values. In other words +% a conversion from illuminance (what we measure with the light meter) to +% luminance +% +% It can work on PsPM files or on numeric vectors. +% +% +% FORMAT: +% [sts, cd] = pspm_convert_lux2cdm2(lux, screen) +% +% ARGUMENTS: +% lux: a numeric vector of lux values +% screen: a struct with the following fields +% diameter: screen diameter in inches +% distance: distance between screen and eyes in meter +% aspect_actual: actual aspect ratio of the screen (property +% of the hardware). a 1x2 vector is espected +% e.g. [16 9] +% aspect_used: used aspect ratio of the screen (set in the +% software) (optional). a 1x2 vector is +% expected e.g. [5 4] +%__________________________________________________________________________ +% PsPM 3.1 +% (C) 2016 Tobias Moser (University of Zurich) +% +% $Id$ +% $Rev$ +% +% initialise +% ------------------------------------------------------------------------- +global settings; +if isempty(settings), pspm_init; end; +sts = -1; + + +if ~isnumeric(lux) + warning('ID:invalid_input', 'Lux is not numeric.'); return; +elseif ~isstruct(screen) + warning('ID:invalid_input', 'Screen is not a struct.'); return; +elseif ~isfield(screen, 'diameter') || ~isnumeric(screen.diameter) + warning('ID:invalid_input', 'screen.diameter does not exist or is not numeric.'); +elseif ~isfield(screen, 'distance') || ~isnumeric(screen.distance) + warning('ID:invalid_input', 'screen.distance does not exist or is not numeric.'); +elseif ~isfield(screen, 'aspect_actual') || ~isnumeric(screen.aspect_actual) + warning('ID:invalid_input', 'screen.aspect_actual does not exist or is not numeric.'); return; +elseif isfield(screen, 'aspect_used') && ~isnumeric(screen.aspect_used) + warning('ID:invalid_input', 'screen.aspect_used is not numeric.'); return; +end; + +% default value from aspect_actual +if ~isfield(screen, 'aspect_used') + screen.aspect_used = screen.aspect_actual; +end; + +% do conversion +dia_cm = screen.diameter*2.54; +h = sqrt((screen.aspect_actual(2)*dia_cm)^2 / (sum(screen.aspect_actual.^2)))/100; +w = h*screen.aspect_used(1)/screen.aspect_used(2)/100; + +cd = (lux.*screen.distance^2)/(h*w); +sts = 1; + + + + + diff --git a/src/backroom/pspm_convert_mm2visdeg.m b/backroom/pspm_convert_mm2visdeg.m similarity index 95% rename from src/backroom/pspm_convert_mm2visdeg.m rename to backroom/pspm_convert_mm2visdeg.m index e0cb115e..3338026a 100644 --- a/src/backroom/pspm_convert_mm2visdeg.m +++ b/backroom/pspm_convert_mm2visdeg.m @@ -1,34 +1,34 @@ -function [sts, vd] = pspm_convert_mm2visdeg(mm, distance) -% SCR_CONVERT_MM2VISDEG converts milimeter values to visual degree values. -% -% It can work on PsPM files or on numeric vectors. -% -% FORMAT: -% [sts, vd] = pspm_convert_mm2visdeg(mm, distance) -% -% ARGUMENTS: -% mm: a numeric vector of milimeter values -% distance: distance between screen and eyes in meter -% -%__________________________________________________________________________ -% PsPM 3.1 -% (C) 2016 Tobias Moser (University of Zurich) - -% $Id$ -% $Rev$ - -% initialise -% ------------------------------------------------------------------------- -global settings; -if isempty(settings), pspm_init; end; -sts = -1; - -if ~isnumeric(mm) - warning('ID:invalid_input', 'mm is not numeric'); -elseif ~isnumeric(distance) - warning('ID:invalid_input', 'distance is not numeric'); return; -end; - -d_mm = distance*1000; -vd = 2.*atan(mm ./ (2*d_mm)).*180./pi; +function [sts, vd] = pspm_convert_mm2visdeg(mm, distance) +% SCR_CONVERT_MM2VISDEG converts milimeter values to visual degree values. +% +% It can work on PsPM files or on numeric vectors. +% +% FORMAT: +% [sts, vd] = pspm_convert_mm2visdeg(mm, distance) +% +% ARGUMENTS: +% mm: a numeric vector of milimeter values +% distance: distance between screen and eyes in meter +% +%__________________________________________________________________________ +% PsPM 3.1 +% (C) 2016 Tobias Moser (University of Zurich) + +% $Id$ +% $Rev$ + +% initialise +% ------------------------------------------------------------------------- +global settings; +if isempty(settings), pspm_init; end; +sts = -1; + +if ~isnumeric(mm) + warning('ID:invalid_input', 'mm is not numeric'); +elseif ~isnumeric(distance) + warning('ID:invalid_input', 'distance is not numeric'); return; +end; + +d_mm = distance*1000; +vd = 2.*atan(mm ./ (2*d_mm)).*180./pi; sts = 1; \ No newline at end of file diff --git a/src/backroom/pspm_find_data_epochs.m b/backroom/pspm_find_data_epochs.m similarity index 97% rename from src/backroom/pspm_find_data_epochs.m rename to backroom/pspm_find_data_epochs.m index 8d7cd0e9..e7dd0498 100644 --- a/src/backroom/pspm_find_data_epochs.m +++ b/backroom/pspm_find_data_epochs.m @@ -1,126 +1,126 @@ -function [sts, epochfile] = pspm_find_data_epochs(datafile, chan_id, options) -% pspm_find_data_epochs tries to find epochs of non-zero values in the data -% of a channel. It then writes it to a file depending on the input and -% returns the location of that file. -% -% FORMAT: -% [sts, epochfile] = pspm_find_data_epochs(datafile, chan_id, options) -% -% ARGUMENTS: -% datafile: File which contains the corresponding channel to -% look for epochs. -% chan_id: Number or chantype of the the channel. If -% multiple channels match the specified chantype -% only the first found channel will be used. -% options: -% output_file: Name and path to the output file. Default is the -% same as datafile but prepended with an 'e'. -% overwrite: Overwrite output file if it already exists. Default -% is 0. -% -% OUTPUT: -% sts: Return status of the function. If equals 1 no -% error or warnings were produced. -% epochfile: File where the epochs have been saved to. -%__________________________________________________________________________ -% PsPM 3.1 -% (C) 2016 Tobias Moser (University of Zurich) - -% $Id$ -% $Rev$ - -% initialise -% ------------------------------------------------------------------------- -global settings; -if isempty(settings), pspm_init; end; -sts = -1; - -% check input -if ~exist('options', 'var') - options = struct(); -end; - -if ~isfield(options, 'output_file') - [path, name, ext] = fileparts(datafile); - options.output_file = [path, filesep, 'e', name, ext]; -end; - -if ~isfield(options, 'overwrite') - options.overwrite = 0; -end; - -if ~isfield(options, 'dont_ask_overwrite') - options.dont_ask_overwrite = 0; -end; - -if isempty(datafile) || ~ischar(datafile) - warning('ID:invalid_input', 'Datafile is empty or not a valid string.'); return; -elseif ~exist(datafile, 'file') - warning('ID:invalid_input', 'Datafile (%s) does not exist.', datafile); return; -elseif ~isnumeric(chan_id) && ~ischar(chan_id) - warning('ID:invalid_input', 'Chan_id is neither numeric nor a valid string.'); return; -elseif ~ischar(options.output_file) - warning('ID:invalid_input', 'Options.output_file is not a valid string.'); return; -elseif ~islogical(options.overwrite) && ~isnumeric(options.overwrite) - warning('ID:invalid_input', 'Options.overwrite is neither logical nor numeric.'); - return; -elseif ~islogical(options.dont_ask_overwrite) && ... - ~isnumeric(options.dont_ask_overwrite) - warning('ID:invalid_input', 'Options.overwrite is neither logical nor numeric.'); - return; -end; - -% load data -[~, ~, data] = pspm_load_data(datafile); - -if chan_id > numel(data) - warning('ID:invalid_input', 'Channel id exceeds channel count.'); return; -end; - -% create logical array in order to distinguish between non-zero and zero -logi = data{chan_id}.data ~= 0; -changes = diff(logi); - -% find starts and stops -start = find(changes == 1) + 1; -stop = find(changes == -1); - -% correct if data at the edges is non-zero -if ~isempty(start) || ~isempty(stop) - if (isempty(stop) && ~isempty(start)) || (start(end) > stop(end)) - stop = [stop; numel(logi)]; - end; - - if (isempty(start) && ~isempty(stop)) || (start(1) > stop(1)) - start = [1; start]; - end; -end; - -% create epochs and divide by samplerate -epochs = ([start, stop]).*data{chan_id}.header.sr^-1; - -file_exist = exist(options.output_file, 'file'); -write_ok = false; -if file_exist - if options.overwrite - write_ok = true; - elseif ~options.dont_ask_overwrite - if feature('ShowFigureWindows') - msg = ['File already exists. Overwrite?', newline, 'Existing file: ',options.output_file]; - ov = questdlg(msg, 'File already exists', 'Yes', 'No', 'Yes'); % default to overwrite by users - else - ov = 'Yes'; % default to overwrite on Jenkins - end - write_ok = strcmp(ov,'Yes'); - end; -else - write_ok = true; -end; - -if write_ok - save(options.output_file, 'epochs'); -end; - -epochfile = options.output_file; - -sts = 1; +function [sts, epochfile] = pspm_find_data_epochs(datafile, chan_id, options) +% pspm_find_data_epochs tries to find epochs of non-zero values in the data +% of a channel. It then writes it to a file depending on the input and +% returns the location of that file. +% +% FORMAT: +% [sts, epochfile] = pspm_find_data_epochs(datafile, chan_id, options) +% +% ARGUMENTS: +% datafile: File which contains the corresponding channel to +% look for epochs. +% chan_id: Number or chantype of the the channel. If +% multiple channels match the specified chantype +% only the first found channel will be used. +% options: +% output_file: Name and path to the output file. Default is the +% same as datafile but prepended with an 'e'. +% overwrite: Overwrite output file if it already exists. Default +% is 0. +% +% OUTPUT: +% sts: Return status of the function. If equals 1 no +% error or warnings were produced. +% epochfile: File where the epochs have been saved to. +%__________________________________________________________________________ +% PsPM 3.1 +% (C) 2016 Tobias Moser (University of Zurich) + +% $Id$ +% $Rev$ + +% initialise +% ------------------------------------------------------------------------- +global settings; +if isempty(settings), pspm_init; end; +sts = -1; + +% check input +if ~exist('options', 'var') + options = struct(); +end; + +if ~isfield(options, 'output_file') + [path, name, ext] = fileparts(datafile); + options.output_file = [path, filesep, 'e', name, ext]; +end; + +if ~isfield(options, 'overwrite') + options.overwrite = 0; +end; + +if ~isfield(options, 'dont_ask_overwrite') + options.dont_ask_overwrite = 0; +end; + +if isempty(datafile) || ~ischar(datafile) + warning('ID:invalid_input', 'Datafile is empty or not a valid string.'); return; +elseif ~exist(datafile, 'file') + warning('ID:invalid_input', 'Datafile (%s) does not exist.', datafile); return; +elseif ~isnumeric(chan_id) && ~ischar(chan_id) + warning('ID:invalid_input', 'Chan_id is neither numeric nor a valid string.'); return; +elseif ~ischar(options.output_file) + warning('ID:invalid_input', 'Options.output_file is not a valid string.'); return; +elseif ~islogical(options.overwrite) && ~isnumeric(options.overwrite) + warning('ID:invalid_input', 'Options.overwrite is neither logical nor numeric.'); + return; +elseif ~islogical(options.dont_ask_overwrite) && ... + ~isnumeric(options.dont_ask_overwrite) + warning('ID:invalid_input', 'Options.overwrite is neither logical nor numeric.'); + return; +end; + +% load data +[~, ~, data] = pspm_load_data(datafile); + +if chan_id > numel(data) + warning('ID:invalid_input', 'Channel id exceeds channel count.'); return; +end; + +% create logical array in order to distinguish between non-zero and zero +logi = data{chan_id}.data ~= 0; +changes = diff(logi); + +% find starts and stops +start = find(changes == 1) + 1; +stop = find(changes == -1); + +% correct if data at the edges is non-zero +if ~isempty(start) || ~isempty(stop) + if (isempty(stop) && ~isempty(start)) || (start(end) > stop(end)) + stop = [stop; numel(logi)]; + end; + + if (isempty(start) && ~isempty(stop)) || (start(1) > stop(1)) + start = [1; start]; + end; +end; + +% create epochs and divide by samplerate +epochs = ([start, stop]).*data{chan_id}.header.sr^-1; + +file_exist = exist(options.output_file, 'file'); +write_ok = false; +if file_exist + if options.overwrite + write_ok = true; + elseif ~options.dont_ask_overwrite + if feature('ShowFigureWindows') + msg = ['File already exists. Overwrite?', newline, 'Existing file: ',options.output_file]; + ov = questdlg(msg, 'File already exists', 'Yes', 'No', 'Yes'); % default to overwrite by users + else + ov = 'Yes'; % default to overwrite on Jenkins + end + write_ok = strcmp(ov,'Yes'); + end; +else + write_ok = true; +end; + +if write_ok + save(options.output_file, 'epochs'); +end; + +epochfile = options.output_file; + +sts = 1; diff --git a/src/backroom/pspm_get_transfer_function.m b/backroom/pspm_get_transfer_function.m similarity index 97% rename from src/backroom/pspm_get_transfer_function.m rename to backroom/pspm_get_transfer_function.m index 2f94914e..8676f0c8 100644 --- a/src/backroom/pspm_get_transfer_function.m +++ b/backroom/pspm_get_transfer_function.m @@ -1,194 +1,194 @@ -function pspm_get_transfer_function(infile, outfile, Rs, Rtest, scrchan, skipvalues) -% SCR_GET_TRANSFER_FUNCTION automatically reads a calibration spike 2 dataset and -% estimates a transfer function, assuming non linear transfer due to -% (known) serial resistors in the fMRI equipment and an offset in the pulse -% converter -% -% FORMAT: -% pspm_get_transfer_function(SCR file, output file, serial resistor value, -% [test resistor value, scr channel number, skipvalues]) -% -% where SCR file is either an .smr file or an SCRalyze file -% DEFAULTS: -% test resistors: load from pspm_filtestbox.mat (equivalent to value -% 'filtestbox') -% scr channel number: look for scr channel number -% -% if the calibration dataset contains multiple channels, the SCR channel -% name must contain 'scr', 'gsr' or 'eda', or the channel number must be -% given as input argument -% -% each resistor value needs to be measured for at least 5 seconds, -% after the last (highest) resistor, the circuit needs to be interrupted -% for at least 2 seconds to get pulse offset -% -% RETURNS: -% a .mat file is automatically written that will contain a values for -% pspm_transfer_function.m -% graphical output is presented on the screen and to a file -% -%__________________________________________________________________________ -% PsPM -% (C) 2008 Dominik R Bach (Wellcome Trust Centre for Neuroimaging) - -% $Id$ -% $Rev$ - -% CONSTANTS -global settings; -if isempty(settings), pspm_init; end; - -% chars to identify SCR channel -scrnames=settings.import.channames.scr; - -% check input argumens -if nargin<5, scrchan=0; end; -if nargin<6,skipvalues=0; end; - -% check testresistors -if nargin>=4 - if ischar(Rtest) - if strcmp(Rtest, 'filtestbox') - k=1000; - % load the "true", measured resistor values for the FIL testbox - load('pspm_filtestbox.mat'); - end; - end; -else - load('pspm_filtestbox.mat'); -end; - -% check input file -if exist(infile)~=2 - errmsg='Data file not found'; warning(errmsg); return; -end; - -% check output file -[pathname filename]=fileparts(outfile); -outfile=fullfile(pathname, filename); -clear pathname filename extension vers; - -% import data -[pth fn ext] = fileparts(infile); -switch ext - case {'.smr'} - import{1}.type = 'scr'; - import{1}.channel = scrchan; - options = struct('overwrite', 1); - newfn = pspm_import(infile, 'spike', import, options); - - case {'.mat'} - newfn = infile; -end - -[sts infos data] = pspm_load_data(newfn{1}, 'scr'); -if sts == -1, warning('Data could not be loaded'); return; end; -scr = data{1}.data; -sr = data{1}.header.sr; - - - -% identify resistance steps -% ------------------------------------------------------------------------- -% - create smoothed scr series -scrs = conv(scr, ones(round(sr/5), 1)./round(sr/5)); -% - find possible offset (last value) -offset = scrs(end-sr); -% - set dummy (infinite) offset resistor -Rtest(end + 1) = 1e100; -% - initialise -point(1)=find(scrs>1.5*offset, 1); -% - loop over resistor values -for step=1:(numel(Rtest) - 1) - % look at std in second 2-4 - x(step) = mean(scrs(round((point(step)+2*sr):(point(step)+4*sr)))); - sd(step) = std(scrs(round((point(step)+2*sr):(point(step)+4*sr)))); - % look for deviation > 3*sd and > .2 * expected change - nextx = (Rtest(step) + Rs) .* (x(step) - offset) ./ (Rtest(step + 1) + Rs) + offset; - nextdiff = x(step) - nextx; - cutoff = max([0.2*nextdiff, 3*sd(step)]); - ind = round((point(step)+4*sr):numel(scrs)); - dummy = find(scrs(ind) < (x(step) - cutoff), 1); - if isempty(dummy); warning('Resistance change not found'); return; end; - point(step + 1) = ind(1) + dummy; -end; -% - delete dummy Rtest -Rtest(end) = []; - -% - get end of file -if numel(scr) > (point(end) + 5 * sr) - point(end + 1) = numel(scr); -end; - -% identify corresponding pulse frequencies -for step=1:(numel(point)-1) - pulse(step)=mean(scr((point(step)+1*sr):(point(step+1)-1*sr))); -end; - -% now estimate transfer function -if numel(point)>(numel(Rtest)+1) - offset=pulse(end); - PR=pulse(1:(end-1))-offset; -else - offset=0; - PR=pulse; -end; -R=Rtest+Rs; - -% get rid of values to be skipped -PR=PR((skipvalues+1):end); -R=R((skipvalues+1):end); - -%estimate values -init_value = 50; % if estimation doesn't work, change start to an approximation -LB = 1e-10; -UB = inf; -options=optimset('Display','off','TolFun',1e-20, 'LargeScale','off', 'MaxFunEvals', 1000, 'Algorithm', 'active-set'); -c = fmincon('pspm_transfer_fit',init_value,[],[],[],[],LB,UB,[],options, R, PR); -% write transfer function values -if exist(outfile)==2 - overwrite=menu('File already exists. Overwrite?', 'Yes', 'No'); -else - overwrite=1; -end -if overwrite==1 - infos.date=date; - infos.data=infile; - save([outfile, '.mat'], 'infos', 'c', 'Rs', 'offset'); -end; -% make figures for graphical output -fig.h=figure('Position', [100 100 800 1000], 'PaperPositionMode', 'auto', 'PaperOrientation', 'Portrait', 'InvertHardCopy', 'off', 'Color', 'w'); -annotation('textbox', [0.1 0.9 0.8 0.1], 'String', ['Transfer function estimation of ', date], 'FontWeight', 'Bold', 'FontSize', 16, 'LineStyle', 'none', 'HorizontalAlignment', 'center'); -pos=pspm_axpos(2,1,0.05,0.05,0.1,0.2,0.05); -% show recognition of resistor -fig.ax(1).h=axes('Position', pos(1,:)); -plot(scr, 'r'); -hold on -scatter(point, scr(point), 'g'); -scatter(point(1:end-1)+diff(point)/2, pulse, 'b') -legend({'pulse rate', 'resistor change', 'mean pulse rate'}); -title('Separation of resistor values', 'FontWeight', 'Bold', 'FontSize', 14); -set(fig.ax(1).h, 'FontWeight', 'Bold', 'FontSize', 10, 'XTick', []); -% show fit of transfer function -fig.ax(2).h=axes('Position', pos(2,:)); -scatter(1:numel(PR), 1e6./Rtest((skipvalues+1):end), 'b'); -hold on -scatter(1:numel(PR), 1./(c./PR-(1e-6)*Rs), 'r'); -legend({'conductance of resistors (mcS)', 'conductance predicted from pulse rate (mcS)'}); -title( 'Predicted and true conductance values', 'FontWeight', 'Bold', 'FontSize', 14); -me=max(1./Rtest((skipvalues+1):end).*1e6-1./(c./PR-Rs)); -set(fig.ax(2).h, 'FontWeight', 'Bold', 'FontSize', 10, 'XTick', []); -% give values -if skipvalues>0 - annotation('textbox', [0.1 0.15 0.8 0.05], 'String', sprintf('First %d value(s) skipped', skipvalues), 'FontWeight', 'Bold', 'FontSize', 10, 'LineStyle', 'none'); -end; -annotation('textbox', [0.1 0.12 0.8 0.04], 'String', ['Maximum Difference (true/pred): ', num2str(me, '%0.2f'), ' mcS'], 'FontWeight', 'Bold', 'FontSize', 10, 'LineStyle', 'none'); -annotation('textbox', [0.1 0.09 0.8 0.04], 'String', 'Transfer function: C_B_o_d_y = (c/(data-offset)-Rs*1e-6)^-^1', 'FontWeight', 'Bold', 'FontSize', 10, 'LineStyle', 'none'); -annotation('textbox', [0.1 0.06 0.8 0.04], 'String', ['c = ', num2str(c, '%0.2f')], 'FontWeight', 'Bold', 'FontSize', 10, 'LineStyle', 'none'); -annotation('textbox', [0.1 0.03 0.8 0.04], 'String', ['offset = ', num2str(offset, '%0.2f')], 'FontWeight', 'Bold', 'FontSize', 10, 'LineStyle', 'none'); -annotation('textbox', [0.1 0.00 0.8 0.04], 'String', ['written to ', outfile, '.mat'], 'FontWeight', 'Bold', 'FontSize', 10, 'LineStyle', 'none', 'Interpreter', 'none'); -print ('-depsc', outfile) - - - - +function pspm_get_transfer_function(infile, outfile, Rs, Rtest, scrchan, skipvalues) +% SCR_GET_TRANSFER_FUNCTION automatically reads a calibration spike 2 dataset and +% estimates a transfer function, assuming non linear transfer due to +% (known) serial resistors in the fMRI equipment and an offset in the pulse +% converter +% +% FORMAT: +% pspm_get_transfer_function(SCR file, output file, serial resistor value, +% [test resistor value, scr channel number, skipvalues]) +% +% where SCR file is either an .smr file or an SCRalyze file +% DEFAULTS: +% test resistors: load from pspm_filtestbox.mat (equivalent to value +% 'filtestbox') +% scr channel number: look for scr channel number +% +% if the calibration dataset contains multiple channels, the SCR channel +% name must contain 'scr', 'gsr' or 'eda', or the channel number must be +% given as input argument +% +% each resistor value needs to be measured for at least 5 seconds, +% after the last (highest) resistor, the circuit needs to be interrupted +% for at least 2 seconds to get pulse offset +% +% RETURNS: +% a .mat file is automatically written that will contain a values for +% pspm_transfer_function.m +% graphical output is presented on the screen and to a file +% +%__________________________________________________________________________ +% PsPM +% (C) 2008 Dominik R Bach (Wellcome Trust Centre for Neuroimaging) + +% $Id$ +% $Rev$ + +% CONSTANTS +global settings; +if isempty(settings), pspm_init; end; + +% chars to identify SCR channel +scrnames=settings.import.channames.scr; + +% check input argumens +if nargin<5, scrchan=0; end; +if nargin<6,skipvalues=0; end; + +% check testresistors +if nargin>=4 + if ischar(Rtest) + if strcmp(Rtest, 'filtestbox') + k=1000; + % load the "true", measured resistor values for the FIL testbox + load('pspm_filtestbox.mat'); + end; + end; +else + load('pspm_filtestbox.mat'); +end; + +% check input file +if exist(infile)~=2 + errmsg='Data file not found'; warning(errmsg); return; +end; + +% check output file +[pathname filename]=fileparts(outfile); +outfile=fullfile(pathname, filename); +clear pathname filename extension vers; + +% import data +[pth fn ext] = fileparts(infile); +switch ext + case {'.smr'} + import{1}.type = 'scr'; + import{1}.channel = scrchan; + options = struct('overwrite', 1); + newfn = pspm_import(infile, 'spike', import, options); + + case {'.mat'} + newfn = infile; +end + +[sts infos data] = pspm_load_data(newfn{1}, 'scr'); +if sts == -1, warning('Data could not be loaded'); return; end; +scr = data{1}.data; +sr = data{1}.header.sr; + + + +% identify resistance steps +% ------------------------------------------------------------------------- +% - create smoothed scr series +scrs = conv(scr, ones(round(sr/5), 1)./round(sr/5)); +% - find possible offset (last value) +offset = scrs(end-sr); +% - set dummy (infinite) offset resistor +Rtest(end + 1) = 1e100; +% - initialise +point(1)=find(scrs>1.5*offset, 1); +% - loop over resistor values +for step=1:(numel(Rtest) - 1) + % look at std in second 2-4 + x(step) = mean(scrs(round((point(step)+2*sr):(point(step)+4*sr)))); + sd(step) = std(scrs(round((point(step)+2*sr):(point(step)+4*sr)))); + % look for deviation > 3*sd and > .2 * expected change + nextx = (Rtest(step) + Rs) .* (x(step) - offset) ./ (Rtest(step + 1) + Rs) + offset; + nextdiff = x(step) - nextx; + cutoff = max([0.2*nextdiff, 3*sd(step)]); + ind = round((point(step)+4*sr):numel(scrs)); + dummy = find(scrs(ind) < (x(step) - cutoff), 1); + if isempty(dummy); warning('Resistance change not found'); return; end; + point(step + 1) = ind(1) + dummy; +end; +% - delete dummy Rtest +Rtest(end) = []; + +% - get end of file +if numel(scr) > (point(end) + 5 * sr) + point(end + 1) = numel(scr); +end; + +% identify corresponding pulse frequencies +for step=1:(numel(point)-1) + pulse(step)=mean(scr((point(step)+1*sr):(point(step+1)-1*sr))); +end; + +% now estimate transfer function +if numel(point)>(numel(Rtest)+1) + offset=pulse(end); + PR=pulse(1:(end-1))-offset; +else + offset=0; + PR=pulse; +end; +R=Rtest+Rs; + +% get rid of values to be skipped +PR=PR((skipvalues+1):end); +R=R((skipvalues+1):end); + +%estimate values +init_value = 50; % if estimation doesn't work, change start to an approximation +LB = 1e-10; +UB = inf; +options=optimset('Display','off','TolFun',1e-20, 'LargeScale','off', 'MaxFunEvals', 1000, 'Algorithm', 'active-set'); +c = fmincon('pspm_transfer_fit',init_value,[],[],[],[],LB,UB,[],options, R, PR); +% write transfer function values +if exist(outfile)==2 + overwrite=menu('File already exists. Overwrite?', 'Yes', 'No'); +else + overwrite=1; +end +if overwrite==1 + infos.date=date; + infos.data=infile; + save([outfile, '.mat'], 'infos', 'c', 'Rs', 'offset'); +end; +% make figures for graphical output +fig.h=figure('Position', [100 100 800 1000], 'PaperPositionMode', 'auto', 'PaperOrientation', 'Portrait', 'InvertHardCopy', 'off', 'Color', 'w'); +annotation('textbox', [0.1 0.9 0.8 0.1], 'String', ['Transfer function estimation of ', date], 'FontWeight', 'Bold', 'FontSize', 16, 'LineStyle', 'none', 'HorizontalAlignment', 'center'); +pos=pspm_axpos(2,1,0.05,0.05,0.1,0.2,0.05); +% show recognition of resistor +fig.ax(1).h=axes('Position', pos(1,:)); +plot(scr, 'r'); +hold on +scatter(point, scr(point), 'g'); +scatter(point(1:end-1)+diff(point)/2, pulse, 'b') +legend({'pulse rate', 'resistor change', 'mean pulse rate'}); +title('Separation of resistor values', 'FontWeight', 'Bold', 'FontSize', 14); +set(fig.ax(1).h, 'FontWeight', 'Bold', 'FontSize', 10, 'XTick', []); +% show fit of transfer function +fig.ax(2).h=axes('Position', pos(2,:)); +scatter(1:numel(PR), 1e6./Rtest((skipvalues+1):end), 'b'); +hold on +scatter(1:numel(PR), 1./(c./PR-(1e-6)*Rs), 'r'); +legend({'conductance of resistors (mcS)', 'conductance predicted from pulse rate (mcS)'}); +title( 'Predicted and true conductance values', 'FontWeight', 'Bold', 'FontSize', 14); +me=max(1./Rtest((skipvalues+1):end).*1e6-1./(c./PR-Rs)); +set(fig.ax(2).h, 'FontWeight', 'Bold', 'FontSize', 10, 'XTick', []); +% give values +if skipvalues>0 + annotation('textbox', [0.1 0.15 0.8 0.05], 'String', sprintf('First %d value(s) skipped', skipvalues), 'FontWeight', 'Bold', 'FontSize', 10, 'LineStyle', 'none'); +end; +annotation('textbox', [0.1 0.12 0.8 0.04], 'String', ['Maximum Difference (true/pred): ', num2str(me, '%0.2f'), ' mcS'], 'FontWeight', 'Bold', 'FontSize', 10, 'LineStyle', 'none'); +annotation('textbox', [0.1 0.09 0.8 0.04], 'String', 'Transfer function: C_B_o_d_y = (c/(data-offset)-Rs*1e-6)^-^1', 'FontWeight', 'Bold', 'FontSize', 10, 'LineStyle', 'none'); +annotation('textbox', [0.1 0.06 0.8 0.04], 'String', ['c = ', num2str(c, '%0.2f')], 'FontWeight', 'Bold', 'FontSize', 10, 'LineStyle', 'none'); +annotation('textbox', [0.1 0.03 0.8 0.04], 'String', ['offset = ', num2str(offset, '%0.2f')], 'FontWeight', 'Bold', 'FontSize', 10, 'LineStyle', 'none'); +annotation('textbox', [0.1 0.00 0.8 0.04], 'String', ['written to ', outfile, '.mat'], 'FontWeight', 'Bold', 'FontSize', 10, 'LineStyle', 'none', 'Interpreter', 'none'); +print ('-depsc', outfile) + + + + diff --git a/src/backroom/pspm_ledalab.m b/backroom/pspm_ledalab.m similarity index 100% rename from src/backroom/pspm_ledalab.m rename to backroom/pspm_ledalab.m diff --git a/src/backroom/pspm_load_single_chan.m b/backroom/pspm_load_single_chan.m similarity index 100% rename from src/backroom/pspm_load_single_chan.m rename to backroom/pspm_load_single_chan.m diff --git a/src/backroom/pspm_peakscore.m b/backroom/pspm_peakscore.m similarity index 97% rename from src/backroom/pspm_peakscore.m rename to backroom/pspm_peakscore.m index b5ed1f1b..43333566 100644 --- a/src/backroom/pspm_peakscore.m +++ b/backroom/pspm_peakscore.m @@ -1,479 +1,479 @@ - function pspm_peakscore(datafile, regfile, modelfile, timeunits, normalize, chan, options) - -% pspm_peakscore calculates event-related responses by scoring the peak -% response against a pre-stimulus baseline. The input is similar to -% pspm_glm, and the output is written into a DUMMY glm structure to make it -% readable for pspm_con1 -% -% FORMAT: -% SCR_PEAKSCORE (DATAFILE, REGFILE, MODELFILE, TIMEUNITS, NORMALISE, CHAN, OPTIONS) -% -% datafile, regfile: either one datafile and one regfile, or a cell array of -% datefiles to be concatenated (e.g. several sessions of an fMRI -% experiment) and a cell array of regfiles (onsets with respect to session -% start), or one regfile for the whole model (the duration of each -% datafile will be needed to construct the regfile, and can be assessed via -% the variable infos.duration) -% -% timeunits: 'seconds', 'markers', 'samples' -% -% normalize (default = 1) determines whether the data are normalized. This -% can help to reduce variance due to peripheral factors (e. g. skin -% properties) -% -% chan: by default, SCRalyze looks for the only waveform channel, or for -% the first scr channel. Provide an argument to pick a specific waveform -% channel (and a second one for events, if timeunits = 'markers') -% -% options.overwrite = 1: overwrite existing files -% options.method: 'simple' - computes a max/baseline difference -% 'min' - same but computes a min/baseline difference -% 'abs' - signed peak of largest modulus -% 'spr' - method preferred by the Society for -% Psychophysiological Research (SPR). Detect peak in peak -% window, then find onset in onset window, score 0 if no -% peak occurs -% options.summary: for options.spr - 'amplitude' (based only on values > -% .01 mcS)m 'magnitude' (based on all values) -% options.window: for method 'simple', baseline post stimulus peak window -% (default: [-1 0; 1 4], was formerly termed 'baseline' and -% 'peakwindow') -% for method 'spr', post stimulus onset and post onset peak -% window (default: [1 4; 0.5 5]); -% options.diagnostics: makes a plot after every detected peak (for -% development purposes, default = 0) -%__________________________________________________________________________ -% PsPM 3.1 -% (c) 2008-2015 Dominik R Bach (Wellcome Trust Centre for Neuroimaging) - -% $Id$ -% $Rev$ - -global settings; -if isempty(settings), pspm_init; end; - -% check input arguments -if nargin<1 - errmsg=sprintf('No data file specified'); warning(errmsg); return; -elseif nargin<2 - errmsg=sprintf('No condition file specified'); warning(errmsg); return; -elseif nargin<3 - errmsg=sprintf('No modelfile specified'); warning(errmsg); return; -elseif nargin<4 - errmsg=sprintf('No timeunits specified'); warning(errmsg); return; -elseif ~ismember(timeunits, {'seconds', 'markers', 'samples'}) - errmsg=sprintf('Timeunits (%s) not recognised; only ''seconds'', ''markers'' and ''samples'' are supported', timeunits); warning(errmsg); return; -elseif nargin<5 - normalize=1; -end; -if nargin<6 || isempty(chan) - chan = 0; -end; - -% set options -try options.overwrite; catch, options.overwrite = 0; end; -try options.method; catch, options.method = 'simple'; end; -try options.diagnostics; catch, options.diagnostics = 0; end; - -if strcmpi(options.method, 'spr') - try options.summary; - catch - options.summary = 'amplitude'; - end; -end; - -try options.window; -catch - switch options.method - case {'simple', 'min', 'abs'} - options.window = [-1 0; 1 4]; - case 'spr' - options.window = [1 4; 0.5 5]; - otherwise - warning('Method unknown'); return; - end; -end; - - -% check modelfile -if options.overwrite ~= 1 && exist(modelfile)==2 - overwrite=menu(sprintf('Model file (%s) already exists. Overwrite?', modelfile), 'yes', 'no'); - close gcf; - if overwrite==2, return; end; -end; - -% check datafile(s) -if ~iscell(datafile) - datafile={datafile}; -end; -for d=1:numel(datafile) - sts = pspm_load_data(datafile{d}, 'none'); - if sts == -1 - return; - end; -end; - -% check regressor files -if ~iscell(regfile) - regfile={regfile}; -end; - -[sts multi] = check_regfile(regfile, timeunits); -if sts < 0, return; end; - -% set filter -model.filter = settings.glm(1).filter; - -%------------------------------------------------------------------------- -% user output -%------------------------------------------------------------------------- - -fprintf('Peak scoring: %s ...', modelfile); - -%------------------------------------------------------------------------- -% prepare data & concatenate regressors -%------------------------------------------------------------------------- - -Y=[]; -for d=1:numel(datafile) - - clear scr infos filt down pspm_hp pspm_lp pspm_down - - if chan == 0 - % load waveform channels - [sts, infos, data] = pspm_load_data(datafile{d}, 'wave'); - if sts == -1; return; end; - % if there is none, or more than one waveform channel - if isempty(data) || numel(data) > 1 - % load scr channel(s) - [sts, infos, data] = pspm_load_data(datafile{d}, 'scr'); - if sts == -1 || isempty(data); return; end; - end; - % use data from single waveform, or first scr channel - scr = data{1}; - % if required, load events - if any(strcmp(timeunits, {'trigger', 'markers'})) - [sts, infos, data] = pspm_load_data(datafile{d}, 'events'); - if sts == -1 || isempty(data); - warning('No event data'); return; - else - events = data{1}.data; - end; - else - events = []; - end; - else - [sts, infos, data] = pspm_load_data(datafile{d}, chan); - if sts == -1 || isempty(data), warning('Could not load file %s', datafile{d}); return; end; - if strcmp(data{1}.header.units, 'events'); warning('No waveform data'); return; end; - scr = data{1}; - if any(strcmp(timeunits, {'trigger', 'markers'})) - [sts, infos, data] = pspm_load_data(datafile{d}, 'events'); - if sts == -1 || isempty(data); - warning('No event data'); return; - else - events = data{1}.data; - end; - else - events = []; - end; - end; - - % prepare (filter & downsample) data (no high pass filtering) - model.filter.hpfreq = 'none'; - model.filter.sr = scr.header.sr; - [sts, pspm_down, sr] = pspm_prepdata(scr.data, model.filter); - - % concatenate if necessary - Y=[Y; pspm_down]; - - % get duration of single sessions - snduration(d)=numel(pspm_down); - - % concatenate regressors & convert to samples - if d <= numel(multi) - for n = 1:numel(multi(1).n) - % convert onsets to samples - switch timeunits - case 'samples' - dummy = round(multi(d).o{n} * sr/scr.header.sr); - foo = round(multi(d).d{n} * sr/scr.header.sr); - case 'seconds' - dummy = round(multi(d).o{n} * sr); - foo = round(multi(d).d{n} * sr); - case 'markers' - try - dummy = round(events(multi(d).o{n}) * sr); % markers are timestamps in seconds - catch - warning('\nSome events in condition %01.0f were not found in the data file %s', n, datafile{d}); return; - end; - if any(multi(d).d{n} ~= 0) - warning('markers is a convenience timeunits option that does not allow to specify events of non-zero duration.'); return; - else - foo = multi(d).d{n}; - end; - end; - % get the first regressor file - if d == 1 - names{n} = multi(1).n{n}; - onsets{n} = dummy(:); - else - dummy = dummy + sum(snduration(1:(d - 1))); - onsets{n} = [onsets{n}; dummy(:)]; - end; - end; - end; -end; - -% z-transform if desired -if normalize - Y=(Y-mean(Y))/std(Y); -end; - -Y = Y(:); - -% smooth if SPR method -if strcmpi(options.method, 'spr') - Y = medfilt1(Y, 3); -end; - -%------------------------------------------------------------------------- -% initialise design matrix -%------------------------------------------------------------------------- -clear glm tmp -glm.sourcefile=datafile; -glm.Y=Y; clear Y; -glm.sr.init=scr.header.sr; -glm.sr.fin=sr; -glm.duration=numel(glm.Y)/glm.sr.fin; -glm.durationinfo='duration in seconds'; -tmp.duration=numel(glm.Y); -glm.norm=normalize; -glm.name = names; -glm.modeltype = 'glm'; -glm.modality = settings.modalities.glm; - -%------------------------------------------------------------------------- -% peak scoring -%------------------------------------------------------------------------- - -for k = 1:numel(onsets) - clear peakscore - for n = 1:numel(onsets{k}) - firstwin = onsets{k}(n) + (round(options.window(1, 1) * glm.sr.fin):round(options.window(1, 2) * glm.sr.fin)); - secondwin = onsets{k}(n) + (round(options.window(2, 1) * glm.sr.fin):round(options.window(2, 2) * glm.sr.fin)); - initialfirstwin = firstwin; % for diagnostics - initialsecondwin = secondwin; % for diagnostics - % if final peak window is cut off, don't analyse - if all(secondwin < numel(glm.Y)) - if strcmpi(options.method, 'simple') - baseline = mean(glm.Y(firstwin)); - peak = max(glm.Y(secondwin)); - peakscore(n) = peak - baseline; - elseif strcmpi(options.method, 'min') - baseline = mean(glm.Y(firstwin)); - peak = min(glm.Y(secondwin)); - peakscore(n) = peak - baseline; - elseif strcmpi(options.method, 'abs') - baseline = mean(glm.Y(firstwin)); - [peak, peakindx] = max(abs(glm.Y(secondwin)- baseline)); - peakscore(n) = peak * sign(glm.Y(secondwin(peakindx))- baseline); - elseif strcmpi(options.method, 'spr') - % create running average - b = [1/3 1/3 1/3]; a = 1; - scr = filter(b, a, glm.Y); - scr1 = filter(b, a, diff(scr)); - scr2 = filter(b, a, diff(scr1)); - foundpeak = 0; - % first, look for maximum curvature in SCR, i. e. - % maximum of second derivative (according to Boucsein - % method) - [pks, lcs] = findpeaks(scr2(firstwin)); - onsetindx = 1; - while (~foundpeak) && (onsetindx <= numel(lcs)); - onset = firstwin(lcs(onsetindx)); - % look for first peak after onset - secondwin = onset + (round(options.window(2, 1) * glm.sr.fin):round(options.window(2, 2) * glm.sr.fin)); - peak = find(diff(sign(scr1(secondwin))) == -2, 1); % look for local maximum as change from pos to neg - % found peak? Otherwise, look for next onset - if ~isempty(peak) - peak = secondwin(1) + peak; - foundpeak = 1; - else - onsetindx = onsetindx + 1; - end; - end; - % do check on first derivative (old peak score method used - % until Staib, Castegnetti & Bach 2015) if diagnostics - % required - foundfirstpeak = 0; - while (options.diagnostics) && (~foundfirstpeak) && (numel(firstwin) > 1); - % look for minimum as change in first derivative from - % neg to pos - firstonset = find(diff(sign(scr1(firstwin))) == 2, 1); - if isempty(firstonset) - firstwin = []; - else - firstonset = firstonset + firstwin(1); - % look for first peak after onset - secondwin = firstonset + (round(options.window(2, 1) * glm.sr.fin):round(options.window(2, 2) * glm.sr.fin)); - firstpeak = find(diff(sign(scr1(secondwin))) == -2, 1); % look for local maximum as change from pos to neg - % found peak? Otherwise, look for next onset - if ~isempty(firstpeak) - firstpeak = secondwin(1) + firstpeak; - foundfirstpeak = 1; - else - firstwin(1:find(firstwin == firstonset)) = []; - end; - end; - end; - if foundpeak - peakscore(n) = scr(peak) - scr(onset); - % if an onset is followed by first peak before the peak - % window and by a second one within, then this can be - % negative - peakscore(n) = max(0, peakscore(n)); - else - peakscore(n) = 0; - end; - if options.diagnostics - figure; axes; hold on - win = initialfirstwin(1):secondwin(end); - plot(win, scr(win) - scr(win(1)), 'k'); - plot(win, scr1(win), 'r'); - plot(win, scr2(win), 'b'); - if foundpeak - stem(onset, scr(onset)); - stem(peak, scr(peak)); - end; - if foundfirstpeak - stem(firstonset,scr(firstonset)); - stem(firstpeak, scr(firstpeak)); - end; - s = input('Press RETURN to continue.', 's'); - close(gcf); - end; - end; - end; - end; - if strcmpi(options.method, 'spr') && strcmpi(options.summary, 'amplitude') - glm.stats(k, 1) = mean(peakscore(peakscore > .01)); - else - glm.stats(k, 1) = mean(peakscore); - end; - clear peakscore - glm.names = {}; -end; - -save(modelfile, 'glm'); - - -%------------------------------------------------------------------------- -% user output -%------------------------------------------------------------------------- - -fprintf(' done. \n'); - -% cleanup -clear glm scr -return - -%------------------------------------------------------------------------- -% internal functions: check regressor file(s) -%------------------------------------------------------------------------- - -function [sts multi] = check_regfile(fns, timeunits) - -if ~iscell(fns) - fns = {fns}; -end; - -sts = 1; -multi = []; - -for f = 1:numel(fns) - fn = fns{f}; - merrmsg=sprintf('Regressor file (%s) is invalid ... ', fn); - if exist(fn)~=2 - errmsg=sprintf('Regressor file (%s) doesn''t exist', fn); - warning(errmsg); - sts = -1; - return; - end; - - load(fn); - if (isempty(find(ismember(who, 'names'), 1)))||(isempty(find(ismember(who, 'onsets'), 1))), - warning(merrmsg); sts = -1; return; - end; - if isempty(find(ismember(who, 'durations'), 1)), - durations=num2cell(zeros(numel(names), 1)); - end; - if isempty(find(ismember(who, 'parametric_confound'), 1)) - parametric_confound=zeros(numel(names), 1); - end; - if ~iscell(names)||~iscell(onsets) - errmsg = 'Names and onsets need to be cell arrays'; warning([merrmsg, errmsg]); sts=-1; return; - end; - if numel(names)~=numel(onsets), errmsg=sprintf('Number of event names (%d) does not match the number of onsets (%d).',... - numel(names),numel(onsets)); warning([merrmsg, errmsg]); sts = -1; return; - elseif numel(names)~=numel(durations), errmsg=sprintf('Number of event names (%d) does not match the number of durations (%d).',... - numel(onsets),numel(durations)); warning([merrmsg, errmsg]); sts = -1; return; - elseif numel(names)~=numel(parametric_confound), errmsg=sprintf('Number of event names (%d) does not match the number of parametric confound specifications (%d).',... - numel(onsets),numel(parametric_confound)); warning([merrmsg, errmsg]); sts = -1; return; - else - for n=1:numel(names) - if numel(durations{n})==1, durations{n}=repmat(durations{n}, numel(onsets{n}), 1); - elseif (numel(onsets{n}) ~= numel(durations{n})) - errmsg=sprintf('"%s": Number of event onsets (%d) does not match the number of durations (%d).',... - names{n}, numel(onsets{n}),numel(durations{n})); warning([merrmsg, errmsg]); sts = - 1; return; - end; - switch timeunits - case 'seconds' - if any(onsets{n})<0 - errmsg=sprintf('Onset vector %d contains onsets smaller than 0 s', n); warning([merrmsg, errmsg]); sts = -1; return; - end; - case {'samples', 'markers'} - if any(fix(onsets{n})~=onsets{n}) - errmsg=sprintf('Onset vector %d contains non-integers', n); warning([merrmsg, errmsg]); sts = -1; return; - end; - end; - if any(onsets{n} < 0) - if numel(onsets{n}) == 1, onsets{n} = []; - else - errmsg=sprintf('Negative event onsets in regressor %s', names{n}); warning([merrmsg, errmsg]); sts = -1; return; - end; - end; - end; - end; - if ~isempty(find(ismember(who, 'pmod'), 1)) - if numel(pmod)>numel(names), errmsg=sprintf('Number of parametric modulators (%d) does not match the number of onsets (%d).',... - numel(pmod),numel(onsets)); warning([merrmsg, errmsg]); sts = -1; return; - else - for n=1:numel(pmod), - for o=1:numel(pmod(n).param) - if numel(onsets{n}) ~= numel(pmod(n).param{o}), - errmsg= sprintf('"%s" & "%s": Number of event onsets (%d) does not equal the number of parameters (%d).',... - names{n}, pmod(n).name{o}, numel(onsets{n}),numel(pmod(n).param{o})); warning([merrmsg, errmsg]); sts = -1; return; - end; - end; - end; - end; - end; - - if f > 1 - for n = 1:numel(names) - if ~strcmpi(multi(1).n{n}, names{n}) - errmsg('Event names in sessions 1 and %.0f don''t match (%s and %s)', f, multi(1).n{n},names{n}); - warning(errmsg); sts = -1; return; - end; - end - end; - multi(f).n = names; - multi(f).o = onsets; - multi(f).d = durations; - multi(f).p = parametric_confound; - if exist('pmod') - multi(f).pmod = pmod; - end; - clear names onsets durations parametric_confound pmod + function pspm_peakscore(datafile, regfile, modelfile, timeunits, normalize, chan, options) + +% pspm_peakscore calculates event-related responses by scoring the peak +% response against a pre-stimulus baseline. The input is similar to +% pspm_glm, and the output is written into a DUMMY glm structure to make it +% readable for pspm_con1 +% +% FORMAT: +% SCR_PEAKSCORE (DATAFILE, REGFILE, MODELFILE, TIMEUNITS, NORMALISE, CHAN, OPTIONS) +% +% datafile, regfile: either one datafile and one regfile, or a cell array of +% datefiles to be concatenated (e.g. several sessions of an fMRI +% experiment) and a cell array of regfiles (onsets with respect to session +% start), or one regfile for the whole model (the duration of each +% datafile will be needed to construct the regfile, and can be assessed via +% the variable infos.duration) +% +% timeunits: 'seconds', 'markers', 'samples' +% +% normalize (default = 1) determines whether the data are normalized. This +% can help to reduce variance due to peripheral factors (e. g. skin +% properties) +% +% chan: by default, SCRalyze looks for the only waveform channel, or for +% the first scr channel. Provide an argument to pick a specific waveform +% channel (and a second one for events, if timeunits = 'markers') +% +% options.overwrite = 1: overwrite existing files +% options.method: 'simple' - computes a max/baseline difference +% 'min' - same but computes a min/baseline difference +% 'abs' - signed peak of largest modulus +% 'spr' - method preferred by the Society for +% Psychophysiological Research (SPR). Detect peak in peak +% window, then find onset in onset window, score 0 if no +% peak occurs +% options.summary: for options.spr - 'amplitude' (based only on values > +% .01 mcS)m 'magnitude' (based on all values) +% options.window: for method 'simple', baseline post stimulus peak window +% (default: [-1 0; 1 4], was formerly termed 'baseline' and +% 'peakwindow') +% for method 'spr', post stimulus onset and post onset peak +% window (default: [1 4; 0.5 5]); +% options.diagnostics: makes a plot after every detected peak (for +% development purposes, default = 0) +%__________________________________________________________________________ +% PsPM 3.1 +% (c) 2008-2015 Dominik R Bach (Wellcome Trust Centre for Neuroimaging) + +% $Id$ +% $Rev$ + +global settings; +if isempty(settings), pspm_init; end; + +% check input arguments +if nargin<1 + errmsg=sprintf('No data file specified'); warning(errmsg); return; +elseif nargin<2 + errmsg=sprintf('No condition file specified'); warning(errmsg); return; +elseif nargin<3 + errmsg=sprintf('No modelfile specified'); warning(errmsg); return; +elseif nargin<4 + errmsg=sprintf('No timeunits specified'); warning(errmsg); return; +elseif ~ismember(timeunits, {'seconds', 'markers', 'samples'}) + errmsg=sprintf('Timeunits (%s) not recognised; only ''seconds'', ''markers'' and ''samples'' are supported', timeunits); warning(errmsg); return; +elseif nargin<5 + normalize=1; +end; +if nargin<6 || isempty(chan) + chan = 0; +end; + +% set options +try options.overwrite; catch, options.overwrite = 0; end; +try options.method; catch, options.method = 'simple'; end; +try options.diagnostics; catch, options.diagnostics = 0; end; + +if strcmpi(options.method, 'spr') + try options.summary; + catch + options.summary = 'amplitude'; + end; +end; + +try options.window; +catch + switch options.method + case {'simple', 'min', 'abs'} + options.window = [-1 0; 1 4]; + case 'spr' + options.window = [1 4; 0.5 5]; + otherwise + warning('Method unknown'); return; + end; +end; + + +% check modelfile +if options.overwrite ~= 1 && exist(modelfile)==2 + overwrite=menu(sprintf('Model file (%s) already exists. Overwrite?', modelfile), 'yes', 'no'); + close gcf; + if overwrite==2, return; end; +end; + +% check datafile(s) +if ~iscell(datafile) + datafile={datafile}; +end; +for d=1:numel(datafile) + sts = pspm_load_data(datafile{d}, 'none'); + if sts == -1 + return; + end; +end; + +% check regressor files +if ~iscell(regfile) + regfile={regfile}; +end; + +[sts multi] = check_regfile(regfile, timeunits); +if sts < 0, return; end; + +% set filter +model.filter = settings.glm(1).filter; + +%------------------------------------------------------------------------- +% user output +%------------------------------------------------------------------------- + +fprintf('Peak scoring: %s ...', modelfile); + +%------------------------------------------------------------------------- +% prepare data & concatenate regressors +%------------------------------------------------------------------------- + +Y=[]; +for d=1:numel(datafile) + + clear scr infos filt down pspm_hp pspm_lp pspm_down + + if chan == 0 + % load waveform channels + [sts, infos, data] = pspm_load_data(datafile{d}, 'wave'); + if sts == -1; return; end; + % if there is none, or more than one waveform channel + if isempty(data) || numel(data) > 1 + % load scr channel(s) + [sts, infos, data] = pspm_load_data(datafile{d}, 'scr'); + if sts == -1 || isempty(data); return; end; + end; + % use data from single waveform, or first scr channel + scr = data{1}; + % if required, load events + if any(strcmp(timeunits, {'trigger', 'markers'})) + [sts, infos, data] = pspm_load_data(datafile{d}, 'events'); + if sts == -1 || isempty(data); + warning('No event data'); return; + else + events = data{1}.data; + end; + else + events = []; + end; + else + [sts, infos, data] = pspm_load_data(datafile{d}, chan); + if sts == -1 || isempty(data), warning('Could not load file %s', datafile{d}); return; end; + if strcmp(data{1}.header.units, 'events'); warning('No waveform data'); return; end; + scr = data{1}; + if any(strcmp(timeunits, {'trigger', 'markers'})) + [sts, infos, data] = pspm_load_data(datafile{d}, 'events'); + if sts == -1 || isempty(data); + warning('No event data'); return; + else + events = data{1}.data; + end; + else + events = []; + end; + end; + + % prepare (filter & downsample) data (no high pass filtering) + model.filter.hpfreq = 'none'; + model.filter.sr = scr.header.sr; + [sts, pspm_down, sr] = pspm_prepdata(scr.data, model.filter); + + % concatenate if necessary + Y=[Y; pspm_down]; + + % get duration of single sessions + snduration(d)=numel(pspm_down); + + % concatenate regressors & convert to samples + if d <= numel(multi) + for n = 1:numel(multi(1).n) + % convert onsets to samples + switch timeunits + case 'samples' + dummy = round(multi(d).o{n} * sr/scr.header.sr); + foo = round(multi(d).d{n} * sr/scr.header.sr); + case 'seconds' + dummy = round(multi(d).o{n} * sr); + foo = round(multi(d).d{n} * sr); + case 'markers' + try + dummy = round(events(multi(d).o{n}) * sr); % markers are timestamps in seconds + catch + warning('\nSome events in condition %01.0f were not found in the data file %s', n, datafile{d}); return; + end; + if any(multi(d).d{n} ~= 0) + warning('markers is a convenience timeunits option that does not allow to specify events of non-zero duration.'); return; + else + foo = multi(d).d{n}; + end; + end; + % get the first regressor file + if d == 1 + names{n} = multi(1).n{n}; + onsets{n} = dummy(:); + else + dummy = dummy + sum(snduration(1:(d - 1))); + onsets{n} = [onsets{n}; dummy(:)]; + end; + end; + end; +end; + +% z-transform if desired +if normalize + Y=(Y-mean(Y))/std(Y); +end; + +Y = Y(:); + +% smooth if SPR method +if strcmpi(options.method, 'spr') + Y = medfilt1(Y, 3); +end; + +%------------------------------------------------------------------------- +% initialise design matrix +%------------------------------------------------------------------------- +clear glm tmp +glm.sourcefile=datafile; +glm.Y=Y; clear Y; +glm.sr.init=scr.header.sr; +glm.sr.fin=sr; +glm.duration=numel(glm.Y)/glm.sr.fin; +glm.durationinfo='duration in seconds'; +tmp.duration=numel(glm.Y); +glm.norm=normalize; +glm.name = names; +glm.modeltype = 'glm'; +glm.modality = settings.modalities.glm; + +%------------------------------------------------------------------------- +% peak scoring +%------------------------------------------------------------------------- + +for k = 1:numel(onsets) + clear peakscore + for n = 1:numel(onsets{k}) + firstwin = onsets{k}(n) + (round(options.window(1, 1) * glm.sr.fin):round(options.window(1, 2) * glm.sr.fin)); + secondwin = onsets{k}(n) + (round(options.window(2, 1) * glm.sr.fin):round(options.window(2, 2) * glm.sr.fin)); + initialfirstwin = firstwin; % for diagnostics + initialsecondwin = secondwin; % for diagnostics + % if final peak window is cut off, don't analyse + if all(secondwin < numel(glm.Y)) + if strcmpi(options.method, 'simple') + baseline = mean(glm.Y(firstwin)); + peak = max(glm.Y(secondwin)); + peakscore(n) = peak - baseline; + elseif strcmpi(options.method, 'min') + baseline = mean(glm.Y(firstwin)); + peak = min(glm.Y(secondwin)); + peakscore(n) = peak - baseline; + elseif strcmpi(options.method, 'abs') + baseline = mean(glm.Y(firstwin)); + [peak, peakindx] = max(abs(glm.Y(secondwin)- baseline)); + peakscore(n) = peak * sign(glm.Y(secondwin(peakindx))- baseline); + elseif strcmpi(options.method, 'spr') + % create running average + b = [1/3 1/3 1/3]; a = 1; + scr = filter(b, a, glm.Y); + scr1 = filter(b, a, diff(scr)); + scr2 = filter(b, a, diff(scr1)); + foundpeak = 0; + % first, look for maximum curvature in SCR, i. e. + % maximum of second derivative (according to Boucsein + % method) + [pks, lcs] = findpeaks(scr2(firstwin)); + onsetindx = 1; + while (~foundpeak) && (onsetindx <= numel(lcs)); + onset = firstwin(lcs(onsetindx)); + % look for first peak after onset + secondwin = onset + (round(options.window(2, 1) * glm.sr.fin):round(options.window(2, 2) * glm.sr.fin)); + peak = find(diff(sign(scr1(secondwin))) == -2, 1); % look for local maximum as change from pos to neg + % found peak? Otherwise, look for next onset + if ~isempty(peak) + peak = secondwin(1) + peak; + foundpeak = 1; + else + onsetindx = onsetindx + 1; + end; + end; + % do check on first derivative (old peak score method used + % until Staib, Castegnetti & Bach 2015) if diagnostics + % required + foundfirstpeak = 0; + while (options.diagnostics) && (~foundfirstpeak) && (numel(firstwin) > 1); + % look for minimum as change in first derivative from + % neg to pos + firstonset = find(diff(sign(scr1(firstwin))) == 2, 1); + if isempty(firstonset) + firstwin = []; + else + firstonset = firstonset + firstwin(1); + % look for first peak after onset + secondwin = firstonset + (round(options.window(2, 1) * glm.sr.fin):round(options.window(2, 2) * glm.sr.fin)); + firstpeak = find(diff(sign(scr1(secondwin))) == -2, 1); % look for local maximum as change from pos to neg + % found peak? Otherwise, look for next onset + if ~isempty(firstpeak) + firstpeak = secondwin(1) + firstpeak; + foundfirstpeak = 1; + else + firstwin(1:find(firstwin == firstonset)) = []; + end; + end; + end; + if foundpeak + peakscore(n) = scr(peak) - scr(onset); + % if an onset is followed by first peak before the peak + % window and by a second one within, then this can be + % negative + peakscore(n) = max(0, peakscore(n)); + else + peakscore(n) = 0; + end; + if options.diagnostics + figure; axes; hold on + win = initialfirstwin(1):secondwin(end); + plot(win, scr(win) - scr(win(1)), 'k'); + plot(win, scr1(win), 'r'); + plot(win, scr2(win), 'b'); + if foundpeak + stem(onset, scr(onset)); + stem(peak, scr(peak)); + end; + if foundfirstpeak + stem(firstonset,scr(firstonset)); + stem(firstpeak, scr(firstpeak)); + end; + s = input('Press RETURN to continue.', 's'); + close(gcf); + end; + end; + end; + end; + if strcmpi(options.method, 'spr') && strcmpi(options.summary, 'amplitude') + glm.stats(k, 1) = mean(peakscore(peakscore > .01)); + else + glm.stats(k, 1) = mean(peakscore); + end; + clear peakscore + glm.names = {}; +end; + +save(modelfile, 'glm'); + + +%------------------------------------------------------------------------- +% user output +%------------------------------------------------------------------------- + +fprintf(' done. \n'); + +% cleanup +clear glm scr +return + +%------------------------------------------------------------------------- +% internal functions: check regressor file(s) +%------------------------------------------------------------------------- + +function [sts multi] = check_regfile(fns, timeunits) + +if ~iscell(fns) + fns = {fns}; +end; + +sts = 1; +multi = []; + +for f = 1:numel(fns) + fn = fns{f}; + merrmsg=sprintf('Regressor file (%s) is invalid ... ', fn); + if exist(fn)~=2 + errmsg=sprintf('Regressor file (%s) doesn''t exist', fn); + warning(errmsg); + sts = -1; + return; + end; + + load(fn); + if (isempty(find(ismember(who, 'names'), 1)))||(isempty(find(ismember(who, 'onsets'), 1))), + warning(merrmsg); sts = -1; return; + end; + if isempty(find(ismember(who, 'durations'), 1)), + durations=num2cell(zeros(numel(names), 1)); + end; + if isempty(find(ismember(who, 'parametric_confound'), 1)) + parametric_confound=zeros(numel(names), 1); + end; + if ~iscell(names)||~iscell(onsets) + errmsg = 'Names and onsets need to be cell arrays'; warning([merrmsg, errmsg]); sts=-1; return; + end; + if numel(names)~=numel(onsets), errmsg=sprintf('Number of event names (%d) does not match the number of onsets (%d).',... + numel(names),numel(onsets)); warning([merrmsg, errmsg]); sts = -1; return; + elseif numel(names)~=numel(durations), errmsg=sprintf('Number of event names (%d) does not match the number of durations (%d).',... + numel(onsets),numel(durations)); warning([merrmsg, errmsg]); sts = -1; return; + elseif numel(names)~=numel(parametric_confound), errmsg=sprintf('Number of event names (%d) does not match the number of parametric confound specifications (%d).',... + numel(onsets),numel(parametric_confound)); warning([merrmsg, errmsg]); sts = -1; return; + else + for n=1:numel(names) + if numel(durations{n})==1, durations{n}=repmat(durations{n}, numel(onsets{n}), 1); + elseif (numel(onsets{n}) ~= numel(durations{n})) + errmsg=sprintf('"%s": Number of event onsets (%d) does not match the number of durations (%d).',... + names{n}, numel(onsets{n}),numel(durations{n})); warning([merrmsg, errmsg]); sts = - 1; return; + end; + switch timeunits + case 'seconds' + if any(onsets{n})<0 + errmsg=sprintf('Onset vector %d contains onsets smaller than 0 s', n); warning([merrmsg, errmsg]); sts = -1; return; + end; + case {'samples', 'markers'} + if any(fix(onsets{n})~=onsets{n}) + errmsg=sprintf('Onset vector %d contains non-integers', n); warning([merrmsg, errmsg]); sts = -1; return; + end; + end; + if any(onsets{n} < 0) + if numel(onsets{n}) == 1, onsets{n} = []; + else + errmsg=sprintf('Negative event onsets in regressor %s', names{n}); warning([merrmsg, errmsg]); sts = -1; return; + end; + end; + end; + end; + if ~isempty(find(ismember(who, 'pmod'), 1)) + if numel(pmod)>numel(names), errmsg=sprintf('Number of parametric modulators (%d) does not match the number of onsets (%d).',... + numel(pmod),numel(onsets)); warning([merrmsg, errmsg]); sts = -1; return; + else + for n=1:numel(pmod), + for o=1:numel(pmod(n).param) + if numel(onsets{n}) ~= numel(pmod(n).param{o}), + errmsg= sprintf('"%s" & "%s": Number of event onsets (%d) does not equal the number of parameters (%d).',... + names{n}, pmod(n).name{o}, numel(onsets{n}),numel(pmod(n).param{o})); warning([merrmsg, errmsg]); sts = -1; return; + end; + end; + end; + end; + end; + + if f > 1 + for n = 1:numel(names) + if ~strcmpi(multi(1).n{n}, names{n}) + errmsg('Event names in sessions 1 and %.0f don''t match (%s and %s)', f, multi(1).n{n},names{n}); + warning(errmsg); sts = -1; return; + end; + end + end; + multi(f).n = names; + multi(f).o = onsets; + multi(f).d = durations; + multi(f).p = parametric_confound; + if exist('pmod') + multi(f).pmod = pmod; + end; + clear names onsets durations parametric_confound pmod end; \ No newline at end of file diff --git a/src/backroom/pspm_predval.m b/backroom/pspm_predval.m similarity index 100% rename from src/backroom/pspm_predval.m rename to backroom/pspm_predval.m diff --git a/src/backroom/pspm_scr2ledalab.m b/backroom/pspm_scr2ledalab.m similarity index 97% rename from src/backroom/pspm_scr2ledalab.m rename to backroom/pspm_scr2ledalab.m index e9ea7896..36ef9089 100644 --- a/src/backroom/pspm_scr2ledalab.m +++ b/backroom/pspm_scr2ledalab.m @@ -1,123 +1,123 @@ -function [sts, outfile] = pspm_scr2ledalab(datafile, outfile, options) -% pspm_scr2ledalab is a function for exporting SCRalyze files to ledalab -% format (for method comparison) -% exports (first) SCR and (first) evend channel of data file -% this version does not support export of event names/values (instead, a -% '1' is written to all ledalab event fields -% -% FORMAT: [sts, outfile] = pspm_scr2ledalab(datafile, outfile, options) -% options.overwrite - overwrite existing files -% options.filter - apply low pass filter and -% downsample as specified in settings -% options.norm: normalise data (default: no) -% -%__________________________________________________________________________ -% PsPM -% (C) 2012 Dominik R Bach (Wellcome Trust Centre for Neuroimaging) - -% v003 drb 04.11.2013 allow normalisation & bugfixes -% v002 drb 26.09.2012 fixed event import -% v001 drb 27.08.2012 - -% $Id$ -% $Rev$ - -% initialise -%-------------------------------------------------------------------------- - -global settings; -if isempty(settings), pspm_init; end; - -sts = -1; - -% check input arguments, set options -%-------------------------------------------------------------------------- - -if nargin < 1 - warning('No data file specified'); return; -elseif nargin < 2 - warning('No output file specified'); return; -elseif ~exist(datafile, 'file') - warning('Input file does not exist'); return -end; - -try options.overwrite; catch, options.overwrite = 0; end; -try options.filter; catch, options.filter = 0; end; -try options.norm; catch, options.norm = 0; end; - -% get and check SCR file -%-------------------------------------------------------------------------- -[sts, infos, scr] = pspm_load_data(datafile, 'scr'); -if sts == -1 || isempty(scr) - warning('\nExport to ledalab unsuccesful'); return; -elseif numel(scr) > 1 - warning('n\SCRalyze file contains more than one SCR channel - first one will be exported'); -end; - -if options.filter == 1 - filt.lpfreq = 5; filt.lporder = 1; - filt.hpfreq = 'none'; filt.hporder = 1; - filt.direction = 'uni'; - filt.sr = scr{1}.header.sr; - filt.down = 10; - [sts, newscr, newsr] = pspm_prepdata(scr{1}.data, filt); - clear scr - scr.data = newscr; scr.header.sr = newsr; -else - scr = scr{1}; -end; -if options.norm == 1; - scr.data = scr.data/std(scr.data); -end; - -[sts, infos, events] = pspm_load_data(datafile, 'events'); -if sts == -1 || isempty(events) - events.data = []; - events.header = []; -elseif numel(events) > 1 - warning('n\SCRalyze file contains more than one event channel - first one will be exported'); -end; -if ~isempty(events) - events = events{1}; -end; - -% construct elements of ledalab file -%-------------------------------------------------------------------------- -clear data -data.conductance = transpose(scr.data(:)); -data.time = (1/scr.header.sr):(1/scr.header.sr):(numel(scr.data)/scr.header.sr); -data.timeoff = 0; -for k = 1:numel(events.data) - data.event(k).time = events.data(k); - data.event(k).nid = 1; - data.event(k).name = '1'; - data.event(k).userdata.duration = .01; -end; - -clear fileinfo -fileinfo.version = 3.44; -fileinfo.date = date; -fileinfo.log = {'Created by SCRalyze for use with Ledalab 3.44.'}; - -% check output file & save data -%-------------------------------------------------------------------------- -if exist(outfile, 'file') == 2 && options.overwrite ~= 1 - if feature('ShowFigureWindows') - msg = ['Imported file already exists. Overwrite?', newline, 'Existing file: ',outfile]; - overwrite = questdlg(msg, 'File already exists', 'Yes', 'No', 'No'); % default not to overwrite by users - else - overwrite = 'No'; % default not to overwrite on Jenkins - end - close gcf; -else - overwrite = 'Yes'; -end; -if strcmp(overwrite, 'No') - warning('Data discarded ...'); - return; -else - save(outfile, 'data', 'fileinfo'); -end; -sts = 1; -return; - +function [sts, outfile] = pspm_scr2ledalab(datafile, outfile, options) +% pspm_scr2ledalab is a function for exporting SCRalyze files to ledalab +% format (for method comparison) +% exports (first) SCR and (first) evend channel of data file +% this version does not support export of event names/values (instead, a +% '1' is written to all ledalab event fields +% +% FORMAT: [sts, outfile] = pspm_scr2ledalab(datafile, outfile, options) +% options.overwrite - overwrite existing files +% options.filter - apply low pass filter and +% downsample as specified in settings +% options.norm: normalise data (default: no) +% +%__________________________________________________________________________ +% PsPM +% (C) 2012 Dominik R Bach (Wellcome Trust Centre for Neuroimaging) + +% v003 drb 04.11.2013 allow normalisation & bugfixes +% v002 drb 26.09.2012 fixed event import +% v001 drb 27.08.2012 + +% $Id$ +% $Rev$ + +% initialise +%-------------------------------------------------------------------------- + +global settings; +if isempty(settings), pspm_init; end; + +sts = -1; + +% check input arguments, set options +%-------------------------------------------------------------------------- + +if nargin < 1 + warning('No data file specified'); return; +elseif nargin < 2 + warning('No output file specified'); return; +elseif ~exist(datafile, 'file') + warning('Input file does not exist'); return +end; + +try options.overwrite; catch, options.overwrite = 0; end; +try options.filter; catch, options.filter = 0; end; +try options.norm; catch, options.norm = 0; end; + +% get and check SCR file +%-------------------------------------------------------------------------- +[sts, infos, scr] = pspm_load_data(datafile, 'scr'); +if sts == -1 || isempty(scr) + warning('\nExport to ledalab unsuccesful'); return; +elseif numel(scr) > 1 + warning('n\SCRalyze file contains more than one SCR channel - first one will be exported'); +end; + +if options.filter == 1 + filt.lpfreq = 5; filt.lporder = 1; + filt.hpfreq = 'none'; filt.hporder = 1; + filt.direction = 'uni'; + filt.sr = scr{1}.header.sr; + filt.down = 10; + [sts, newscr, newsr] = pspm_prepdata(scr{1}.data, filt); + clear scr + scr.data = newscr; scr.header.sr = newsr; +else + scr = scr{1}; +end; +if options.norm == 1; + scr.data = scr.data/std(scr.data); +end; + +[sts, infos, events] = pspm_load_data(datafile, 'events'); +if sts == -1 || isempty(events) + events.data = []; + events.header = []; +elseif numel(events) > 1 + warning('n\SCRalyze file contains more than one event channel - first one will be exported'); +end; +if ~isempty(events) + events = events{1}; +end; + +% construct elements of ledalab file +%-------------------------------------------------------------------------- +clear data +data.conductance = transpose(scr.data(:)); +data.time = (1/scr.header.sr):(1/scr.header.sr):(numel(scr.data)/scr.header.sr); +data.timeoff = 0; +for k = 1:numel(events.data) + data.event(k).time = events.data(k); + data.event(k).nid = 1; + data.event(k).name = '1'; + data.event(k).userdata.duration = .01; +end; + +clear fileinfo +fileinfo.version = 3.44; +fileinfo.date = date; +fileinfo.log = {'Created by SCRalyze for use with Ledalab 3.44.'}; + +% check output file & save data +%-------------------------------------------------------------------------- +if exist(outfile, 'file') == 2 && options.overwrite ~= 1 + if feature('ShowFigureWindows') + msg = ['Imported file already exists. Overwrite?', newline, 'Existing file: ',outfile]; + overwrite = questdlg(msg, 'File already exists', 'Yes', 'No', 'No'); % default not to overwrite by users + else + overwrite = 'No'; % default not to overwrite on Jenkins + end + close gcf; +else + overwrite = 'Yes'; +end; +if strcmp(overwrite, 'No') + warning('Data discarded ...'); + return; +else + save(outfile, 'data', 'fileinfo'); +end; +sts = 1; +return; + diff --git a/src/backroom/pspm_sf_get_theta.m b/backroom/pspm_sf_get_theta.m similarity index 96% rename from src/backroom/pspm_sf_get_theta.m rename to backroom/pspm_sf_get_theta.m index ed670ea8..7f673205 100644 --- a/src/backroom/pspm_sf_get_theta.m +++ b/backroom/pspm_sf_get_theta.m @@ -1,136 +1,136 @@ -function theta = pspm_sf_get_theta(scr, sr, esr, fn, closewindow) -% create parameters for f_SF, given some data scr -% -% FORMAT -% function theta = pspm_sf_get_theta(scr, sr, fn, closewindow) -% -% theta: parameters -% scr: skin conductance epoch (maximum size depends on comp -% sr: data sampling rate -% esr: sampling rate at which to evaluate -% fn: file where parameters are written to -% closewindow: close graphic display of estimation (default: 1) -% -% -% REFERENCE -% Bach DR, Daunizeau J, Kuelzow N, Friston K, Dolan R (2010). Dynamic -% causal modelling of spontaneous fluctuations in skin conductance. -% Psychophysiology, in press. -% -%__________________________________________________________________________ -% PsPM 3.0 -% (C) 2008-2015 Dominik R Bach (Wellcome Trust Centre for Neuroimaging) - -% $Id$ -% $Rev$ - -% v02 drb 27.4.2010 adapted for general release -% v01 drb 30.7.2009 - -% initialise -% ------------------------------------------------------------------------- -global settings; -if isempty(settings), pspm_init; end; -% ------------------------------------------------------------------------- - -% check input arguments -%========================================================================== -if nargin < 4 - closewindow = 1; -elseif closewindow ~= 0, - closewindow = 1; -end; - -if nargin < 3 - fn = 'pspm_sf_theta.m'; -end; - -fid = fopen(fn, 'w'); -[pth fn ext] = fileparts(fn); - -if fid < 0 - errmsg = 'Could not open file for writing.'; -elseif ~ischar(fn) - errmsg = sprintf('No valid filename.'); -elseif nargin < 2 || ~isnumeric(sr) || numel(sr) > 1 - errmsg = sprintf('No sample rate given.'); -elseif (sr < 1) || (sr > 1e5) - errmsg = sprintf('Sample rate out of range.'); -elseif nargin < 1 || ~isnumeric(scr) - errmsg = 'No data.'; -elseif ~any(size(scr) == 1) - errmsg = 'Input SCR is not a vector'; -else - scr = scr(:); -end; - -if exist('errmsg') == 1, warning(errmsg); return; end; - - -% initial conditions -%========================================================================== -theta = [0.923269 3.919950 2.158973 1.091917 1.570259]; -phi = [0 0]; - -% DAVB settings -g_fname = 'g_Id'; -f_fname = 'f_SF'; -dim.n_phi = 2; % nb of observation parameters -dim.n = 3; % nb of hidden states -priors.muX0 = zeros(dim.n,1); -priors.SigmaX0 = 1e-8*eye(dim.n); -priors.a_sigma = 1e5; % Jeffrey's prior -priors.b_sigma = 1e1; % Jeffrey's prior -priors.a_alpha = Inf; -priors.b_alpha = 0; -options.inG.ind = 1; -options.inF.dt = 1/sr; -options.decim = round(sr/esr); -options.GnFigs = 0; % suppress intermediate figs - -u = []; -u(1, :) = (1:numel(scr))/sr; -u(2, :) = 1; -priors.muTheta = theta'; -dim.n_theta = numel(priors.muTheta); % nb of evolution parameters -priors.muPhi = phi'; -priors.SigmaPhi = zeros(dim.n_phi); -priors.SigmaTheta = 1.*eye(dim.n_theta); -options.priors = priors; - -% prepare data -scr = (scr - min(scr)); -scr = scr/max(scr); - - -% estimate params -%========================================================================== -c = clock; -fprintf(['\nEstimating model parameters for f_SF ... \t%02.0f:%02.0f:%02.0f', ... - '\n=========================================================\n'], c(4:6)); -[posterior,out] = VBA_NLStateSpaceModel(scr(:)',u,f_fname,g_fname,dim,options); -theta = posterior.muTheta'; - - -% write parameters to file -%========================================================================== -job{1} = sprintf('function [theta sr] = %s', fn); -job{2} = sprintf('%% Parameter values for skin conductance response function f_SF'); -job{3} = sprintf('%% Estimated on %s', date); -job{4} = sprintf('%%__________________________________________________________________________'); -job{5} = sprintf('%% SCRalyze'); -job{6} = sprintf('%% (C) 2009 Dominik R Bach (Wellcome Trust Centre for Neuroimaging)'); -job{7} = ' '; -job{8} = sprintf('theta = [%f %f %f %f %f];', theta); -job{9} = sprintf('sr = %f', sr); - -for f = 1:numel(job) - fprintf(fid, '%s\n', job{f}); -end; - - -fclose(fid); -if closewindow == 1, close(gcf); end; - - - +function theta = pspm_sf_get_theta(scr, sr, esr, fn, closewindow) +% create parameters for f_SF, given some data scr +% +% FORMAT +% function theta = pspm_sf_get_theta(scr, sr, fn, closewindow) +% +% theta: parameters +% scr: skin conductance epoch (maximum size depends on comp +% sr: data sampling rate +% esr: sampling rate at which to evaluate +% fn: file where parameters are written to +% closewindow: close graphic display of estimation (default: 1) +% +% +% REFERENCE +% Bach DR, Daunizeau J, Kuelzow N, Friston K, Dolan R (2010). Dynamic +% causal modelling of spontaneous fluctuations in skin conductance. +% Psychophysiology, in press. +% +%__________________________________________________________________________ +% PsPM 3.0 +% (C) 2008-2015 Dominik R Bach (Wellcome Trust Centre for Neuroimaging) + +% $Id$ +% $Rev$ + +% v02 drb 27.4.2010 adapted for general release +% v01 drb 30.7.2009 + +% initialise +% ------------------------------------------------------------------------- +global settings; +if isempty(settings), pspm_init; end; +% ------------------------------------------------------------------------- + +% check input arguments +%========================================================================== +if nargin < 4 + closewindow = 1; +elseif closewindow ~= 0, + closewindow = 1; +end; + +if nargin < 3 + fn = 'pspm_sf_theta.m'; +end; + +fid = fopen(fn, 'w'); +[pth fn ext] = fileparts(fn); + +if fid < 0 + errmsg = 'Could not open file for writing.'; +elseif ~ischar(fn) + errmsg = sprintf('No valid filename.'); +elseif nargin < 2 || ~isnumeric(sr) || numel(sr) > 1 + errmsg = sprintf('No sample rate given.'); +elseif (sr < 1) || (sr > 1e5) + errmsg = sprintf('Sample rate out of range.'); +elseif nargin < 1 || ~isnumeric(scr) + errmsg = 'No data.'; +elseif ~any(size(scr) == 1) + errmsg = 'Input SCR is not a vector'; +else + scr = scr(:); +end; + +if exist('errmsg') == 1, warning(errmsg); return; end; + + +% initial conditions +%========================================================================== +theta = [0.923269 3.919950 2.158973 1.091917 1.570259]; +phi = [0 0]; + +% DAVB settings +g_fname = 'g_Id'; +f_fname = 'f_SF'; +dim.n_phi = 2; % nb of observation parameters +dim.n = 3; % nb of hidden states +priors.muX0 = zeros(dim.n,1); +priors.SigmaX0 = 1e-8*eye(dim.n); +priors.a_sigma = 1e5; % Jeffrey's prior +priors.b_sigma = 1e1; % Jeffrey's prior +priors.a_alpha = Inf; +priors.b_alpha = 0; +options.inG.ind = 1; +options.inF.dt = 1/sr; +options.decim = round(sr/esr); +options.GnFigs = 0; % suppress intermediate figs + +u = []; +u(1, :) = (1:numel(scr))/sr; +u(2, :) = 1; +priors.muTheta = theta'; +dim.n_theta = numel(priors.muTheta); % nb of evolution parameters +priors.muPhi = phi'; +priors.SigmaPhi = zeros(dim.n_phi); +priors.SigmaTheta = 1.*eye(dim.n_theta); +options.priors = priors; + +% prepare data +scr = (scr - min(scr)); +scr = scr/max(scr); + + +% estimate params +%========================================================================== +c = clock; +fprintf(['\nEstimating model parameters for f_SF ... \t%02.0f:%02.0f:%02.0f', ... + '\n=========================================================\n'], c(4:6)); +[posterior,out] = VBA_NLStateSpaceModel(scr(:)',u,f_fname,g_fname,dim,options); +theta = posterior.muTheta'; + + +% write parameters to file +%========================================================================== +job{1} = sprintf('function [theta sr] = %s', fn); +job{2} = sprintf('%% Parameter values for skin conductance response function f_SF'); +job{3} = sprintf('%% Estimated on %s', date); +job{4} = sprintf('%%__________________________________________________________________________'); +job{5} = sprintf('%% SCRalyze'); +job{6} = sprintf('%% (C) 2009 Dominik R Bach (Wellcome Trust Centre for Neuroimaging)'); +job{7} = ' '; +job{8} = sprintf('theta = [%f %f %f %f %f];', theta); +job{9} = sprintf('sr = %f', sr); + +for f = 1:numel(job) + fprintf(fid, '%s\n', job{f}); +end; + + +fclose(fid); +if closewindow == 1, close(gcf); end; + + + diff --git a/src/backroom/pspm_transfer_fit.m b/backroom/pspm_transfer_fit.m similarity index 97% rename from src/backroom/pspm_transfer_fit.m rename to backroom/pspm_transfer_fit.m index 3c2512fd..23ee4883 100644 --- a/src/backroom/pspm_transfer_fit.m +++ b/backroom/pspm_transfer_fit.m @@ -1,30 +1,30 @@ -function MSE=pspm_transfer_fit(c, R, PR) -% SCR_TRANSFER_FIT calculates the mean squared error (MSE) for a given -% constant to convert pulse rate (PR) to resistance/conductance, disregarding a -% serial resistor (which should be added to R) a known PR offset (which -% should be subtracted from PR) -% -% FORMAT: -% MSE=pspm_transfer_fit(R, PR); -% -%__________________________________________________________________________ -% PsPM 3.0 -% (C) 2008-2015 Dominik R Bach (Wellcome Trust Centre for Neuroimaging) - -% $Id$ -% $Rev$ - -% initialise -% ------------------------------------------------------------------------- -global settings; -if isempty(settings), pspm_init; end; -% ------------------------------------------------------------------------- -% SCRalyze2, 30.7.2008 - -% NOTE: the objective function is expressed as conductance (since that's -% what the error should be minimized upon, rather than resistance) and in -% microsiemens (otherwise, matlab precision doesn't suffice to find -% maximum) - -MSE = mean(((PR/c)-(1e6./R)).^2); - +function MSE=pspm_transfer_fit(c, R, PR) +% SCR_TRANSFER_FIT calculates the mean squared error (MSE) for a given +% constant to convert pulse rate (PR) to resistance/conductance, disregarding a +% serial resistor (which should be added to R) a known PR offset (which +% should be subtracted from PR) +% +% FORMAT: +% MSE=pspm_transfer_fit(R, PR); +% +%__________________________________________________________________________ +% PsPM 3.0 +% (C) 2008-2015 Dominik R Bach (Wellcome Trust Centre for Neuroimaging) + +% $Id$ +% $Rev$ + +% initialise +% ------------------------------------------------------------------------- +global settings; +if isempty(settings), pspm_init; end; +% ------------------------------------------------------------------------- +% SCRalyze2, 30.7.2008 + +% NOTE: the objective function is expressed as conductance (since that's +% what the error should be minimized upon, rather than resistance) and in +% microsiemens (otherwise, matlab precision doesn't suffice to find +% maximum) + +MSE = mean(((PR/c)-(1e6./R)).^2); + diff --git a/src/backroom/set_blinks_saccades_to_nan.m b/backroom/set_blinks_saccades_to_nan.m similarity index 100% rename from src/backroom/set_blinks_saccades_to_nan.m rename to backroom/set_blinks_saccades_to_nan.m diff --git a/doc/Figures/2ndlvl_bars.PNG b/doc/Figures/2ndlvl_bars.PNG deleted file mode 100644 index e6b2ed4bc75c4406b30d87545fd843bd9c398a7d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19630 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 E16_U`8vpf#43oEx}!bySuyJ=6T-x-tYdq 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 diff --git a/doc/Figures/Hayes-Petrov2016_Article_MappingAndCorrectingTheInfluen_svg.pdf b/doc/Figures/Hayes-Petrov2016_Article_MappingAndCorrectingTheInfluen_svg.pdf deleted file mode 100644 index bbe01dd595f3a910ae246442ce5dba2e0eefd58b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 307894 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