From 66701d27a9453006fa26db8901032a5979aeb1cd Mon Sep 17 00:00:00 2001 From: ChristianKeine Date: Fri, 14 Jun 2019 09:07:07 -0500 Subject: [PATCH 01/39] Update HEKA_Importer.m --- @HEKA_Importer/HEKA_Importer.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/@HEKA_Importer/HEKA_Importer.m b/@HEKA_Importer/HEKA_Importer.m index 0dc6f84..b1162cc 100644 --- a/@HEKA_Importer/HEKA_Importer.m +++ b/@HEKA_Importer/HEKA_Importer.m @@ -34,7 +34,7 @@ % % - OUTPUTS: % Heka_Importer creates object containing the following properties: -% +% % - trees struct structure containing the dataTree % (from the .pul file), the stimTree % (from the .pgf file)and solTree From 8d6340b23411022157f1eb1c5d632f68b67914c8 Mon Sep 17 00:00:00 2001 From: ChristianKeine Date: Thu, 20 Jun 2019 13:28:43 -0500 Subject: [PATCH 02/39] updating import functions --- @HEKA_Importer/HI_ImportHEKAtoMat.asv | 1116 +++++++++++++++++++++++ @HEKA_Importer/HI_ImportHEKAtoMat.m | 14 +- @HEKA_Importer/HI_extractHEKADataTree.m | 3 +- 3 files changed, 1131 insertions(+), 2 deletions(-) create mode 100644 @HEKA_Importer/HI_ImportHEKAtoMat.asv diff --git a/@HEKA_Importer/HI_ImportHEKAtoMat.asv b/@HEKA_Importer/HI_ImportHEKAtoMat.asv new file mode 100644 index 0000000..eb4dc69 --- /dev/null +++ b/@HEKA_Importer/HI_ImportHEKAtoMat.asv @@ -0,0 +1,1116 @@ +function obj=HI_ImportHEKAtoMat(obj) +% ImportHEKA imports HEKA PatchMaster and ChartMaster .DAT files +% Filepath is taken from the input object. +% +% ImportHEKA has been tested with Windows generated .DAT files on Windows, +% Linux and Mac OS10.4. +% +% Both bundled and unbundled data files are supported. If your files are +% unbundled, they must all be in the same folder. +% +% Details of the HEKA file format are available from +% ftp://server.hekahome.de/pub/FileFormat/Patchmasterv9/ +% +%-------------------------------------------------------------------------- +% Author: Malcolm Lidierth 12/09 +% Copyright © The Author & King's College London 2009- +%-------------------------------------------------------------------------- + +% Revisions +% 17.04.10 TrXUnit: see within +% 28.11.11 TrXUnit: see within +% 15.08.12 Updated to support interleaved channels and PatchMaster 2.60 +% files dated 24-Jan-2011 onwards. +% 19.05.13 Modified by Samata Katta to output Matlab variable containing data +% 12.08.15 Don't save *.kcl file (line 793 commented out). +% 03.07.17 Modified by Samata Katta to read in stimulus parameters from +% .pgf section of .dat file. +% 01.01.2019 Modified by Christian Keine to read solution parameters from +% .sol section of .dat file. +% 04.02.2019: combine readout of dataTree, stimTree and solTree. +% +% See also HEKA_Importer +% HEKA_Importer.HI_loadHEKAFile +% HEKA_Importer.HI_extractHEKASolutionTree +% HEKA_Importer.HI_extractHEKAStimTree +% HEKA_Importer.HI_extractHEKADataTree + + + +[pathname, filename, ext]=fileparts(obj.opt.filepath); + +% Open file and get bundle header. Assume little-endian to begin with +endian='ieee-le'; +fh=fopen(obj.opt.filepath, 'r', endian); +[bundle, littleendianflag, isBundled]=getBundleHeader(fh); + +% Big endian so repeat process +if ~isempty(littleendianflag) && littleendianflag==false + fclose(fh); + endian='ieee-be'; + fh=fopen(obj.opt.filepath, 'r', endian); + bundle=getBundleHeader(fh); +end + +%% GET DATA, STIM AND SOLUTION TREE + +fileExt = {'.pul','.pgf','.sol'}; +treeName = {'dataTree','stimTree','solTree'}; + +for iidx = fileExt + fileExist = true; + if isBundled + % ext = {'.dat','.pul','.pgf','.amp','.sol',[],[],'.mrk','.mth','.onl'}; + ext={bundle.oBundleItems.oExtension}; + % Find the section of the dat file + idx=strcmp(iidx, ext);%15.08.2012 - change from strmatch + if any(idx) % check if section exists, e.g. will be empty when solution base was not active during recordings + start=bundle.oBundleItems(idx).oStart; + else + fileExist = false; + end + else + % Or open pulse file if not bundled + fclose(fh); + start=0; + fh=fopen(fullfile(pathname, [filename, iidx{1}]), 'r', endian); + if fh<0 + fileExist = false; + end + end + + % READ OUT TREE + if fileExist + fseek(fh, start, 'bof'); + Magic = fread(fh, 4, 'uint8=>char'); + Levels=fread(fh, 1, 'int32=>int32'); + Sizes=fread(fh, double(Levels), 'int32=>int32'); + Position=ftell(fh); + + % Get the tree structures form the file sections + obj.trees.(treeName{strcmp(iidx, fileExt)})=getTree(fh, Sizes, Position, iidx{1}); + else + obj.trees.(treeName{strcmp(iidx, fileExt)}) = []; + end +end + +%% GET DATA +if isBundled + % Set offset for data + idx=strcmp('.dat', ext);%15.08.2012 - change from strmatch + start=bundle.oBundleItems(idx).oStart; +else + % Or open data file if not bundled + fclose(fh); + fh=fopen(obj.opt.filepath, 'r', endian); + start=bundle.BundleHeaderSize; +end + +% Now set pointer to the start of the data the data +fseek(fh, start, 'bof'); + +% Get the group headers into a structure array +ngroup=1; +for k=1:size(obj.trees.dataTree,1) + if ~isempty(obj.trees.dataTree{k, 2}) + grp_row(ngroup)=k; %#ok + ngroup=ngroup+1; + end +end + +% ADD MINIMUM RANDOM NUMBER TO AVOID DISCRETIZATION; ADD TO ALL CHANNELS +addEPS = @(x) x+randn(size(x))*eps; + +% For each group +matData2 = cell(numel(grp_row),1); +dataRaw = cell(numel(grp_row),1); + +for iGr = 1:numel(grp_row) + matData2{iGr}=LocalImportGroup(fh, obj.trees.dataTree, iGr, grp_row); + + for iSer = 1:numel(matData2{iGr}) + dataRaw{iGr,:}{iSer,:} = cellfun(addEPS,matData2{iGr}{iSer},'UniformOutput',false); + end + +end + +obj.RecTable.dataRaw = vertcat(dataRaw{:}); +obj.RecTable = struct2table(obj.RecTable); + +end + +%-------------------------------------------------------------------------- +function [h, littleendianflag, isBundled]=getBundleHeader(fh) +%-------------------------------------------------------------------------- +% Get the bundle header from a HEKA .dat file +fseek(fh, 0, 'bof'); +h.oSignature=deblank(fread(fh, 8, 'uint8=>char')'); +switch h.oSignature + case 'DATA' + % Old format: nothing to do + h.oVersion=[]; + h.oTime=[]; + h.oItems=[]; + h.oIsLittleEndian=[]; + h.oBundleItems(1:12)=[]; + h.BundleHeaderSize=0; + isBundled=false; + case {'DAT1' 'DAT2'} + % Newer format + h.oVersion=fread(fh, 32, 'uint8=>char')'; + h.oTime=fread(fh, 1, 'double'); + h.oItems=fread(fh, 1, 'int32=>int32'); + h.oIsLittleEndian=fread(fh, 1, 'uint8=>logical'); + h.BundleHeaderSize=256; + switch h.oSignature + case 'DAT1' + h.oBundleItems=[]; + isBundled=false; + case {'DAT2'} + fseek(fh, 64, 'bof'); + for k=1:12 + h.oBundleItems(k).oStart=fread(fh, 1, 'int32=>int32'); + h.oBundleItems(k).oLength=fread(fh, 1, 'int32=>int32'); + h.oBundleItems(k).oExtension=deblank(fread(fh, 8, 'uint8=>char')'); + h.oBundleItems(k).BundleItemSize=16; + end + isBundled=true; + end + otherwise + error('This legacy file format is not supported'); +end +littleendianflag=h.oIsLittleEndian; + +end + + +%-------------------------------------------------------------------------- +function [Tree, Counter]=getTree(fh, Sizes, Position, ext) +%-------------------------------------------------------------------------- +% Main entry point for loading tree +[Tree, Counter]=getTreeReentrant(fh, {}, Sizes, 0, Position, 0, ext); +end + + +function [Tree, Position, Counter]=getTreeReentrant(fh, Tree, Sizes, Level, Position, Counter, ext) +%-------------------------------------------------------------------------- +% Recursive routine called from LoadTree + +switch ext + case '.pul' + [Tree, Position, Counter, nchild]=getOneDataLevel(fh, Tree, Sizes, Level, Position, Counter); + case '.pgf' + [Tree, Position, Counter, nchild]=getOneStimLevel(fh, Tree, Sizes, Level, Position, Counter); + case '.sol' + [Tree, Position, Counter, nchild]=getOneSolutionLevel(fh, Tree, Sizes, Level, Position, Counter); +end + +for k=1:double(nchild) + [Tree, Position, Counter]=getTreeReentrant(fh, Tree, Sizes, Level+1, Position, Counter, ext); +end + +end + + +%-------------------------------------------------------------------------- +function [Tree, Position, Counter, nchild]=getOneDataLevel(fh, Tree, Sizes, Level, Position, Counter) +%-------------------------------------------------------------------------- +% Gets one record of the tree and the number of children +[s, Counter]=getOneRecord(fh, Level, Counter); +Tree{Counter, Level+1}=s; +Position=Position+Sizes(Level+1); +fseek(fh, Position, 'bof'); +nchild=fread(fh, 1, 'int32=>int32'); +Position=ftell(fh); +end + +%-------------------------------------------------------------------------- +function [rec, Counter]=getOneRecord(fh, Level, Counter) +%-------------------------------------------------------------------------- +% Gets one record +Counter=Counter+1; +switch Level + case 0 + rec=getRoot(fh); + case 1 + rec=getGroup(fh); + case 2 + rec=getSeries(fh); + case 3 + rec=getSweep(fh); + case 4 + rec=getTrace(fh); + otherwise + error('Unexpected Level'); +end +end + +% The functions below return data as defined by the HEKA PatchMaster +% specification + +%-------------------------------------------------------------------------- +function p=getRoot(fh) +%-------------------------------------------------------------------------- +p.RoVersion=fread(fh, 1, 'int32=>int32'); +p.RoMark=fread(fh, 1, 'int32=>int32');% = 4; (* INT32 *) +p.RoVersionName=deblank(fread(fh, 32, 'uint8=>char')');% = 8; (* String32Type *) +p.RoAuxFileName=deblank(fread(fh, 80, 'uint8=>char')');% = 40; (* String80Type *) +p.RoRootText=deblank(fread(fh, 400, 'uint8=>char')');% (* String400Type *) +p.RoStartTime=fread(fh, 1, 'double=>double') ;% = 520; (* LONGREAL *) +p.RoStartTimeMATLAB=time2date(p.RoStartTime); +p.RoMaxSamples=fread(fh, 1, 'int32=>int32'); % = 528; (* INT32 *) +p.RoCRC=fread(fh, 1, 'int32=>int32'); % = 532; (* CARD32 *) +p.RoFeatures=fread(fh, 1, 'int16=>int16'); % = 536; (* SET16 *) +p.RoFiller1=fread(fh, 1, 'int16=>int16');% = 538; (* INT16 *) +p.RoFiller2=fread(fh, 1, 'int32=>int32');% = 540; (* INT32 *) +p.RootRecSize= 544; +p=orderfields(p); + +end + +%-------------------------------------------------------------------------- +function g=getGroup(fh) +%-------------------------------------------------------------------------- +% Group +g.GrMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) +g.GrLabel=deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Size *) +g.GrText=deblank(fread(fh, 80, 'uint8=>char')');% = 36; (* String80Size *) +g.GrExperimentNumber=fread(fh, 1, 'int32=>int32');% = 116; (* INT32 *) +g.GrGroupCount=fread(fh, 1, 'int32=>int32');% = 120; (* INT32 *) +g.GrCRC=fread(fh, 1, 'int32=>int32');% = 124; (* CARD32 *) +g.GroupRecSize=128;% (* = 16 * 8 *) +g=orderfields(g); + +end + +%-------------------------------------------------------------------------- +function s=getSeries(fh) +%-------------------------------------------------------------------------- +s.SeMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) +s.SeLabel=deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Type *) +s.SeComment=deblank(fread(fh, 80, 'uint8=>char')');% = 36; (* String80Type *) +s.SeSeriesCount=fread(fh, 1, 'int32=>int32');% = 116; (* INT32 *) +s.SeNumbersw=fread(fh, 1, 'int32=>int32');% = 120; (* INT32 *) +s.SeAmplStateOffset=fread(fh, 1, 'int32=>int32');% = 124; (* INT32 *) +s.SeAmplStateSeries=fread(fh, 1, 'int32=>int32');% = 128; (* INT32 *) +s.SeSeriesType=fread(fh, 1, 'uint8=>uint8');% = 132; (* BYTE *) + +% Added 15.08.2012 +s.SeUseXStart=logical(fread(fh, 1, 'uint8=>uint8'));% = 133; (* BYTE *) + +s.SeFiller2=fread(fh, 1, 'uint8=>uint8');% = 134; (* BYTE *) +s.SeFiller3=fread(fh, 1, 'uint8=>uint8');% = 135; (* BYTE *) +s.SeTime=fread(fh, 1, 'double=>double') ;% = 136; (* LONGREAL *) +s.SeTimeMATLAB=time2date(s.SeTime); +s.SePageWidth=fread(fh, 1, 'double=>double') ;% = 144; (* LONGREAL *) +for k=1:4 + s.SeSwUserParamDescr(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% + s.SeSwUserParamDescr(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% +end +s.SeFiller4=fread(fh, 32, 'uint8=>uint8');% = 312; (* 32 BYTE *) +s.SeSeUserParams=fread(fh, 4, 'double=>double');% = 344; (* ARRAY[0..3] OF LONGREAL *) +s.SeLockInParams=getSeLockInParams(fh);% = 376; (* SeLockInSize = 96, see "Pulsed.de" *) +s.SeAmplifierState=getAmplifierState(fh);% = 472; (* AmplifierStateSize = 400 *) +s.SeUsername=deblank(fread(fh, 80, 'uint8=>char')');% = 872; (* String80Type *) +for k=1:4 + s.SeSeUserParamDescr(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% (* ARRAY[0..3] OF UserParamDescrType = 4*40 *) + s.SeSeUserParamDescr(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% +end +s.SeFiller5=fread(fh, 1, 'int32=>int32');% = 1112; (* INT32 *) +s.SeCRC=fread(fh, 1, 'int32=>int32');% = 1116; (* CARD32 *) + +% Added 15.08.2012 +s.SeSeUserParams2=fread(fh, 4, 'double=>double'); +for k=1:4 + s.SeSeUserParamDescr2(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% + s.SeSeUserParamDescr2(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% +end +s.SeScanParams=fread(fh, 96, 'uint8=>uint8'); +s.SeriesRecSize=1408;% (* = 176 * 8 *) +s=orderfields(s); +s.Sweeps = []; % used to store all the sweeps within the recording structure later on + +end + +%-------------------------------------------------------------------------- +function sw=getSweep(fh) +%-------------------------------------------------------------------------- +sw.SwMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) +sw.SwLabel=deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Type *) +sw.SwAuxDataFileOffset=fread(fh, 1, 'int32=>int32');% = 36; (* INT32 *) +sw.SwStimCount=fread(fh, 1, 'int32=>int32');% = 40; (* INT32 *) +sw.SwSweepCount=fread(fh, 1, 'int32=>int32');% = 44; (* INT32 *) +sw.SwTime=fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) +sw.SwTimeMATLAB=time2date(sw.SwTime);% Also add in MATLAB datenum format +sw.SwTimer=fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) +sw.SwSwUserParams=fread(fh, 4, 'double=>double');% = 64; (* ARRAY[0..3] OF LONGREAL *) +sw.SwTemperature=fread(fh, 1, 'double=>double');% = 96; (* LONGREAL *) +sw.SwOldIntSol=fread(fh, 1, 'int32=>int32');% = 104; (* INT32 *) +sw.SwOldExtSol=fread(fh, 1, 'int32=>int32');% = 108; (* INT32 *) +sw.SwDigitalIn=fread(fh, 1, 'int16=>int16');% = 112; (* SET16 *) +sw.SwSweepKind=fread(fh, 1, 'int16=>int16');% = 114; (* SET16 *) +sw.SwFiller1=fread(fh, 1, 'int32=>int32');% = 116; (* INT32 *) +sw.SwMarkers=fread(fh, 4, 'double=>double');% = 120; (* ARRAY[0..3] OF LONGREAL *) +sw.SwFiller2=fread(fh, 1, 'int32=>int32');% = 152; (* INT32 *) +sw.SwCRC=fread(fh, 1, 'int32=>int32');% = 156; (* CARD32 *) +sw.SweepRecSize = 160;% (* = 20 * 8 *) +sw=orderfields(sw); +sw.Traces = []; % used to store all the traces/channels within the sweep structure later on +end + +%-------------------------------------------------------------------------- +function tr=getTrace(fh) +%-------------------------------------------------------------------------- +tr.TrMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) +tr.TrLabel=deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Type *) +tr.TrTraceCount=fread(fh, 1, 'int32=>int32');% = 36; (* INT32 *) +tr.TrData=fread(fh, 1, 'int32=>int32');% = 40; (* INT32 *) +tr.TrDataPoints=fread(fh, 1, 'int32=>int32');% = 44; (* INT32 *) +tr.TrInternalSolution=fread(fh, 1, 'int32=>int32');% = 48; (* INT32 *) +tr.TrAverageCount=fread(fh, 1, 'int32=>int32');% = 52; (* INT32 *) +tr.TrLeakCount=fread(fh, 1, 'int32=>int32');% = 56; (* INT32 *) +tr.TrLeakTraces=fread(fh, 1, 'int32=>int32');% = 60; (* INT32 *) +tr.TrDataKind=fread(fh, 1, 'uint16=>uint16');% = 64; (* SET16 *) NB Stored unsigned +tr.TrFiller1=fread(fh, 1, 'int16=>int16');% = 66; (* SET16 *) +tr.TrRecordingMode=fread(fh, 1, 'uint8=>uint8');% = 68; (* BYTE *) +tr.TrAmplIndex=fread(fh, 1, 'uint8=>uint8');% = 69; (* CHAR *) +tr.TrDataFormat=fread(fh, 1, 'uint8=>uint8');% = 70; (* BYTE *) +tr.TrDataAbscissa=fread(fh, 1, 'uint8=>uint8');% = 71; (* BYTE *) +tr.TrDataScaler=fread(fh, 1, 'double=>double');% = 72; (* LONGREAL *) +tr.TrTimeOffset=fread(fh, 1, 'double=>double');% = 80; (* LONGREAL *) +tr.TrZeroData=fread(fh, 1, 'double=>double');% = 88; (* LONGREAL *) +tr.TrYUnit=deblank(fread(fh, 8, 'uint8=>char')');% = 96; (* String8Type *) +tr.TrXInterval=fread(fh, 1, 'double=>double');% = 104; (* LONGREAL *) +tr.TrXStart=fread(fh, 1, 'double=>double');% = 112; (* LONGREAL *) +% 17.04.10 TrXUnit bytes may include some trailing characters after NULL +% byte +tr.TrXUnit=deblank(fread(fh, 8, 'uint8=>char')');% = 120; (* String8Type *) +tr.TrYRange=fread(fh, 1, 'double=>double');% = 128; (* LONGREAL *) +tr.TrYOffset=fread(fh, 1, 'double=>double');% = 136; (* LONGREAL *) +tr.TrBandwidth=fread(fh, 1, 'double=>double');% = 144; (* LONGREAL *) +tr.TrPipetteResistance=fread(fh, 1, 'double=>double');% = 152; (* LONGREAL *) +tr.TrCellPotential=fread(fh, 1, 'double=>double');% = 160; (* LONGREAL *) +tr.TrSealResistance=fread(fh, 1, 'double=>double');% = 168; (* LONGREAL *) +tr.TrCSlow=fread(fh, 1, 'double=>double');% = 176; (* LONGREAL *) +tr.TrGSeries=fread(fh, 1, 'double=>double');% = 184; (* LONGREAL *) +tr.TrRsValue=fread(fh, 1, 'double=>double');% = 192; (* LONGREAL *) +tr.TrGLeak=fread(fh, 1, 'double=>double');% = 200; (* LONGREAL *) +tr.TrMConductance=fread(fh, 1, 'double=>double');% = 208; (* LONGREAL *) +tr.TrLinkDAChannel=fread(fh, 1, 'int32=>int32');% = 216; (* INT32 *) +tr.TrValidYrange=fread(fh, 1, 'uint8=>logical');% = 220; (* BOOLEAN *) +tr.TrAdcMode=fread(fh, 1, 'uint8=>uint8');% = 221; (* CHAR *) +tr.TrAdcChannel=fread(fh, 1, 'int16=>int16');% = 222; (* INT16 *) +tr.TrYmin=fread(fh, 1, 'double=>double');% = 224; (* LONGREAL *) +tr.TrYmax=fread(fh, 1, 'double=>double');% = 232; (* LONGREAL *) +tr.TrSourceChannel=fread(fh, 1, 'int32=>int32');% = 240; (* INT32 *) +tr.TrExternalSolution=fread(fh, 1, 'int32=>int32');% = 244; (* INT32 *) +tr.TrCM=fread(fh, 1, 'double=>double');% = 248; (* LONGREAL *) +tr.TrGM=fread(fh, 1, 'double=>double');% = 256; (* LONGREAL *) +tr.TrPhase=fread(fh, 1, 'double=>double');% = 264; (* LONGREAL *) +tr.TrDataCRC=fread(fh, 1, 'int32=>int32');% = 272; (* CARD32 *) +tr.TrCRC=fread(fh, 1, 'int32=>int32');% = 276; (* CARD32 *) +tr.TrGS=fread(fh, 1, 'double=>double');% = 280; (* LONGREAL *) +tr.TrSelfChannel=fread(fh, 1, 'int32=>int32');% = 288; (* INT32 *) + +% Added 15.08.2012 +tr.TrInterleaveSize=fread(fh, 1, 'int32=>int32');% = 292; (* INT32 *) +tr.TrInterleaveSkip=fread(fh, 1, 'int32=>int32');% = 296; (* INT32 *) +tr.TrImageIndex=fread(fh, 1, 'int32=>int32');% = 300; (* INT32 *) +tr.TrMarkers=fread(fh, 10, 'double=>double');% = 304; (* ARRAY[0..9] OF LONGREAL *) +tr.TrSECM_X=fread(fh, 1, 'double=>double');% = 384; (* LONGREAL *) +tr.TrSECM_Y=fread(fh, 1, 'double=>double');% = 392; (* LONGREAL *) +tr.TrSECM_Z=fread(fh, 1, 'double=>double');% = 400; (* LONGREAL *) + +% added 06/2019 + + +tr.TraceRecSize=408; + +tr=orderfields(tr); + +end + +%% GET SOLUTION TREE +%-------------------------------------------------------------------------- +function [Tree, Position, Counter, nchild]=getOneSolutionLevel(fh, Tree, Sizes, Level, Position, Counter) +%-------------------------------------------------------------------------- +% Gets one record of the tree and the number of children +[s, Counter]=getOneSolutionRecord(fh, Level, Counter); +Tree{Counter, Level+1}=s; +Position=Position+Sizes(Level+1); +fseek(fh, Position, 'bof'); +nchild=fread(fh, 1, 'int32=>int32'); +Position=ftell(fh); + +end + +%-------------------------------------------------------------------------- +function [rec, Counter]=getOneSolutionRecord(fh, Level, Counter) +%-------------------------------------------------------------------------- +% Gets one record +Counter=Counter+1; +switch Level + case 0 + rec=getSolutionRoot(fh); + case 1 + rec=getSolution(fh); + case 2 + rec=getChemical(fh); + + otherwise + error('Unexpected Level'); +end + +end + +%-------------------------------------------------------------------------- +function p=getSolutionRoot(fh) +%-------------------------------------------------------------------------- +p.RoVersion=fread(fh, 1, 'int16=>int16'); % = 0; (* INT16 *) +p.RoDataBaseName=deblank(fread(fh, 80, 'uint8=>char')');% = 2; (* SolutionNameSize *) +p.RoSpare1=fread(fh, 1, 'int16=>int16');% = 82; (* INT16 *) +p.RoCRC=fread(fh, 1, 'int32=>int32'); % = 84; (* CARD32 *) +p.RootSize = 88;% = 88 + +p=orderfields(p); + +end + + +function s=getSolution(fh) +%-------------------------------------------------------------------------- +% Stimulus level +s.SoNumber=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) +s.SoName=deblank(fread(fh, 80, 'uint8=>char')');% = 4; (* SolutionNameSize *) +s.SoNumeric=fread(fh, 1, 'real*4=>double');% = 84; (* REAL *) *) +s.SoNumericName=deblank(fread(fh, 30, 'uint8=>char')');% = 88; (* ChemicalNameSize *) +s.SoPH=fread(fh, 1, 'real*4=>double');% = 118; (* REAL *) +s.SopHCompound=deblank(fread(fh, 30, 'uint8=>char')');% = 122; (* ChemicalNameSize *) +s.soOsmol=fread(fh, 1, 'real*4=>double'); %152; (* REAL *) +s.SoCRC=fread(fh, 1, 'int32=>int32') ;% = 156; (* CARD32 *) +s.SolutionSize=160;% = 160 + +s=orderfields(s); + +end + +%-------------------------------------------------------------------------- +function c=getChemical(fh) +%-------------------------------------------------------------------------- +c.ChConcentration=fread(fh, 1, 'real*4=>double');% = 0; (* REAL *) +c.ChName=deblank(fread(fh, 30, 'uint8=>char')');% = 4; (* ChemicalNameSize *) +c.ChSpare1=fread(fh, 1, 'int16=>int16');% = 34; (* INT16 *) +c.ChCRC=fread(fh, 1, 'int32=>int32')';% 36; (* CARD32 *) +c.ChemicalSize=40;% = 40 + +c=orderfields(c); + +end + + +%% GET STIMULUS TREE +%-------------------------------------------------------------------------- +function [Tree, Position, Counter, nchild]=getOneStimLevel(fh, Tree, Sizes, Level, Position, Counter) +%-------------------------------------------------------------------------- +% Gets one record of the tree and the number of children +[s, Counter]=getOneStimRecord(fh, Level, Counter); +Tree{Counter, Level+1}=s; +Position=Position+Sizes(Level+1); +fseek(fh, Position, 'bof'); +nchild=fread(fh, 1, 'int32=>int32'); +Position=ftell(fh); + +end + +%-------------------------------------------------------------------------- +function [rec, Counter]=getOneStimRecord(fh, Level, Counter) +%-------------------------------------------------------------------------- +% Gets one record +Counter=Counter+1; +switch Level + case 0 + rec=getStimRoot(fh); + case 1 + rec=getStimulation(fh); + case 2 + rec=getChannel(fh); + case 3 + rec=getStimSegment(fh); + otherwise + error('Unexpected Level'); +end + +end + +% The functions below return data as defined by the HEKA PatchMaster +% specification + +%-------------------------------------------------------------------------- +function p=getStimRoot(fh) +%-------------------------------------------------------------------------- +p.RoVersion=fread(fh, 1, 'int32=>int32'); +p.RoMark=fread(fh, 1, 'int32=>int32');% = 4; (* INT32 *) +p.RoVersionName=deblank(fread(fh, 32, 'uint8=>char')');% = 8; (* String32Type *) +p.RoMaxSamples=fread(fh, 1, 'int32=>int32'); % = 40; (* INT32 *) +p.RoFiller1 = fread(fh, 1, 'int32=>int32');% = 44; (* INT32 *) +p.RoParams = fread(fh, 10, 'double=>double');% = 48; (* ARRAY[0..9] OF LONGREAL *) +for k=1:10 + p.RoParamText{k}=deblank(fread(fh, 32, 'uint8=>char')');% = 128; (* ARRAY[0..9],[0..31]OF CHAR *) +end +p.RoReserved = fread(fh, 32, 'int32=>int32');% = 448; (* INT32 *) +p.RoFiller2= fread(fh, 1, 'int32=>int32');% = 576; (* INT32 *) +p.RoCRC= fread(fh, 1, 'int32=>int32');% = 580; (* CARD32 *) +p.RootRecSize= 584; % (* = 73 * 8 *) +p=orderfields(p); + +end + +%-------------------------------------------------------------------------- +function s=getStimulation(fh) +%-------------------------------------------------------------------------- +% Stimulus level +s.stMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) +s.stEntryName=deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Type *) +s.stFileName=deblank(fread(fh, 32, 'uint8=>char')');% = 36; (* String32Type *) +s.stAnalName=deblank(fread(fh, 32, 'uint8=>char')');% = 68; (* String32Type *) +s.stDataStartSegment=fread(fh, 1, 'int32=>int32');% = 100; (* INT32 *) +s.stDataStartTime=fread(fh, 1, 'double=>double') ;% = 104; (* LONGREAL *) +s.stDataStartTimeMATLAB=time2date(s.stDataStartTime); +s.stSampleInterval=fread(fh, 1, 'double=>double') ;% = 112; (* LONGREAL *) +s.stSweepInterval=fread(fh, 1, 'double=>double') ;% = 120; (* LONGREAL *) +s.stLeakDelay=fread(fh, 1, 'double=>double') ;% = 128; (* LONGREAL *) +s.stFilterFactor=fread(fh, 1, 'double=>double') ;% = 136; (* LONGREAL *) +s.stNumberSweeps=fread(fh, 1, 'int32=>int32');% = 144; (* INT32 *) +s.stNumberLeaks=fread(fh, 1, 'int32=>int32');% = 148; (* INT32 *) +s.stNumberAverages=fread(fh, 1, 'int32=>int32');% = 152; (* INT32 *) +s.stActualAdcChannels=fread(fh, 1, 'int32=>int32');% = 156; (* INT32 *) +s.stActualDacChannels=fread(fh, 1, 'int32=>int32');% = 160; (* INT32 *) +s.stExtTrigger=fread(fh, 1, 'uint8=>uint8');% = 164; (* BYTE *) +s.stNoStartWait=fread(fh, 1, 'uint8=>logical');% = 165; (* BOOLEAN *) +s.stUseScanRates=fread(fh, 1, 'uint8=>logical');% = 166; (* BOOLEAN *) +s.stNoContAq=fread(fh, 1, 'uint8=>logical');% = 167; (* BOOLEAN *) +s.stHasLockIn=fread(fh, 1, 'uint8=>logical');% = 168; (* BOOLEAN *) +s.stOldStartMacKind=fread(fh, 1, 'uint8=>char');% = 169; (* CHAR *) +s.stOldEndMacKind=fread(fh, 1, 'uint8=>logical');% = 170; (* BOOLEAN *) +s.stAutoRange=fread(fh, 1, 'uint8=>uint8');% = 171; (* BYTE *) +s.stBreakNext=fread(fh, 1, 'uint8=>logical');% = 172; (* BOOLEAN *) +s.stIsExpanded=fread(fh, 1, 'uint8=>logical');% = 173; (* BOOLEAN *) +s.stLeakCompMode=fread(fh, 1, 'uint8=>logical');% = 174; (* BOOLEAN *) +s.stHasChirp=fread(fh, 1, 'uint8=>logical');% = 175; (* BOOLEAN *) +s.stOldStartMacro=deblank(fread(fh, 32, 'uint8=>char')');% = 176; (* String32Type *) +s.stOldEndMacro=deblank(fread(fh, 32, 'uint8=>char')');% = 208; (* String32Type *) +s.sIsGapFree=fread(fh, 1, 'uint8=>logical');% = 240; (* BOOLEAN *) +s.sHandledExternally=fread(fh, 1, 'uint8=>logical');% = 241; (* BOOLEAN *) +s.stFiller1=fread(fh, 1, 'uint8=>logical');% = 242; (* BOOLEAN *) +s.stFiller2=fread(fh, 1, 'uint8=>logical');% = 243; (* BOOLEAN *) +s.stCRC=fread(fh, 1, 'int32=>int32'); % = 244; (* CARD32 *) +s.stTag=deblank(fread(fh, 32, 'uint8=>char')');% = 248; (* String32Type *) +s.StimulationRecSize = 280;% (* = 35 * 8 *) + +s=orderfields(s); + +end + +%-------------------------------------------------------------------------- +function c=getChannel(fh) +%-------------------------------------------------------------------------- +c.chMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) +c.chLinkedChannel=fread(fh, 1, 'int32=>int32');% = 4; (* INT32 *) +c.chCompressionFactor=fread(fh, 1, 'int32=>int32');% = 8; (* INT32 *) +c.chYUnit=deblank(fread(fh, 8, 'uint8=>char')');% = 12; (* String8Type *) +c.chAdcChannel=fread(fh, 1, 'int16=>int16');% = 20; (* INT16 *) +c.chAdcMode=fread(fh, 1, 'uint8=>uint8');% = 22; (* BYTE *) +c.chDoWrite=fread(fh, 1, 'uint8=>logical');% = 23; (* BOOLEAN *) +c.stLeakStore=fread(fh, 1, 'uint8=>uint8');% = 24; (* BYTE *) +c.chAmplMode=fread(fh, 1, 'uint8=>uint8');% = 25; (* BYTE *) +c.chOwnSegTime=fread(fh, 1, 'uint8=>logical');% = 26; (* BOOLEAN *) +c.chSetLastSegVmemb=fread(fh, 1, 'uint8=>logical');% = 27; (* BOOLEAN *) +c.chDacChannel=fread(fh, 1, 'int16=>int16');% = 28; (* INT16 *) +c.chDacMode=fread(fh, 1, 'uint8=>uint8');% = 30; (* BYTE *) +c.chHasLockInSquare=fread(fh, 1, 'uint8=>uint8');% = 31; (* BYTE *) +c.chRelevantXSegment=fread(fh, 1, 'int32=>int32');% = 32; (* INT32 *) +c.chRelevantYSegment=fread(fh, 1, 'int32=>int32');% = 36; (* INT32 *) +c.chDacUnit=deblank(fread(fh, 8, 'uint8=>char')');% = 40; (* String8Type *) +c.chHolding=fread(fh, 1, 'double=>double') ;% = 48; (* LONGREAL *) +c.chLeakHolding=fread(fh, 1, 'double=>double') ;% = 56; (* LONGREAL *) +c.chLeakSize=fread(fh, 1, 'double=>double') ;% = 64; (* LONGREAL *) +c.chLeakHoldMode=fread(fh, 1, 'uint8=>uint8');% = 72; (* BYTE *) +c.chLeakAlternate=fread(fh, 1, 'uint8=>logical');% = 73; (* BOOLEAN *) +c.chAltLeakAveraging=fread(fh, 1, 'uint8=>logical');% = 74; (* BOOLEAN *) +c.chLeakPulseOn=fread(fh, 1, 'uint8=>logical');% = 75; (* BOOLEAN *) +c.chStimToDacID=fread(fh, 1, 'int16=>int16');% = 76; (* SET16 *) +c.chCompressionMode=fread(fh, 1, 'int16=>int16');% = 78; (* SET16 *) +c.chCompressionSkip=fread(fh, 1, 'int32=>int32');% = 80; (* INT32 *) +c.chDacBit=fread(fh, 1, 'int16=>int16');% = 84; (* INT16 *) +c.chHasLockInSine=fread(fh, 1, 'uint8=>logical');% = 86; (* BOOLEAN *) +c.chBreakMode=fread(fh, 1, 'uint8=>uint8');% = 87; (* BYTE *) +c.chZeroSeg=fread(fh, 1, 'int32=>int32');% = 88; (* INT32 *) +c.chFiller1=fread(fh, 1, 'int32=>int32');% = 92; (* INT32 *) +c.chSine_Cycle=fread(fh, 1, 'double=>double') ;% = 96; (* LONGREAL *) +c.chSine_Amplitude=fread(fh, 1, 'double=>double') ;% = 104; (* LONGREAL *) +c.chLockIn_VReversal=fread(fh, 1, 'double=>double') ;% = 112; (* LONGREAL *) +c.chChirp_StartFreq=fread(fh, 1, 'double=>double') ;% = 120; (* LONGREAL *) +c.chChirp_EndFreq=fread(fh, 1, 'double=>double') ;% = 128; (* LONGREAL *) +c.chChirp_MinPoints=fread(fh, 1, 'double=>double') ;% = 136; (* LONGREAL *) +c.chSquare_NegAmpl=fread(fh, 1, 'double=>double') ;% = 144; (* LONGREAL *) +c.chSquare_DurFactor=fread(fh, 1, 'double=>double') ;% = 152; (* LONGREAL *) +c.chLockIn_Skip=fread(fh, 1, 'int32=>int32');% = 160; (* INT32 *) +c.chPhoto_MaxCycles=fread(fh, 1, 'int32=>int32');% = 164; (* INT32 *) +c.chPhoto_SegmentNo=fread(fh, 1, 'int32=>int32');% = 168; (* INT32 *) +c.chLockIn_AvgCycles=fread(fh, 1, 'int32=>int32');% = 172; (* INT32 *) +c.chImaging_RoiNo=fread(fh, 1, 'int32=>int32');% = 176; (* INT32 *) +c.chChirp_Skip=fread(fh, 1, 'int32=>int32');% = 180; (* INT32 *) +c.chChirp_Amplitude=fread(fh, 1, 'double=>double') ;% = 184; (* LONGREAL *) +c.chPhoto_Adapt=fread(fh, 1, 'uint8=>uint8');% = 192; (* BYTE *) +c.chSine_Kind=fread(fh, 1, 'uint8=>uint8');% = 193; (* BYTE *) +c.chChirp_PreChirp=fread(fh, 1, 'uint8=>uint8');% = 194; (* BYTE *) +c.chSine_Source=fread(fh, 1, 'uint8=>uint8');% = 195; (* BYTE *) +c.chSquare_NegSource=fread(fh, 1, 'uint8=>uint8');% = 196; (* BYTE *) +c.chSquare_PosSource=fread(fh, 1, 'uint8=>uint8');% = 197; (* BYTE *) +c.chChirp_Kind=fread(fh, 1, 'uint8=>uint8');% = 198; (* BYTE *) +c.chChirp_Source=fread(fh, 1, 'uint8=>uint8');% = 199; (* BYTE *) +c.chDacOffset=fread(fh, 1, 'double=>double') ;% = 200; (* LONGREAL *) +c.chAdcOffset=fread(fh, 1, 'double=>double') ;% = 208; (* LONGREAL *) +c.chTraceMathFormat=fread(fh, 1, 'uint8=>uint8');% = 216; (* BYTE *) +c.chHasChirp=fread(fh, 1, 'uint8=>logical');% = 217; (* BOOLEAN *) +c.chSquare_Kind=fread(fh, 1, 'uint8=>uint8');% = 218; (* BYTE *) +c.chFiller2=fread(fh,13,'uint8=>char');% = 219; (* ARRAY[0..13] OF CHAR *) +c.chSquare_Cycle=fread(fh, 1, 'double=>double') ;% = 232; (* LONGREAL *) +c.chSquare_PosAmpl=fread(fh, 1, 'double=>double') ;% = 240; (* LONGREAL *) +c.chCompressionOffset=fread(fh, 1, 'int32=>int32');% = 248; (* INT32 *) +c.chPhotoMode=fread(fh, 1, 'int32=>int32');% = 252; (* INT32 *) +c.chBreakLevel=fread(fh, 1, 'double=>double') ;% = 256; (* LONGREAL *) +c.chTraceMath=deblank(fread(fh,128,'uint8=>char')');% = 264; (* String128Type *) +c.chOldCRC=fread(fh, 1, 'int32=>int32');% = 268; (* CARD32 *) +c.chFiller3=fread(fh, 1, 'int32=>int32');% = 392; (* INT32 *) +c.chCRC=fread(fh, 1, 'int32=>int32');% = 396; (* CARD32 *) +c.ChannelRecSize = 400;% (* = 50 * 8 *) +c=orderfields(c); + +end + +%-------------------------------------------------------------------------- +function ss=getStimSegment(fh) +%-------------------------------------------------------------------------- +ss.seMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) +ss.seClass=fread(fh, 1, 'uint8=>uint8');% = 4; (* BYTE *) +ss.seDoStore=fread(fh, 1, 'uint8=>logical');% = 5; (* BOOLEAN *) +ss.seVoltageIncMode=fread(fh, 1, 'uint8=>uint8');% = 6; (* BYTE *) +ss.seDurationIncMode=fread(fh, 1, 'uint8=>uint8');% = 7; (* BYTE *) +ss.seVoltage=fread(fh, 1, 'double=>double');% = 8; (* LONGREAL *) +ss.seVoltageSource=fread(fh, 1, 'int32=>int32');% = 16; (* INT32 *) +ss.seDeltaVFactor=fread(fh, 1, 'double=>double');% = 20; (* LONGREAL *) +ss.seDeltaVIncrement=fread(fh, 1, 'double=>double');% = 28; (* LONGREAL *) +ss.seDuration=fread(fh, 1, 'double=>double');% = 36; (* LONGREAL *) +ss.seDurationSource=fread(fh, 1, 'int32=>int32');% = 44; (* INT32 *) +ss.seDeltaTFactor=fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) +ss.seDeltaTIncrement=fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) +ss.seFiller1=fread(fh, 1, 'int32=>int32');% = 64; (* INT32 *) +ss.seCRC=fread(fh, 1, 'int32=>int32');% = 68; (* CARD32 *) +ss.seScanRate=fread(fh, 1, 'double=>double');% = 72; (* LONGREAL *) +ss.StimSegmentRecSize = 80;% (* = 10 * 8 *) +ss=orderfields(ss); + +end + + + +%% GET AMPLIFIER DATA +%-------------------------------------------------------------------------- +function L=getSeLockInParams(fh) +%-------------------------------------------------------------------------- +offset=ftell(fh); +L.loExtCalPhase=fread(fh, 1, 'double=>double') ;% = 0; (* LONGREAL *) +L.loExtCalAtten=fread(fh, 1, 'double=>double') ;% = 8; (* LONGREAL *) +L.loPLPhase=fread(fh, 1, 'double=>double') ;% = 16; (* LONGREAL *) +L.loPLPhaseY1=fread(fh, 1, 'double=>double') ;% = 24; (* LONGREAL *) +L.loPLPhaseY2=fread(fh, 1, 'double=>double') ;% = 32; (* LONGREAL *) +L.loUsedPhaseShift=fread(fh, 1, 'double=>double') ;% = 40; (* LONGREAL *) +L.loUsedAttenuation=fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) +L.loFiller1=fread(fh, 1, 'double=>double'); +L.loExtCalValid=fread(fh, 1, 'uint8=>logical') ;% = 64; (* BOOLEAN *) +L.loPLPhaseValid=fread(fh, 1, 'uint8=>logical') ;% = 65; (* BOOLEAN *) +L.loLockInMode=fread(fh, 1, 'uint8=>uint8') ;% = 66; (* BYTE *) +L.loCalMode=fread(fh, 1, 'uint8=>uint8') ;% = 67; (* BYTE *) +L.LockInParamsSize=96; +fseek(fh, offset+L.LockInParamsSize, 'bof'); + +end + +%-------------------------------------------------------------------------- +function A=getAmplifierState(fh) +%-------------------------------------------------------------------------- +offset=ftell(fh); +A.E9StateVersion=fread(fh, 1, 'double=>double');% = 0; (* 8 = SizeStateVersion *) +A.E9RealCurrentGain=fread(fh, 1, 'double=>double');% = 8; (* LONGREAL *) +A.E9RealF2Bandwidth=fread(fh, 1, 'double=>double');% = 16; (* LONGREAL *) +A.E9F2Frequency=fread(fh, 1, 'double=>double');% = 24; (* LONGREAL *) +A.E9RsValue=fread(fh, 1, 'double=>double');% = 32; (* LONGREAL *) +A.E9RsFraction=fread(fh, 1, 'double=>double');% = 40; (* LONGREAL *) +A.E9GLeak=fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) +A.E9CFastAmp1=fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) +A.E9CFastAmp2=fread(fh, 1, 'double=>double');% = 64; (* LONGREAL *) +A.E9CFastTau=fread(fh, 1, 'double=>double');% = 72; (* LONGREAL *) +A.E9CSlow=fread(fh, 1, 'double=>double');% = 80; (* LONGREAL *) +A.E9GSeries=fread(fh, 1, 'double=>double');% = 88; (* LONGREAL *) +A.E9StimDacScale=fread(fh, 1, 'double=>double');% = 96; (* LONGREAL *) +A.E9CCStimScale=fread(fh, 1, 'double=>double');% = 104; (* LONGREAL *) +A.E9VHold=fread(fh, 1, 'double=>double');% = 112; (* LONGREAL *) +A.E9LastVHold=fread(fh, 1, 'double=>double');% = 120; (* LONGREAL *) +A.E9VpOffset=fread(fh, 1, 'double=>double');% = 128; (* LONGREAL *) +A.E9VLiquidJunction=fread(fh, 1, 'double=>double');% = 136; (* LONGREAL *) +A.E9CCIHold=fread(fh, 1, 'double=>double');% = 144; (* LONGREAL *) +A.E9CSlowStimVolts=fread(fh, 1, 'double=>double');% = 152; (* LONGREAL *) +A.E9CCtr.TrackVHold=fread(fh, 1, 'double=>double');% = 160; (* LONGREAL *) +A.E9TimeoutLength=fread(fh, 1, 'double=>double');% = 168; (* LONGREAL *) +A.E9SearchDelay=fread(fh, 1, 'double=>double');% = 176; (* LONGREAL *) +A.E9MConductance=fread(fh, 1, 'double=>double');% = 184; (* LONGREAL *) +A.E9MCapacitance=fread(fh, 1, 'double=>double');% = 192; (* LONGREAL *) +A.E9SerialNumber=fread(fh, 1, 'double=>double');% = 200; (* 8 = SizeSerialNumber *) +A.E9E9Boards=fread(fh, 1, 'int16=>int16');% = 208; (* INT16 *) +A.E9CSlowCycles=fread(fh, 1, 'int16=>int16');% = 210; (* INT16 *) +A.E9IMonAdc=fread(fh, 1, 'int16=>int16');% = 212; (* INT16 *) +A.E9VMonAdc=fread(fh, 1, 'int16=>int16');% = 214; (* INT16 *) +A.E9MuxAdc=fread(fh, 1, 'int16=>int16');% = 216; (* INT16 *) +A.E9TstDac=fread(fh, 1, 'int16=>int16');% = 218; (* INT16 *) +A.E9StimDac=fread(fh, 1, 'int16=>int16');% = 220; (* INT16 *) +A.E9StimDacOffset=fread(fh, 1, 'int16=>int16');% = 222; (* INT16 *) +A.E9MaxDigitalBit=fread(fh, 1, 'int16=>int16');% = 224; (* INT16 *) +A.E9SpareInt1=fread(fh, 1, 'int16=>int16');% = 226; (* INT16 *) +A.E9SpareInt2=fread(fh, 1, 'int16=>int16');% = 228; (* INT16 *) +A.E9SpareInt3=fread(fh, 1, 'int16=>int16');% = 230; (* INT16 *) + +A.E9AmplKind=fread(fh, 1, 'uint8=>uint8');% = 232; (* BYTE *) +A.E9IsEpc9N=fread(fh, 1, 'uint8=>uint8');% = 233; (* BYTE *) +A.E9ADBoard=fread(fh, 1, 'uint8=>uint8');% = 234; (* BYTE *) +A.E9BoardVersion=fread(fh, 1, 'uint8=>uint8');% = 235; (* BYTE *) +A.E9ActiveE9Board=fread(fh, 1, 'uint8=>uint8');% = 236; (* BYTE *) +A.E9Mode=fread(fh, 1, 'uint8=>uint8');% = 237; (* BYTE *) +A.E9Range=fread(fh, 1, 'uint8=>uint8');% = 238; (* BYTE *) +A.E9F2Response=fread(fh, 1, 'uint8=>uint8');% = 239; (* BYTE *) + +A.E9RsOn=fread(fh, 1, 'uint8=>uint8');% = 240; (* BYTE *) +A.E9CSlowRange=fread(fh, 1, 'uint8=>uint8');% = 241; (* BYTE *) +A.E9CCRange=fread(fh, 1, 'uint8=>uint8');% = 242; (* BYTE *) +A.E9CCGain=fread(fh, 1, 'uint8=>uint8');% = 243; (* BYTE *) +A.E9CSlowToTstDac=fread(fh, 1, 'uint8=>uint8');% = 244; (* BYTE *) +A.E9StimPath=fread(fh, 1, 'uint8=>uint8');% = 245; (* BYTE *) +A.E9CCtr.TrackTau=fread(fh, 1, 'uint8=>uint8');% = 246; (* BYTE *) +A.E9WasClipping=fread(fh, 1, 'uint8=>uint8');% = 247; (* BYTE *) + +A.E9RepetitiveCSlow=fread(fh, 1, 'uint8=>uint8');% = 248; (* BYTE *) +A.E9LastCSlowRange=fread(fh, 1, 'uint8=>uint8');% = 249; (* BYTE *) +A.E9Locked=fread(fh, 1, 'uint8=>uint8');% = 250; (* BYTE *) +A.E9CanCCFast=fread(fh, 1, 'uint8=>uint8');% = 251; (* BYTE *) +A.E9CanLowCCRange=fread(fh, 1, 'uint8=>uint8');% = 252; (* BYTE *) +A.E9CanHighCCRange=fread(fh, 1, 'uint8=>uint8');% = 253; (* BYTE *) +A.E9CanCCtr.Tracking=fread(fh, 1, 'uint8=>uint8');% = 254; (* BYTE *) +A.E9HasVmonPath=fread(fh, 1, 'uint8=>uint8');% = 255; (* BYTE *) + +A.E9HasNewCCMode=fread(fh, 1, 'uint8=>uint8');% = 256; (* BYTE *) +A.E9Selector=fread(fh, 1, 'uint8=>char');% = 257; (* CHAR *) +A.E9HoldInverted=fread(fh, 1, 'uint8=>uint8');% = 258; (* BYTE *) +A.E9AutoCFast=fread(fh, 1, 'uint8=>uint8');% = 259; (* BYTE *) +A.E9AutoCSlow=fread(fh, 1, 'uint8=>uint8');% = 260; (* BYTE *) +A.E9HasVmonX100=fread(fh, 1, 'uint8=>uint8');% = 261; (* BYTE *) +A.E9TestDacOn=fread(fh, 1, 'uint8=>uint8');% = 262; (* BYTE *) +A.E9QMuxAdcOn=fread(fh, 1, 'uint8=>uint8');% = 263; (* BYTE *) + +A.E9RealImon1Bandwidth=fread(fh, 1, 'double=>double');% = 264; (* LONGREAL *) +A.E9StimScale=fread(fh, 1, 'double=>double');% = 272; (* LONGREAL *) + +A.E9Gain=fread(fh, 1, 'uint8=>uint8');% = 280; (* BYTE *) +A.E9Filter1=fread(fh, 1, 'uint8=>uint8');% = 281; (* BYTE *) +A.E9StimFilterOn=fread(fh, 1, 'uint8=>uint8');% = 282; (* BYTE *) +A.E9RsSlow=fread(fh, 1, 'uint8=>uint8');% = 283; (* BYTE *) +A.E9Old1=fread(fh, 1, 'uint8=>uint8');% = 284; (* BYTE *) +A.E9CCCFastOn=fread(fh, 1, 'uint8=>uint8');% = 285; (* BYTE *) +A.E9CCFastSpeed=fread(fh, 1, 'uint8=>uint8');% = 286; (* BYTE *) +A.E9F2Source=fread(fh, 1, 'uint8=>uint8');% = 287; (* BYTE *) + +A.E9TestRange=fread(fh, 1, 'uint8=>uint8');% = 288; (* BYTE *) +A.E9TestDacPath=fread(fh, 1, 'uint8=>uint8');% = 289; (* BYTE *) +A.E9MuxChannel=fread(fh, 1, 'uint8=>uint8');% = 290; (* BYTE *) +A.E9MuxGain64=fread(fh, 1, 'uint8=>uint8');% = 291; (* BYTE *) +A.E9VmonX100=fread(fh, 1, 'uint8=>uint8');% = 292; (* BYTE *) +A.E9IsQuadro=fread(fh, 1, 'uint8=>uint8');% = 293; (* BYTE *) +A.E9SpareBool4=fread(fh, 1, 'uint8=>uint8');% = 294; (* BYTE *) +A.E9SpareBool5=fread(fh, 1, 'uint8=>uint8');% = 295; (* BYTE *) + +A.E9StimFilterHz=fread(fh, 1, 'double=>double');% = 296; (* LONGREAL *) +A.E9RsTau=fread(fh, 1, 'double=>double');% = 304; (* LONGREAL *) +A.E9FilterOffsetDac=fread(fh, 1, 'int16=>int16');% = 312; (* INT16 *) +A.E9ReferenceDac=fread(fh, 1, 'int16=>int16');% = 314; (* INT16 *) +A.E9SpareInt6=fread(fh, 1, 'int16=>int16');% = 316; (* INT16 *) +A.E9SpareInt7=fread(fh, 1, 'int16=>int16');% = 318; (* INT16 *) +A.E9Spares1=320; + +A.E9CalibDate=fread(fh, 2, 'double=>double');% = 344; (* 16 = SizeCalibDate *) +A.E9SelHold=fread(fh, 1, 'double=>double');% = 360; (* LONGREAL *) +A.AmplifierStateSize = 400; +fseek(fh, offset+A.AmplifierStateSize, 'bof'); + +end + +%-------------------------------------------------------------------------- +function matData2=LocalImportGroup(fh, dataTree, grp, grp_row) +%-------------------------------------------------------------------------- +% Create a structure for the series headers + + +% Pad the indices for last series of last group +grp_row(end+1)=size(dataTree,1); + +% Collect the series headers and row numbers for this group into a +% structure array +[ser_s, ser_row, nseries]=getSeriesHeaders(dataTree, grp_row, grp); + +% Pad for last series +ser_row(nseries+1)=grp_row(grp+1); + +dataoffsets=[]; +% Create the channels + +matData2 = cell(nseries,1); +for ser=1:nseries + + [sw_s, sw_row, nsweeps]=getSweepHeaders(dataTree, ser_row, ser); + + % Make sure the sweeps are in temporal sequence + if any(diff(cell2mat({sw_s.SwTime}))<=0) + % TODO: sort them if this can ever happen. + % For the moment just throw an error + error('Sweeps not in temporal sequence'); + end + + + sw_row(nsweeps+1)=ser_row(ser+1); + % Get the trace headers for this sweep + [tr_row]=getTraceHeaders(dataTree, sw_row); + + + for k=1:size(tr_row, 1) + + [tr_s, isConstantScaling, isConstantFormat, isFramed]=LocalCheckEntries(dataTree, tr_row, k); + + % TODO: Need a better way to do this + % Check whether interleaving is supported with this file version + % Note: HEKA added interleaving Jan 2011. + % TrInterleaveSkip was previously in a filler block, so should always + % be zero with older files. + if tr_s(1).TrInterleaveSize>0 && tr_s(1).TrInterleaveSkip>0 + INTERLEAVE_SUPPORTED=true; + else + INTERLEAVE_SUPPORTED=false; + end + + data=zeros(max(cell2mat({tr_s.TrDataPoints})), size(tr_row,2)); + + for tr=1:size(tr_row,2) + % Disc format + [fmt, nbytes]=LocalFormatToString(tr_s(tr).TrDataFormat); + % Always read into double + readfmt=[fmt '=>double']; + % Skip to start of the data + fseek(fh, dataTree{tr_row(k,tr),5}.TrData, 'bof'); + % Store data offset for later error checks + dataoffsets(end+1)=dataTree{tr_row(k,tr),5}.TrData; %#ok + % Read the data + if ~INTERLEAVE_SUPPORTED || dataTree{tr_row(k,tr),5}.TrInterleaveSize==0 + [data(1:dataTree{tr_row(k,tr),5}.TrDataPoints, tr)]=... + fread(fh, double(dataTree{tr_row(k,tr),5}.TrDataPoints), readfmt); + else + offset=1; + nelements= double(dataTree{tr_row(k,tr),5}.TrInterleaveSize/nbytes); + for nread=1:floor(numel(data)/double(dataTree{tr_row(k,tr),5}.TrInterleaveSize/nbytes)) + [data(offset:offset+nelements-1), N]=fread(fh, nelements, readfmt); + if (N + ser_row(nseries+1)=k; %#ok + nseries=nseries+1; + end +end +return +end + +%-------------------------------------------------------------------------- +function [sw_s, sw_row, nsweeps]=getSweepHeaders(tree, ser_row, ser) +%-------------------------------------------------------------------------- +nsweeps=0; +for k=ser_row(ser)+1:ser_row(ser+1) + if ~isempty(tree{k, 4}) + sw_s(nsweeps+1)=tree{k, 4}; %#ok + sw_row(nsweeps+1)=k; %#ok + nsweeps=nsweeps+1; + end +end +return +end + +%-------------------------------------------------------------------------- +function [tr_row, ntrace]=getTraceHeaders(tree, sw_row) +%-------------------------------------------------------------------------- +ntrace=0; +m=1; +n=1; +for k=sw_row(1)+1:sw_row(end) + if ~isempty(tree{k, 5}) + %tr_s(m,n)=tree{k, 5}; %#ok + tr_row(m,n)=k; %#ok + ntrace=ntrace+1; + m=m+1; + else + m=1; + n=n+1; + end +end +return +end + + +%-------------------------------------------------------------------------- +function [tr_s, isConstantScaling, isConstantFormat, isFramed]=LocalCheckEntries(tree, tr_row, k) +%-------------------------------------------------------------------------- +% Check units are the same for all traces +tr_s=[tree{tr_row(k, :),5}]; + + +if numel(unique({tr_s.TrYUnit}))>1 + error('1002: Waveform units are not constant'); +end + +if numel(unique({tr_s.TrXUnit}))>1 + error('1003: Time units are not constant'); +end + +if numel(unique(cell2mat({tr_s.TrXInterval})))~=1 + error('1004: Unequal sample intervals'); +end + +% Other unexpected conditions - give user freedom to create these but warn +% about them +if numel(unique({tr_s.TrLabel}))>1 + warning('LocalCheckEntries:w2001', 'Different trace labels'); +end + +if numel(unique(cell2mat({tr_s.TrAdcChannel})))>1 + warning('LocalCheckEntries:w2002', 'Data collected from different ADC channels'); +end + +if numel(unique(cell2mat({tr_s.TrRecordingMode})))>1 + warning('LocalCheckEntries:w2003', 'Traces collected using different recording modes'); +end + +if numel(unique(cell2mat({tr_s.TrCellPotential})))>1 + warning('LocalCheckEntries:w2004', 'Traces collected using different Em'); +end + +% Check scaling factor is constant +ScaleFactor=unique(cell2mat({tr_s.TrDataScaler})); +if numel(ScaleFactor)==1 + isConstantScaling=true; +else + isConstantScaling=false; +end + + +%... and data format +if numel(unique(cell2mat({tr_s.TrDataFormat})))==1 + isConstantFormat=true; +else + isConstantFormat=false; +end + +% Do we have constant epoch lengths and offsets? +if numel(unique(cell2mat({tr_s.TrDataPoints})))==1 &&... + numel(unique(cell2mat({tr_s.TrTimeOffset })))==1 + isFramed=true; +else + isFramed=false; +end +return +end + +%-------------------------------------------------------------------------- +function str=time2date(t) +%-------------------------------------------------------------------------- +t=t-1580970496; +if t<0 + t=t+4294967296; +end +t=t+9561652096; +str=datestr(t/(24*60*60)+datenum(1601,1,1)); +return +end +%-------------------------------------------------------------------------- \ No newline at end of file diff --git a/@HEKA_Importer/HI_ImportHEKAtoMat.m b/@HEKA_Importer/HI_ImportHEKAtoMat.m index 9744ce7..1ade0ec 100644 --- a/@HEKA_Importer/HI_ImportHEKAtoMat.m +++ b/@HEKA_Importer/HI_ImportHEKAtoMat.m @@ -420,7 +420,19 @@ tr.TrSECM_X=fread(fh, 1, 'double=>double');% = 384; (* LONGREAL *) tr.TrSECM_Y=fread(fh, 1, 'double=>double');% = 392; (* LONGREAL *) tr.TrSECM_Z=fread(fh, 1, 'double=>double');% = 400; (* LONGREAL *) -tr.TraceRecSize=408; + +% added 06/2019 +tr.TrTrHolding = fread(fh, 1, 'double=>double');% = 408; (* LONGREAL *) +tr.TrTcEnumerator = fread(fh, 1, 'int32=>int32');% = 416; (* INT32 *) +tr.TrXTrace = fread(fh, 1, 'int32=>int32');% = 420; (* INT32 *) +tr.TrIntSolValue = fread(fh, 1, 'double=>double');% = 424; (* LONGREAL *) +tr.TrExtSolValue = fread(fh, 1, 'double=>double');% = 432; (* LONGREAL *) +tr.TrIntSolName = deblank(fread(fh, 32, 'uint8=>char')');% = 440; (* String32Size *) +tr.TrExtSolName = deblank(fread(fh, 32, 'uint8=>char')');% = 472; (* String32Size *) +tr.TrDataPedestal = fread(fh, 1, 'double=>double');% = 504; (* LONGREAL *) + + +tr.TraceRecSize=512; tr=orderfields(tr); diff --git a/@HEKA_Importer/HI_extractHEKADataTree.m b/@HEKA_Importer/HI_extractHEKADataTree.m index b049132..e583286 100644 --- a/@HEKA_Importer/HI_extractHEKADataTree.m +++ b/@HEKA_Importer/HI_extractHEKADataTree.m @@ -138,7 +138,8 @@ function HI_extractHEKADataTree(obj) end - for iS=1:Recs(iR).SeNumbersw +% for iS=1:Recs(iR).SeNumbersw +for iS=1:numel(Recs(iR).Sweeps) Rs_uncomp{iR}(1,iS) = 1/Recs(iR).Sweeps(iS).Traces(1).TrGSeries; Rs{iR}(1,iS) = Rs_uncomp{iR}(iS) - Recs(iR).Sweeps(iS).Traces(1).TrRsValue; Cm{iR}(1,iS) = Recs(iR).Sweeps(iS).Traces(1).TrCSlow; From 92738ae7d50c43198ebc10f99d9e608deb3f6b38 Mon Sep 17 00:00:00 2001 From: ChristianKeine Date: Thu, 20 Jun 2019 15:36:31 -0500 Subject: [PATCH 03/39] Update HI_extractHEKADataTree.m --- @HEKA_Importer/HI_extractHEKADataTree.m | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/@HEKA_Importer/HI_extractHEKADataTree.m b/@HEKA_Importer/HI_extractHEKADataTree.m index e583286..f857729 100644 --- a/@HEKA_Importer/HI_extractHEKADataTree.m +++ b/@HEKA_Importer/HI_extractHEKADataTree.m @@ -81,7 +81,6 @@ function HI_extractHEKADataTree(obj) %EXTRACT INFORMATION FROM AMPLIFIER STATE, LEVEL 3 AmpState = [Recs(:).SeAmplifierState]; -Vhold = reshape([AmpState(:).E9VHold],numel(AmpState),1); % THIS ONLY READS OUT THE Rs/Cm VALUES FOR FIRST SWEEP % RsFractionComp = reshape([AmpState(:).E9RsFraction],numel(AmpState),1); @@ -105,6 +104,7 @@ function HI_extractHEKADataTree(obj) Rs_uncomp = cell(nRecs,1); RsFractionComp = cell(nRecs,1); Cm = cell(nRecs,1); +Vhold = cell(nRecs,1); TimeStamp = cell(nRecs,1); RecModeNames = {'inside-out V-clamp','on-cell V-clamp','outside-out V-clamp','Whole-cell V-clamp','C-clamp','V-clamp','NoMode'}; @@ -127,10 +127,12 @@ function HI_extractHEKADataTree(obj) ExternalSolutionID{iR,:} = [Recs(iR).Sweeps(1).Traces(1).TrExternalSolution]; InternalSolutionID{iR,:} = [Recs(iR).Sweeps(1).Traces(1).TrInternalSolution]; - Rs{iR} = NaN(1,Recs(iR).SeNumbersw); - Rs_uncomp{iR} = NaN(1,Recs(iR).SeNumbersw); - RsFractionComp{iR} = NaN(1,Recs(iR).SeNumbersw); - Cm{iR} = NaN(1,Recs(iR).SeNumbersw); + Rs{iR} = cell(1,Recs(iR).SeNumbersw); + Rs_uncomp{iR} = cell(1,Recs(iR).SeNumbersw); + RsFractionComp{iR} = cell(1,Recs(iR).SeNumbersw); + Cm{iR} = cell(1,Recs(iR).SeNumbersw); + Vhold{iR} = cell(1,Recs(iR).SeNumbersw); + if hasDateTime TimeStamp{iR} = NaT(1,Recs(iR).SeNumbersw); else @@ -140,16 +142,18 @@ function HI_extractHEKADataTree(obj) % for iS=1:Recs(iR).SeNumbersw for iS=1:numel(Recs(iR).Sweeps) - Rs_uncomp{iR}(1,iS) = 1/Recs(iR).Sweeps(iS).Traces(1).TrGSeries; - Rs{iR}(1,iS) = Rs_uncomp{iR}(iS) - Recs(iR).Sweeps(iS).Traces(1).TrRsValue; - Cm{iR}(1,iS) = Recs(iR).Sweeps(iS).Traces(1).TrCSlow; + Rs_uncomp{iR}{1,iS} = 1./[Recs(iR).Sweeps(iS).Traces(:).TrGSeries]; + Rs{iR}{1,iS} = Rs_uncomp{iR}{1,iS} - [Recs(iR).Sweeps(iS).Traces(:).TrRsValue]; + Cm{iR}{1,iS} = [Recs(iR).Sweeps(iS).Traces(:).TrCSlow]; + Vhold{iR}{1,iS} = [Recs(iR).Sweeps(iS).Traces(1).TrTrHolding]; + RsFractionComp{iR}{1,iS} = 1-Rs{iR}{1,iS}./Rs_uncomp{iR}{1,iS}; + if hasDateTime TimeStamp{iR}(iS) = datetime(Recs(iR).Sweeps(iS).SwTimeMATLAB); else TimeStamp{iR}{iS} = Recs(iR).Sweeps(iS).SwTimeMATLAB; end end - RsFractionComp{iR} = 1-Rs{iR}./Rs_uncomp{iR}; end From b9993ed74f66ec2f7a410f39a1d951cb5549ef96 Mon Sep 17 00:00:00 2001 From: ChristianKeine Date: Thu, 20 Jun 2019 15:44:49 -0500 Subject: [PATCH 04/39] updating import to channel --- @HEKA_Importer/HI_extractHEKADataTree.asv | 226 ++++++++++++++++++++++ @HEKA_Importer/HI_extractHEKADataTree.m | 26 +-- 2 files changed, 241 insertions(+), 11 deletions(-) create mode 100644 @HEKA_Importer/HI_extractHEKADataTree.asv diff --git a/@HEKA_Importer/HI_extractHEKADataTree.asv b/@HEKA_Importer/HI_extractHEKADataTree.asv new file mode 100644 index 0000000..fe009c4 --- /dev/null +++ b/@HEKA_Importer/HI_extractHEKADataTree.asv @@ -0,0 +1,226 @@ +function HI_extractHEKADataTree(obj) + +% Function to extract parameters from the HEKA data tree and sort them +% according to the recordings. +% Takes HEKA_IMPORTER object as input and creates RecTable +% containing the recording parameters for each recording/series. +% +% See also HEKA_Importer +% HEKA_Importer.HI_loadHEKAFile +% HEKA_Importer.HI_ImportHEKAtoMat +% HEKA_Importer.HI_extractHEKASolutionTree +% HEKA_Importer.HI_extractHEKAStimTree + +%1: Root +%2: Group/Experiment +%3: Series/Recording number +%4: Sweep +%5: Trace/Channel + +%check if datetime functions exist + +if ~isempty(which('datetime')) && ~isempty(which('NaT')) + hasDateTime = true; +else + hasDateTime = false; +end + + + +dataTree = obj.trees.dataTree; + +allExp = find(~cellfun(@isempty,dataTree(:,2))); +nExperiments = numel(allExp); + +Rt = cell(nExperiments,1); + +for iExp = 1:nExperiments + if iExp == nExperiments + nextExp = size(dataTree,1)+1; + else + nextExp = allExp(iExp+1); + end + Rt{iExp} = ImportRecordings(dataTree,allExp(iExp),nextExp,iExp,hasDateTime); +end + +obj.RecTable = [vertcat(Rt{:}),obj.RecTable]; + + + +end + + + +function RecTab = ImportRecordings(dataTree,thisExpID,nextExpID,ExpNum,hasDateTime) + + +% RESORT STRUCTURES TO ALSO CONTAIN SWEEP AND TRACE/CHANNEL INFORMATION +recIDs = find(~cellfun(@isempty,dataTree(:,3))); +recIDs = recIDs(recIDs>thisExpID & recIDs1 + traceEnd = [sweepIDs(2:end)-1;size(dataTree,1)]; +else + traceEnd = size(dataTree,1); +end + +for iS = 1:numel(sweepIDs) + Sweeps(iS) = dataTree{sweepIDs(iS),1}; + Sweeps(iS).Traces = [dataTree{traceSt(iS):traceEnd(iS),2}]; +end + + + +end + + + + diff --git a/@HEKA_Importer/HI_extractHEKADataTree.m b/@HEKA_Importer/HI_extractHEKADataTree.m index f857729..66f129d 100644 --- a/@HEKA_Importer/HI_extractHEKADataTree.m +++ b/@HEKA_Importer/HI_extractHEKADataTree.m @@ -77,7 +77,7 @@ function HI_extractHEKADataTree(obj) %EXTRACT INFORMATION FROM LEVEL 3 Stimulus = reshape({Recs(:).SeLabel},numel(Recs),1); Comment = reshape({Recs(:).SeComment},numel(Recs),1); -nSweeps = reshape([Recs(:).SeNumbersw],numel(Recs),1); +% nSweeps = reshape([Recs(:).SeNumbersw],numel(Recs),1); %EXTRACT INFORMATION FROM AMPLIFIER STATE, LEVEL 3 AmpState = [Recs(:).SeAmplifierState]; @@ -91,6 +91,8 @@ function HI_extractHEKADataTree(obj) % ASSUME TEMPERATURE AND SOLUTIONS ARE IDENTICAL BETWEEN SWEEPS AND LOAD % FIRST SWEEP ONLY OF EACH RECORDING Temperature = NaN(nRecs,1); +nSweeps = NaN(nRecs,1); + TimeUnit = cell(nRecs,1); ChUnit = cell(nRecs,1); ChName = cell(nRecs,1); @@ -127,21 +129,23 @@ function HI_extractHEKADataTree(obj) ExternalSolutionID{iR,:} = [Recs(iR).Sweeps(1).Traces(1).TrExternalSolution]; InternalSolutionID{iR,:} = [Recs(iR).Sweeps(1).Traces(1).TrInternalSolution]; - Rs{iR} = cell(1,Recs(iR).SeNumbersw); - Rs_uncomp{iR} = cell(1,Recs(iR).SeNumbersw); - RsFractionComp{iR} = cell(1,Recs(iR).SeNumbersw); - Cm{iR} = cell(1,Recs(iR).SeNumbersw); - Vhold{iR} = cell(1,Recs(iR).SeNumbersw); + nSweeps(iR) = numel(Recs(iR).Sweeps); % replaced from Recs(iR).SeNumbersw due to occasional mismatch between data and metadata + + Rs{iR} = cell(1,nSweeps(iR)); + Rs_uncomp{iR} = cell(1,nSweeps(iR)); + RsFractionComp{iR} = cell(1,nSweeps(iR)); + Cm{iR} = cell(1,nSweeps(iR)); + Vhold{iR} = cell(1,nSweeps(iR)); if hasDateTime - TimeStamp{iR} = NaT(1,Recs(iR).SeNumbersw); + TimeStamp{iR} = NaT(1,nSweeps(iR)); else - TimeStamp{iR} = cell(1,Recs(iR).SeNumbersw); + TimeStamp{iR} = cell(1,nSweeps(iR)); end - -% for iS=1:Recs(iR).SeNumbersw -for iS=1:numel(Recs(iR).Sweeps) +% added export for each sweep and channel + +for iS=1:numel(Recs(iR).Sweeps) % replaced from Recs(iR).SeNumbersw due to occasional mismatch Rs_uncomp{iR}{1,iS} = 1./[Recs(iR).Sweeps(iS).Traces(:).TrGSeries]; Rs{iR}{1,iS} = Rs_uncomp{iR}{1,iS} - [Recs(iR).Sweeps(iS).Traces(:).TrRsValue]; Cm{iR}{1,iS} = [Recs(iR).Sweeps(iS).Traces(:).TrCSlow]; From e8730da1872d83dfbfbdd41e07a4b3421ca32c81 Mon Sep 17 00:00:00 2001 From: ChristianKeine Date: Thu, 20 Jun 2019 16:13:26 -0500 Subject: [PATCH 05/39] Update HI_extractHEKADataTree.m --- @HEKA_Importer/HI_extractHEKADataTree.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/@HEKA_Importer/HI_extractHEKADataTree.m b/@HEKA_Importer/HI_extractHEKADataTree.m index 66f129d..7fd754d 100644 --- a/@HEKA_Importer/HI_extractHEKADataTree.m +++ b/@HEKA_Importer/HI_extractHEKADataTree.m @@ -149,7 +149,7 @@ function HI_extractHEKADataTree(obj) Rs_uncomp{iR}{1,iS} = 1./[Recs(iR).Sweeps(iS).Traces(:).TrGSeries]; Rs{iR}{1,iS} = Rs_uncomp{iR}{1,iS} - [Recs(iR).Sweeps(iS).Traces(:).TrRsValue]; Cm{iR}{1,iS} = [Recs(iR).Sweeps(iS).Traces(:).TrCSlow]; - Vhold{iR}{1,iS} = [Recs(iR).Sweeps(iS).Traces(1).TrTrHolding]; + Vhold{iR}{1,iS} = [Recs(iR).Sweeps(iS).Traces(:).TrTrHolding]; RsFractionComp{iR}{1,iS} = 1-Rs{iR}{1,iS}./Rs_uncomp{iR}{1,iS}; if hasDateTime From 9061bb39239697af3cb11005c4ddc23f41b21fe8 Mon Sep 17 00:00:00 2001 From: ChristianKeine Date: Thu, 20 Jun 2019 16:48:08 -0500 Subject: [PATCH 06/39] resorting channels/sweeps --- @HEKA_Importer/HI_extractHEKADataTree.asv | 55 +++++++++++++++++------ @HEKA_Importer/HI_extractHEKADataTree.m | 54 +++++++++++++++------- 2 files changed, 80 insertions(+), 29 deletions(-) diff --git a/@HEKA_Importer/HI_extractHEKADataTree.asv b/@HEKA_Importer/HI_extractHEKADataTree.asv index fe009c4..7f35e82 100644 --- a/@HEKA_Importer/HI_extractHEKADataTree.asv +++ b/@HEKA_Importer/HI_extractHEKADataTree.asv @@ -77,7 +77,7 @@ RecNum = reshape(1:nRecs,nRecs,1); %EXTRACT INFORMATION FROM LEVEL 3 Stimulus = reshape({Recs(:).SeLabel},numel(Recs),1); Comment = reshape({Recs(:).SeComment},numel(Recs),1); -nSweeps = reshape([Recs(:).SeNumbersw],numel(Recs),1); +% nSweeps = reshape([Recs(:).SeNumbersw],numel(Recs),1); %EXTRACT INFORMATION FROM AMPLIFIER STATE, LEVEL 3 AmpState = [Recs(:).SeAmplifierState]; @@ -91,6 +91,8 @@ AmpState = [Recs(:).SeAmplifierState]; % ASSUME TEMPERATURE AND SOLUTIONS ARE IDENTICAL BETWEEN SWEEPS AND LOAD % FIRST SWEEP ONLY OF EACH RECORDING Temperature = NaN(nRecs,1); +nSweeps = NaN(nRecs,1); + TimeUnit = cell(nRecs,1); ChUnit = cell(nRecs,1); ChName = cell(nRecs,1); @@ -127,33 +129,58 @@ for iR=1:nRecs ExternalSolutionID{iR,:} = [Recs(iR).Sweeps(1).Traces(1).TrExternalSolution]; InternalSolutionID{iR,:} = [Recs(iR).Sweeps(1).Traces(1).TrInternalSolution]; - Rs{iR} = cell(1,Recs(iR).SeNumbersw); - Rs_uncomp{iR} = cell(1,Recs(iR).SeNumbersw); - RsFractionComp{iR} = cell(1,Recs(iR).SeNumbersw); - Cm{iR} = cell(1,Recs(iR).SeNumbersw); - Vhold{iR} = cell(1,Recs(iR).SeNumbersw); + nSweeps(iR) = numel(Recs(iR).Sweeps); % replaced from Recs(iR).SeNumbersw due to occasional mismatch between data and metadata + + Rs{iR} = cell(1,nSweeps(iR)); + Rs_uncomp{iR} = cell(1,nSweeps(iR)); + RsFractionComp{iR} = cell(1,nSweeps(iR)); + Cm{iR} = cell(1,nSweeps(iR)); + Vhold{iR} = cell(1,nSweeps(iR)); if hasDateTime - TimeStamp{iR} = NaT(1,Recs(iR).SeNumbersw); + TimeStamp{iR} = NaT(1,nSweeps(iR)); else - TimeStamp{iR} = cell(1,Recs(iR).SeNumbersw); + TimeStamp{iR} = cell(1,nSweeps(iR)); end % added export for each sweep and channel -for iS=1:numel(Recs(iR).Sweeps) % replaced from Recs(iR).SeNumbersw due to occasional mismatch - Rs_uncomp{iR}{1,iS} = 1./[Recs(iR).Sweeps(iS).Traces(:).TrGSeries]; - Rs{iR}{1,iS} = Rs_uncomp{iR}{1,iS} - [Recs(iR).Sweeps(iS).Traces(:).TrRsValue]; - Cm{iR}{1,iS} = [Recs(iR).Sweeps(iS).Traces(:).TrCSlow]; - Vhold{iR}{1,iS} = [Recs(iR).Sweeps(iS).Traces(1).TrTrHolding]; - RsFractionComp{iR}{1,iS} = 1-Rs{iR}{1,iS}./Rs_uncomp{iR}{1,iS}; +% testing: + +nChannels = numel(ChUnit{iR,:}); + +for iCh = 1:nChannels + for iS = 1:nSweeps(iR) + Rs_uncomp{iR}{1,iCh}(1,iS) = Recs(iR).Sweeps(iS).Traces(iCh).TrGSeries; + Rs{iR}{1,iCh}(1,iS) = Rs_uncomp{iR}{1,iCh}(1,iS) - Recs(iR).Sweeps(iS).Traces(iCh).TrRsValue; + Cm{iR}{1,iCh}(1,iS) = Recs(iR).Sweeps(iS).Traces(iCh).TrCSlow; + Vhold{iR}{1,iCh}(1,iS) = Recs(iR).Sweeps(iS).Traces(iCh).TrTrHolding; + if iCh == 1 if hasDateTime TimeStamp{iR}(iS) = datetime(Recs(iR).Sweeps(iS).SwTimeMATLAB); else TimeStamp{iR}{iS} = Recs(iR).Sweeps(iS).SwTimeMATLAB; end end + RsFractionComp{iR}{1,iCh} = 1-Rs{iR}{1,iCh}./Rs_uncomp{iR}{1,iCh}; + +end + + +% for iS=1:nSweeps(iR) % replaced from Recs(iR).SeNumbersw due to occasional mismatch +% Rs_uncomp{iR}{1:nChannels} = 1./[Recs(iR).Sweeps(iS).Traces(:).TrGSeries]; +% Rs{iR}{1,iS} = Rs_uncomp{iR}{1,iS} - [Recs(iR).Sweeps(iS).Traces(:).TrRsValue]; +% Cm{iR}{1,iS} = [Recs(iR).Sweeps(iS).Traces(:).TrCSlow]; +% Vhold{iR}{1,iS} = [Recs(iR).Sweeps(iS).Traces(:).TrTrHolding]; +% RsFractionComp{iR}{1,iS} = 1-Rs{iR}{1,iS}./Rs_uncomp{iR}{1,iS}; +% +% if hasDateTime +% TimeStamp{iR}(iS) = datetime(Recs(iR).Sweeps(iS).SwTimeMATLAB); +% else +% TimeStamp{iR}{iS} = Recs(iR).Sweeps(iS).SwTimeMATLAB; +% end +% end end diff --git a/@HEKA_Importer/HI_extractHEKADataTree.m b/@HEKA_Importer/HI_extractHEKADataTree.m index 7fd754d..89a36a7 100644 --- a/@HEKA_Importer/HI_extractHEKADataTree.m +++ b/@HEKA_Importer/HI_extractHEKADataTree.m @@ -130,34 +130,58 @@ function HI_extractHEKADataTree(obj) InternalSolutionID{iR,:} = [Recs(iR).Sweeps(1).Traces(1).TrInternalSolution]; nSweeps(iR) = numel(Recs(iR).Sweeps); % replaced from Recs(iR).SeNumbersw due to occasional mismatch between data and metadata - - Rs{iR} = cell(1,nSweeps(iR)); - Rs_uncomp{iR} = cell(1,nSweeps(iR)); - RsFractionComp{iR} = cell(1,nSweeps(iR)); - Cm{iR} = cell(1,nSweeps(iR)); - Vhold{iR} = cell(1,nSweeps(iR)); + nChannels = numel(ChUnit{iR,:}); + + Rs{iR} = cell(1,nChannels); + Rs_uncomp{iR} = cell(1,nChannels); + RsFractionComp{iR} = cell(1,nChannels); + Cm{iR} = cell(1,nChannels); + Vhold{iR} = cell(1,nChannels); if hasDateTime - TimeStamp{iR} = NaT(1,nSweeps(iR)); + TimeStamp{iR} = NaT(1,nChannels); else - TimeStamp{iR} = cell(1,nSweeps(iR)); + TimeStamp{iR} = cell(1,nChannels); end % added export for each sweep and channel -for iS=1:numel(Recs(iR).Sweeps) % replaced from Recs(iR).SeNumbersw due to occasional mismatch - Rs_uncomp{iR}{1,iS} = 1./[Recs(iR).Sweeps(iS).Traces(:).TrGSeries]; - Rs{iR}{1,iS} = Rs_uncomp{iR}{1,iS} - [Recs(iR).Sweeps(iS).Traces(:).TrRsValue]; - Cm{iR}{1,iS} = [Recs(iR).Sweeps(iS).Traces(:).TrCSlow]; - Vhold{iR}{1,iS} = [Recs(iR).Sweeps(iS).Traces(:).TrTrHolding]; - RsFractionComp{iR}{1,iS} = 1-Rs{iR}{1,iS}./Rs_uncomp{iR}{1,iS}; +% testing: - if hasDateTime + +for iCh = 1:nChannels + for iS = 1:nSweeps(iR) + Rs_uncomp{iR}{1,iCh}(1,iS) = Recs(iR).Sweeps(iS).Traces(iCh).TrGSeries; + Rs{iR}{1,iCh}(1,iS) = Rs_uncomp{iR}{1,iCh}(1,iS) - Recs(iR).Sweeps(iS).Traces(iCh).TrRsValue; + Cm{iR}{1,iCh}(1,iS) = Recs(iR).Sweeps(iS).Traces(iCh).TrCSlow; + Vhold{iR}{1,iCh}(1,iS) = Recs(iR).Sweeps(iS).Traces(iCh).TrTrHolding; + + if iCh == 1 + if hasDateTime TimeStamp{iR}(iS) = datetime(Recs(iR).Sweeps(iS).SwTimeMATLAB); else TimeStamp{iR}{iS} = Recs(iR).Sweeps(iS).SwTimeMATLAB; end + + end end + RsFractionComp{iR}{1,iCh} = 1-Rs{iR}{1,iCh}./Rs_uncomp{iR}{1,iCh}; +end + + +% for iS=1:nSweeps(iR) % replaced from Recs(iR).SeNumbersw due to occasional mismatch +% Rs_uncomp{iR}{1:nChannels} = 1./[Recs(iR).Sweeps(iS).Traces(:).TrGSeries]; +% Rs{iR}{1,iS} = Rs_uncomp{iR}{1,iS} - [Recs(iR).Sweeps(iS).Traces(:).TrRsValue]; +% Cm{iR}{1,iS} = [Recs(iR).Sweeps(iS).Traces(:).TrCSlow]; +% Vhold{iR}{1,iS} = [Recs(iR).Sweeps(iS).Traces(:).TrTrHolding]; +% RsFractionComp{iR}{1,iS} = 1-Rs{iR}{1,iS}./Rs_uncomp{iR}{1,iS}; +% +% if hasDateTime +% TimeStamp{iR}(iS) = datetime(Recs(iR).Sweeps(iS).SwTimeMATLAB); +% else +% TimeStamp{iR}{iS} = Recs(iR).Sweeps(iS).SwTimeMATLAB; +% end +% end end From b2cd10a6ca18210fece841c0e2e9956de4a6b8bb Mon Sep 17 00:00:00 2001 From: ChristianKeine Date: Thu, 20 Jun 2019 17:08:44 -0500 Subject: [PATCH 07/39] clean up --- @HEKA_Importer/HI_ImportHEKAtoMat.asv | 1116 --------------------- @HEKA_Importer/HI_extractHEKADataTree.asv | 253 ----- 2 files changed, 1369 deletions(-) delete mode 100644 @HEKA_Importer/HI_ImportHEKAtoMat.asv delete mode 100644 @HEKA_Importer/HI_extractHEKADataTree.asv diff --git a/@HEKA_Importer/HI_ImportHEKAtoMat.asv b/@HEKA_Importer/HI_ImportHEKAtoMat.asv deleted file mode 100644 index eb4dc69..0000000 --- a/@HEKA_Importer/HI_ImportHEKAtoMat.asv +++ /dev/null @@ -1,1116 +0,0 @@ -function obj=HI_ImportHEKAtoMat(obj) -% ImportHEKA imports HEKA PatchMaster and ChartMaster .DAT files -% Filepath is taken from the input object. -% -% ImportHEKA has been tested with Windows generated .DAT files on Windows, -% Linux and Mac OS10.4. -% -% Both bundled and unbundled data files are supported. If your files are -% unbundled, they must all be in the same folder. -% -% Details of the HEKA file format are available from -% ftp://server.hekahome.de/pub/FileFormat/Patchmasterv9/ -% -%-------------------------------------------------------------------------- -% Author: Malcolm Lidierth 12/09 -% Copyright © The Author & King's College London 2009- -%-------------------------------------------------------------------------- - -% Revisions -% 17.04.10 TrXUnit: see within -% 28.11.11 TrXUnit: see within -% 15.08.12 Updated to support interleaved channels and PatchMaster 2.60 -% files dated 24-Jan-2011 onwards. -% 19.05.13 Modified by Samata Katta to output Matlab variable containing data -% 12.08.15 Don't save *.kcl file (line 793 commented out). -% 03.07.17 Modified by Samata Katta to read in stimulus parameters from -% .pgf section of .dat file. -% 01.01.2019 Modified by Christian Keine to read solution parameters from -% .sol section of .dat file. -% 04.02.2019: combine readout of dataTree, stimTree and solTree. -% -% See also HEKA_Importer -% HEKA_Importer.HI_loadHEKAFile -% HEKA_Importer.HI_extractHEKASolutionTree -% HEKA_Importer.HI_extractHEKAStimTree -% HEKA_Importer.HI_extractHEKADataTree - - - -[pathname, filename, ext]=fileparts(obj.opt.filepath); - -% Open file and get bundle header. Assume little-endian to begin with -endian='ieee-le'; -fh=fopen(obj.opt.filepath, 'r', endian); -[bundle, littleendianflag, isBundled]=getBundleHeader(fh); - -% Big endian so repeat process -if ~isempty(littleendianflag) && littleendianflag==false - fclose(fh); - endian='ieee-be'; - fh=fopen(obj.opt.filepath, 'r', endian); - bundle=getBundleHeader(fh); -end - -%% GET DATA, STIM AND SOLUTION TREE - -fileExt = {'.pul','.pgf','.sol'}; -treeName = {'dataTree','stimTree','solTree'}; - -for iidx = fileExt - fileExist = true; - if isBundled - % ext = {'.dat','.pul','.pgf','.amp','.sol',[],[],'.mrk','.mth','.onl'}; - ext={bundle.oBundleItems.oExtension}; - % Find the section of the dat file - idx=strcmp(iidx, ext);%15.08.2012 - change from strmatch - if any(idx) % check if section exists, e.g. will be empty when solution base was not active during recordings - start=bundle.oBundleItems(idx).oStart; - else - fileExist = false; - end - else - % Or open pulse file if not bundled - fclose(fh); - start=0; - fh=fopen(fullfile(pathname, [filename, iidx{1}]), 'r', endian); - if fh<0 - fileExist = false; - end - end - - % READ OUT TREE - if fileExist - fseek(fh, start, 'bof'); - Magic = fread(fh, 4, 'uint8=>char'); - Levels=fread(fh, 1, 'int32=>int32'); - Sizes=fread(fh, double(Levels), 'int32=>int32'); - Position=ftell(fh); - - % Get the tree structures form the file sections - obj.trees.(treeName{strcmp(iidx, fileExt)})=getTree(fh, Sizes, Position, iidx{1}); - else - obj.trees.(treeName{strcmp(iidx, fileExt)}) = []; - end -end - -%% GET DATA -if isBundled - % Set offset for data - idx=strcmp('.dat', ext);%15.08.2012 - change from strmatch - start=bundle.oBundleItems(idx).oStart; -else - % Or open data file if not bundled - fclose(fh); - fh=fopen(obj.opt.filepath, 'r', endian); - start=bundle.BundleHeaderSize; -end - -% Now set pointer to the start of the data the data -fseek(fh, start, 'bof'); - -% Get the group headers into a structure array -ngroup=1; -for k=1:size(obj.trees.dataTree,1) - if ~isempty(obj.trees.dataTree{k, 2}) - grp_row(ngroup)=k; %#ok - ngroup=ngroup+1; - end -end - -% ADD MINIMUM RANDOM NUMBER TO AVOID DISCRETIZATION; ADD TO ALL CHANNELS -addEPS = @(x) x+randn(size(x))*eps; - -% For each group -matData2 = cell(numel(grp_row),1); -dataRaw = cell(numel(grp_row),1); - -for iGr = 1:numel(grp_row) - matData2{iGr}=LocalImportGroup(fh, obj.trees.dataTree, iGr, grp_row); - - for iSer = 1:numel(matData2{iGr}) - dataRaw{iGr,:}{iSer,:} = cellfun(addEPS,matData2{iGr}{iSer},'UniformOutput',false); - end - -end - -obj.RecTable.dataRaw = vertcat(dataRaw{:}); -obj.RecTable = struct2table(obj.RecTable); - -end - -%-------------------------------------------------------------------------- -function [h, littleendianflag, isBundled]=getBundleHeader(fh) -%-------------------------------------------------------------------------- -% Get the bundle header from a HEKA .dat file -fseek(fh, 0, 'bof'); -h.oSignature=deblank(fread(fh, 8, 'uint8=>char')'); -switch h.oSignature - case 'DATA' - % Old format: nothing to do - h.oVersion=[]; - h.oTime=[]; - h.oItems=[]; - h.oIsLittleEndian=[]; - h.oBundleItems(1:12)=[]; - h.BundleHeaderSize=0; - isBundled=false; - case {'DAT1' 'DAT2'} - % Newer format - h.oVersion=fread(fh, 32, 'uint8=>char')'; - h.oTime=fread(fh, 1, 'double'); - h.oItems=fread(fh, 1, 'int32=>int32'); - h.oIsLittleEndian=fread(fh, 1, 'uint8=>logical'); - h.BundleHeaderSize=256; - switch h.oSignature - case 'DAT1' - h.oBundleItems=[]; - isBundled=false; - case {'DAT2'} - fseek(fh, 64, 'bof'); - for k=1:12 - h.oBundleItems(k).oStart=fread(fh, 1, 'int32=>int32'); - h.oBundleItems(k).oLength=fread(fh, 1, 'int32=>int32'); - h.oBundleItems(k).oExtension=deblank(fread(fh, 8, 'uint8=>char')'); - h.oBundleItems(k).BundleItemSize=16; - end - isBundled=true; - end - otherwise - error('This legacy file format is not supported'); -end -littleendianflag=h.oIsLittleEndian; - -end - - -%-------------------------------------------------------------------------- -function [Tree, Counter]=getTree(fh, Sizes, Position, ext) -%-------------------------------------------------------------------------- -% Main entry point for loading tree -[Tree, Counter]=getTreeReentrant(fh, {}, Sizes, 0, Position, 0, ext); -end - - -function [Tree, Position, Counter]=getTreeReentrant(fh, Tree, Sizes, Level, Position, Counter, ext) -%-------------------------------------------------------------------------- -% Recursive routine called from LoadTree - -switch ext - case '.pul' - [Tree, Position, Counter, nchild]=getOneDataLevel(fh, Tree, Sizes, Level, Position, Counter); - case '.pgf' - [Tree, Position, Counter, nchild]=getOneStimLevel(fh, Tree, Sizes, Level, Position, Counter); - case '.sol' - [Tree, Position, Counter, nchild]=getOneSolutionLevel(fh, Tree, Sizes, Level, Position, Counter); -end - -for k=1:double(nchild) - [Tree, Position, Counter]=getTreeReentrant(fh, Tree, Sizes, Level+1, Position, Counter, ext); -end - -end - - -%-------------------------------------------------------------------------- -function [Tree, Position, Counter, nchild]=getOneDataLevel(fh, Tree, Sizes, Level, Position, Counter) -%-------------------------------------------------------------------------- -% Gets one record of the tree and the number of children -[s, Counter]=getOneRecord(fh, Level, Counter); -Tree{Counter, Level+1}=s; -Position=Position+Sizes(Level+1); -fseek(fh, Position, 'bof'); -nchild=fread(fh, 1, 'int32=>int32'); -Position=ftell(fh); -end - -%-------------------------------------------------------------------------- -function [rec, Counter]=getOneRecord(fh, Level, Counter) -%-------------------------------------------------------------------------- -% Gets one record -Counter=Counter+1; -switch Level - case 0 - rec=getRoot(fh); - case 1 - rec=getGroup(fh); - case 2 - rec=getSeries(fh); - case 3 - rec=getSweep(fh); - case 4 - rec=getTrace(fh); - otherwise - error('Unexpected Level'); -end -end - -% The functions below return data as defined by the HEKA PatchMaster -% specification - -%-------------------------------------------------------------------------- -function p=getRoot(fh) -%-------------------------------------------------------------------------- -p.RoVersion=fread(fh, 1, 'int32=>int32'); -p.RoMark=fread(fh, 1, 'int32=>int32');% = 4; (* INT32 *) -p.RoVersionName=deblank(fread(fh, 32, 'uint8=>char')');% = 8; (* String32Type *) -p.RoAuxFileName=deblank(fread(fh, 80, 'uint8=>char')');% = 40; (* String80Type *) -p.RoRootText=deblank(fread(fh, 400, 'uint8=>char')');% (* String400Type *) -p.RoStartTime=fread(fh, 1, 'double=>double') ;% = 520; (* LONGREAL *) -p.RoStartTimeMATLAB=time2date(p.RoStartTime); -p.RoMaxSamples=fread(fh, 1, 'int32=>int32'); % = 528; (* INT32 *) -p.RoCRC=fread(fh, 1, 'int32=>int32'); % = 532; (* CARD32 *) -p.RoFeatures=fread(fh, 1, 'int16=>int16'); % = 536; (* SET16 *) -p.RoFiller1=fread(fh, 1, 'int16=>int16');% = 538; (* INT16 *) -p.RoFiller2=fread(fh, 1, 'int32=>int32');% = 540; (* INT32 *) -p.RootRecSize= 544; -p=orderfields(p); - -end - -%-------------------------------------------------------------------------- -function g=getGroup(fh) -%-------------------------------------------------------------------------- -% Group -g.GrMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) -g.GrLabel=deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Size *) -g.GrText=deblank(fread(fh, 80, 'uint8=>char')');% = 36; (* String80Size *) -g.GrExperimentNumber=fread(fh, 1, 'int32=>int32');% = 116; (* INT32 *) -g.GrGroupCount=fread(fh, 1, 'int32=>int32');% = 120; (* INT32 *) -g.GrCRC=fread(fh, 1, 'int32=>int32');% = 124; (* CARD32 *) -g.GroupRecSize=128;% (* = 16 * 8 *) -g=orderfields(g); - -end - -%-------------------------------------------------------------------------- -function s=getSeries(fh) -%-------------------------------------------------------------------------- -s.SeMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) -s.SeLabel=deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Type *) -s.SeComment=deblank(fread(fh, 80, 'uint8=>char')');% = 36; (* String80Type *) -s.SeSeriesCount=fread(fh, 1, 'int32=>int32');% = 116; (* INT32 *) -s.SeNumbersw=fread(fh, 1, 'int32=>int32');% = 120; (* INT32 *) -s.SeAmplStateOffset=fread(fh, 1, 'int32=>int32');% = 124; (* INT32 *) -s.SeAmplStateSeries=fread(fh, 1, 'int32=>int32');% = 128; (* INT32 *) -s.SeSeriesType=fread(fh, 1, 'uint8=>uint8');% = 132; (* BYTE *) - -% Added 15.08.2012 -s.SeUseXStart=logical(fread(fh, 1, 'uint8=>uint8'));% = 133; (* BYTE *) - -s.SeFiller2=fread(fh, 1, 'uint8=>uint8');% = 134; (* BYTE *) -s.SeFiller3=fread(fh, 1, 'uint8=>uint8');% = 135; (* BYTE *) -s.SeTime=fread(fh, 1, 'double=>double') ;% = 136; (* LONGREAL *) -s.SeTimeMATLAB=time2date(s.SeTime); -s.SePageWidth=fread(fh, 1, 'double=>double') ;% = 144; (* LONGREAL *) -for k=1:4 - s.SeSwUserParamDescr(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% - s.SeSwUserParamDescr(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% -end -s.SeFiller4=fread(fh, 32, 'uint8=>uint8');% = 312; (* 32 BYTE *) -s.SeSeUserParams=fread(fh, 4, 'double=>double');% = 344; (* ARRAY[0..3] OF LONGREAL *) -s.SeLockInParams=getSeLockInParams(fh);% = 376; (* SeLockInSize = 96, see "Pulsed.de" *) -s.SeAmplifierState=getAmplifierState(fh);% = 472; (* AmplifierStateSize = 400 *) -s.SeUsername=deblank(fread(fh, 80, 'uint8=>char')');% = 872; (* String80Type *) -for k=1:4 - s.SeSeUserParamDescr(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% (* ARRAY[0..3] OF UserParamDescrType = 4*40 *) - s.SeSeUserParamDescr(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% -end -s.SeFiller5=fread(fh, 1, 'int32=>int32');% = 1112; (* INT32 *) -s.SeCRC=fread(fh, 1, 'int32=>int32');% = 1116; (* CARD32 *) - -% Added 15.08.2012 -s.SeSeUserParams2=fread(fh, 4, 'double=>double'); -for k=1:4 - s.SeSeUserParamDescr2(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% - s.SeSeUserParamDescr2(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% -end -s.SeScanParams=fread(fh, 96, 'uint8=>uint8'); -s.SeriesRecSize=1408;% (* = 176 * 8 *) -s=orderfields(s); -s.Sweeps = []; % used to store all the sweeps within the recording structure later on - -end - -%-------------------------------------------------------------------------- -function sw=getSweep(fh) -%-------------------------------------------------------------------------- -sw.SwMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) -sw.SwLabel=deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Type *) -sw.SwAuxDataFileOffset=fread(fh, 1, 'int32=>int32');% = 36; (* INT32 *) -sw.SwStimCount=fread(fh, 1, 'int32=>int32');% = 40; (* INT32 *) -sw.SwSweepCount=fread(fh, 1, 'int32=>int32');% = 44; (* INT32 *) -sw.SwTime=fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) -sw.SwTimeMATLAB=time2date(sw.SwTime);% Also add in MATLAB datenum format -sw.SwTimer=fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) -sw.SwSwUserParams=fread(fh, 4, 'double=>double');% = 64; (* ARRAY[0..3] OF LONGREAL *) -sw.SwTemperature=fread(fh, 1, 'double=>double');% = 96; (* LONGREAL *) -sw.SwOldIntSol=fread(fh, 1, 'int32=>int32');% = 104; (* INT32 *) -sw.SwOldExtSol=fread(fh, 1, 'int32=>int32');% = 108; (* INT32 *) -sw.SwDigitalIn=fread(fh, 1, 'int16=>int16');% = 112; (* SET16 *) -sw.SwSweepKind=fread(fh, 1, 'int16=>int16');% = 114; (* SET16 *) -sw.SwFiller1=fread(fh, 1, 'int32=>int32');% = 116; (* INT32 *) -sw.SwMarkers=fread(fh, 4, 'double=>double');% = 120; (* ARRAY[0..3] OF LONGREAL *) -sw.SwFiller2=fread(fh, 1, 'int32=>int32');% = 152; (* INT32 *) -sw.SwCRC=fread(fh, 1, 'int32=>int32');% = 156; (* CARD32 *) -sw.SweepRecSize = 160;% (* = 20 * 8 *) -sw=orderfields(sw); -sw.Traces = []; % used to store all the traces/channels within the sweep structure later on -end - -%-------------------------------------------------------------------------- -function tr=getTrace(fh) -%-------------------------------------------------------------------------- -tr.TrMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) -tr.TrLabel=deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Type *) -tr.TrTraceCount=fread(fh, 1, 'int32=>int32');% = 36; (* INT32 *) -tr.TrData=fread(fh, 1, 'int32=>int32');% = 40; (* INT32 *) -tr.TrDataPoints=fread(fh, 1, 'int32=>int32');% = 44; (* INT32 *) -tr.TrInternalSolution=fread(fh, 1, 'int32=>int32');% = 48; (* INT32 *) -tr.TrAverageCount=fread(fh, 1, 'int32=>int32');% = 52; (* INT32 *) -tr.TrLeakCount=fread(fh, 1, 'int32=>int32');% = 56; (* INT32 *) -tr.TrLeakTraces=fread(fh, 1, 'int32=>int32');% = 60; (* INT32 *) -tr.TrDataKind=fread(fh, 1, 'uint16=>uint16');% = 64; (* SET16 *) NB Stored unsigned -tr.TrFiller1=fread(fh, 1, 'int16=>int16');% = 66; (* SET16 *) -tr.TrRecordingMode=fread(fh, 1, 'uint8=>uint8');% = 68; (* BYTE *) -tr.TrAmplIndex=fread(fh, 1, 'uint8=>uint8');% = 69; (* CHAR *) -tr.TrDataFormat=fread(fh, 1, 'uint8=>uint8');% = 70; (* BYTE *) -tr.TrDataAbscissa=fread(fh, 1, 'uint8=>uint8');% = 71; (* BYTE *) -tr.TrDataScaler=fread(fh, 1, 'double=>double');% = 72; (* LONGREAL *) -tr.TrTimeOffset=fread(fh, 1, 'double=>double');% = 80; (* LONGREAL *) -tr.TrZeroData=fread(fh, 1, 'double=>double');% = 88; (* LONGREAL *) -tr.TrYUnit=deblank(fread(fh, 8, 'uint8=>char')');% = 96; (* String8Type *) -tr.TrXInterval=fread(fh, 1, 'double=>double');% = 104; (* LONGREAL *) -tr.TrXStart=fread(fh, 1, 'double=>double');% = 112; (* LONGREAL *) -% 17.04.10 TrXUnit bytes may include some trailing characters after NULL -% byte -tr.TrXUnit=deblank(fread(fh, 8, 'uint8=>char')');% = 120; (* String8Type *) -tr.TrYRange=fread(fh, 1, 'double=>double');% = 128; (* LONGREAL *) -tr.TrYOffset=fread(fh, 1, 'double=>double');% = 136; (* LONGREAL *) -tr.TrBandwidth=fread(fh, 1, 'double=>double');% = 144; (* LONGREAL *) -tr.TrPipetteResistance=fread(fh, 1, 'double=>double');% = 152; (* LONGREAL *) -tr.TrCellPotential=fread(fh, 1, 'double=>double');% = 160; (* LONGREAL *) -tr.TrSealResistance=fread(fh, 1, 'double=>double');% = 168; (* LONGREAL *) -tr.TrCSlow=fread(fh, 1, 'double=>double');% = 176; (* LONGREAL *) -tr.TrGSeries=fread(fh, 1, 'double=>double');% = 184; (* LONGREAL *) -tr.TrRsValue=fread(fh, 1, 'double=>double');% = 192; (* LONGREAL *) -tr.TrGLeak=fread(fh, 1, 'double=>double');% = 200; (* LONGREAL *) -tr.TrMConductance=fread(fh, 1, 'double=>double');% = 208; (* LONGREAL *) -tr.TrLinkDAChannel=fread(fh, 1, 'int32=>int32');% = 216; (* INT32 *) -tr.TrValidYrange=fread(fh, 1, 'uint8=>logical');% = 220; (* BOOLEAN *) -tr.TrAdcMode=fread(fh, 1, 'uint8=>uint8');% = 221; (* CHAR *) -tr.TrAdcChannel=fread(fh, 1, 'int16=>int16');% = 222; (* INT16 *) -tr.TrYmin=fread(fh, 1, 'double=>double');% = 224; (* LONGREAL *) -tr.TrYmax=fread(fh, 1, 'double=>double');% = 232; (* LONGREAL *) -tr.TrSourceChannel=fread(fh, 1, 'int32=>int32');% = 240; (* INT32 *) -tr.TrExternalSolution=fread(fh, 1, 'int32=>int32');% = 244; (* INT32 *) -tr.TrCM=fread(fh, 1, 'double=>double');% = 248; (* LONGREAL *) -tr.TrGM=fread(fh, 1, 'double=>double');% = 256; (* LONGREAL *) -tr.TrPhase=fread(fh, 1, 'double=>double');% = 264; (* LONGREAL *) -tr.TrDataCRC=fread(fh, 1, 'int32=>int32');% = 272; (* CARD32 *) -tr.TrCRC=fread(fh, 1, 'int32=>int32');% = 276; (* CARD32 *) -tr.TrGS=fread(fh, 1, 'double=>double');% = 280; (* LONGREAL *) -tr.TrSelfChannel=fread(fh, 1, 'int32=>int32');% = 288; (* INT32 *) - -% Added 15.08.2012 -tr.TrInterleaveSize=fread(fh, 1, 'int32=>int32');% = 292; (* INT32 *) -tr.TrInterleaveSkip=fread(fh, 1, 'int32=>int32');% = 296; (* INT32 *) -tr.TrImageIndex=fread(fh, 1, 'int32=>int32');% = 300; (* INT32 *) -tr.TrMarkers=fread(fh, 10, 'double=>double');% = 304; (* ARRAY[0..9] OF LONGREAL *) -tr.TrSECM_X=fread(fh, 1, 'double=>double');% = 384; (* LONGREAL *) -tr.TrSECM_Y=fread(fh, 1, 'double=>double');% = 392; (* LONGREAL *) -tr.TrSECM_Z=fread(fh, 1, 'double=>double');% = 400; (* LONGREAL *) - -% added 06/2019 - - -tr.TraceRecSize=408; - -tr=orderfields(tr); - -end - -%% GET SOLUTION TREE -%-------------------------------------------------------------------------- -function [Tree, Position, Counter, nchild]=getOneSolutionLevel(fh, Tree, Sizes, Level, Position, Counter) -%-------------------------------------------------------------------------- -% Gets one record of the tree and the number of children -[s, Counter]=getOneSolutionRecord(fh, Level, Counter); -Tree{Counter, Level+1}=s; -Position=Position+Sizes(Level+1); -fseek(fh, Position, 'bof'); -nchild=fread(fh, 1, 'int32=>int32'); -Position=ftell(fh); - -end - -%-------------------------------------------------------------------------- -function [rec, Counter]=getOneSolutionRecord(fh, Level, Counter) -%-------------------------------------------------------------------------- -% Gets one record -Counter=Counter+1; -switch Level - case 0 - rec=getSolutionRoot(fh); - case 1 - rec=getSolution(fh); - case 2 - rec=getChemical(fh); - - otherwise - error('Unexpected Level'); -end - -end - -%-------------------------------------------------------------------------- -function p=getSolutionRoot(fh) -%-------------------------------------------------------------------------- -p.RoVersion=fread(fh, 1, 'int16=>int16'); % = 0; (* INT16 *) -p.RoDataBaseName=deblank(fread(fh, 80, 'uint8=>char')');% = 2; (* SolutionNameSize *) -p.RoSpare1=fread(fh, 1, 'int16=>int16');% = 82; (* INT16 *) -p.RoCRC=fread(fh, 1, 'int32=>int32'); % = 84; (* CARD32 *) -p.RootSize = 88;% = 88 - -p=orderfields(p); - -end - - -function s=getSolution(fh) -%-------------------------------------------------------------------------- -% Stimulus level -s.SoNumber=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) -s.SoName=deblank(fread(fh, 80, 'uint8=>char')');% = 4; (* SolutionNameSize *) -s.SoNumeric=fread(fh, 1, 'real*4=>double');% = 84; (* REAL *) *) -s.SoNumericName=deblank(fread(fh, 30, 'uint8=>char')');% = 88; (* ChemicalNameSize *) -s.SoPH=fread(fh, 1, 'real*4=>double');% = 118; (* REAL *) -s.SopHCompound=deblank(fread(fh, 30, 'uint8=>char')');% = 122; (* ChemicalNameSize *) -s.soOsmol=fread(fh, 1, 'real*4=>double'); %152; (* REAL *) -s.SoCRC=fread(fh, 1, 'int32=>int32') ;% = 156; (* CARD32 *) -s.SolutionSize=160;% = 160 - -s=orderfields(s); - -end - -%-------------------------------------------------------------------------- -function c=getChemical(fh) -%-------------------------------------------------------------------------- -c.ChConcentration=fread(fh, 1, 'real*4=>double');% = 0; (* REAL *) -c.ChName=deblank(fread(fh, 30, 'uint8=>char')');% = 4; (* ChemicalNameSize *) -c.ChSpare1=fread(fh, 1, 'int16=>int16');% = 34; (* INT16 *) -c.ChCRC=fread(fh, 1, 'int32=>int32')';% 36; (* CARD32 *) -c.ChemicalSize=40;% = 40 - -c=orderfields(c); - -end - - -%% GET STIMULUS TREE -%-------------------------------------------------------------------------- -function [Tree, Position, Counter, nchild]=getOneStimLevel(fh, Tree, Sizes, Level, Position, Counter) -%-------------------------------------------------------------------------- -% Gets one record of the tree and the number of children -[s, Counter]=getOneStimRecord(fh, Level, Counter); -Tree{Counter, Level+1}=s; -Position=Position+Sizes(Level+1); -fseek(fh, Position, 'bof'); -nchild=fread(fh, 1, 'int32=>int32'); -Position=ftell(fh); - -end - -%-------------------------------------------------------------------------- -function [rec, Counter]=getOneStimRecord(fh, Level, Counter) -%-------------------------------------------------------------------------- -% Gets one record -Counter=Counter+1; -switch Level - case 0 - rec=getStimRoot(fh); - case 1 - rec=getStimulation(fh); - case 2 - rec=getChannel(fh); - case 3 - rec=getStimSegment(fh); - otherwise - error('Unexpected Level'); -end - -end - -% The functions below return data as defined by the HEKA PatchMaster -% specification - -%-------------------------------------------------------------------------- -function p=getStimRoot(fh) -%-------------------------------------------------------------------------- -p.RoVersion=fread(fh, 1, 'int32=>int32'); -p.RoMark=fread(fh, 1, 'int32=>int32');% = 4; (* INT32 *) -p.RoVersionName=deblank(fread(fh, 32, 'uint8=>char')');% = 8; (* String32Type *) -p.RoMaxSamples=fread(fh, 1, 'int32=>int32'); % = 40; (* INT32 *) -p.RoFiller1 = fread(fh, 1, 'int32=>int32');% = 44; (* INT32 *) -p.RoParams = fread(fh, 10, 'double=>double');% = 48; (* ARRAY[0..9] OF LONGREAL *) -for k=1:10 - p.RoParamText{k}=deblank(fread(fh, 32, 'uint8=>char')');% = 128; (* ARRAY[0..9],[0..31]OF CHAR *) -end -p.RoReserved = fread(fh, 32, 'int32=>int32');% = 448; (* INT32 *) -p.RoFiller2= fread(fh, 1, 'int32=>int32');% = 576; (* INT32 *) -p.RoCRC= fread(fh, 1, 'int32=>int32');% = 580; (* CARD32 *) -p.RootRecSize= 584; % (* = 73 * 8 *) -p=orderfields(p); - -end - -%-------------------------------------------------------------------------- -function s=getStimulation(fh) -%-------------------------------------------------------------------------- -% Stimulus level -s.stMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) -s.stEntryName=deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Type *) -s.stFileName=deblank(fread(fh, 32, 'uint8=>char')');% = 36; (* String32Type *) -s.stAnalName=deblank(fread(fh, 32, 'uint8=>char')');% = 68; (* String32Type *) -s.stDataStartSegment=fread(fh, 1, 'int32=>int32');% = 100; (* INT32 *) -s.stDataStartTime=fread(fh, 1, 'double=>double') ;% = 104; (* LONGREAL *) -s.stDataStartTimeMATLAB=time2date(s.stDataStartTime); -s.stSampleInterval=fread(fh, 1, 'double=>double') ;% = 112; (* LONGREAL *) -s.stSweepInterval=fread(fh, 1, 'double=>double') ;% = 120; (* LONGREAL *) -s.stLeakDelay=fread(fh, 1, 'double=>double') ;% = 128; (* LONGREAL *) -s.stFilterFactor=fread(fh, 1, 'double=>double') ;% = 136; (* LONGREAL *) -s.stNumberSweeps=fread(fh, 1, 'int32=>int32');% = 144; (* INT32 *) -s.stNumberLeaks=fread(fh, 1, 'int32=>int32');% = 148; (* INT32 *) -s.stNumberAverages=fread(fh, 1, 'int32=>int32');% = 152; (* INT32 *) -s.stActualAdcChannels=fread(fh, 1, 'int32=>int32');% = 156; (* INT32 *) -s.stActualDacChannels=fread(fh, 1, 'int32=>int32');% = 160; (* INT32 *) -s.stExtTrigger=fread(fh, 1, 'uint8=>uint8');% = 164; (* BYTE *) -s.stNoStartWait=fread(fh, 1, 'uint8=>logical');% = 165; (* BOOLEAN *) -s.stUseScanRates=fread(fh, 1, 'uint8=>logical');% = 166; (* BOOLEAN *) -s.stNoContAq=fread(fh, 1, 'uint8=>logical');% = 167; (* BOOLEAN *) -s.stHasLockIn=fread(fh, 1, 'uint8=>logical');% = 168; (* BOOLEAN *) -s.stOldStartMacKind=fread(fh, 1, 'uint8=>char');% = 169; (* CHAR *) -s.stOldEndMacKind=fread(fh, 1, 'uint8=>logical');% = 170; (* BOOLEAN *) -s.stAutoRange=fread(fh, 1, 'uint8=>uint8');% = 171; (* BYTE *) -s.stBreakNext=fread(fh, 1, 'uint8=>logical');% = 172; (* BOOLEAN *) -s.stIsExpanded=fread(fh, 1, 'uint8=>logical');% = 173; (* BOOLEAN *) -s.stLeakCompMode=fread(fh, 1, 'uint8=>logical');% = 174; (* BOOLEAN *) -s.stHasChirp=fread(fh, 1, 'uint8=>logical');% = 175; (* BOOLEAN *) -s.stOldStartMacro=deblank(fread(fh, 32, 'uint8=>char')');% = 176; (* String32Type *) -s.stOldEndMacro=deblank(fread(fh, 32, 'uint8=>char')');% = 208; (* String32Type *) -s.sIsGapFree=fread(fh, 1, 'uint8=>logical');% = 240; (* BOOLEAN *) -s.sHandledExternally=fread(fh, 1, 'uint8=>logical');% = 241; (* BOOLEAN *) -s.stFiller1=fread(fh, 1, 'uint8=>logical');% = 242; (* BOOLEAN *) -s.stFiller2=fread(fh, 1, 'uint8=>logical');% = 243; (* BOOLEAN *) -s.stCRC=fread(fh, 1, 'int32=>int32'); % = 244; (* CARD32 *) -s.stTag=deblank(fread(fh, 32, 'uint8=>char')');% = 248; (* String32Type *) -s.StimulationRecSize = 280;% (* = 35 * 8 *) - -s=orderfields(s); - -end - -%-------------------------------------------------------------------------- -function c=getChannel(fh) -%-------------------------------------------------------------------------- -c.chMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) -c.chLinkedChannel=fread(fh, 1, 'int32=>int32');% = 4; (* INT32 *) -c.chCompressionFactor=fread(fh, 1, 'int32=>int32');% = 8; (* INT32 *) -c.chYUnit=deblank(fread(fh, 8, 'uint8=>char')');% = 12; (* String8Type *) -c.chAdcChannel=fread(fh, 1, 'int16=>int16');% = 20; (* INT16 *) -c.chAdcMode=fread(fh, 1, 'uint8=>uint8');% = 22; (* BYTE *) -c.chDoWrite=fread(fh, 1, 'uint8=>logical');% = 23; (* BOOLEAN *) -c.stLeakStore=fread(fh, 1, 'uint8=>uint8');% = 24; (* BYTE *) -c.chAmplMode=fread(fh, 1, 'uint8=>uint8');% = 25; (* BYTE *) -c.chOwnSegTime=fread(fh, 1, 'uint8=>logical');% = 26; (* BOOLEAN *) -c.chSetLastSegVmemb=fread(fh, 1, 'uint8=>logical');% = 27; (* BOOLEAN *) -c.chDacChannel=fread(fh, 1, 'int16=>int16');% = 28; (* INT16 *) -c.chDacMode=fread(fh, 1, 'uint8=>uint8');% = 30; (* BYTE *) -c.chHasLockInSquare=fread(fh, 1, 'uint8=>uint8');% = 31; (* BYTE *) -c.chRelevantXSegment=fread(fh, 1, 'int32=>int32');% = 32; (* INT32 *) -c.chRelevantYSegment=fread(fh, 1, 'int32=>int32');% = 36; (* INT32 *) -c.chDacUnit=deblank(fread(fh, 8, 'uint8=>char')');% = 40; (* String8Type *) -c.chHolding=fread(fh, 1, 'double=>double') ;% = 48; (* LONGREAL *) -c.chLeakHolding=fread(fh, 1, 'double=>double') ;% = 56; (* LONGREAL *) -c.chLeakSize=fread(fh, 1, 'double=>double') ;% = 64; (* LONGREAL *) -c.chLeakHoldMode=fread(fh, 1, 'uint8=>uint8');% = 72; (* BYTE *) -c.chLeakAlternate=fread(fh, 1, 'uint8=>logical');% = 73; (* BOOLEAN *) -c.chAltLeakAveraging=fread(fh, 1, 'uint8=>logical');% = 74; (* BOOLEAN *) -c.chLeakPulseOn=fread(fh, 1, 'uint8=>logical');% = 75; (* BOOLEAN *) -c.chStimToDacID=fread(fh, 1, 'int16=>int16');% = 76; (* SET16 *) -c.chCompressionMode=fread(fh, 1, 'int16=>int16');% = 78; (* SET16 *) -c.chCompressionSkip=fread(fh, 1, 'int32=>int32');% = 80; (* INT32 *) -c.chDacBit=fread(fh, 1, 'int16=>int16');% = 84; (* INT16 *) -c.chHasLockInSine=fread(fh, 1, 'uint8=>logical');% = 86; (* BOOLEAN *) -c.chBreakMode=fread(fh, 1, 'uint8=>uint8');% = 87; (* BYTE *) -c.chZeroSeg=fread(fh, 1, 'int32=>int32');% = 88; (* INT32 *) -c.chFiller1=fread(fh, 1, 'int32=>int32');% = 92; (* INT32 *) -c.chSine_Cycle=fread(fh, 1, 'double=>double') ;% = 96; (* LONGREAL *) -c.chSine_Amplitude=fread(fh, 1, 'double=>double') ;% = 104; (* LONGREAL *) -c.chLockIn_VReversal=fread(fh, 1, 'double=>double') ;% = 112; (* LONGREAL *) -c.chChirp_StartFreq=fread(fh, 1, 'double=>double') ;% = 120; (* LONGREAL *) -c.chChirp_EndFreq=fread(fh, 1, 'double=>double') ;% = 128; (* LONGREAL *) -c.chChirp_MinPoints=fread(fh, 1, 'double=>double') ;% = 136; (* LONGREAL *) -c.chSquare_NegAmpl=fread(fh, 1, 'double=>double') ;% = 144; (* LONGREAL *) -c.chSquare_DurFactor=fread(fh, 1, 'double=>double') ;% = 152; (* LONGREAL *) -c.chLockIn_Skip=fread(fh, 1, 'int32=>int32');% = 160; (* INT32 *) -c.chPhoto_MaxCycles=fread(fh, 1, 'int32=>int32');% = 164; (* INT32 *) -c.chPhoto_SegmentNo=fread(fh, 1, 'int32=>int32');% = 168; (* INT32 *) -c.chLockIn_AvgCycles=fread(fh, 1, 'int32=>int32');% = 172; (* INT32 *) -c.chImaging_RoiNo=fread(fh, 1, 'int32=>int32');% = 176; (* INT32 *) -c.chChirp_Skip=fread(fh, 1, 'int32=>int32');% = 180; (* INT32 *) -c.chChirp_Amplitude=fread(fh, 1, 'double=>double') ;% = 184; (* LONGREAL *) -c.chPhoto_Adapt=fread(fh, 1, 'uint8=>uint8');% = 192; (* BYTE *) -c.chSine_Kind=fread(fh, 1, 'uint8=>uint8');% = 193; (* BYTE *) -c.chChirp_PreChirp=fread(fh, 1, 'uint8=>uint8');% = 194; (* BYTE *) -c.chSine_Source=fread(fh, 1, 'uint8=>uint8');% = 195; (* BYTE *) -c.chSquare_NegSource=fread(fh, 1, 'uint8=>uint8');% = 196; (* BYTE *) -c.chSquare_PosSource=fread(fh, 1, 'uint8=>uint8');% = 197; (* BYTE *) -c.chChirp_Kind=fread(fh, 1, 'uint8=>uint8');% = 198; (* BYTE *) -c.chChirp_Source=fread(fh, 1, 'uint8=>uint8');% = 199; (* BYTE *) -c.chDacOffset=fread(fh, 1, 'double=>double') ;% = 200; (* LONGREAL *) -c.chAdcOffset=fread(fh, 1, 'double=>double') ;% = 208; (* LONGREAL *) -c.chTraceMathFormat=fread(fh, 1, 'uint8=>uint8');% = 216; (* BYTE *) -c.chHasChirp=fread(fh, 1, 'uint8=>logical');% = 217; (* BOOLEAN *) -c.chSquare_Kind=fread(fh, 1, 'uint8=>uint8');% = 218; (* BYTE *) -c.chFiller2=fread(fh,13,'uint8=>char');% = 219; (* ARRAY[0..13] OF CHAR *) -c.chSquare_Cycle=fread(fh, 1, 'double=>double') ;% = 232; (* LONGREAL *) -c.chSquare_PosAmpl=fread(fh, 1, 'double=>double') ;% = 240; (* LONGREAL *) -c.chCompressionOffset=fread(fh, 1, 'int32=>int32');% = 248; (* INT32 *) -c.chPhotoMode=fread(fh, 1, 'int32=>int32');% = 252; (* INT32 *) -c.chBreakLevel=fread(fh, 1, 'double=>double') ;% = 256; (* LONGREAL *) -c.chTraceMath=deblank(fread(fh,128,'uint8=>char')');% = 264; (* String128Type *) -c.chOldCRC=fread(fh, 1, 'int32=>int32');% = 268; (* CARD32 *) -c.chFiller3=fread(fh, 1, 'int32=>int32');% = 392; (* INT32 *) -c.chCRC=fread(fh, 1, 'int32=>int32');% = 396; (* CARD32 *) -c.ChannelRecSize = 400;% (* = 50 * 8 *) -c=orderfields(c); - -end - -%-------------------------------------------------------------------------- -function ss=getStimSegment(fh) -%-------------------------------------------------------------------------- -ss.seMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) -ss.seClass=fread(fh, 1, 'uint8=>uint8');% = 4; (* BYTE *) -ss.seDoStore=fread(fh, 1, 'uint8=>logical');% = 5; (* BOOLEAN *) -ss.seVoltageIncMode=fread(fh, 1, 'uint8=>uint8');% = 6; (* BYTE *) -ss.seDurationIncMode=fread(fh, 1, 'uint8=>uint8');% = 7; (* BYTE *) -ss.seVoltage=fread(fh, 1, 'double=>double');% = 8; (* LONGREAL *) -ss.seVoltageSource=fread(fh, 1, 'int32=>int32');% = 16; (* INT32 *) -ss.seDeltaVFactor=fread(fh, 1, 'double=>double');% = 20; (* LONGREAL *) -ss.seDeltaVIncrement=fread(fh, 1, 'double=>double');% = 28; (* LONGREAL *) -ss.seDuration=fread(fh, 1, 'double=>double');% = 36; (* LONGREAL *) -ss.seDurationSource=fread(fh, 1, 'int32=>int32');% = 44; (* INT32 *) -ss.seDeltaTFactor=fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) -ss.seDeltaTIncrement=fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) -ss.seFiller1=fread(fh, 1, 'int32=>int32');% = 64; (* INT32 *) -ss.seCRC=fread(fh, 1, 'int32=>int32');% = 68; (* CARD32 *) -ss.seScanRate=fread(fh, 1, 'double=>double');% = 72; (* LONGREAL *) -ss.StimSegmentRecSize = 80;% (* = 10 * 8 *) -ss=orderfields(ss); - -end - - - -%% GET AMPLIFIER DATA -%-------------------------------------------------------------------------- -function L=getSeLockInParams(fh) -%-------------------------------------------------------------------------- -offset=ftell(fh); -L.loExtCalPhase=fread(fh, 1, 'double=>double') ;% = 0; (* LONGREAL *) -L.loExtCalAtten=fread(fh, 1, 'double=>double') ;% = 8; (* LONGREAL *) -L.loPLPhase=fread(fh, 1, 'double=>double') ;% = 16; (* LONGREAL *) -L.loPLPhaseY1=fread(fh, 1, 'double=>double') ;% = 24; (* LONGREAL *) -L.loPLPhaseY2=fread(fh, 1, 'double=>double') ;% = 32; (* LONGREAL *) -L.loUsedPhaseShift=fread(fh, 1, 'double=>double') ;% = 40; (* LONGREAL *) -L.loUsedAttenuation=fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) -L.loFiller1=fread(fh, 1, 'double=>double'); -L.loExtCalValid=fread(fh, 1, 'uint8=>logical') ;% = 64; (* BOOLEAN *) -L.loPLPhaseValid=fread(fh, 1, 'uint8=>logical') ;% = 65; (* BOOLEAN *) -L.loLockInMode=fread(fh, 1, 'uint8=>uint8') ;% = 66; (* BYTE *) -L.loCalMode=fread(fh, 1, 'uint8=>uint8') ;% = 67; (* BYTE *) -L.LockInParamsSize=96; -fseek(fh, offset+L.LockInParamsSize, 'bof'); - -end - -%-------------------------------------------------------------------------- -function A=getAmplifierState(fh) -%-------------------------------------------------------------------------- -offset=ftell(fh); -A.E9StateVersion=fread(fh, 1, 'double=>double');% = 0; (* 8 = SizeStateVersion *) -A.E9RealCurrentGain=fread(fh, 1, 'double=>double');% = 8; (* LONGREAL *) -A.E9RealF2Bandwidth=fread(fh, 1, 'double=>double');% = 16; (* LONGREAL *) -A.E9F2Frequency=fread(fh, 1, 'double=>double');% = 24; (* LONGREAL *) -A.E9RsValue=fread(fh, 1, 'double=>double');% = 32; (* LONGREAL *) -A.E9RsFraction=fread(fh, 1, 'double=>double');% = 40; (* LONGREAL *) -A.E9GLeak=fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) -A.E9CFastAmp1=fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) -A.E9CFastAmp2=fread(fh, 1, 'double=>double');% = 64; (* LONGREAL *) -A.E9CFastTau=fread(fh, 1, 'double=>double');% = 72; (* LONGREAL *) -A.E9CSlow=fread(fh, 1, 'double=>double');% = 80; (* LONGREAL *) -A.E9GSeries=fread(fh, 1, 'double=>double');% = 88; (* LONGREAL *) -A.E9StimDacScale=fread(fh, 1, 'double=>double');% = 96; (* LONGREAL *) -A.E9CCStimScale=fread(fh, 1, 'double=>double');% = 104; (* LONGREAL *) -A.E9VHold=fread(fh, 1, 'double=>double');% = 112; (* LONGREAL *) -A.E9LastVHold=fread(fh, 1, 'double=>double');% = 120; (* LONGREAL *) -A.E9VpOffset=fread(fh, 1, 'double=>double');% = 128; (* LONGREAL *) -A.E9VLiquidJunction=fread(fh, 1, 'double=>double');% = 136; (* LONGREAL *) -A.E9CCIHold=fread(fh, 1, 'double=>double');% = 144; (* LONGREAL *) -A.E9CSlowStimVolts=fread(fh, 1, 'double=>double');% = 152; (* LONGREAL *) -A.E9CCtr.TrackVHold=fread(fh, 1, 'double=>double');% = 160; (* LONGREAL *) -A.E9TimeoutLength=fread(fh, 1, 'double=>double');% = 168; (* LONGREAL *) -A.E9SearchDelay=fread(fh, 1, 'double=>double');% = 176; (* LONGREAL *) -A.E9MConductance=fread(fh, 1, 'double=>double');% = 184; (* LONGREAL *) -A.E9MCapacitance=fread(fh, 1, 'double=>double');% = 192; (* LONGREAL *) -A.E9SerialNumber=fread(fh, 1, 'double=>double');% = 200; (* 8 = SizeSerialNumber *) -A.E9E9Boards=fread(fh, 1, 'int16=>int16');% = 208; (* INT16 *) -A.E9CSlowCycles=fread(fh, 1, 'int16=>int16');% = 210; (* INT16 *) -A.E9IMonAdc=fread(fh, 1, 'int16=>int16');% = 212; (* INT16 *) -A.E9VMonAdc=fread(fh, 1, 'int16=>int16');% = 214; (* INT16 *) -A.E9MuxAdc=fread(fh, 1, 'int16=>int16');% = 216; (* INT16 *) -A.E9TstDac=fread(fh, 1, 'int16=>int16');% = 218; (* INT16 *) -A.E9StimDac=fread(fh, 1, 'int16=>int16');% = 220; (* INT16 *) -A.E9StimDacOffset=fread(fh, 1, 'int16=>int16');% = 222; (* INT16 *) -A.E9MaxDigitalBit=fread(fh, 1, 'int16=>int16');% = 224; (* INT16 *) -A.E9SpareInt1=fread(fh, 1, 'int16=>int16');% = 226; (* INT16 *) -A.E9SpareInt2=fread(fh, 1, 'int16=>int16');% = 228; (* INT16 *) -A.E9SpareInt3=fread(fh, 1, 'int16=>int16');% = 230; (* INT16 *) - -A.E9AmplKind=fread(fh, 1, 'uint8=>uint8');% = 232; (* BYTE *) -A.E9IsEpc9N=fread(fh, 1, 'uint8=>uint8');% = 233; (* BYTE *) -A.E9ADBoard=fread(fh, 1, 'uint8=>uint8');% = 234; (* BYTE *) -A.E9BoardVersion=fread(fh, 1, 'uint8=>uint8');% = 235; (* BYTE *) -A.E9ActiveE9Board=fread(fh, 1, 'uint8=>uint8');% = 236; (* BYTE *) -A.E9Mode=fread(fh, 1, 'uint8=>uint8');% = 237; (* BYTE *) -A.E9Range=fread(fh, 1, 'uint8=>uint8');% = 238; (* BYTE *) -A.E9F2Response=fread(fh, 1, 'uint8=>uint8');% = 239; (* BYTE *) - -A.E9RsOn=fread(fh, 1, 'uint8=>uint8');% = 240; (* BYTE *) -A.E9CSlowRange=fread(fh, 1, 'uint8=>uint8');% = 241; (* BYTE *) -A.E9CCRange=fread(fh, 1, 'uint8=>uint8');% = 242; (* BYTE *) -A.E9CCGain=fread(fh, 1, 'uint8=>uint8');% = 243; (* BYTE *) -A.E9CSlowToTstDac=fread(fh, 1, 'uint8=>uint8');% = 244; (* BYTE *) -A.E9StimPath=fread(fh, 1, 'uint8=>uint8');% = 245; (* BYTE *) -A.E9CCtr.TrackTau=fread(fh, 1, 'uint8=>uint8');% = 246; (* BYTE *) -A.E9WasClipping=fread(fh, 1, 'uint8=>uint8');% = 247; (* BYTE *) - -A.E9RepetitiveCSlow=fread(fh, 1, 'uint8=>uint8');% = 248; (* BYTE *) -A.E9LastCSlowRange=fread(fh, 1, 'uint8=>uint8');% = 249; (* BYTE *) -A.E9Locked=fread(fh, 1, 'uint8=>uint8');% = 250; (* BYTE *) -A.E9CanCCFast=fread(fh, 1, 'uint8=>uint8');% = 251; (* BYTE *) -A.E9CanLowCCRange=fread(fh, 1, 'uint8=>uint8');% = 252; (* BYTE *) -A.E9CanHighCCRange=fread(fh, 1, 'uint8=>uint8');% = 253; (* BYTE *) -A.E9CanCCtr.Tracking=fread(fh, 1, 'uint8=>uint8');% = 254; (* BYTE *) -A.E9HasVmonPath=fread(fh, 1, 'uint8=>uint8');% = 255; (* BYTE *) - -A.E9HasNewCCMode=fread(fh, 1, 'uint8=>uint8');% = 256; (* BYTE *) -A.E9Selector=fread(fh, 1, 'uint8=>char');% = 257; (* CHAR *) -A.E9HoldInverted=fread(fh, 1, 'uint8=>uint8');% = 258; (* BYTE *) -A.E9AutoCFast=fread(fh, 1, 'uint8=>uint8');% = 259; (* BYTE *) -A.E9AutoCSlow=fread(fh, 1, 'uint8=>uint8');% = 260; (* BYTE *) -A.E9HasVmonX100=fread(fh, 1, 'uint8=>uint8');% = 261; (* BYTE *) -A.E9TestDacOn=fread(fh, 1, 'uint8=>uint8');% = 262; (* BYTE *) -A.E9QMuxAdcOn=fread(fh, 1, 'uint8=>uint8');% = 263; (* BYTE *) - -A.E9RealImon1Bandwidth=fread(fh, 1, 'double=>double');% = 264; (* LONGREAL *) -A.E9StimScale=fread(fh, 1, 'double=>double');% = 272; (* LONGREAL *) - -A.E9Gain=fread(fh, 1, 'uint8=>uint8');% = 280; (* BYTE *) -A.E9Filter1=fread(fh, 1, 'uint8=>uint8');% = 281; (* BYTE *) -A.E9StimFilterOn=fread(fh, 1, 'uint8=>uint8');% = 282; (* BYTE *) -A.E9RsSlow=fread(fh, 1, 'uint8=>uint8');% = 283; (* BYTE *) -A.E9Old1=fread(fh, 1, 'uint8=>uint8');% = 284; (* BYTE *) -A.E9CCCFastOn=fread(fh, 1, 'uint8=>uint8');% = 285; (* BYTE *) -A.E9CCFastSpeed=fread(fh, 1, 'uint8=>uint8');% = 286; (* BYTE *) -A.E9F2Source=fread(fh, 1, 'uint8=>uint8');% = 287; (* BYTE *) - -A.E9TestRange=fread(fh, 1, 'uint8=>uint8');% = 288; (* BYTE *) -A.E9TestDacPath=fread(fh, 1, 'uint8=>uint8');% = 289; (* BYTE *) -A.E9MuxChannel=fread(fh, 1, 'uint8=>uint8');% = 290; (* BYTE *) -A.E9MuxGain64=fread(fh, 1, 'uint8=>uint8');% = 291; (* BYTE *) -A.E9VmonX100=fread(fh, 1, 'uint8=>uint8');% = 292; (* BYTE *) -A.E9IsQuadro=fread(fh, 1, 'uint8=>uint8');% = 293; (* BYTE *) -A.E9SpareBool4=fread(fh, 1, 'uint8=>uint8');% = 294; (* BYTE *) -A.E9SpareBool5=fread(fh, 1, 'uint8=>uint8');% = 295; (* BYTE *) - -A.E9StimFilterHz=fread(fh, 1, 'double=>double');% = 296; (* LONGREAL *) -A.E9RsTau=fread(fh, 1, 'double=>double');% = 304; (* LONGREAL *) -A.E9FilterOffsetDac=fread(fh, 1, 'int16=>int16');% = 312; (* INT16 *) -A.E9ReferenceDac=fread(fh, 1, 'int16=>int16');% = 314; (* INT16 *) -A.E9SpareInt6=fread(fh, 1, 'int16=>int16');% = 316; (* INT16 *) -A.E9SpareInt7=fread(fh, 1, 'int16=>int16');% = 318; (* INT16 *) -A.E9Spares1=320; - -A.E9CalibDate=fread(fh, 2, 'double=>double');% = 344; (* 16 = SizeCalibDate *) -A.E9SelHold=fread(fh, 1, 'double=>double');% = 360; (* LONGREAL *) -A.AmplifierStateSize = 400; -fseek(fh, offset+A.AmplifierStateSize, 'bof'); - -end - -%-------------------------------------------------------------------------- -function matData2=LocalImportGroup(fh, dataTree, grp, grp_row) -%-------------------------------------------------------------------------- -% Create a structure for the series headers - - -% Pad the indices for last series of last group -grp_row(end+1)=size(dataTree,1); - -% Collect the series headers and row numbers for this group into a -% structure array -[ser_s, ser_row, nseries]=getSeriesHeaders(dataTree, grp_row, grp); - -% Pad for last series -ser_row(nseries+1)=grp_row(grp+1); - -dataoffsets=[]; -% Create the channels - -matData2 = cell(nseries,1); -for ser=1:nseries - - [sw_s, sw_row, nsweeps]=getSweepHeaders(dataTree, ser_row, ser); - - % Make sure the sweeps are in temporal sequence - if any(diff(cell2mat({sw_s.SwTime}))<=0) - % TODO: sort them if this can ever happen. - % For the moment just throw an error - error('Sweeps not in temporal sequence'); - end - - - sw_row(nsweeps+1)=ser_row(ser+1); - % Get the trace headers for this sweep - [tr_row]=getTraceHeaders(dataTree, sw_row); - - - for k=1:size(tr_row, 1) - - [tr_s, isConstantScaling, isConstantFormat, isFramed]=LocalCheckEntries(dataTree, tr_row, k); - - % TODO: Need a better way to do this - % Check whether interleaving is supported with this file version - % Note: HEKA added interleaving Jan 2011. - % TrInterleaveSkip was previously in a filler block, so should always - % be zero with older files. - if tr_s(1).TrInterleaveSize>0 && tr_s(1).TrInterleaveSkip>0 - INTERLEAVE_SUPPORTED=true; - else - INTERLEAVE_SUPPORTED=false; - end - - data=zeros(max(cell2mat({tr_s.TrDataPoints})), size(tr_row,2)); - - for tr=1:size(tr_row,2) - % Disc format - [fmt, nbytes]=LocalFormatToString(tr_s(tr).TrDataFormat); - % Always read into double - readfmt=[fmt '=>double']; - % Skip to start of the data - fseek(fh, dataTree{tr_row(k,tr),5}.TrData, 'bof'); - % Store data offset for later error checks - dataoffsets(end+1)=dataTree{tr_row(k,tr),5}.TrData; %#ok - % Read the data - if ~INTERLEAVE_SUPPORTED || dataTree{tr_row(k,tr),5}.TrInterleaveSize==0 - [data(1:dataTree{tr_row(k,tr),5}.TrDataPoints, tr)]=... - fread(fh, double(dataTree{tr_row(k,tr),5}.TrDataPoints), readfmt); - else - offset=1; - nelements= double(dataTree{tr_row(k,tr),5}.TrInterleaveSize/nbytes); - for nread=1:floor(numel(data)/double(dataTree{tr_row(k,tr),5}.TrInterleaveSize/nbytes)) - [data(offset:offset+nelements-1), N]=fread(fh, nelements, readfmt); - if (N - ser_row(nseries+1)=k; %#ok - nseries=nseries+1; - end -end -return -end - -%-------------------------------------------------------------------------- -function [sw_s, sw_row, nsweeps]=getSweepHeaders(tree, ser_row, ser) -%-------------------------------------------------------------------------- -nsweeps=0; -for k=ser_row(ser)+1:ser_row(ser+1) - if ~isempty(tree{k, 4}) - sw_s(nsweeps+1)=tree{k, 4}; %#ok - sw_row(nsweeps+1)=k; %#ok - nsweeps=nsweeps+1; - end -end -return -end - -%-------------------------------------------------------------------------- -function [tr_row, ntrace]=getTraceHeaders(tree, sw_row) -%-------------------------------------------------------------------------- -ntrace=0; -m=1; -n=1; -for k=sw_row(1)+1:sw_row(end) - if ~isempty(tree{k, 5}) - %tr_s(m,n)=tree{k, 5}; %#ok - tr_row(m,n)=k; %#ok - ntrace=ntrace+1; - m=m+1; - else - m=1; - n=n+1; - end -end -return -end - - -%-------------------------------------------------------------------------- -function [tr_s, isConstantScaling, isConstantFormat, isFramed]=LocalCheckEntries(tree, tr_row, k) -%-------------------------------------------------------------------------- -% Check units are the same for all traces -tr_s=[tree{tr_row(k, :),5}]; - - -if numel(unique({tr_s.TrYUnit}))>1 - error('1002: Waveform units are not constant'); -end - -if numel(unique({tr_s.TrXUnit}))>1 - error('1003: Time units are not constant'); -end - -if numel(unique(cell2mat({tr_s.TrXInterval})))~=1 - error('1004: Unequal sample intervals'); -end - -% Other unexpected conditions - give user freedom to create these but warn -% about them -if numel(unique({tr_s.TrLabel}))>1 - warning('LocalCheckEntries:w2001', 'Different trace labels'); -end - -if numel(unique(cell2mat({tr_s.TrAdcChannel})))>1 - warning('LocalCheckEntries:w2002', 'Data collected from different ADC channels'); -end - -if numel(unique(cell2mat({tr_s.TrRecordingMode})))>1 - warning('LocalCheckEntries:w2003', 'Traces collected using different recording modes'); -end - -if numel(unique(cell2mat({tr_s.TrCellPotential})))>1 - warning('LocalCheckEntries:w2004', 'Traces collected using different Em'); -end - -% Check scaling factor is constant -ScaleFactor=unique(cell2mat({tr_s.TrDataScaler})); -if numel(ScaleFactor)==1 - isConstantScaling=true; -else - isConstantScaling=false; -end - - -%... and data format -if numel(unique(cell2mat({tr_s.TrDataFormat})))==1 - isConstantFormat=true; -else - isConstantFormat=false; -end - -% Do we have constant epoch lengths and offsets? -if numel(unique(cell2mat({tr_s.TrDataPoints})))==1 &&... - numel(unique(cell2mat({tr_s.TrTimeOffset })))==1 - isFramed=true; -else - isFramed=false; -end -return -end - -%-------------------------------------------------------------------------- -function str=time2date(t) -%-------------------------------------------------------------------------- -t=t-1580970496; -if t<0 - t=t+4294967296; -end -t=t+9561652096; -str=datestr(t/(24*60*60)+datenum(1601,1,1)); -return -end -%-------------------------------------------------------------------------- \ No newline at end of file diff --git a/@HEKA_Importer/HI_extractHEKADataTree.asv b/@HEKA_Importer/HI_extractHEKADataTree.asv deleted file mode 100644 index 7f35e82..0000000 --- a/@HEKA_Importer/HI_extractHEKADataTree.asv +++ /dev/null @@ -1,253 +0,0 @@ -function HI_extractHEKADataTree(obj) - -% Function to extract parameters from the HEKA data tree and sort them -% according to the recordings. -% Takes HEKA_IMPORTER object as input and creates RecTable -% containing the recording parameters for each recording/series. -% -% See also HEKA_Importer -% HEKA_Importer.HI_loadHEKAFile -% HEKA_Importer.HI_ImportHEKAtoMat -% HEKA_Importer.HI_extractHEKASolutionTree -% HEKA_Importer.HI_extractHEKAStimTree - -%1: Root -%2: Group/Experiment -%3: Series/Recording number -%4: Sweep -%5: Trace/Channel - -%check if datetime functions exist - -if ~isempty(which('datetime')) && ~isempty(which('NaT')) - hasDateTime = true; -else - hasDateTime = false; -end - - - -dataTree = obj.trees.dataTree; - -allExp = find(~cellfun(@isempty,dataTree(:,2))); -nExperiments = numel(allExp); - -Rt = cell(nExperiments,1); - -for iExp = 1:nExperiments - if iExp == nExperiments - nextExp = size(dataTree,1)+1; - else - nextExp = allExp(iExp+1); - end - Rt{iExp} = ImportRecordings(dataTree,allExp(iExp),nextExp,iExp,hasDateTime); -end - -obj.RecTable = [vertcat(Rt{:}),obj.RecTable]; - - - -end - - - -function RecTab = ImportRecordings(dataTree,thisExpID,nextExpID,ExpNum,hasDateTime) - - -% RESORT STRUCTURES TO ALSO CONTAIN SWEEP AND TRACE/CHANNEL INFORMATION -recIDs = find(~cellfun(@isempty,dataTree(:,3))); -recIDs = recIDs(recIDs>thisExpID & recIDs1 - traceEnd = [sweepIDs(2:end)-1;size(dataTree,1)]; -else - traceEnd = size(dataTree,1); -end - -for iS = 1:numel(sweepIDs) - Sweeps(iS) = dataTree{sweepIDs(iS),1}; - Sweeps(iS).Traces = [dataTree{traceSt(iS):traceEnd(iS),2}]; -end - - - -end - - - - From 6a5aea89fa3594cd6a859c9bc19e0456ec12a5ba Mon Sep 17 00:00:00 2001 From: ChristianKeine Date: Fri, 21 Jun 2019 14:14:16 -0500 Subject: [PATCH 08/39] Update HI_ImportHEKAtoMat.m --- @HEKA_Importer/HI_ImportHEKAtoMat.m | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/@HEKA_Importer/HI_ImportHEKAtoMat.m b/@HEKA_Importer/HI_ImportHEKAtoMat.m index 1ade0ec..7acc0d2 100644 --- a/@HEKA_Importer/HI_ImportHEKAtoMat.m +++ b/@HEKA_Importer/HI_ImportHEKAtoMat.m @@ -353,14 +353,28 @@ sw.SwMarkers=fread(fh, 4, 'double=>double');% = 120; (* ARRAY[0..3] OF LONGREAL *) sw.SwFiller2=fread(fh, 1, 'int32=>int32');% = 152; (* INT32 *) sw.SwCRC=fread(fh, 1, 'int32=>int32');% = 156; (* CARD32 *) -sw.SweepRecSize = 160;% (* = 20 * 8 *) +sw.SwSwHolding = fread(fh,16,'double=>double');% = 160; (* ARRAY[0..15] OF LONGREAL, see SwHoldingNo *) +sw.SweepRecSize = 288;% (* = 36*8) +% % added in v1000 +% sw.SwSwUserParamEx = fread(fh,8,'double=>double'); % = (* ARRAY[0..7] OF LONGREAL *) +% sw.SweepRecSize = 352;% (* = 36*8) + + + + sw=orderfields(sw); sw.Traces = []; % used to store all the traces/channels within the sweep structure later on + + + end %-------------------------------------------------------------------------- function tr=getTrace(fh) %-------------------------------------------------------------------------- + +% identical between v9 and v1000 + tr.TrMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) tr.TrLabel=deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Type *) tr.TrTraceCount=fread(fh, 1, 'int32=>int32');% = 36; (* INT32 *) @@ -431,7 +445,6 @@ tr.TrExtSolName = deblank(fread(fh, 32, 'uint8=>char')');% = 472; (* String32Size *) tr.TrDataPedestal = fread(fh, 1, 'double=>double');% = 504; (* LONGREAL *) - tr.TraceRecSize=512; tr=orderfields(tr); From 3fa627a2e9a42b3d0a36ed79d6a8551381e587a1 Mon Sep 17 00:00:00 2001 From: ChristianKeine Date: Fri, 21 Jun 2019 14:23:49 -0500 Subject: [PATCH 09/39] Update HI_ImportHEKAtoMat.m --- @HEKA_Importer/HI_ImportHEKAtoMat.m | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/@HEKA_Importer/HI_ImportHEKAtoMat.m b/@HEKA_Importer/HI_ImportHEKAtoMat.m index 7acc0d2..ac6ffef 100644 --- a/@HEKA_Importer/HI_ImportHEKAtoMat.m +++ b/@HEKA_Importer/HI_ImportHEKAtoMat.m @@ -495,6 +495,14 @@ p=orderfields(p); +% in v1000: +% (* RootRecord = RECORD *) +% RoVersion = 0; (* INT32 *) +% RoDataBaseName = 4; (* SolutionNameSize *) +% RoCRC = 84; (* CARD32 *) +% RootSize = 88; + + end From 59f598dc604f8d067edc95a199d4335f001fceef Mon Sep 17 00:00:00 2001 From: ChristianKeine Date: Sun, 23 Jun 2019 11:21:28 -0500 Subject: [PATCH 10/39] reorganizing HEKA readout starting to make v1000 compatible --- @HEKA_Importer/HI_ImportHEKAtoMat.asv | 1148 +++++++++++++++++++++++++ @HEKA_Importer/HI_ImportHEKAtoMat.m | 53 +- 2 files changed, 1175 insertions(+), 26 deletions(-) create mode 100644 @HEKA_Importer/HI_ImportHEKAtoMat.asv diff --git a/@HEKA_Importer/HI_ImportHEKAtoMat.asv b/@HEKA_Importer/HI_ImportHEKAtoMat.asv new file mode 100644 index 0000000..3c03e63 --- /dev/null +++ b/@HEKA_Importer/HI_ImportHEKAtoMat.asv @@ -0,0 +1,1148 @@ +function obj=HI_ImportHEKAtoMat(obj) +% ImportHEKA imports HEKA PatchMaster and ChartMaster .DAT files +% Filepath is taken from the input object. +% +% ImportHEKA has been tested with Windows generated .DAT files on Windows, +% Linux and Mac OS10.4. +% +% Both bundled and unbundled data files are supported. If your files are +% unbundled, they must all be in the same folder. +% +% Details of the HEKA file format are available from +% ftp://server.hekahome.de/pub/FileFormat/Patchmasterv9/ +% +%-------------------------------------------------------------------------- +% Author: Malcolm Lidierth 12/09 +% Copyright © The Author & King's College London 2009- +%-------------------------------------------------------------------------- + +% Revisions +% 17.04.10 TrXUnit: see within +% 28.11.11 TrXUnit: see within +% 15.08.12 Updated to support interleaved channels and PatchMaster 2.60 +% files dated 24-Jan-2011 onwards. +% 19.05.13 Modified by Samata Katta to output Matlab variable containing data +% 12.08.15 Don't save *.kcl file (line 793 commented out). +% 03.07.17 Modified by Samata Katta to read in stimulus parameters from +% .pgf section of .dat file. +% 01.01.2019 Modified by Christian Keine to read solution parameters from +% .sol section of .dat file. +% 04.02.2019: combine readout of dataTree, stimTree and solTree. +% +% See also HEKA_Importer +% HEKA_Importer.HI_loadHEKAFile +% HEKA_Importer.HI_extractHEKASolutionTree +% HEKA_Importer.HI_extractHEKAStimTree +% HEKA_Importer.HI_extractHEKADataTree + + + +[pathname, filename, ext]=fileparts(obj.opt.filepath); + +% Open file and get bundle header. Assume little-endian to begin with +endian='ieee-le'; +fh=fopen(obj.opt.filepath, 'r', endian); +[bundle, littleendianflag, isBundled]=getBundleHeader(fh); + +% Big endian so repeat process +if ~isempty(littleendianflag) && littleendianflag==false + fclose(fh); + endian='ieee-be'; + fh=fopen(obj.opt.filepath, 'r', endian); + bundle=getBundleHeader(fh); +end + +%% GET DATA, STIM AND SOLUTION TREE + +fileExt = {'.pul','.pgf','.sol'}; +treeName = {'dataTree','stimTree','solTree'}; + +for iidx = fileExt + fileExist = true; + if isBundled + % ext = {'.dat','.pul','.pgf','.amp','.sol',[],[],'.mrk','.mth','.onl'}; + ext={bundle.oBundleItems.oExtension}; + % Find the section of the dat file + idx=strcmp(iidx, ext);%15.08.2012 - change from strmatch + if any(idx) % check if section exists, e.g. will be empty when solution base was not active during recordings + start=bundle.oBundleItems(idx).oStart; + else + fileExist = false; + end + else + % Or open pulse file if not bundled + fclose(fh); + start=0; + fh=fopen(fullfile(pathname, [filename, iidx{1}]), 'r', endian); + if fh<0 + fileExist = false; + end + end + + % READ OUT TREE + if fileExist + fseek(fh, start, 'bof'); + Magic = fread(fh, 4, 'uint8=>char'); + Levels=fread(fh, 1, 'int32=>int32'); + Sizes=fread(fh, double(Levels), 'int32=>int32'); + Position=ftell(fh); + + % Get the tree structures form the file sections + obj.trees.(treeName{strcmp(iidx, fileExt)})=getTree(fh, Sizes, Position, iidx{1}); + else + obj.trees.(treeName{strcmp(iidx, fileExt)}) = []; + end +end + +%% GET DATA +if isBundled + % Set offset for data + idx=strcmp('.dat', ext);%15.08.2012 - change from strmatch + start=bundle.oBundleItems(idx).oStart; +else + % Or open data file if not bundled + fclose(fh); + fh=fopen(obj.opt.filepath, 'r', endian); + start=bundle.BundleHeaderSize; +end + +% Now set pointer to the start of the data the data +fseek(fh, start, 'bof'); + +% Get the group headers into a structure array +ngroup=1; +for k=1:size(obj.trees.dataTree,1) + if ~isempty(obj.trees.dataTree{k, 2}) + grp_row(ngroup)=k; %#ok + ngroup=ngroup+1; + end +end + +% ADD MINIMUM RANDOM NUMBER TO AVOID DISCRETIZATION; ADD TO ALL CHANNELS +addEPS = @(x) x+randn(size(x))*eps; + +% For each group +matData2 = cell(numel(grp_row),1); +dataRaw = cell(numel(grp_row),1); + +for iGr = 1:numel(grp_row) + matData2{iGr}=LocalImportGroup(fh, obj.trees.dataTree, iGr, grp_row); + + for iSer = 1:numel(matData2{iGr}) + dataRaw{iGr,:}{iSer,:} = cellfun(addEPS,matData2{iGr}{iSer},'UniformOutput',false); + end + +end + +obj.RecTable.dataRaw = vertcat(dataRaw{:}); +obj.RecTable = struct2table(obj.RecTable); + +end + +%-------------------------------------------------------------------------- +function [h, littleendianflag, isBundled]=getBundleHeader(fh) +%-------------------------------------------------------------------------- +% Get the bundle header from a HEKA .dat file +fseek(fh, 0, 'bof'); +h.oSignature=deblank(fread(fh, 8, 'uint8=>char')'); +switch h.oSignature + case 'DATA' + % Old format: nothing to do + h.oVersion=[]; + h.oTime=[]; + h.oItems=[]; + h.oIsLittleEndian=[]; + h.oBundleItems(1:12)=[]; + h.BundleHeaderSize=0; + isBundled=false; + case {'DAT1' 'DAT2'} + % Newer format + h.oVersion=fread(fh, 32, 'uint8=>char')'; + h.oTime=fread(fh, 1, 'double'); + h.oItems=fread(fh, 1, 'int32=>int32'); + h.oIsLittleEndian=fread(fh, 1, 'uint8=>logical'); + h.BundleHeaderSize=256; + switch h.oSignature + case 'DAT1' + h.oBundleItems=[]; + isBundled=false; + case {'DAT2'} + fseek(fh, 64, 'bof'); + for k=1:12 + h.oBundleItems(k).oStart=fread(fh, 1, 'int32=>int32'); + h.oBundleItems(k).oLength=fread(fh, 1, 'int32=>int32'); + h.oBundleItems(k).oExtension=deblank(fread(fh, 8, 'uint8=>char')'); + h.oBundleItems(k).BundleItemSize=16; + end + isBundled=true; + end + otherwise + error('This legacy file format is not supported'); +end +littleendianflag=h.oIsLittleEndian; + +end + + +%-------------------------------------------------------------------------- +function [Tree, Counter]=getTree(fh, Sizes, Position, ext) +%-------------------------------------------------------------------------- +% Main entry point for loading tree +[Tree, Counter]=getTreeReentrant(fh, {}, Sizes, 0, Position, 0, ext); +end + + +function [Tree, Position, Counter]=getTreeReentrant(fh, Tree, Sizes, Level, Position, Counter, ext) +%-------------------------------------------------------------------------- +% Recursive routine called from LoadTree + +switch ext + case '.pul' + [Tree, Position, Counter, nchild]=getOneDataLevel(fh, Tree, Sizes, Level, Position, Counter); + case '.pgf' + [Tree, Position, Counter, nchild]=getOneStimLevel(fh, Tree, Sizes, Level, Position, Counter); + case '.sol' + [Tree, Position, Counter, nchild]=getOneSolutionLevel(fh, Tree, Sizes, Level, Position, Counter); +end + +for k=1:double(nchild) + [Tree, Position, Counter]=getTreeReentrant(fh, Tree, Sizes, Level+1, Position, Counter, ext); +end + +end + + +%-------------------------------------------------------------------------- +function [Tree, Position, Counter, nchild]=getOneDataLevel(fh, Tree, Sizes, Level, Position, Counter) +%-------------------------------------------------------------------------- +% Gets one record of the tree and the number of children +[s, Counter]=getOneRecord(fh, Level, Counter); +Tree{Counter, Level+1}=s; +Position=Position+Sizes(Level+1); +fseek(fh, Position, 'bof'); +nchild=fread(fh, 1, 'int32=>int32'); +Position=ftell(fh); +end + +%-------------------------------------------------------------------------- +function [rec, Counter]=getOneRecord(fh, Level, Counter) +%-------------------------------------------------------------------------- +% Gets one record +Counter=Counter+1; +switch Level + case 0 + rec=getRoot(fh); + case 1 + rec=getGroup(fh); + case 2 + rec=getSeries(fh); + case 3 + rec=getSweep(fh); + case 4 + rec=getTrace(fh); + otherwise + error('Unexpected Level'); +end +end + +% The functions below return data as defined by the HEKA PatchMaster +% specification + +%-------------------------------------------------------------------------- +function p=getRoot(fh) +%-------------------------------------------------------------------------- +p.RoVersion=fread(fh, 1, 'int32=>int32'); +p.RoMark=fread(fh, 1, 'int32=>int32');% = 4; (* INT32 *) +p.RoVersionName=deblank(fread(fh, 32, 'uint8=>char')');% = 8; (* String32Type *) +p.RoAuxFileName=deblank(fread(fh, 80, 'uint8=>char')');% = 40; (* String80Type *) +p.RoRootText=deblank(fread(fh, 400, 'uint8=>char')');% (* String400Type *) +p.RoStartTime=fread(fh, 1, 'double=>double') ;% = 520; (* LONGREAL *) +p.RoStartTimeMATLAB=time2date(p.RoStartTime); +p.RoMaxSamples=fread(fh, 1, 'int32=>int32'); % = 528; (* INT32 *) +p.RoCRC=fread(fh, 1, 'int32=>int32'); % = 532; (* CARD32 *) +p.RoFeatures=fread(fh, 1, 'int16=>int16'); % = 536; (* SET16 *) +p.RoFiller1=fread(fh, 1, 'int16=>int16');% = 538; (* INT16 *) +p.RoFiller2=fread(fh, 1, 'int32=>int32');% = 540; (* INT32 *) +p.RootRecSize= 544; +p=orderfields(p); + +end + +%-------------------------------------------------------------------------- +function g=getGroup(fh) +%-------------------------------------------------------------------------- +% Group +g.GrMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) +g.GrLabel=deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Size *) +g.GrText=deblank(fread(fh, 80, 'uint8=>char')');% = 36; (* String80Size *) +g.GrExperimentNumber=fread(fh, 1, 'int32=>int32');% = 116; (* INT32 *) +g.GrGroupCount=fread(fh, 1, 'int32=>int32');% = 120; (* INT32 *) +g.GrCRC=fread(fh, 1, 'int32=>int32');% = 124; (* CARD32 *) +g.GroupRecSize=128;% (* = 16 * 8 *) +g=orderfields(g); + +end + +%-------------------------------------------------------------------------- +function s=getSeries(fh) +%-------------------------------------------------------------------------- +s.SeMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) +s.SeLabel=deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Type *) +s.SeComment=deblank(fread(fh, 80, 'uint8=>char')');% = 36; (* String80Type *) +s.SeSeriesCount=fread(fh, 1, 'int32=>int32');% = 116; (* INT32 *) +s.SeNumbersw=fread(fh, 1, 'int32=>int32');% = 120; (* INT32 *) +s.SeAmplStateOffset=fread(fh, 1, 'int32=>int32');% = 124; (* INT32 *) +s.SeAmplStateSeries=fread(fh, 1, 'int32=>int32');% = 128; (* INT32 *) +s.SeSeriesType=fread(fh, 1, 'uint8=>uint8');% = 132; (* BYTE *) + +% Added 15.08.2012 +s.SeUseXStart=logical(fread(fh, 1, 'uint8=>uint8'));% = 133; (* BYTE *) + +s.SeFiller2=fread(fh, 1, 'uint8=>uint8');% = 134; (* BYTE *) +s.SeFiller3=fread(fh, 1, 'uint8=>uint8');% = 135; (* BYTE *) +s.SeTime=fread(fh, 1, 'double=>double') ;% = 136; (* LONGREAL *) +s.SeTimeMATLAB=time2date(s.SeTime); +s.SePageWidth=fread(fh, 1, 'double=>double') ;% = 144; (* LONGREAL *) +for k=1:4 + s.SeSwUserParamDescr(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% + s.SeSwUserParamDescr(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% +end +s.SeFiller4=fread(fh, 32, 'uint8=>uint8');% = 312; (* 32 BYTE *) +s.SeSeUserParams=fread(fh, 4, 'double=>double');% = 344; (* ARRAY[0..3] OF LONGREAL *) +s.SeLockInParams=getSeLockInParams(fh);% = 376; (* SeLockInSize = 96, see "Pulsed.de" *) +s.SeAmplifierState=getAmplifierState(fh);% = 472; (* AmplifierStateSize = 400 *) +s.SeUsername=deblank(fread(fh, 80, 'uint8=>char')');% = 872; (* String80Type *) +for k=1:4 + s.SeSeUserParamDescr(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% (* ARRAY[0..3] OF UserParamDescrType = 4*40 *) + s.SeSeUserParamDescr(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% +end +s.SeFiller5=fread(fh, 1, 'int32=>int32');% = 1112; (* INT32 *) +s.SeCRC=fread(fh, 1, 'int32=>int32');% = 1116; (* CARD32 *) + +% Added 15.08.2012 +s.SeSeUserParams2=fread(fh, 4, 'double=>double'); +for k=1:4 + s.SeSeUserParamDescr2(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% + s.SeSeUserParamDescr2(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% +end +s.SeScanParams=fread(fh, 96, 'uint8=>uint8'); +s.SeriesRecSize=1408;% (* = 176 * 8 *) +s=orderfields(s); +s.Sweeps = []; % used to store all the sweeps within the recording structure later on + +end + +%-------------------------------------------------------------------------- +function sw=getSweep(fh) +%-------------------------------------------------------------------------- +sw.SwMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) +sw.SwLabel=deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Type *) +sw.SwAuxDataFileOffset=fread(fh, 1, 'int32=>int32');% = 36; (* INT32 *) +sw.SwStimCount=fread(fh, 1, 'int32=>int32');% = 40; (* INT32 *) +sw.SwSweepCount=fread(fh, 1, 'int32=>int32');% = 44; (* INT32 *) +sw.SwTime=fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) +sw.SwTimeMATLAB=time2date(sw.SwTime);% Also add in MATLAB datenum format +sw.SwTimer=fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) +sw.SwSwUserParams=fread(fh, 4, 'double=>double');% = 64; (* ARRAY[0..3] OF LONGREAL *) +sw.SwTemperature=fread(fh, 1, 'double=>double');% = 96; (* LONGREAL *) +sw.SwOldIntSol=fread(fh, 1, 'int32=>int32');% = 104; (* INT32 *) +sw.SwOldExtSol=fread(fh, 1, 'int32=>int32');% = 108; (* INT32 *) +sw.SwDigitalIn=fread(fh, 1, 'int16=>int16');% = 112; (* SET16 *) +sw.SwSweepKind=fread(fh, 1, 'int16=>int16');% = 114; (* SET16 *) +sw.SwFiller1=fread(fh, 1, 'int32=>int32');% = 116; (* INT32 *) +sw.SwMarkers=fread(fh, 4, 'double=>double');% = 120; (* ARRAY[0..3] OF LONGREAL *) +sw.SwFiller2=fread(fh, 1, 'int32=>int32');% = 152; (* INT32 *) +sw.SwCRC=fread(fh, 1, 'int32=>int32');% = 156; (* CARD32 *) +sw.SwSwHolding = fread(fh,16,'double=>double');% = 160; (* ARRAY[0..15] OF LONGREAL, see SwHoldingNo *) +sw.SweepRecSize = 288;% (* = 36*8) +% % added in v1000 +% sw.SwSwUserParamEx = fread(fh,8,'double=>double'); % = (* ARRAY[0..7] OF LONGREAL *) +% sw.SweepRecSize = 352;% (* = 36*8) + + + + +sw=orderfields(sw); +sw.Traces = []; % used to store all the traces/channels within the sweep structure later on + + + +end + +%-------------------------------------------------------------------------- +function tr=getTrace(fh) +%-------------------------------------------------------------------------- + +% identical between v9 and v1000 + +tr.TrMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) +tr.TrLabel=deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Type *) +tr.TrTraceCount=fread(fh, 1, 'int32=>int32');% = 36; (* INT32 *) +tr.TrData=fread(fh, 1, 'int32=>int32');% = 40; (* INT32 *) +tr.TrDataPoints=fread(fh, 1, 'int32=>int32');% = 44; (* INT32 *) +tr.TrInternalSolution=fread(fh, 1, 'int32=>int32');% = 48; (* INT32 *) +tr.TrAverageCount=fread(fh, 1, 'int32=>int32');% = 52; (* INT32 *) +tr.TrLeakCount=fread(fh, 1, 'int32=>int32');% = 56; (* INT32 *) +tr.TrLeakTraces=fread(fh, 1, 'int32=>int32');% = 60; (* INT32 *) +tr.TrDataKind=fread(fh, 1, 'uint16=>uint16');% = 64; (* SET16 *) NB Stored unsigned +tr.TrFiller1=fread(fh, 1, 'int16=>int16');% = 66; (* SET16 *) +tr.TrRecordingMode=fread(fh, 1, 'uint8=>uint8');% = 68; (* BYTE *) +tr.TrAmplIndex=fread(fh, 1, 'uint8=>uint8');% = 69; (* CHAR *) +tr.TrDataFormat=fread(fh, 1, 'uint8=>uint8');% = 70; (* BYTE *) +tr.TrDataAbscissa=fread(fh, 1, 'uint8=>uint8');% = 71; (* BYTE *) +tr.TrDataScaler=fread(fh, 1, 'double=>double');% = 72; (* LONGREAL *) +tr.TrTimeOffset=fread(fh, 1, 'double=>double');% = 80; (* LONGREAL *) +tr.TrZeroData=fread(fh, 1, 'double=>double');% = 88; (* LONGREAL *) +tr.TrYUnit=deblank(fread(fh, 8, 'uint8=>char')');% = 96; (* String8Type *) +tr.TrXInterval=fread(fh, 1, 'double=>double');% = 104; (* LONGREAL *) +tr.TrXStart=fread(fh, 1, 'double=>double');% = 112; (* LONGREAL *) +% 17.04.10 TrXUnit bytes may include some trailing characters after NULL +% byte +tr.TrXUnit=deblank(fread(fh, 8, 'uint8=>char')');% = 120; (* String8Type *) +tr.TrYRange=fread(fh, 1, 'double=>double');% = 128; (* LONGREAL *) +tr.TrYOffset=fread(fh, 1, 'double=>double');% = 136; (* LONGREAL *) +tr.TrBandwidth=fread(fh, 1, 'double=>double');% = 144; (* LONGREAL *) +tr.TrPipetteResistance=fread(fh, 1, 'double=>double');% = 152; (* LONGREAL *) +tr.TrCellPotential=fread(fh, 1, 'double=>double');% = 160; (* LONGREAL *) +tr.TrSealResistance=fread(fh, 1, 'double=>double');% = 168; (* LONGREAL *) +tr.TrCSlow=fread(fh, 1, 'double=>double');% = 176; (* LONGREAL *) +tr.TrGSeries=fread(fh, 1, 'double=>double');% = 184; (* LONGREAL *) +tr.TrRsValue=fread(fh, 1, 'double=>double');% = 192; (* LONGREAL *) +tr.TrGLeak=fread(fh, 1, 'double=>double');% = 200; (* LONGREAL *) +tr.TrMConductance=fread(fh, 1, 'double=>double');% = 208; (* LONGREAL *) +tr.TrLinkDAChannel=fread(fh, 1, 'int32=>int32');% = 216; (* INT32 *) +tr.TrValidYrange=fread(fh, 1, 'uint8=>logical');% = 220; (* BOOLEAN *) +tr.TrAdcMode=fread(fh, 1, 'uint8=>uint8');% = 221; (* CHAR *) +tr.TrAdcChannel=fread(fh, 1, 'int16=>int16');% = 222; (* INT16 *) +tr.TrYmin=fread(fh, 1, 'double=>double');% = 224; (* LONGREAL *) +tr.TrYmax=fread(fh, 1, 'double=>double');% = 232; (* LONGREAL *) +tr.TrSourceChannel=fread(fh, 1, 'int32=>int32');% = 240; (* INT32 *) +tr.TrExternalSolution=fread(fh, 1, 'int32=>int32');% = 244; (* INT32 *) +tr.TrCM=fread(fh, 1, 'double=>double');% = 248; (* LONGREAL *) +tr.TrGM=fread(fh, 1, 'double=>double');% = 256; (* LONGREAL *) +tr.TrPhase=fread(fh, 1, 'double=>double');% = 264; (* LONGREAL *) +tr.TrDataCRC=fread(fh, 1, 'int32=>int32');% = 272; (* CARD32 *) +tr.TrCRC=fread(fh, 1, 'int32=>int32');% = 276; (* CARD32 *) +tr.TrGS=fread(fh, 1, 'double=>double');% = 280; (* LONGREAL *) +tr.TrSelfChannel=fread(fh, 1, 'int32=>int32');% = 288; (* INT32 *) + +% Added 15.08.2012 +tr.TrInterleaveSize=fread(fh, 1, 'int32=>int32');% = 292; (* INT32 *) +tr.TrInterleaveSkip=fread(fh, 1, 'int32=>int32');% = 296; (* INT32 *) +tr.TrImageIndex=fread(fh, 1, 'int32=>int32');% = 300; (* INT32 *) +tr.TrMarkers=fread(fh, 10, 'double=>double');% = 304; (* ARRAY[0..9] OF LONGREAL *) +tr.TrSECM_X=fread(fh, 1, 'double=>double');% = 384; (* LONGREAL *) +tr.TrSECM_Y=fread(fh, 1, 'double=>double');% = 392; (* LONGREAL *) +tr.TrSECM_Z=fread(fh, 1, 'double=>double');% = 400; (* LONGREAL *) + +% added 06/2019 +tr.TrTrHolding = fread(fh, 1, 'double=>double');% = 408; (* LONGREAL *) +tr.TrTcEnumerator = fread(fh, 1, 'int32=>int32');% = 416; (* INT32 *) +tr.TrXTrace = fread(fh, 1, 'int32=>int32');% = 420; (* INT32 *) +tr.TrIntSolValue = fread(fh, 1, 'double=>double');% = 424; (* LONGREAL *) +tr.TrExtSolValue = fread(fh, 1, 'double=>double');% = 432; (* LONGREAL *) +tr.TrIntSolName = deblank(fread(fh, 32, 'uint8=>char')');% = 440; (* String32Size *) +tr.TrExtSolName = deblank(fread(fh, 32, 'uint8=>char')');% = 472; (* String32Size *) +tr.TrDataPedestal = fread(fh, 1, 'double=>double');% = 504; (* LONGREAL *) + +tr.TraceRecSize=512; + +tr=orderfields(tr); + +end + +%% GET SOLUTION TREE +%-------------------------------------------------------------------------- +function [Tree, Position, Counter, nchild]=getOneSolutionLevel(fh, Tree, Sizes, Level, Position, Counter) +%-------------------------------------------------------------------------- +% Gets one record of the tree and the number of children +[s, Counter]=getOneSolutionRecord(fh, Level, Counter); +Tree{Counter, Level+1}=s; +Position=Position+Sizes(Level+1); +fseek(fh, Position, 'bof'); +nchild=fread(fh, 1, 'int32=>int32'); +Position=ftell(fh); + +end + +%-------------------------------------------------------------------------- +function [rec, Counter]=getOneSolutionRecord(fh, Level, Counter) +%-------------------------------------------------------------------------- +% Gets one record +Counter=Counter+1; +switch Level + case 0 + rec=getSolutionRoot(fh); + case 1 + rec=getSolution(fh); + case 2 + rec=getChemical(fh); + + otherwise + error('Unexpected Level'); +end + +end + +%-------------------------------------------------------------------------- +function p=getSolutionRoot(fh) +%-------------------------------------------------------------------------- +p.RoVersion=fread(fh, 1, 'int16=>int16'); % = 0; (* INT16 *) +p.RoDataBaseName=deblank(fread(fh, 80, 'uint8=>char')');% = 2; (* SolutionNameSize *) +p.RoSpare1=fread(fh, 1, 'int16=>int16');% = 82; (* INT16 *) +p.RoCRC=fread(fh, 1, 'int32=>int32'); % = 84; (* CARD32 *) +p.RootSize = 88;% = 88 + +p=orderfields(p); + +% in v1000: +% (* RootRecord = RECORD *) +% RoVersion = 0; (* INT32 *) +% RoDataBaseName = 4; (* SolutionNameSize *) +% RoCRC = 84; (* CARD32 *) +% RootSize = 88; + + +end + + +function s=getSolution(fh) +%-------------------------------------------------------------------------- +% Stimulus level +s.SoNumber=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) +s.SoName=deblank(fread(fh, 80, 'uint8=>char')');% = 4; (* SolutionNameSize *) +s.SoNumeric=fread(fh, 1, 'real*4=>double');% = 84; (* REAL *) *) +s.SoNumericName=deblank(fread(fh, 30, 'uint8=>char')');% = 88; (* ChemicalNameSize *) +s.SoPH=fread(fh, 1, 'real*4=>double');% = 118; (* REAL *) +s.SopHCompound=deblank(fread(fh, 30, 'uint8=>char')');% = 122; (* ChemicalNameSize *) +s.soOsmol=fread(fh, 1, 'real*4=>double'); %152; (* REAL *) +s.SoCRC=fread(fh, 1, 'int32=>int32') ;% = 156; (* CARD32 *) +s.SolutionSize=160;% = 160 + +s=orderfields(s); + +end + +%-------------------------------------------------------------------------- +function c=getChemical(fh) +%-------------------------------------------------------------------------- +c.ChConcentration=fread(fh, 1, 'real*4=>double');% = 0; (* REAL *) +c.ChName=deblank(fread(fh, 30, 'uint8=>char')');% = 4; (* ChemicalNameSize *) +c.ChSpare1=fread(fh, 1, 'int16=>int16');% = 34; (* INT16 *) +c.ChCRC=fread(fh, 1, 'int32=>int32')';% 36; (* CARD32 *) +c.ChemicalSize=40;% = 40 + +c=orderfields(c); + +end + + +%% GET STIMULUS TREE +%-------------------------------------------------------------------------- +function [Tree, Position, Counter, nchild]=getOneStimLevel(fh, Tree, Sizes, Level, Position, Counter) +%-------------------------------------------------------------------------- +% Gets one record of the tree and the number of children +[s, Counter]=getOneStimRecord(fh, Level, Counter); +Tree{Counter, Level+1}=s; +Position=Position+Sizes(Level+1); +fseek(fh, Position, 'bof'); +nchild=fread(fh, 1, 'int32=>int32'); +Position=ftell(fh); + +end + +%-------------------------------------------------------------------------- +function [rec, Counter]=getOneStimRecord(fh, Level, Counter) +%-------------------------------------------------------------------------- +% Gets one record +Counter=Counter+1; +switch Level + case 0 + rec=getStimRoot(fh); + case 1 + rec=getStimulation(fh); + case 2 + rec=getChannel(fh); + case 3 + rec=getStimSegment(fh); + otherwise + error('Unexpected Level'); +end + +end + +% The functions below return data as defined by the HEKA PatchMaster +% specification + +%-------------------------------------------------------------------------- +function p=getStimRoot(fh) +%-------------------------------------------------------------------------- +p.RoVersion=fread(fh, 1, 'int32=>int32'); +p.RoMark=fread(fh, 1, 'int32=>int32');% = 4; (* INT32 *) +p.RoVersionName=deblank(fread(fh, 32, 'uint8=>char')');% = 8; (* String32Type *) +p.RoMaxSamples=fread(fh, 1, 'int32=>int32'); % = 40; (* INT32 *) +p.RoFiller1 = fread(fh, 1, 'int32=>int32');% = 44; (* INT32 *) +p.RoParams = fread(fh, 10, 'double=>double');% = 48; (* ARRAY[0..9] OF LONGREAL *) +for k=1:10 + p.RoParamText{k}=deblank(fread(fh, 32, 'uint8=>char')');% = 128; (* ARRAY[0..9],[0..31]OF CHAR *) +end +p.RoReserved = fread(fh, 32, 'int32=>int32');% = 448; (* INT32 *) +p.RoFiller2= fread(fh, 1, 'int32=>int32');% = 576; (* INT32 *) +p.RoCRC= fread(fh, 1, 'int32=>int32');% = 580; (* CARD32 *) +p.RootRecSize= 584; % (* = 73 * 8 *) +p=orderfields(p); + +end + +%-------------------------------------------------------------------------- +function s=getStimulation(fh) +%-------------------------------------------------------------------------- +% Stimulus level +s.stMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) +s.stEntryName=deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Type *) +s.stFileName=deblank(fread(fh, 32, 'uint8=>char')');% = 36; (* String32Type *) +s.stAnalName=deblank(fread(fh, 32, 'uint8=>char')');% = 68; (* String32Type *) +s.stDataStartSegment=fread(fh, 1, 'int32=>int32');% = 100; (* INT32 *) +s.stDataStartTime=fread(fh, 1, 'double=>double') ;% = 104; (* LONGREAL *) +s.stDataStartTimeMATLAB=time2date(s.stDataStartTime); +s.stSampleInterval=fread(fh, 1, 'double=>double') ;% = 112; (* LONGREAL *) +s.stSweepInterval=fread(fh, 1, 'double=>double') ;% = 120; (* LONGREAL *) +s.stLeakDelay=fread(fh, 1, 'double=>double') ;% = 128; (* LONGREAL *) +s.stFilterFactor=fread(fh, 1, 'double=>double') ;% = 136; (* LONGREAL *) +s.stNumberSweeps=fread(fh, 1, 'int32=>int32');% = 144; (* INT32 *) +s.stNumberLeaks=fread(fh, 1, 'int32=>int32');% = 148; (* INT32 *) +s.stNumberAverages=fread(fh, 1, 'int32=>int32');% = 152; (* INT32 *) +s.stActualAdcChannels=fread(fh, 1, 'int32=>int32');% = 156; (* INT32 *) +s.stActualDacChannels=fread(fh, 1, 'int32=>int32');% = 160; (* INT32 *) +s.stExtTrigger=fread(fh, 1, 'uint8=>uint8');% = 164; (* BYTE *) +s.stNoStartWait=fread(fh, 1, 'uint8=>logical');% = 165; (* BOOLEAN *) +s.stUseScanRates=fread(fh, 1, 'uint8=>logical');% = 166; (* BOOLEAN *) +s.stNoContAq=fread(fh, 1, 'uint8=>logical');% = 167; (* BOOLEAN *) +s.stHasLockIn=fread(fh, 1, 'uint8=>logical');% = 168; (* BOOLEAN *) +s.stOldStartMacKind=fread(fh, 1, 'uint8=>char');% = 169; (* CHAR *) +s.stOldEndMacKind=fread(fh, 1, 'uint8=>logical');% = 170; (* BOOLEAN *) +s.stAutoRange=fread(fh, 1, 'uint8=>uint8');% = 171; (* BYTE *) +s.stBreakNext=fread(fh, 1, 'uint8=>logical');% = 172; (* BOOLEAN *) +s.stIsExpanded=fread(fh, 1, 'uint8=>logical');% = 173; (* BOOLEAN *) +s.stLeakCompMode=fread(fh, 1, 'uint8=>logical');% = 174; (* BOOLEAN *) +s.stHasChirp=fread(fh, 1, 'uint8=>logical');% = 175; (* BOOLEAN *) +s.stOldStartMacro=deblank(fread(fh, 32, 'uint8=>char')');% = 176; (* String32Type *) +s.stOldEndMacro=deblank(fread(fh, 32, 'uint8=>char')');% = 208; (* String32Type *) +s.sIsGapFree=fread(fh, 1, 'uint8=>logical');% = 240; (* BOOLEAN *) +s.sHandledExternally=fread(fh, 1, 'uint8=>logical');% = 241; (* BOOLEAN *) +s.stFiller1=fread(fh, 1, 'uint8=>logical');% = 242; (* BOOLEAN *) +s.stFiller2=fread(fh, 1, 'uint8=>logical');% = 243; (* BOOLEAN *) +s.stCRC=fread(fh, 1, 'int32=>int32'); % = 244; (* CARD32 *) +s.stTag=deblank(fread(fh, 32, 'uint8=>char')');% = 248; (* String32Type *) +s.StimulationRecSize = 280;% (* = 35 * 8 *) + +s=orderfields(s); + +end + +%-------------------------------------------------------------------------- +function c=getChannel(fh) +%-------------------------------------------------------------------------- +c.chMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) +c.chLinkedChannel=fread(fh, 1, 'int32=>int32');% = 4; (* INT32 *) +c.chCompressionFactor=fread(fh, 1, 'int32=>int32');% = 8; (* INT32 *) +c.chYUnit=deblank(fread(fh, 8, 'uint8=>char')');% = 12; (* String8Type *) +c.chAdcChannel=fread(fh, 1, 'int16=>int16');% = 20; (* INT16 *) +c.chAdcMode=fread(fh, 1, 'uint8=>uint8');% = 22; (* BYTE *) +c.chDoWrite=fread(fh, 1, 'uint8=>logical');% = 23; (* BOOLEAN *) +c.stLeakStore=fread(fh, 1, 'uint8=>uint8');% = 24; (* BYTE *) +c.chAmplMode=fread(fh, 1, 'uint8=>uint8');% = 25; (* BYTE *) +c.chOwnSegTime=fread(fh, 1, 'uint8=>logical');% = 26; (* BOOLEAN *) +c.chSetLastSegVmemb=fread(fh, 1, 'uint8=>logical');% = 27; (* BOOLEAN *) +c.chDacChannel=fread(fh, 1, 'int16=>int16');% = 28; (* INT16 *) +c.chDacMode=fread(fh, 1, 'uint8=>uint8');% = 30; (* BYTE *) +c.chHasLockInSquare=fread(fh, 1, 'uint8=>uint8');% = 31; (* BYTE *) +c.chRelevantXSegment=fread(fh, 1, 'int32=>int32');% = 32; (* INT32 *) +c.chRelevantYSegment=fread(fh, 1, 'int32=>int32');% = 36; (* INT32 *) +c.chDacUnit=deblank(fread(fh, 8, 'uint8=>char')');% = 40; (* String8Type *) +c.chHolding=fread(fh, 1, 'double=>double') ;% = 48; (* LONGREAL *) +c.chLeakHolding=fread(fh, 1, 'double=>double') ;% = 56; (* LONGREAL *) +c.chLeakSize=fread(fh, 1, 'double=>double') ;% = 64; (* LONGREAL *) +c.chLeakHoldMode=fread(fh, 1, 'uint8=>uint8');% = 72; (* BYTE *) +c.chLeakAlternate=fread(fh, 1, 'uint8=>logical');% = 73; (* BOOLEAN *) +c.chAltLeakAveraging=fread(fh, 1, 'uint8=>logical');% = 74; (* BOOLEAN *) +c.chLeakPulseOn=fread(fh, 1, 'uint8=>logical');% = 75; (* BOOLEAN *) +c.chStimToDacID=fread(fh, 1, 'int16=>int16');% = 76; (* SET16 *) +c.chCompressionMode=fread(fh, 1, 'int16=>int16');% = 78; (* SET16 *) +c.chCompressionSkip=fread(fh, 1, 'int32=>int32');% = 80; (* INT32 *) +c.chDacBit=fread(fh, 1, 'int16=>int16');% = 84; (* INT16 *) +c.chHasLockInSine=fread(fh, 1, 'uint8=>logical');% = 86; (* BOOLEAN *) +c.chBreakMode=fread(fh, 1, 'uint8=>uint8');% = 87; (* BYTE *) +c.chZeroSeg=fread(fh, 1, 'int32=>int32');% = 88; (* INT32 *) +c.chFiller1=fread(fh, 1, 'int32=>int32');% = 92; (* INT32 *) +c.chSine_Cycle=fread(fh, 1, 'double=>double') ;% = 96; (* LONGREAL *) +c.chSine_Amplitude=fread(fh, 1, 'double=>double') ;% = 104; (* LONGREAL *) +c.chLockIn_VReversal=fread(fh, 1, 'double=>double') ;% = 112; (* LONGREAL *) +c.chChirp_StartFreq=fread(fh, 1, 'double=>double') ;% = 120; (* LONGREAL *) +c.chChirp_EndFreq=fread(fh, 1, 'double=>double') ;% = 128; (* LONGREAL *) +c.chChirp_MinPoints=fread(fh, 1, 'double=>double') ;% = 136; (* LONGREAL *) +c.chSquare_NegAmpl=fread(fh, 1, 'double=>double') ;% = 144; (* LONGREAL *) +c.chSquare_DurFactor=fread(fh, 1, 'double=>double') ;% = 152; (* LONGREAL *) +c.chLockIn_Skip=fread(fh, 1, 'int32=>int32');% = 160; (* INT32 *) +c.chPhoto_MaxCycles=fread(fh, 1, 'int32=>int32');% = 164; (* INT32 *) +c.chPhoto_SegmentNo=fread(fh, 1, 'int32=>int32');% = 168; (* INT32 *) +c.chLockIn_AvgCycles=fread(fh, 1, 'int32=>int32');% = 172; (* INT32 *) +c.chImaging_RoiNo=fread(fh, 1, 'int32=>int32');% = 176; (* INT32 *) +c.chChirp_Skip=fread(fh, 1, 'int32=>int32');% = 180; (* INT32 *) +c.chChirp_Amplitude=fread(fh, 1, 'double=>double') ;% = 184; (* LONGREAL *) +c.chPhoto_Adapt=fread(fh, 1, 'uint8=>uint8');% = 192; (* BYTE *) +c.chSine_Kind=fread(fh, 1, 'uint8=>uint8');% = 193; (* BYTE *) +c.chChirp_PreChirp=fread(fh, 1, 'uint8=>uint8');% = 194; (* BYTE *) +c.chSine_Source=fread(fh, 1, 'uint8=>uint8');% = 195; (* BYTE *) +c.chSquare_NegSource=fread(fh, 1, 'uint8=>uint8');% = 196; (* BYTE *) +c.chSquare_PosSource=fread(fh, 1, 'uint8=>uint8');% = 197; (* BYTE *) +c.chChirp_Kind=fread(fh, 1, 'uint8=>uint8');% = 198; (* BYTE *) +c.chChirp_Source=fread(fh, 1, 'uint8=>uint8');% = 199; (* BYTE *) +c.chDacOffset=fread(fh, 1, 'double=>double') ;% = 200; (* LONGREAL *) +c.chAdcOffset=fread(fh, 1, 'double=>double') ;% = 208; (* LONGREAL *) +c.chTraceMathFormat=fread(fh, 1, 'uint8=>uint8');% = 216; (* BYTE *) +c.chHasChirp=fread(fh, 1, 'uint8=>logical');% = 217; (* BOOLEAN *) +c.chSquare_Kind=fread(fh, 1, 'uint8=>uint8');% = 218; (* BYTE *) +c.chFiller2=fread(fh,13,'uint8=>char');% = 219; (* ARRAY[0..13] OF CHAR *) +c.chSquare_Cycle=fread(fh, 1, 'double=>double') ;% = 232; (* LONGREAL *) +c.chSquare_PosAmpl=fread(fh, 1, 'double=>double') ;% = 240; (* LONGREAL *) +c.chCompressionOffset=fread(fh, 1, 'int32=>int32');% = 248; (* INT32 *) +c.chPhotoMode=fread(fh, 1, 'int32=>int32');% = 252; (* INT32 *) +c.chBreakLevel=fread(fh, 1, 'double=>double') ;% = 256; (* LONGREAL *) +c.chTraceMath=deblank(fread(fh,128,'uint8=>char')');% = 264; (* String128Type *) +c.chOldCRC=fread(fh, 1, 'int32=>int32');% = 268; (* CARD32 *) +c.chFiller3=fread(fh, 1, 'int32=>int32');% = 392; (* INT32 *) +c.chCRC=fread(fh, 1, 'int32=>int32');% = 396; (* CARD32 *) +c.ChannelRecSize = 400;% (* = 50 * 8 *) +c=orderfields(c); + +end + +%-------------------------------------------------------------------------- +function ss=getStimSegment(fh) +%-------------------------------------------------------------------------- +ss.seMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) +ss.seClass=fread(fh, 1, 'uint8=>uint8');% = 4; (* BYTE *) +ss.seDoStore=fread(fh, 1, 'uint8=>logical');% = 5; (* BOOLEAN *) +ss.seVoltageIncMode=fread(fh, 1, 'uint8=>uint8');% = 6; (* BYTE *) +ss.seDurationIncMode=fread(fh, 1, 'uint8=>uint8');% = 7; (* BYTE *) +ss.seVoltage=fread(fh, 1, 'double=>double');% = 8; (* LONGREAL *) +ss.seVoltageSource=fread(fh, 1, 'int32=>int32');% = 16; (* INT32 *) +ss.seDeltaVFactor=fread(fh, 1, 'double=>double');% = 20; (* LONGREAL *) +ss.seDeltaVIncrement=fread(fh, 1, 'double=>double');% = 28; (* LONGREAL *) +ss.seDuration=fread(fh, 1, 'double=>double');% = 36; (* LONGREAL *) +ss.seDurationSource=fread(fh, 1, 'int32=>int32');% = 44; (* INT32 *) +ss.seDeltaTFactor=fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) +ss.seDeltaTIncrement=fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) +ss.seFiller1=fread(fh, 1, 'int32=>int32');% = 64; (* INT32 *) +ss.seCRC=fread(fh, 1, 'int32=>int32');% = 68; (* CARD32 *) +ss.seScanRate=fread(fh, 1, 'double=>double');% = 72; (* LONGREAL *) +ss.StimSegmentRecSize = 80;% (* = 10 * 8 *) +ss=orderfields(ss); + +end + + + +%% GET AMPLIFIER DATA +%-------------------------------------------------------------------------- +function L=getSeLockInParams(fh) +%-------------------------------------------------------------------------- +offset=ftell(fh); +L.loExtCalPhase=fread(fh, 1, 'double=>double') ;% = 0; (* LONGREAL *) +L.loExtCalAtten=fread(fh, 1, 'double=>double') ;% = 8; (* LONGREAL *) +L.loPLPhase=fread(fh, 1, 'double=>double') ;% = 16; (* LONGREAL *) +L.loPLPhaseY1=fread(fh, 1, 'double=>double') ;% = 24; (* LONGREAL *) +L.loPLPhaseY2=fread(fh, 1, 'double=>double') ;% = 32; (* LONGREAL *) +L.loUsedPhaseShift=fread(fh, 1, 'double=>double') ;% = 40; (* LONGREAL *) +L.loUsedAttenuation=fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) +L.loFiller1=fread(fh, 1, 'double=>double'); +L.loExtCalValid=fread(fh, 1, 'uint8=>logical') ;% = 64; (* BOOLEAN *) +L.loPLPhaseValid=fread(fh, 1, 'uint8=>logical') ;% = 65; (* BOOLEAN *) +L.loLockInMode=fread(fh, 1, 'uint8=>uint8') ;% = 66; (* BYTE *) +L.loCalMode=fread(fh, 1, 'uint8=>uint8') ;% = 67; (* BYTE *) +L.LockInParamsSize=96; +fseek(fh, offset+L.LockInParamsSize, 'bof'); + +end + +%-------------------------------------------------------------------------- +function A=getAmplifierState(fh) +%-------------------------------------------------------------------------- +offset=ftell(fh); +A.sStateVersion = fread(fh, 1, 'double=>double');% = 0; (* 8 = SizeStateVersion *) +A.sCurrentGain = fread(fh, 1, 'double=>double');% = 8; (* LONGREAL *) +A.sF2Bandwidth = fread(fh, 1, 'double=>double');% = 16; (* LONGREAL *) + +A.sF2Frequency = fread(fh, 1, 'double=>double');% = 24; (* LONGREAL *) +A.sRsValue = fread(fh, 1, 'double=>double');% = 32; (* LONGREAL *) +A.sRsFraction = fread(fh, 1, 'double=>double');% = 40; (* LONGREAL *) +A.sGLeak=fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) +A.sCFastAmp1=fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) +A.sCFastAmp2=fread(fh, 1, 'double=>double');% = 64; (* LONGREAL *) +A.sCFastTau=fread(fh, 1, 'double=>double');% = 72; (* LONGREAL *) +A.sCSlow=fread(fh, 1, 'double=>double');% = 80; (* LONGREAL *) +A.sGSeries=fread(fh, 1, 'double=>double');% = 88; (* LONGREAL *) +A.sVCStimDacScale=fread(fh, 1, 'double=>double');% = 96; (* LONGREAL *) + +A.sCCStimScale=fread(fh, 1, 'double=>double');% = 104; (* LONGREAL *) +A.sVHold=fread(fh, 1, 'double=>double');% = 112; (* LONGREAL *) +A.sLastVHold=fread(fh, 1, 'double=>double');% = 120; (* LONGREAL *) +A.sVpOffset=fread(fh, 1, 'double=>double');% = 128; (* LONGREAL *) + +A.sVLiquidJunction=fread(fh, 1, 'double=>double');% = 136; (* LONGREAL *) +A.sCCIHold=fread(fh, 1, 'double=>double');% = 144; (* LONGREAL *) +A.E9CSlowStimVolts=fread(fh, 1, 'double=>double');% = 152; (* LONGREAL *) +A.E9CCtr.TrackVHold=fread(fh, 1, 'double=>double');% = 160; (* LONGREAL *) +A.E9TimeoutLength=fread(fh, 1, 'double=>double');% = 168; (* LONGREAL *) +A.E9SearchDelay=fread(fh, 1, 'double=>double');% = 176; (* LONGREAL *) +A.E9MConductance=fread(fh, 1, 'double=>double');% = 184; (* LONGREAL *) +A.E9MCapacitance=fread(fh, 1, 'double=>double');% = 192; (* LONGREAL *) +A.E9SerialNumber=fread(fh, 1, 'double=>double');% = 200; (* 8 = SizeSerialNumber *) +A.E9E9Boards=fread(fh, 1, 'int16=>int16');% = 208; (* INT16 *) +A.E9CSlowCycles=fread(fh, 1, 'int16=>int16');% = 210; (* INT16 *) +A.E9IMonAdc=fread(fh, 1, 'int16=>int16');% = 212; (* INT16 *) +A.E9VMonAdc=fread(fh, 1, 'int16=>int16');% = 214; (* INT16 *) +A.E9MuxAdc=fread(fh, 1, 'int16=>int16');% = 216; (* INT16 *) +A.E9TstDac=fread(fh, 1, 'int16=>int16');% = 218; (* INT16 *) +A.E9StimDac=fread(fh, 1, 'int16=>int16');% = 220; (* INT16 *) +A.E9StimDacOffset=fread(fh, 1, 'int16=>int16');% = 222; (* INT16 *) +A.E9MaxDigitalBit=fread(fh, 1, 'int16=>int16');% = 224; (* INT16 *) +A.E9SpareInt1=fread(fh, 1, 'int16=>int16');% = 226; (* INT16 *) +A.E9SpareInt2=fread(fh, 1, 'int16=>int16');% = 228; (* INT16 *) +A.E9SpareInt3=fread(fh, 1, 'int16=>int16');% = 230; (* INT16 *) + +A.E9AmplKind=fread(fh, 1, 'uint8=>uint8');% = 232; (* BYTE *) +A.E9IsEpc9N=fread(fh, 1, 'uint8=>uint8');% = 233; (* BYTE *) +A.E9ADBoard=fread(fh, 1, 'uint8=>uint8');% = 234; (* BYTE *) +A.E9BoardVersion=fread(fh, 1, 'uint8=>uint8');% = 235; (* BYTE *) +A.E9ActiveE9Board=fread(fh, 1, 'uint8=>uint8');% = 236; (* BYTE *) +A.E9Mode=fread(fh, 1, 'uint8=>uint8');% = 237; (* BYTE *) +A.E9Range=fread(fh, 1, 'uint8=>uint8');% = 238; (* BYTE *) +A.E9F2Response=fread(fh, 1, 'uint8=>uint8');% = 239; (* BYTE *) + +A.E9RsOn=fread(fh, 1, 'uint8=>uint8');% = 240; (* BYTE *) +A.E9CSlowRange=fread(fh, 1, 'uint8=>uint8');% = 241; (* BYTE *) +A.E9CCRange=fread(fh, 1, 'uint8=>uint8');% = 242; (* BYTE *) +A.E9CCGain=fread(fh, 1, 'uint8=>uint8');% = 243; (* BYTE *) +A.E9CSlowToTstDac=fread(fh, 1, 'uint8=>uint8');% = 244; (* BYTE *) +A.E9StimPath=fread(fh, 1, 'uint8=>uint8');% = 245; (* BYTE *) +A.E9CCtr.TrackTau=fread(fh, 1, 'uint8=>uint8');% = 246; (* BYTE *) +A.E9WasClipping=fread(fh, 1, 'uint8=>uint8');% = 247; (* BYTE *) + +A.E9RepetitiveCSlow=fread(fh, 1, 'uint8=>uint8');% = 248; (* BYTE *) +A.E9LastCSlowRange=fread(fh, 1, 'uint8=>uint8');% = 249; (* BYTE *) +A.E9Locked=fread(fh, 1, 'uint8=>uint8');% = 250; (* BYTE *) +A.E9CanCCFast=fread(fh, 1, 'uint8=>uint8');% = 251; (* BYTE *) +A.E9CanLowCCRange=fread(fh, 1, 'uint8=>uint8');% = 252; (* BYTE *) +A.E9CanHighCCRange=fread(fh, 1, 'uint8=>uint8');% = 253; (* BYTE *) +A.E9CanCCtr.Tracking=fread(fh, 1, 'uint8=>uint8');% = 254; (* BYTE *) +A.E9HasVmonPath=fread(fh, 1, 'uint8=>uint8');% = 255; (* BYTE *) + +A.E9HasNewCCMode=fread(fh, 1, 'uint8=>uint8');% = 256; (* BYTE *) +A.E9Selector=fread(fh, 1, 'uint8=>char');% = 257; (* CHAR *) +A.E9HoldInverted=fread(fh, 1, 'uint8=>uint8');% = 258; (* BYTE *) +A.E9AutoCFast=fread(fh, 1, 'uint8=>uint8');% = 259; (* BYTE *) +A.E9AutoCSlow=fread(fh, 1, 'uint8=>uint8');% = 260; (* BYTE *) +A.E9HasVmonX100=fread(fh, 1, 'uint8=>uint8');% = 261; (* BYTE *) +A.E9TestDacOn=fread(fh, 1, 'uint8=>uint8');% = 262; (* BYTE *) +A.E9QMuxAdcOn=fread(fh, 1, 'uint8=>uint8');% = 263; (* BYTE *) + +A.E9RealImon1Bandwidth=fread(fh, 1, 'double=>double');% = 264; (* LONGREAL *) +A.E9StimScale=fread(fh, 1, 'double=>double');% = 272; (* LONGREAL *) + +A.E9Gain=fread(fh, 1, 'uint8=>uint8');% = 280; (* BYTE *) +A.E9Filter1=fread(fh, 1, 'uint8=>uint8');% = 281; (* BYTE *) +A.E9StimFilterOn=fread(fh, 1, 'uint8=>uint8');% = 282; (* BYTE *) +A.E9RsSlow=fread(fh, 1, 'uint8=>uint8');% = 283; (* BYTE *) +A.E9Old1=fread(fh, 1, 'uint8=>uint8');% = 284; (* BYTE *) +A.E9CCCFastOn=fread(fh, 1, 'uint8=>uint8');% = 285; (* BYTE *) +A.E9CCFastSpeed=fread(fh, 1, 'uint8=>uint8');% = 286; (* BYTE *) +A.E9F2Source=fread(fh, 1, 'uint8=>uint8');% = 287; (* BYTE *) + +A.E9TestRange=fread(fh, 1, 'uint8=>uint8');% = 288; (* BYTE *) +A.E9TestDacPath=fread(fh, 1, 'uint8=>uint8');% = 289; (* BYTE *) +A.E9MuxChannel=fread(fh, 1, 'uint8=>uint8');% = 290; (* BYTE *) +A.E9MuxGain64=fread(fh, 1, 'uint8=>uint8');% = 291; (* BYTE *) +A.E9VmonX100=fread(fh, 1, 'uint8=>uint8');% = 292; (* BYTE *) +A.E9IsQuadro=fread(fh, 1, 'uint8=>uint8');% = 293; (* BYTE *) +A.E9SpareBool4=fread(fh, 1, 'uint8=>uint8');% = 294; (* BYTE *) +A.E9SpareBool5=fread(fh, 1, 'uint8=>uint8');% = 295; (* BYTE *) + +A.E9StimFilterHz=fread(fh, 1, 'double=>double');% = 296; (* LONGREAL *) +A.E9RsTau=fread(fh, 1, 'double=>double');% = 304; (* LONGREAL *) +A.E9FilterOffsetDac=fread(fh, 1, 'int16=>int16');% = 312; (* INT16 *) +A.E9ReferenceDac=fread(fh, 1, 'int16=>int16');% = 314; (* INT16 *) +A.E9SpareInt6=fread(fh, 1, 'int16=>int16');% = 316; (* INT16 *) +A.E9SpareInt7=fread(fh, 1, 'int16=>int16');% = 318; (* INT16 *) +A.E9Spares1=320; + +A.E9CalibDate=fread(fh, 2, 'double=>double');% = 344; (* 16 = SizeCalibDate *) +A.E9SelHold=fread(fh, 1, 'double=>double');% = 360; (* LONGREAL *) +A.AmplifierStateSize = 400; +fseek(fh, offset+A.AmplifierStateSize, 'bof'); + +end + +%-------------------------------------------------------------------------- +function matData2=LocalImportGroup(fh, dataTree, grp, grp_row) +%-------------------------------------------------------------------------- +% Create a structure for the series headers + + +% Pad the indices for last series of last group +grp_row(end+1)=size(dataTree,1); + +% Collect the series headers and row numbers for this group into a +% structure array +[ser_s, ser_row, nseries]=getSeriesHeaders(dataTree, grp_row, grp); + +% Pad for last series +ser_row(nseries+1)=grp_row(grp+1); + +dataoffsets=[]; +% Create the channels + +matData2 = cell(nseries,1); +for ser=1:nseries + + [sw_s, sw_row, nsweeps]=getSweepHeaders(dataTree, ser_row, ser); + + % Make sure the sweeps are in temporal sequence + if any(diff(cell2mat({sw_s.SwTime}))<=0) + % TODO: sort them if this can ever happen. + % For the moment just throw an error + error('Sweeps not in temporal sequence'); + end + + + sw_row(nsweeps+1)=ser_row(ser+1); + % Get the trace headers for this sweep + [tr_row]=getTraceHeaders(dataTree, sw_row); + + + for k=1:size(tr_row, 1) + + [tr_s, isConstantScaling, isConstantFormat, isFramed]=LocalCheckEntries(dataTree, tr_row, k); + + % TODO: Need a better way to do this + % Check whether interleaving is supported with this file version + % Note: HEKA added interleaving Jan 2011. + % TrInterleaveSkip was previously in a filler block, so should always + % be zero with older files. + if tr_s(1).TrInterleaveSize>0 && tr_s(1).TrInterleaveSkip>0 + INTERLEAVE_SUPPORTED=true; + else + INTERLEAVE_SUPPORTED=false; + end + + data=zeros(max(cell2mat({tr_s.TrDataPoints})), size(tr_row,2)); + + for tr=1:size(tr_row,2) + % Disc format + [fmt, nbytes]=LocalFormatToString(tr_s(tr).TrDataFormat); + % Always read into double + readfmt=[fmt '=>double']; + % Skip to start of the data + fseek(fh, dataTree{tr_row(k,tr),5}.TrData, 'bof'); + % Store data offset for later error checks + dataoffsets(end+1)=dataTree{tr_row(k,tr),5}.TrData; %#ok + % Read the data + if ~INTERLEAVE_SUPPORTED || dataTree{tr_row(k,tr),5}.TrInterleaveSize==0 + [data(1:dataTree{tr_row(k,tr),5}.TrDataPoints, tr)]=... + fread(fh, double(dataTree{tr_row(k,tr),5}.TrDataPoints), readfmt); + else + offset=1; + nelements= double(dataTree{tr_row(k,tr),5}.TrInterleaveSize/nbytes); + for nread=1:floor(numel(data)/double(dataTree{tr_row(k,tr),5}.TrInterleaveSize/nbytes)) + [data(offset:offset+nelements-1), N]=fread(fh, nelements, readfmt); + if (N + ser_row(nseries+1)=k; %#ok + nseries=nseries+1; + end +end +return +end + +%-------------------------------------------------------------------------- +function [sw_s, sw_row, nsweeps]=getSweepHeaders(tree, ser_row, ser) +%-------------------------------------------------------------------------- +nsweeps=0; +for k=ser_row(ser)+1:ser_row(ser+1) + if ~isempty(tree{k, 4}) + sw_s(nsweeps+1)=tree{k, 4}; %#ok + sw_row(nsweeps+1)=k; %#ok + nsweeps=nsweeps+1; + end +end +return +end + +%-------------------------------------------------------------------------- +function [tr_row, ntrace]=getTraceHeaders(tree, sw_row) +%-------------------------------------------------------------------------- +ntrace=0; +m=1; +n=1; +for k=sw_row(1)+1:sw_row(end) + if ~isempty(tree{k, 5}) + %tr_s(m,n)=tree{k, 5}; %#ok + tr_row(m,n)=k; %#ok + ntrace=ntrace+1; + m=m+1; + else + m=1; + n=n+1; + end +end +return +end + + +%-------------------------------------------------------------------------- +function [tr_s, isConstantScaling, isConstantFormat, isFramed]=LocalCheckEntries(tree, tr_row, k) +%-------------------------------------------------------------------------- +% Check units are the same for all traces +tr_s=[tree{tr_row(k, :),5}]; + + +if numel(unique({tr_s.TrYUnit}))>1 + error('1002: Waveform units are not constant'); +end + +if numel(unique({tr_s.TrXUnit}))>1 + error('1003: Time units are not constant'); +end + +if numel(unique(cell2mat({tr_s.TrXInterval})))~=1 + error('1004: Unequal sample intervals'); +end + +% Other unexpected conditions - give user freedom to create these but warn +% about them +if numel(unique({tr_s.TrLabel}))>1 + warning('LocalCheckEntries:w2001', 'Different trace labels'); +end + +if numel(unique(cell2mat({tr_s.TrAdcChannel})))>1 + warning('LocalCheckEntries:w2002', 'Data collected from different ADC channels'); +end + +if numel(unique(cell2mat({tr_s.TrRecordingMode})))>1 + warning('LocalCheckEntries:w2003', 'Traces collected using different recording modes'); +end + +if numel(unique(cell2mat({tr_s.TrCellPotential})))>1 + warning('LocalCheckEntries:w2004', 'Traces collected using different Em'); +end + +% Check scaling factor is constant +ScaleFactor=unique(cell2mat({tr_s.TrDataScaler})); +if numel(ScaleFactor)==1 + isConstantScaling=true; +else + isConstantScaling=false; +end + + +%... and data format +if numel(unique(cell2mat({tr_s.TrDataFormat})))==1 + isConstantFormat=true; +else + isConstantFormat=false; +end + +% Do we have constant epoch lengths and offsets? +if numel(unique(cell2mat({tr_s.TrDataPoints})))==1 &&... + numel(unique(cell2mat({tr_s.TrTimeOffset })))==1 + isFramed=true; +else + isFramed=false; +end +return +end + +%-------------------------------------------------------------------------- +function str=time2date(t) +%-------------------------------------------------------------------------- +t=t-1580970496; +if t<0 + t=t+4294967296; +end +t=t+9561652096; +str=datestr(t/(24*60*60)+datenum(1601,1,1)); +return +end +%-------------------------------------------------------------------------- \ No newline at end of file diff --git a/@HEKA_Importer/HI_ImportHEKAtoMat.m b/@HEKA_Importer/HI_ImportHEKAtoMat.m index ac6ffef..577daa8 100644 --- a/@HEKA_Importer/HI_ImportHEKAtoMat.m +++ b/@HEKA_Importer/HI_ImportHEKAtoMat.m @@ -770,32 +770,33 @@ function A=getAmplifierState(fh) %-------------------------------------------------------------------------- offset=ftell(fh); -A.E9StateVersion=fread(fh, 1, 'double=>double');% = 0; (* 8 = SizeStateVersion *) -A.E9RealCurrentGain=fread(fh, 1, 'double=>double');% = 8; (* LONGREAL *) -A.E9RealF2Bandwidth=fread(fh, 1, 'double=>double');% = 16; (* LONGREAL *) -A.E9F2Frequency=fread(fh, 1, 'double=>double');% = 24; (* LONGREAL *) -A.E9RsValue=fread(fh, 1, 'double=>double');% = 32; (* LONGREAL *) -A.E9RsFraction=fread(fh, 1, 'double=>double');% = 40; (* LONGREAL *) -A.E9GLeak=fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) -A.E9CFastAmp1=fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) -A.E9CFastAmp2=fread(fh, 1, 'double=>double');% = 64; (* LONGREAL *) -A.E9CFastTau=fread(fh, 1, 'double=>double');% = 72; (* LONGREAL *) -A.E9CSlow=fread(fh, 1, 'double=>double');% = 80; (* LONGREAL *) -A.E9GSeries=fread(fh, 1, 'double=>double');% = 88; (* LONGREAL *) -A.E9StimDacScale=fread(fh, 1, 'double=>double');% = 96; (* LONGREAL *) -A.E9CCStimScale=fread(fh, 1, 'double=>double');% = 104; (* LONGREAL *) -A.E9VHold=fread(fh, 1, 'double=>double');% = 112; (* LONGREAL *) -A.E9LastVHold=fread(fh, 1, 'double=>double');% = 120; (* LONGREAL *) -A.E9VpOffset=fread(fh, 1, 'double=>double');% = 128; (* LONGREAL *) -A.E9VLiquidJunction=fread(fh, 1, 'double=>double');% = 136; (* LONGREAL *) -A.E9CCIHold=fread(fh, 1, 'double=>double');% = 144; (* LONGREAL *) -A.E9CSlowStimVolts=fread(fh, 1, 'double=>double');% = 152; (* LONGREAL *) -A.E9CCtr.TrackVHold=fread(fh, 1, 'double=>double');% = 160; (* LONGREAL *) -A.E9TimeoutLength=fread(fh, 1, 'double=>double');% = 168; (* LONGREAL *) -A.E9SearchDelay=fread(fh, 1, 'double=>double');% = 176; (* LONGREAL *) -A.E9MConductance=fread(fh, 1, 'double=>double');% = 184; (* LONGREAL *) -A.E9MCapacitance=fread(fh, 1, 'double=>double');% = 192; (* LONGREAL *) -A.E9SerialNumber=fread(fh, 1, 'double=>double');% = 200; (* 8 = SizeSerialNumber *) +A.sStateVersion = fread(fh, 1, 'double=>double');% = 0; (* 8 = SizeStateVersion *) +A.sCurrentGain = fread(fh, 1, 'double=>double');% = 8; (* LONGREAL *) +A.sF2Bandwidth = fread(fh, 1, 'double=>double');% = 16; (* LONGREAL *) +A.sF2Frequency = fread(fh, 1, 'double=>double');% = 24; (* LONGREAL *) +A.sRsValue = fread(fh, 1, 'double=>double');% = 32; (* LONGREAL *) +A.sRsFraction = fread(fh, 1, 'double=>double');% = 40; (* LONGREAL *) +A.sGLeak = fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) +A.sCFastAmp1 = fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) +A.sCFastAmp2 = fread(fh, 1, 'double=>double');% = 64; (* LONGREAL *) +A.sCFastTau = fread(fh, 1, 'double=>double');% = 72; (* LONGREAL *) +A.sCSlow = fread(fh, 1, 'double=>double');% = 80; (* LONGREAL *) +A.sGSeries = fread(fh, 1, 'double=>double');% = 88; (* LONGREAL *) +A.sVCStimDacScale = fread(fh, 1, 'double=>double');% = 96; (* LONGREAL *) +A.sCCStimScale = fread(fh, 1, 'double=>double');% = 104; (* LONGREAL *) +A.sVHold = fread(fh, 1, 'double=>double');% = 112; (* LONGREAL *) +A.sLastVHold = fread(fh, 1, 'double=>double');% = 120; (* LONGREAL *) +A.sVpOffset = fread(fh, 1, 'double=>double');% = 128; (* LONGREAL *) +A.sVLiquidJunction = fread(fh, 1, 'double=>double');% = 136; (* LONGREAL *) +A.sCCIHold = fread(fh, 1, 'double=>double');% = 144; (* LONGREAL *) +A.sCSlowStimVolts = fread(fh, 1, 'double=>double');% = 152; (* LONGREAL *) +A.sCCTrackVHold = fread(fh, 1, 'double=>double');% = 160; (* LONGREAL *) +A.sTimeoutCSlow = fread(fh, 1, 'double=>double');% = 168; (* LONGREAL *) +A.sSearchDelay = fread(fh, 1, 'double=>double');% = 176; (* LONGREAL *) +A.sMConductance = fread(fh, 1, 'double=>double');% = 184; (* LONGREAL *) +A.sMCapacitance = fread(fh, 1, 'double=>double');% = 192; (* LONGREAL *) +A.sSerialNumber = fread(fh, 1, 'double=>double');% = 200; (* 8 = SizeSerialNumber *) + A.E9E9Boards=fread(fh, 1, 'int16=>int16');% = 208; (* INT16 *) A.E9CSlowCycles=fread(fh, 1, 'int16=>int16');% = 210; (* INT16 *) A.E9IMonAdc=fread(fh, 1, 'int16=>int16');% = 212; (* INT16 *) From 580d93efdc6f04fe6622ed3c6bcb2cdf7b5fc783 Mon Sep 17 00:00:00 2001 From: ChristianKeine Date: Sun, 23 Jun 2019 11:48:16 -0500 Subject: [PATCH 11/39] enforcing consistency with HEKA specification According to ftp://server.hekahome.de/pub/FileFormat/Patchmasterv9/ --- @HEKA_Importer/HI_ImportHEKAtoMat.asv | 237 ++++++++++++++------------ @HEKA_Importer/HI_ImportHEKAtoMat.m | 234 +++++++++++++------------ 2 files changed, 254 insertions(+), 217 deletions(-) diff --git a/@HEKA_Importer/HI_ImportHEKAtoMat.asv b/@HEKA_Importer/HI_ImportHEKAtoMat.asv index 3c03e63..fd37ddf 100644 --- a/@HEKA_Importer/HI_ImportHEKAtoMat.asv +++ b/@HEKA_Importer/HI_ImportHEKAtoMat.asv @@ -770,115 +770,134 @@ end function A=getAmplifierState(fh) %-------------------------------------------------------------------------- offset=ftell(fh); -A.sStateVersion = fread(fh, 1, 'double=>double');% = 0; (* 8 = SizeStateVersion *) -A.sCurrentGain = fread(fh, 1, 'double=>double');% = 8; (* LONGREAL *) -A.sF2Bandwidth = fread(fh, 1, 'double=>double');% = 16; (* LONGREAL *) - -A.sF2Frequency = fread(fh, 1, 'double=>double');% = 24; (* LONGREAL *) -A.sRsValue = fread(fh, 1, 'double=>double');% = 32; (* LONGREAL *) -A.sRsFraction = fread(fh, 1, 'double=>double');% = 40; (* LONGREAL *) -A.sGLeak=fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) -A.sCFastAmp1=fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) -A.sCFastAmp2=fread(fh, 1, 'double=>double');% = 64; (* LONGREAL *) -A.sCFastTau=fread(fh, 1, 'double=>double');% = 72; (* LONGREAL *) -A.sCSlow=fread(fh, 1, 'double=>double');% = 80; (* LONGREAL *) -A.sGSeries=fread(fh, 1, 'double=>double');% = 88; (* LONGREAL *) -A.sVCStimDacScale=fread(fh, 1, 'double=>double');% = 96; (* LONGREAL *) - -A.sCCStimScale=fread(fh, 1, 'double=>double');% = 104; (* LONGREAL *) -A.sVHold=fread(fh, 1, 'double=>double');% = 112; (* LONGREAL *) -A.sLastVHold=fread(fh, 1, 'double=>double');% = 120; (* LONGREAL *) -A.sVpOffset=fread(fh, 1, 'double=>double');% = 128; (* LONGREAL *) - -A.sVLiquidJunction=fread(fh, 1, 'double=>double');% = 136; (* LONGREAL *) -A.sCCIHold=fread(fh, 1, 'double=>double');% = 144; (* LONGREAL *) -A.E9CSlowStimVolts=fread(fh, 1, 'double=>double');% = 152; (* LONGREAL *) -A.E9CCtr.TrackVHold=fread(fh, 1, 'double=>double');% = 160; (* LONGREAL *) -A.E9TimeoutLength=fread(fh, 1, 'double=>double');% = 168; (* LONGREAL *) -A.E9SearchDelay=fread(fh, 1, 'double=>double');% = 176; (* LONGREAL *) -A.E9MConductance=fread(fh, 1, 'double=>double');% = 184; (* LONGREAL *) -A.E9MCapacitance=fread(fh, 1, 'double=>double');% = 192; (* LONGREAL *) -A.E9SerialNumber=fread(fh, 1, 'double=>double');% = 200; (* 8 = SizeSerialNumber *) -A.E9E9Boards=fread(fh, 1, 'int16=>int16');% = 208; (* INT16 *) -A.E9CSlowCycles=fread(fh, 1, 'int16=>int16');% = 210; (* INT16 *) -A.E9IMonAdc=fread(fh, 1, 'int16=>int16');% = 212; (* INT16 *) -A.E9VMonAdc=fread(fh, 1, 'int16=>int16');% = 214; (* INT16 *) -A.E9MuxAdc=fread(fh, 1, 'int16=>int16');% = 216; (* INT16 *) -A.E9TstDac=fread(fh, 1, 'int16=>int16');% = 218; (* INT16 *) -A.E9StimDac=fread(fh, 1, 'int16=>int16');% = 220; (* INT16 *) -A.E9StimDacOffset=fread(fh, 1, 'int16=>int16');% = 222; (* INT16 *) -A.E9MaxDigitalBit=fread(fh, 1, 'int16=>int16');% = 224; (* INT16 *) -A.E9SpareInt1=fread(fh, 1, 'int16=>int16');% = 226; (* INT16 *) -A.E9SpareInt2=fread(fh, 1, 'int16=>int16');% = 228; (* INT16 *) -A.E9SpareInt3=fread(fh, 1, 'int16=>int16');% = 230; (* INT16 *) - -A.E9AmplKind=fread(fh, 1, 'uint8=>uint8');% = 232; (* BYTE *) -A.E9IsEpc9N=fread(fh, 1, 'uint8=>uint8');% = 233; (* BYTE *) -A.E9ADBoard=fread(fh, 1, 'uint8=>uint8');% = 234; (* BYTE *) -A.E9BoardVersion=fread(fh, 1, 'uint8=>uint8');% = 235; (* BYTE *) -A.E9ActiveE9Board=fread(fh, 1, 'uint8=>uint8');% = 236; (* BYTE *) -A.E9Mode=fread(fh, 1, 'uint8=>uint8');% = 237; (* BYTE *) -A.E9Range=fread(fh, 1, 'uint8=>uint8');% = 238; (* BYTE *) -A.E9F2Response=fread(fh, 1, 'uint8=>uint8');% = 239; (* BYTE *) - -A.E9RsOn=fread(fh, 1, 'uint8=>uint8');% = 240; (* BYTE *) -A.E9CSlowRange=fread(fh, 1, 'uint8=>uint8');% = 241; (* BYTE *) -A.E9CCRange=fread(fh, 1, 'uint8=>uint8');% = 242; (* BYTE *) -A.E9CCGain=fread(fh, 1, 'uint8=>uint8');% = 243; (* BYTE *) -A.E9CSlowToTstDac=fread(fh, 1, 'uint8=>uint8');% = 244; (* BYTE *) -A.E9StimPath=fread(fh, 1, 'uint8=>uint8');% = 245; (* BYTE *) -A.E9CCtr.TrackTau=fread(fh, 1, 'uint8=>uint8');% = 246; (* BYTE *) -A.E9WasClipping=fread(fh, 1, 'uint8=>uint8');% = 247; (* BYTE *) - -A.E9RepetitiveCSlow=fread(fh, 1, 'uint8=>uint8');% = 248; (* BYTE *) -A.E9LastCSlowRange=fread(fh, 1, 'uint8=>uint8');% = 249; (* BYTE *) -A.E9Locked=fread(fh, 1, 'uint8=>uint8');% = 250; (* BYTE *) -A.E9CanCCFast=fread(fh, 1, 'uint8=>uint8');% = 251; (* BYTE *) -A.E9CanLowCCRange=fread(fh, 1, 'uint8=>uint8');% = 252; (* BYTE *) -A.E9CanHighCCRange=fread(fh, 1, 'uint8=>uint8');% = 253; (* BYTE *) -A.E9CanCCtr.Tracking=fread(fh, 1, 'uint8=>uint8');% = 254; (* BYTE *) -A.E9HasVmonPath=fread(fh, 1, 'uint8=>uint8');% = 255; (* BYTE *) - -A.E9HasNewCCMode=fread(fh, 1, 'uint8=>uint8');% = 256; (* BYTE *) -A.E9Selector=fread(fh, 1, 'uint8=>char');% = 257; (* CHAR *) -A.E9HoldInverted=fread(fh, 1, 'uint8=>uint8');% = 258; (* BYTE *) -A.E9AutoCFast=fread(fh, 1, 'uint8=>uint8');% = 259; (* BYTE *) -A.E9AutoCSlow=fread(fh, 1, 'uint8=>uint8');% = 260; (* BYTE *) -A.E9HasVmonX100=fread(fh, 1, 'uint8=>uint8');% = 261; (* BYTE *) -A.E9TestDacOn=fread(fh, 1, 'uint8=>uint8');% = 262; (* BYTE *) -A.E9QMuxAdcOn=fread(fh, 1, 'uint8=>uint8');% = 263; (* BYTE *) - -A.E9RealImon1Bandwidth=fread(fh, 1, 'double=>double');% = 264; (* LONGREAL *) -A.E9StimScale=fread(fh, 1, 'double=>double');% = 272; (* LONGREAL *) - -A.E9Gain=fread(fh, 1, 'uint8=>uint8');% = 280; (* BYTE *) -A.E9Filter1=fread(fh, 1, 'uint8=>uint8');% = 281; (* BYTE *) -A.E9StimFilterOn=fread(fh, 1, 'uint8=>uint8');% = 282; (* BYTE *) -A.E9RsSlow=fread(fh, 1, 'uint8=>uint8');% = 283; (* BYTE *) -A.E9Old1=fread(fh, 1, 'uint8=>uint8');% = 284; (* BYTE *) -A.E9CCCFastOn=fread(fh, 1, 'uint8=>uint8');% = 285; (* BYTE *) -A.E9CCFastSpeed=fread(fh, 1, 'uint8=>uint8');% = 286; (* BYTE *) -A.E9F2Source=fread(fh, 1, 'uint8=>uint8');% = 287; (* BYTE *) - -A.E9TestRange=fread(fh, 1, 'uint8=>uint8');% = 288; (* BYTE *) -A.E9TestDacPath=fread(fh, 1, 'uint8=>uint8');% = 289; (* BYTE *) -A.E9MuxChannel=fread(fh, 1, 'uint8=>uint8');% = 290; (* BYTE *) -A.E9MuxGain64=fread(fh, 1, 'uint8=>uint8');% = 291; (* BYTE *) -A.E9VmonX100=fread(fh, 1, 'uint8=>uint8');% = 292; (* BYTE *) -A.E9IsQuadro=fread(fh, 1, 'uint8=>uint8');% = 293; (* BYTE *) -A.E9SpareBool4=fread(fh, 1, 'uint8=>uint8');% = 294; (* BYTE *) -A.E9SpareBool5=fread(fh, 1, 'uint8=>uint8');% = 295; (* BYTE *) - -A.E9StimFilterHz=fread(fh, 1, 'double=>double');% = 296; (* LONGREAL *) -A.E9RsTau=fread(fh, 1, 'double=>double');% = 304; (* LONGREAL *) -A.E9FilterOffsetDac=fread(fh, 1, 'int16=>int16');% = 312; (* INT16 *) -A.E9ReferenceDac=fread(fh, 1, 'int16=>int16');% = 314; (* INT16 *) -A.E9SpareInt6=fread(fh, 1, 'int16=>int16');% = 316; (* INT16 *) -A.E9SpareInt7=fread(fh, 1, 'int16=>int16');% = 318; (* INT16 *) -A.E9Spares1=320; - -A.E9CalibDate=fread(fh, 2, 'double=>double');% = 344; (* 16 = SizeCalibDate *) -A.E9SelHold=fread(fh, 1, 'double=>double');% = 360; (* LONGREAL *) +A.sStateVersion = fread(fh, 1, 'double=>double');% = 0; (* 8 = SizeStateVersion *) +A.sCurrentGain = fread(fh, 1, 'double=>double');% = 8; (* LONGREAL *) +A.sF2Bandwidth = fread(fh, 1, 'double=>double');% = 16; (* LONGREAL *) +A.sF2Frequency = fread(fh, 1, 'double=>double');% = 24; (* LONGREAL *) +A.sRsValue = fread(fh, 1, 'double=>double');% = 32; (* LONGREAL *) +A.sRsFraction = fread(fh, 1, 'double=>double');% = 40; (* LONGREAL *) +A.sGLeak = fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) +A.sCFastAmp1 = fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) +A.sCFastAmp2 = fread(fh, 1, 'double=>double');% = 64; (* LONGREAL *) +A.sCFastTau = fread(fh, 1, 'double=>double');% = 72; (* LONGREAL *) +A.sCSlow = fread(fh, 1, 'double=>double');% = 80; (* LONGREAL *) +A.sGSeries = fread(fh, 1, 'double=>double');% = 88; (* LONGREAL *) +A.sVCStimDacScale = fread(fh, 1, 'double=>double');% = 96; (* LONGREAL *) +A.sCCStimScale = fread(fh, 1, 'double=>double');% = 104; (* LONGREAL *) +A.sVHold = fread(fh, 1, 'double=>double');% = 112; (* LONGREAL *) +A.sLastVHold = fread(fh, 1, 'double=>double');% = 120; (* LONGREAL *) +A.sVpOffset = fread(fh, 1, 'double=>double');% = 128; (* LONGREAL *) +A.sVLiquidJunction = fread(fh, 1, 'double=>double');% = 136; (* LONGREAL *) +A.sCCIHold = fread(fh, 1, 'double=>double');% = 144; (* LONGREAL *) +A.sCSlowStimVolts = fread(fh, 1, 'double=>double');% = 152; (* LONGREAL *) +A.sCCTrackVHold = fread(fh, 1, 'double=>double');% = 160; (* LONGREAL *) +A.sTimeoutCSlow = fread(fh, 1, 'double=>double');% = 168; (* LONGREAL *) +A.sSearchDelay = fread(fh, 1, 'double=>double');% = 176; (* LONGREAL *) +A.sMConductance = fread(fh, 1, 'double=>double');% = 184; (* LONGREAL *) +A.sMCapacitance = fread(fh, 1, 'double=>double');% = 192; (* LONGREAL *) +A.sSerialNumber = fread(fh, 1, 'double=>double');% = 200; (* 8 = SizeSerialNumber *) + +A.sE9Boards = fread(fh, 1, 'int16=>int16');% = 208; (* INT16 *) +A.sCSlowCycles = fread(fh, 1, 'int16=>int16');% = 210; (* INT16 *) +A.sIMonAdc = fread(fh, 1, 'int16=>int16');% = 212; (* INT16 *) +A.sVMonAdc = fread(fh, 1, 'int16=>int16');% = 214; (* INT16 *) + +A.sMuxAdc = fread(fh, 1, 'int16=>int16');% = 216; (* INT16 *) +A.sTestDac = fread(fh, 1, 'int16=>int16');% = 218; (* INT16 *) +A.sStimDac = fread(fh, 1, 'int16=>int16');% = 220; (* INT16 *) +A.sStimDacOffset = fread(fh, 1, 'int16=>int16');% = 222; (* INT16 *) + +A.sMaxDigitalBit = fread(fh, 1, 'int16=>int16');% = 224; (* INT16 *) +A.sHasCFastHigh = fread(fh, 1, 'uint8=>uint8');% = 226; (* BYTE *) +A.sCFastHigh = fread(fh, 1, 'uint8=>uint8');% = 227; (* BYTE *) +A.sHasBathSense = fread(fh, 1, 'uint8=>uint8');% = 228; (* BYTE *) +A.sBathSense = fread(fh, 1, 'uint8=>uint8');% = 229; (* BYTE *) +A.sHasF2Bypass = fread(fh, 1, 'uint8=>uint8');% = 230; (* BYTE *) +A.sF2Mode = fread(fh, 1, 'uint8=>uint8');% = 231; (* BYTE *) + +A.sAmplKind = fread(fh, 1, 'uint8=>uint8');% = 232; (* BYTE *) +A.sIsEpc9N = fread(fh, 1, 'uint8=>uint8');% = 233; (* BYTE *) +A.sADBoard = fread(fh, 1, 'uint8=>uint8');% = 234; (* BYTE *) +A.sBoardVersion = fread(fh, 1, 'uint8=>uint8');% = 235; (* BYTE *) +A.sActiveE9Board = fread(fh, 1, 'uint8=>uint8');% = 236; (* BYTE *) +A.sMode = fread(fh, 1, 'uint8=>uint8');% = 237; (* BYTE *) +A.sRange = fread(fh, 1, 'uint8=>uint8');% = 238; (* BYTE *) +A.sF2Response = fread(fh, 1, 'uint8=>uint8');% = 239; (* BYTE *) + +A.sRsOn = fread(fh, 1, 'uint8=>uint8');% = 240; (* BYTE *) +A.sCSlowRange = fread(fh, 1, 'uint8=>uint8');% = 241; (* BYTE *) +A.sCCRange = fread(fh, 1, 'uint8=>uint8');% = 242; (* BYTE *) +A.sCCGain = fread(fh, 1, 'uint8=>uint8');% = 243; (* BYTE *) +A.sCSlowToTestDac = fread(fh, 1, 'uint8=>uint8');% = 244; (* BYTE *) +A.sStimPath = fread(fh, 1, 'uint8=>uint8');% = 245; (* BYTE *) +A.sCCTrackTau = fread(fh, 1, 'uint8=>uint8');% = 246; (* BYTE *) +A.sWasClipping = fread(fh, 1, 'uint8=>uint8');% = 247; (* BYTE *) + +A.sRepetitiveCSlow = fread(fh, 1, 'uint8=>uint8');% = 248; (* BYTE *) +A.sLastCSlowRange = fread(fh, 1, 'uint8=>uint8');% = 249; (* BYTE *) + A.sOld1 = fread(fh, 1, 'uint8=>uint8');% = 250; (* BYTE *) +A.sCanCCFast = fread(fh, 1, 'uint8=>uint8');% = 251; (* BYTE *) +A.sCanLowCCRange = fread(fh, 1, 'uint8=>uint8');% = 252; (* BYTE *) +A.sCanHighCCRange = fread(fh, 1, 'uint8=>uint8');% = 253; (* BYTE *) +A.sCanCCTrackingg = fread(fh, 1, 'uint8=>uint8');% = 254; (* BYTE *) +A.sCHasVmonPath = fread(fh, 1, 'uint8=>uint8');% = 255; (* BYTE *) + +A.sHasNewCCMode = fread(fh, 1, 'uint8=>uint8');% = 256; (* BYTE *) +A.sSelector = fread(fh, 1, 'uint8=>char');% = 257; (* CHAR *) +A.sHoldInverted = fread(fh, 1, 'uint8=>uint8');% = 258; (* BYTE *) +A.sAutoCFast = fread(fh, 1, 'uint8=>uint8');% = 259; (* BYTE *) +A.sAutoCSlow = fread(fh, 1, 'uint8=>uint8');% = 260; (* BYTE *) +A.sHasVmonX100 = fread(fh, 1, 'uint8=>uint8');% = 261; (* BYTE *) +A.sTestDacOn = fread(fh, 1, 'uint8=>uint8');% = 262; (* BYTE *) +A.sQMuxAdcOn = fread(fh, 1, 'uint8=>uint8');% = 263; (* BYTE *) + +A.sImon1Bandwidth = fread(fh, 1, 'double=>double');% = 264; (* LONGREAL *) +A.sStimScale = fread(fh, 1, 'double=>double');% = 272; (* LONGREAL *) + +A.sGain = fread(fh, 1, 'uint8=>uint8');% = 280; (* BYTE *) +A.sFilter1 = fread(fh, 1, 'uint8=>uint8');% = 281; (* BYTE *) +A.sStimFilterOn = fread(fh, 1, 'uint8=>uint8');% = 282; (* BYTE *) +A.sRsSlow = fread(fh, 1, 'uint8=>uint8');% = 283; (* BYTE *) + A.sOld2 = fread(fh, 1, 'uint8=>uint8');% = 284; (* BYTE *) +A.sCCCFastOn = fread(fh, 1, 'uint8=>uint8');% = 285; (* BYTE *) +A.sCCFastSpeed = fread(fh, 1, 'uint8=>uint8');% = 286; (* BYTE *) +A.sF2Source = fread(fh, 1, 'uint8=>uint8');% = 287; (* BYTE *) + +A.sTestRange = fread(fh, 1, 'uint8=>uint8');% = 288; (* BYTE *) +A.sTestDacPath = fread(fh, 1, 'uint8=>uint8');% = 289; (* BYTE *) +A.sMuxChannel = fread(fh, 1, 'uint8=>uint8');% = 290; (* BYTE *) +A.sMuxGain64 = fread(fh, 1, 'uint8=>uint8');% = 291; (* BYTE *) +A.sVmonX100 = fread(fh, 1, 'uint8=>uint8');% = 292; (* BYTE *) +A.sIsQuadro = fread(fh, 1, 'uint8=>uint8');% = 293; (* BYTE *) +A.sF1Mode = fread(fh, 1, 'uint8=>uint8');% = 294; (* BYTE *) + A.sOld3 = fread(fh, 1, 'uint8=>uint8');% = 295; (* BYTE *) + +A.sStimFilterHz = fread(fh, 1, 'double=>double');% = 296; (* LONGREAL *) +A.sRsTau = fread(fh, 1, 'double=>double');% = 304; (* LONGREAL *) +A.sDacToAdcDelay = fread(fh, 1, 'double=>double');% = 312; (* LONGREAL *) +A.sInputFilterTau = fread(fh, 1, 'double=>double');% = 320; (* LONGREAL *) +A.sOutputFilterTau = fread(fh, 1, 'double=>double');% = 328; (* LONGREAL *) +A.sVmonFactor = fread(fh, 1, 'double=>double');% = 336; (* LONGREAL *) +A.sCalibDate = fread(fh, 2, 'double=>double');% = 344; (* 16 = SizeCalibDate *) +A.sVmonOffset = fread(fh, 1, 'double=>double');% = 360; (* LONGREAL *) + +A.sEEPROMKind = fread(fh, 1, 'uint8=>uint8'); = 368; (* BYTE *) +A.sVrefX2 = fread(fh, 1, 'uint8=>uint8'); = 369; (* BYTE *) +A.sHasVrefX2AndF2Vmon = fread(fh, 1, 'uint8=>uint8'); = 370; (* BYTE *) +A.sSpare1 = 371; (* BYTE *) +A.sSpare2 = 372; (* BYTE *) +A.sSpare3 = 373; (* BYTE *) +A.sSpare4 = 374; (* BYTE *) +A.sSpare5 = 375; (* BYTE *) + + sCCStimDacScale = 376; (* LONGREAL *) + sVmonFiltBandwidth = 384; (* LONGREAL *) + sVmonFiltFrequency = 392; (* LONGREAL *) + AmplifierStateSize = 400; (* = 50 * 8 *) + + + + A.AmplifierStateSize = 400; fseek(fh, offset+A.AmplifierStateSize, 'bof'); diff --git a/@HEKA_Importer/HI_ImportHEKAtoMat.m b/@HEKA_Importer/HI_ImportHEKAtoMat.m index 577daa8..e289e90 100644 --- a/@HEKA_Importer/HI_ImportHEKAtoMat.m +++ b/@HEKA_Importer/HI_ImportHEKAtoMat.m @@ -770,114 +770,132 @@ function A=getAmplifierState(fh) %-------------------------------------------------------------------------- offset=ftell(fh); -A.sStateVersion = fread(fh, 1, 'double=>double');% = 0; (* 8 = SizeStateVersion *) -A.sCurrentGain = fread(fh, 1, 'double=>double');% = 8; (* LONGREAL *) -A.sF2Bandwidth = fread(fh, 1, 'double=>double');% = 16; (* LONGREAL *) -A.sF2Frequency = fread(fh, 1, 'double=>double');% = 24; (* LONGREAL *) -A.sRsValue = fread(fh, 1, 'double=>double');% = 32; (* LONGREAL *) -A.sRsFraction = fread(fh, 1, 'double=>double');% = 40; (* LONGREAL *) -A.sGLeak = fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) -A.sCFastAmp1 = fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) -A.sCFastAmp2 = fread(fh, 1, 'double=>double');% = 64; (* LONGREAL *) -A.sCFastTau = fread(fh, 1, 'double=>double');% = 72; (* LONGREAL *) -A.sCSlow = fread(fh, 1, 'double=>double');% = 80; (* LONGREAL *) -A.sGSeries = fread(fh, 1, 'double=>double');% = 88; (* LONGREAL *) -A.sVCStimDacScale = fread(fh, 1, 'double=>double');% = 96; (* LONGREAL *) -A.sCCStimScale = fread(fh, 1, 'double=>double');% = 104; (* LONGREAL *) -A.sVHold = fread(fh, 1, 'double=>double');% = 112; (* LONGREAL *) -A.sLastVHold = fread(fh, 1, 'double=>double');% = 120; (* LONGREAL *) -A.sVpOffset = fread(fh, 1, 'double=>double');% = 128; (* LONGREAL *) -A.sVLiquidJunction = fread(fh, 1, 'double=>double');% = 136; (* LONGREAL *) -A.sCCIHold = fread(fh, 1, 'double=>double');% = 144; (* LONGREAL *) -A.sCSlowStimVolts = fread(fh, 1, 'double=>double');% = 152; (* LONGREAL *) -A.sCCTrackVHold = fread(fh, 1, 'double=>double');% = 160; (* LONGREAL *) -A.sTimeoutCSlow = fread(fh, 1, 'double=>double');% = 168; (* LONGREAL *) -A.sSearchDelay = fread(fh, 1, 'double=>double');% = 176; (* LONGREAL *) -A.sMConductance = fread(fh, 1, 'double=>double');% = 184; (* LONGREAL *) -A.sMCapacitance = fread(fh, 1, 'double=>double');% = 192; (* LONGREAL *) -A.sSerialNumber = fread(fh, 1, 'double=>double');% = 200; (* 8 = SizeSerialNumber *) - -A.E9E9Boards=fread(fh, 1, 'int16=>int16');% = 208; (* INT16 *) -A.E9CSlowCycles=fread(fh, 1, 'int16=>int16');% = 210; (* INT16 *) -A.E9IMonAdc=fread(fh, 1, 'int16=>int16');% = 212; (* INT16 *) -A.E9VMonAdc=fread(fh, 1, 'int16=>int16');% = 214; (* INT16 *) -A.E9MuxAdc=fread(fh, 1, 'int16=>int16');% = 216; (* INT16 *) -A.E9TstDac=fread(fh, 1, 'int16=>int16');% = 218; (* INT16 *) -A.E9StimDac=fread(fh, 1, 'int16=>int16');% = 220; (* INT16 *) -A.E9StimDacOffset=fread(fh, 1, 'int16=>int16');% = 222; (* INT16 *) -A.E9MaxDigitalBit=fread(fh, 1, 'int16=>int16');% = 224; (* INT16 *) -A.E9SpareInt1=fread(fh, 1, 'int16=>int16');% = 226; (* INT16 *) -A.E9SpareInt2=fread(fh, 1, 'int16=>int16');% = 228; (* INT16 *) -A.E9SpareInt3=fread(fh, 1, 'int16=>int16');% = 230; (* INT16 *) - -A.E9AmplKind=fread(fh, 1, 'uint8=>uint8');% = 232; (* BYTE *) -A.E9IsEpc9N=fread(fh, 1, 'uint8=>uint8');% = 233; (* BYTE *) -A.E9ADBoard=fread(fh, 1, 'uint8=>uint8');% = 234; (* BYTE *) -A.E9BoardVersion=fread(fh, 1, 'uint8=>uint8');% = 235; (* BYTE *) -A.E9ActiveE9Board=fread(fh, 1, 'uint8=>uint8');% = 236; (* BYTE *) -A.E9Mode=fread(fh, 1, 'uint8=>uint8');% = 237; (* BYTE *) -A.E9Range=fread(fh, 1, 'uint8=>uint8');% = 238; (* BYTE *) -A.E9F2Response=fread(fh, 1, 'uint8=>uint8');% = 239; (* BYTE *) - -A.E9RsOn=fread(fh, 1, 'uint8=>uint8');% = 240; (* BYTE *) -A.E9CSlowRange=fread(fh, 1, 'uint8=>uint8');% = 241; (* BYTE *) -A.E9CCRange=fread(fh, 1, 'uint8=>uint8');% = 242; (* BYTE *) -A.E9CCGain=fread(fh, 1, 'uint8=>uint8');% = 243; (* BYTE *) -A.E9CSlowToTstDac=fread(fh, 1, 'uint8=>uint8');% = 244; (* BYTE *) -A.E9StimPath=fread(fh, 1, 'uint8=>uint8');% = 245; (* BYTE *) -A.E9CCtr.TrackTau=fread(fh, 1, 'uint8=>uint8');% = 246; (* BYTE *) -A.E9WasClipping=fread(fh, 1, 'uint8=>uint8');% = 247; (* BYTE *) - -A.E9RepetitiveCSlow=fread(fh, 1, 'uint8=>uint8');% = 248; (* BYTE *) -A.E9LastCSlowRange=fread(fh, 1, 'uint8=>uint8');% = 249; (* BYTE *) -A.E9Locked=fread(fh, 1, 'uint8=>uint8');% = 250; (* BYTE *) -A.E9CanCCFast=fread(fh, 1, 'uint8=>uint8');% = 251; (* BYTE *) -A.E9CanLowCCRange=fread(fh, 1, 'uint8=>uint8');% = 252; (* BYTE *) -A.E9CanHighCCRange=fread(fh, 1, 'uint8=>uint8');% = 253; (* BYTE *) -A.E9CanCCtr.Tracking=fread(fh, 1, 'uint8=>uint8');% = 254; (* BYTE *) -A.E9HasVmonPath=fread(fh, 1, 'uint8=>uint8');% = 255; (* BYTE *) - -A.E9HasNewCCMode=fread(fh, 1, 'uint8=>uint8');% = 256; (* BYTE *) -A.E9Selector=fread(fh, 1, 'uint8=>char');% = 257; (* CHAR *) -A.E9HoldInverted=fread(fh, 1, 'uint8=>uint8');% = 258; (* BYTE *) -A.E9AutoCFast=fread(fh, 1, 'uint8=>uint8');% = 259; (* BYTE *) -A.E9AutoCSlow=fread(fh, 1, 'uint8=>uint8');% = 260; (* BYTE *) -A.E9HasVmonX100=fread(fh, 1, 'uint8=>uint8');% = 261; (* BYTE *) -A.E9TestDacOn=fread(fh, 1, 'uint8=>uint8');% = 262; (* BYTE *) -A.E9QMuxAdcOn=fread(fh, 1, 'uint8=>uint8');% = 263; (* BYTE *) - -A.E9RealImon1Bandwidth=fread(fh, 1, 'double=>double');% = 264; (* LONGREAL *) -A.E9StimScale=fread(fh, 1, 'double=>double');% = 272; (* LONGREAL *) - -A.E9Gain=fread(fh, 1, 'uint8=>uint8');% = 280; (* BYTE *) -A.E9Filter1=fread(fh, 1, 'uint8=>uint8');% = 281; (* BYTE *) -A.E9StimFilterOn=fread(fh, 1, 'uint8=>uint8');% = 282; (* BYTE *) -A.E9RsSlow=fread(fh, 1, 'uint8=>uint8');% = 283; (* BYTE *) -A.E9Old1=fread(fh, 1, 'uint8=>uint8');% = 284; (* BYTE *) -A.E9CCCFastOn=fread(fh, 1, 'uint8=>uint8');% = 285; (* BYTE *) -A.E9CCFastSpeed=fread(fh, 1, 'uint8=>uint8');% = 286; (* BYTE *) -A.E9F2Source=fread(fh, 1, 'uint8=>uint8');% = 287; (* BYTE *) - -A.E9TestRange=fread(fh, 1, 'uint8=>uint8');% = 288; (* BYTE *) -A.E9TestDacPath=fread(fh, 1, 'uint8=>uint8');% = 289; (* BYTE *) -A.E9MuxChannel=fread(fh, 1, 'uint8=>uint8');% = 290; (* BYTE *) -A.E9MuxGain64=fread(fh, 1, 'uint8=>uint8');% = 291; (* BYTE *) -A.E9VmonX100=fread(fh, 1, 'uint8=>uint8');% = 292; (* BYTE *) -A.E9IsQuadro=fread(fh, 1, 'uint8=>uint8');% = 293; (* BYTE *) -A.E9SpareBool4=fread(fh, 1, 'uint8=>uint8');% = 294; (* BYTE *) -A.E9SpareBool5=fread(fh, 1, 'uint8=>uint8');% = 295; (* BYTE *) - -A.E9StimFilterHz=fread(fh, 1, 'double=>double');% = 296; (* LONGREAL *) -A.E9RsTau=fread(fh, 1, 'double=>double');% = 304; (* LONGREAL *) -A.E9FilterOffsetDac=fread(fh, 1, 'int16=>int16');% = 312; (* INT16 *) -A.E9ReferenceDac=fread(fh, 1, 'int16=>int16');% = 314; (* INT16 *) -A.E9SpareInt6=fread(fh, 1, 'int16=>int16');% = 316; (* INT16 *) -A.E9SpareInt7=fread(fh, 1, 'int16=>int16');% = 318; (* INT16 *) -A.E9Spares1=320; - -A.E9CalibDate=fread(fh, 2, 'double=>double');% = 344; (* 16 = SizeCalibDate *) -A.E9SelHold=fread(fh, 1, 'double=>double');% = 360; (* LONGREAL *) -A.AmplifierStateSize = 400; +A.sStateVersion = fread(fh, 1, 'double=>double');% = 0; (* 8 = SizeStateVersion *) +A.sCurrentGain = fread(fh, 1, 'double=>double');% = 8; (* LONGREAL *) +A.sF2Bandwidth = fread(fh, 1, 'double=>double');% = 16; (* LONGREAL *) +A.sF2Frequency = fread(fh, 1, 'double=>double');% = 24; (* LONGREAL *) +A.sRsValue = fread(fh, 1, 'double=>double');% = 32; (* LONGREAL *) +A.sRsFraction = fread(fh, 1, 'double=>double');% = 40; (* LONGREAL *) +A.sGLeak = fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) +A.sCFastAmp1 = fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) +A.sCFastAmp2 = fread(fh, 1, 'double=>double');% = 64; (* LONGREAL *) +A.sCFastTau = fread(fh, 1, 'double=>double');% = 72; (* LONGREAL *) +A.sCSlow = fread(fh, 1, 'double=>double');% = 80; (* LONGREAL *) +A.sGSeries = fread(fh, 1, 'double=>double');% = 88; (* LONGREAL *) +A.sVCStimDacScale = fread(fh, 1, 'double=>double');% = 96; (* LONGREAL *) +A.sCCStimScale = fread(fh, 1, 'double=>double');% = 104; (* LONGREAL *) +A.sVHold = fread(fh, 1, 'double=>double');% = 112; (* LONGREAL *) +A.sLastVHold = fread(fh, 1, 'double=>double');% = 120; (* LONGREAL *) +A.sVpOffset = fread(fh, 1, 'double=>double');% = 128; (* LONGREAL *) +A.sVLiquidJunction = fread(fh, 1, 'double=>double');% = 136; (* LONGREAL *) +A.sCCIHold = fread(fh, 1, 'double=>double');% = 144; (* LONGREAL *) +A.sCSlowStimVolts = fread(fh, 1, 'double=>double');% = 152; (* LONGREAL *) +A.sCCTrackVHold = fread(fh, 1, 'double=>double');% = 160; (* LONGREAL *) +A.sTimeoutCSlow = fread(fh, 1, 'double=>double');% = 168; (* LONGREAL *) +A.sSearchDelay = fread(fh, 1, 'double=>double');% = 176; (* LONGREAL *) +A.sMConductance = fread(fh, 1, 'double=>double');% = 184; (* LONGREAL *) +A.sMCapacitance = fread(fh, 1, 'double=>double');% = 192; (* LONGREAL *) +A.sSerialNumber = fread(fh, 1, 'double=>double');% = 200; (* 8 = SizeSerialNumber *) + +A.sE9Boards = fread(fh, 1, 'int16=>int16');% = 208; (* INT16 *) +A.sCSlowCycles = fread(fh, 1, 'int16=>int16');% = 210; (* INT16 *) +A.sIMonAdc = fread(fh, 1, 'int16=>int16');% = 212; (* INT16 *) +A.sVMonAdc = fread(fh, 1, 'int16=>int16');% = 214; (* INT16 *) + +A.sMuxAdc = fread(fh, 1, 'int16=>int16');% = 216; (* INT16 *) +A.sTestDac = fread(fh, 1, 'int16=>int16');% = 218; (* INT16 *) +A.sStimDac = fread(fh, 1, 'int16=>int16');% = 220; (* INT16 *) +A.sStimDacOffset = fread(fh, 1, 'int16=>int16');% = 222; (* INT16 *) + +A.sMaxDigitalBit = fread(fh, 1, 'int16=>int16');% = 224; (* INT16 *) +A.sHasCFastHigh = fread(fh, 1, 'uint8=>uint8');% = 226; (* BYTE *) +A.sCFastHigh = fread(fh, 1, 'uint8=>uint8');% = 227; (* BYTE *) +A.sHasBathSense = fread(fh, 1, 'uint8=>uint8');% = 228; (* BYTE *) +A.sBathSense = fread(fh, 1, 'uint8=>uint8');% = 229; (* BYTE *) +A.sHasF2Bypass = fread(fh, 1, 'uint8=>uint8');% = 230; (* BYTE *) +A.sF2Mode = fread(fh, 1, 'uint8=>uint8');% = 231; (* BYTE *) + +A.sAmplKind = fread(fh, 1, 'uint8=>uint8');% = 232; (* BYTE *) +A.sIsEpc9N = fread(fh, 1, 'uint8=>uint8');% = 233; (* BYTE *) +A.sADBoard = fread(fh, 1, 'uint8=>uint8');% = 234; (* BYTE *) +A.sBoardVersion = fread(fh, 1, 'uint8=>uint8');% = 235; (* BYTE *) +A.sActiveE9Board = fread(fh, 1, 'uint8=>uint8');% = 236; (* BYTE *) +A.sMode = fread(fh, 1, 'uint8=>uint8');% = 237; (* BYTE *) +A.sRange = fread(fh, 1, 'uint8=>uint8');% = 238; (* BYTE *) +A.sF2Response = fread(fh, 1, 'uint8=>uint8');% = 239; (* BYTE *) + +A.sRsOn = fread(fh, 1, 'uint8=>uint8');% = 240; (* BYTE *) +A.sCSlowRange = fread(fh, 1, 'uint8=>uint8');% = 241; (* BYTE *) +A.sCCRange = fread(fh, 1, 'uint8=>uint8');% = 242; (* BYTE *) +A.sCCGain = fread(fh, 1, 'uint8=>uint8');% = 243; (* BYTE *) +A.sCSlowToTestDac = fread(fh, 1, 'uint8=>uint8');% = 244; (* BYTE *) +A.sStimPath = fread(fh, 1, 'uint8=>uint8');% = 245; (* BYTE *) +A.sCCTrackTau = fread(fh, 1, 'uint8=>uint8');% = 246; (* BYTE *) +A.sWasClipping = fread(fh, 1, 'uint8=>uint8');% = 247; (* BYTE *) + +A.sRepetitiveCSlow = fread(fh, 1, 'uint8=>uint8');% = 248; (* BYTE *) +A.sLastCSlowRange = fread(fh, 1, 'uint8=>uint8');% = 249; (* BYTE *) + A.sOld1 = fread(fh, 1, 'uint8=>uint8');% = 250; (* BYTE *) +A.sCanCCFast = fread(fh, 1, 'uint8=>uint8');% = 251; (* BYTE *) +A.sCanLowCCRange = fread(fh, 1, 'uint8=>uint8');% = 252; (* BYTE *) +A.sCanHighCCRange = fread(fh, 1, 'uint8=>uint8');% = 253; (* BYTE *) +A.sCanCCTrackingg = fread(fh, 1, 'uint8=>uint8');% = 254; (* BYTE *) +A.sCHasVmonPath = fread(fh, 1, 'uint8=>uint8');% = 255; (* BYTE *) + +A.sHasNewCCMode = fread(fh, 1, 'uint8=>uint8');% = 256; (* BYTE *) +A.sSelector = fread(fh, 1, 'uint8=>char');% = 257; (* CHAR *) +A.sHoldInverted = fread(fh, 1, 'uint8=>uint8');% = 258; (* BYTE *) +A.sAutoCFast = fread(fh, 1, 'uint8=>uint8');% = 259; (* BYTE *) +A.sAutoCSlow = fread(fh, 1, 'uint8=>uint8');% = 260; (* BYTE *) +A.sHasVmonX100 = fread(fh, 1, 'uint8=>uint8');% = 261; (* BYTE *) +A.sTestDacOn = fread(fh, 1, 'uint8=>uint8');% = 262; (* BYTE *) +A.sQMuxAdcOn = fread(fh, 1, 'uint8=>uint8');% = 263; (* BYTE *) + +A.sImon1Bandwidth = fread(fh, 1, 'double=>double');% = 264; (* LONGREAL *) +A.sStimScale = fread(fh, 1, 'double=>double');% = 272; (* LONGREAL *) + +A.sGain = fread(fh, 1, 'uint8=>uint8');% = 280; (* BYTE *) +A.sFilter1 = fread(fh, 1, 'uint8=>uint8');% = 281; (* BYTE *) +A.sStimFilterOn = fread(fh, 1, 'uint8=>uint8');% = 282; (* BYTE *) +A.sRsSlow = fread(fh, 1, 'uint8=>uint8');% = 283; (* BYTE *) + A.sOld2 = fread(fh, 1, 'uint8=>uint8');% = 284; (* BYTE *) +A.sCCCFastOn = fread(fh, 1, 'uint8=>uint8');% = 285; (* BYTE *) +A.sCCFastSpeed = fread(fh, 1, 'uint8=>uint8');% = 286; (* BYTE *) +A.sF2Source = fread(fh, 1, 'uint8=>uint8');% = 287; (* BYTE *) + +A.sTestRange = fread(fh, 1, 'uint8=>uint8');% = 288; (* BYTE *) +A.sTestDacPath = fread(fh, 1, 'uint8=>uint8');% = 289; (* BYTE *) +A.sMuxChannel = fread(fh, 1, 'uint8=>uint8');% = 290; (* BYTE *) +A.sMuxGain64 = fread(fh, 1, 'uint8=>uint8');% = 291; (* BYTE *) +A.sVmonX100 = fread(fh, 1, 'uint8=>uint8');% = 292; (* BYTE *) +A.sIsQuadro = fread(fh, 1, 'uint8=>uint8');% = 293; (* BYTE *) +A.sF1Mode = fread(fh, 1, 'uint8=>uint8');% = 294; (* BYTE *) + A.sOld3 = fread(fh, 1, 'uint8=>uint8');% = 295; (* BYTE *) + +A.sStimFilterHz = fread(fh, 1, 'double=>double');% = 296; (* LONGREAL *) +A.sRsTau = fread(fh, 1, 'double=>double');% = 304; (* LONGREAL *) +A.sDacToAdcDelay = fread(fh, 1, 'double=>double');% = 312; (* LONGREAL *) +A.sInputFilterTau = fread(fh, 1, 'double=>double');% = 320; (* LONGREAL *) +A.sOutputFilterTau = fread(fh, 1, 'double=>double');% = 328; (* LONGREAL *) +A.sVmonFactor = fread(fh, 1, 'double=>double');% = 336; (* LONGREAL *) +A.sCalibDate = fread(fh, 2, 'double=>double');% = 344; (* 16 = SizeCalibDate *) +A.sVmonOffset = fread(fh, 1, 'double=>double');% = 360; (* LONGREAL *) + +A.sEEPROMKind = fread(fh, 1, 'uint8=>uint8');% = 368; (* BYTE *) +A.sVrefX2 = fread(fh, 1, 'uint8=>uint8');% = 369; (* BYTE *) +A.sHasVrefX2AndF2Vmon = fread(fh, 1, 'uint8=>uint8');% = 370; (* BYTE *) +A.sSpare1 = fread(fh, 1, 'uint8=>uint8');% = 371; (* BYTE *) +A.sSpare2 = fread(fh, 1, 'uint8=>uint8');% = 372; (* BYTE *) +A.sSpare3 = fread(fh, 1, 'uint8=>uint8');% = 373; (* BYTE *) +A.sSpare4 = fread(fh, 1, 'uint8=>uint8');% = 374; (* BYTE *) +A.sSpare5 = fread(fh, 1, 'uint8=>uint8');% = 375; (* BYTE *) + +A.sCCStimDacScale = fread(fh, 1, 'double=>double');% = 376; (* LONGREAL *) +A.sVmonFiltBandwidth = fread(fh, 1, 'double=>double');% = 384; (* LONGREAL *) +A.sVmonFiltFrequency = fread(fh, 1, 'double=>double');% = 392; (* LONGREAL *) +A.AmplifierStateSize = 400;% (* = 50 * 8 *) + + fseek(fh, offset+A.AmplifierStateSize, 'bof'); end From 55292fca37c66ee98d725e7974c708b24da02c56 Mon Sep 17 00:00:00 2001 From: ChristianKeine Date: Sun, 23 Jun 2019 12:05:24 -0500 Subject: [PATCH 12/39] updating import groups --- @HEKA_Importer/HI_ImportHEKAtoMat.asv | 192 +++++++++++++------------- @HEKA_Importer/HI_ImportHEKAtoMat.m | 31 +++-- 2 files changed, 112 insertions(+), 111 deletions(-) diff --git a/@HEKA_Importer/HI_ImportHEKAtoMat.asv b/@HEKA_Importer/HI_ImportHEKAtoMat.asv index fd37ddf..6a6f83f 100644 --- a/@HEKA_Importer/HI_ImportHEKAtoMat.asv +++ b/@HEKA_Importer/HI_ImportHEKAtoMat.asv @@ -749,19 +749,23 @@ end function L=getSeLockInParams(fh) %-------------------------------------------------------------------------- offset=ftell(fh); -L.loExtCalPhase=fread(fh, 1, 'double=>double') ;% = 0; (* LONGREAL *) -L.loExtCalAtten=fread(fh, 1, 'double=>double') ;% = 8; (* LONGREAL *) -L.loPLPhase=fread(fh, 1, 'double=>double') ;% = 16; (* LONGREAL *) -L.loPLPhaseY1=fread(fh, 1, 'double=>double') ;% = 24; (* LONGREAL *) -L.loPLPhaseY2=fread(fh, 1, 'double=>double') ;% = 32; (* LONGREAL *) -L.loUsedPhaseShift=fread(fh, 1, 'double=>double') ;% = 40; (* LONGREAL *) -L.loUsedAttenuation=fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) -L.loFiller1=fread(fh, 1, 'double=>double'); -L.loExtCalValid=fread(fh, 1, 'uint8=>logical') ;% = 64; (* BOOLEAN *) -L.loPLPhaseValid=fread(fh, 1, 'uint8=>logical') ;% = 65; (* BOOLEAN *) -L.loLockInMode=fread(fh, 1, 'uint8=>uint8') ;% = 66; (* BYTE *) -L.loCalMode=fread(fh, 1, 'uint8=>uint8') ;% = 67; (* BYTE *) -L.LockInParamsSize=96; +L.loExtCalPhase = fread(fh, 1, 'double=>double');% = 0; (* LONGREAL *) +L.loExtCalAtten = fread(fh, 1, 'double=>double');% = 8; (* LONGREAL *) +L.loPLPhase = fread(fh, 1, 'double=>double');% = 16; (* LONGREAL *) +L.loPLPhaseY1 = fread(fh, 1, 'double=>double');% = 24; (* LONGREAL *) +L.loPLPhaseY2 = fread(fh, 1, 'double=>double');% = 32; (* LONGREAL *) +L.loUsedPhaseShift = fread(fh, 1, 'double=>double');% = 40; (* LONGREAL *) +L.loUsedAttenuation = fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) + L.loSpare = fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) +L.loExtCalValid = fread(fh, 1, 'uint8=>logical');% = 64; (* BOOLEAN *) +L.loPLPhaseValid = fread(fh, 1, 'uint8=>logical');% = 65; (* BOOLEAN *) +L.loLockInMode = fread(fh, 1, 'uint8=>uint8');% = 66; (* BYTE *) +L.loCalMode = fread(fh, 1, 'uint8=>uint8');% = 67; (* BYTE *) + L.loSpare2 = fread(fh, 3, 'double=>double');% = 68; (* LONGREAL *) + L.loSpare3 = fread(fh, 3, 'double=>double');% = 68; (* LONGREAL *) + L.loSpare3 = fread(fh, 3, 'double=>double'); +L.LockInParamsSize = 96; + fseek(fh, offset+L.LockInParamsSize, 'bof'); end @@ -779,73 +783,73 @@ A.sRsFraction = fread(fh, 1, 'double=>double');% = 40; (* LONGREAL *) A.sGLeak = fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) A.sCFastAmp1 = fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) A.sCFastAmp2 = fread(fh, 1, 'double=>double');% = 64; (* LONGREAL *) -A.sCFastTau = fread(fh, 1, 'double=>double');% = 72; (* LONGREAL *) -A.sCSlow = fread(fh, 1, 'double=>double');% = 80; (* LONGREAL *) -A.sGSeries = fread(fh, 1, 'double=>double');% = 88; (* LONGREAL *) -A.sVCStimDacScale = fread(fh, 1, 'double=>double');% = 96; (* LONGREAL *) -A.sCCStimScale = fread(fh, 1, 'double=>double');% = 104; (* LONGREAL *) -A.sVHold = fread(fh, 1, 'double=>double');% = 112; (* LONGREAL *) -A.sLastVHold = fread(fh, 1, 'double=>double');% = 120; (* LONGREAL *) -A.sVpOffset = fread(fh, 1, 'double=>double');% = 128; (* LONGREAL *) -A.sVLiquidJunction = fread(fh, 1, 'double=>double');% = 136; (* LONGREAL *) -A.sCCIHold = fread(fh, 1, 'double=>double');% = 144; (* LONGREAL *) -A.sCSlowStimVolts = fread(fh, 1, 'double=>double');% = 152; (* LONGREAL *) -A.sCCTrackVHold = fread(fh, 1, 'double=>double');% = 160; (* LONGREAL *) -A.sTimeoutCSlow = fread(fh, 1, 'double=>double');% = 168; (* LONGREAL *) -A.sSearchDelay = fread(fh, 1, 'double=>double');% = 176; (* LONGREAL *) -A.sMConductance = fread(fh, 1, 'double=>double');% = 184; (* LONGREAL *) -A.sMCapacitance = fread(fh, 1, 'double=>double');% = 192; (* LONGREAL *) -A.sSerialNumber = fread(fh, 1, 'double=>double');% = 200; (* 8 = SizeSerialNumber *) - -A.sE9Boards = fread(fh, 1, 'int16=>int16');% = 208; (* INT16 *) -A.sCSlowCycles = fread(fh, 1, 'int16=>int16');% = 210; (* INT16 *) -A.sIMonAdc = fread(fh, 1, 'int16=>int16');% = 212; (* INT16 *) -A.sVMonAdc = fread(fh, 1, 'int16=>int16');% = 214; (* INT16 *) - -A.sMuxAdc = fread(fh, 1, 'int16=>int16');% = 216; (* INT16 *) -A.sTestDac = fread(fh, 1, 'int16=>int16');% = 218; (* INT16 *) -A.sStimDac = fread(fh, 1, 'int16=>int16');% = 220; (* INT16 *) -A.sStimDacOffset = fread(fh, 1, 'int16=>int16');% = 222; (* INT16 *) - -A.sMaxDigitalBit = fread(fh, 1, 'int16=>int16');% = 224; (* INT16 *) -A.sHasCFastHigh = fread(fh, 1, 'uint8=>uint8');% = 226; (* BYTE *) -A.sCFastHigh = fread(fh, 1, 'uint8=>uint8');% = 227; (* BYTE *) -A.sHasBathSense = fread(fh, 1, 'uint8=>uint8');% = 228; (* BYTE *) -A.sBathSense = fread(fh, 1, 'uint8=>uint8');% = 229; (* BYTE *) -A.sHasF2Bypass = fread(fh, 1, 'uint8=>uint8');% = 230; (* BYTE *) -A.sF2Mode = fread(fh, 1, 'uint8=>uint8');% = 231; (* BYTE *) - -A.sAmplKind = fread(fh, 1, 'uint8=>uint8');% = 232; (* BYTE *) -A.sIsEpc9N = fread(fh, 1, 'uint8=>uint8');% = 233; (* BYTE *) -A.sADBoard = fread(fh, 1, 'uint8=>uint8');% = 234; (* BYTE *) -A.sBoardVersion = fread(fh, 1, 'uint8=>uint8');% = 235; (* BYTE *) -A.sActiveE9Board = fread(fh, 1, 'uint8=>uint8');% = 236; (* BYTE *) -A.sMode = fread(fh, 1, 'uint8=>uint8');% = 237; (* BYTE *) -A.sRange = fread(fh, 1, 'uint8=>uint8');% = 238; (* BYTE *) -A.sF2Response = fread(fh, 1, 'uint8=>uint8');% = 239; (* BYTE *) - -A.sRsOn = fread(fh, 1, 'uint8=>uint8');% = 240; (* BYTE *) -A.sCSlowRange = fread(fh, 1, 'uint8=>uint8');% = 241; (* BYTE *) -A.sCCRange = fread(fh, 1, 'uint8=>uint8');% = 242; (* BYTE *) -A.sCCGain = fread(fh, 1, 'uint8=>uint8');% = 243; (* BYTE *) -A.sCSlowToTestDac = fread(fh, 1, 'uint8=>uint8');% = 244; (* BYTE *) -A.sStimPath = fread(fh, 1, 'uint8=>uint8');% = 245; (* BYTE *) -A.sCCTrackTau = fread(fh, 1, 'uint8=>uint8');% = 246; (* BYTE *) -A.sWasClipping = fread(fh, 1, 'uint8=>uint8');% = 247; (* BYTE *) - -A.sRepetitiveCSlow = fread(fh, 1, 'uint8=>uint8');% = 248; (* BYTE *) -A.sLastCSlowRange = fread(fh, 1, 'uint8=>uint8');% = 249; (* BYTE *) - A.sOld1 = fread(fh, 1, 'uint8=>uint8');% = 250; (* BYTE *) -A.sCanCCFast = fread(fh, 1, 'uint8=>uint8');% = 251; (* BYTE *) -A.sCanLowCCRange = fread(fh, 1, 'uint8=>uint8');% = 252; (* BYTE *) -A.sCanHighCCRange = fread(fh, 1, 'uint8=>uint8');% = 253; (* BYTE *) -A.sCanCCTrackingg = fread(fh, 1, 'uint8=>uint8');% = 254; (* BYTE *) -A.sCHasVmonPath = fread(fh, 1, 'uint8=>uint8');% = 255; (* BYTE *) - -A.sHasNewCCMode = fread(fh, 1, 'uint8=>uint8');% = 256; (* BYTE *) -A.sSelector = fread(fh, 1, 'uint8=>char');% = 257; (* CHAR *) -A.sHoldInverted = fread(fh, 1, 'uint8=>uint8');% = 258; (* BYTE *) -A.sAutoCFast = fread(fh, 1, 'uint8=>uint8');% = 259; (* BYTE *) +A.sCFastTau = fread(fh, 1, 'double=>double');% = 72; (* LONGREAL *) +A.sCSlow = fread(fh, 1, 'double=>double');% = 80; (* LONGREAL *) +A.sGSeries = fread(fh, 1, 'double=>double');% = 88; (* LONGREAL *) +A.sVCStimDacScale = fread(fh, 1, 'double=>double');% = 96; (* LONGREAL *) +A.sCCStimScale = fread(fh, 1, 'double=>double');% = 104; (* LONGREAL *) +A.sVHold = fread(fh, 1, 'double=>double');% = 112; (* LONGREAL *) +A.sLastVHold = fread(fh, 1, 'double=>double');% = 120; (* LONGREAL *) +A.sVpOffset = fread(fh, 1, 'double=>double');% = 128; (* LONGREAL *) +A.sVLiquidJunction = fread(fh, 1, 'double=>double');% = 136; (* LONGREAL *) +A.sCCIHold = fread(fh, 1, 'double=>double');% = 144; (* LONGREAL *) +A.sCSlowStimVolts = fread(fh, 1, 'double=>double');% = 152; (* LONGREAL *) +A.sCCTrackVHold = fread(fh, 1, 'double=>double');% = 160; (* LONGREAL *) +A.sTimeoutCSlow = fread(fh, 1, 'double=>double');% = 168; (* LONGREAL *) +A.sSearchDelay = fread(fh, 1, 'double=>double');% = 176; (* LONGREAL *) +A.sMConductance = fread(fh, 1, 'double=>double');% = 184; (* LONGREAL *) +A.sMCapacitance = fread(fh, 1, 'double=>double');% = 192; (* LONGREAL *) +A.sSerialNumber = fread(fh, 1, 'double=>double');% = 200; (* 8 = SizeSerialNumber *) + +A.sE9Boards = fread(fh, 1, 'int16=>int16');% = 208; (* INT16 *) +A.sCSlowCycles = fread(fh, 1, 'int16=>int16');% = 210; (* INT16 *) +A.sIMonAdc = fread(fh, 1, 'int16=>int16');% = 212; (* INT16 *) +A.sVMonAdc = fread(fh, 1, 'int16=>int16');% = 214; (* INT16 *) + +A.sMuxAdc = fread(fh, 1, 'int16=>int16');% = 216; (* INT16 *) +A.sTestDac = fread(fh, 1, 'int16=>int16');% = 218; (* INT16 *) +A.sStimDac = fread(fh, 1, 'int16=>int16');% = 220; (* INT16 *) +A.sStimDacOffset = fread(fh, 1, 'int16=>int16');% = 222; (* INT16 *) + +A.sMaxDigitalBit = fread(fh, 1, 'int16=>int16');% = 224; (* INT16 *) +A.sHasCFastHigh = fread(fh, 1, 'uint8=>uint8');% = 226; (* BYTE *) +A.sCFastHigh = fread(fh, 1, 'uint8=>uint8');% = 227; (* BYTE *) +A.sHasBathSense = fread(fh, 1, 'uint8=>uint8');% = 228; (* BYTE *) +A.sBathSense = fread(fh, 1, 'uint8=>uint8');% = 229; (* BYTE *) +A.sHasF2Bypass = fread(fh, 1, 'uint8=>uint8');% = 230; (* BYTE *) +A.sF2Mode = fread(fh, 1, 'uint8=>uint8');% = 231; (* BYTE *) + +A.sAmplKind = fread(fh, 1, 'uint8=>uint8');% = 232; (* BYTE *) +A.sIsEpc9N = fread(fh, 1, 'uint8=>uint8');% = 233; (* BYTE *) +A.sADBoard = fread(fh, 1, 'uint8=>uint8');% = 234; (* BYTE *) +A.sBoardVersion = fread(fh, 1, 'uint8=>uint8');% = 235; (* BYTE *) +A.sActiveE9Board = fread(fh, 1, 'uint8=>uint8');% = 236; (* BYTE *) +A.sMode = fread(fh, 1, 'uint8=>uint8');% = 237; (* BYTE *) +A.sRange = fread(fh, 1, 'uint8=>uint8');% = 238; (* BYTE *) +A.sF2Response = fread(fh, 1, 'uint8=>uint8');% = 239; (* BYTE *) + +A.sRsOn = fread(fh, 1, 'uint8=>uint8');% = 240; (* BYTE *) +A.sCSlowRange = fread(fh, 1, 'uint8=>uint8');% = 241; (* BYTE *) +A.sCCRange = fread(fh, 1, 'uint8=>uint8');% = 242; (* BYTE *) +A.sCCGain = fread(fh, 1, 'uint8=>uint8');% = 243; (* BYTE *) +A.sCSlowToTestDac = fread(fh, 1, 'uint8=>uint8');% = 244; (* BYTE *) +A.sStimPath = fread(fh, 1, 'uint8=>uint8');% = 245; (* BYTE *) +A.sCCTrackTau = fread(fh, 1, 'uint8=>uint8');% = 246; (* BYTE *) +A.sWasClipping = fread(fh, 1, 'uint8=>uint8');% = 247; (* BYTE *) + +A.sRepetitiveCSlow = fread(fh, 1, 'uint8=>uint8');% = 248; (* BYTE *) +A.sLastCSlowRange = fread(fh, 1, 'uint8=>uint8');% = 249; (* BYTE *) + A.sOld1 = fread(fh, 1, 'uint8=>uint8');% = 250; (* BYTE *) +A.sCanCCFast = fread(fh, 1, 'uint8=>uint8');% = 251; (* BYTE *) +A.sCanLowCCRange = fread(fh, 1, 'uint8=>uint8');% = 252; (* BYTE *) +A.sCanHighCCRange = fread(fh, 1, 'uint8=>uint8');% = 253; (* BYTE *) +A.sCanCCTrackingg = fread(fh, 1, 'uint8=>uint8');% = 254; (* BYTE *) +A.sCHasVmonPath = fread(fh, 1, 'uint8=>uint8');% = 255; (* BYTE *) + +A.sHasNewCCMode = fread(fh, 1, 'uint8=>uint8');% = 256; (* BYTE *) +A.sSelector = fread(fh, 1, 'uint8=>char');% = 257; (* CHAR *) +A.sHoldInverted = fread(fh, 1, 'uint8=>uint8');% = 258; (* BYTE *) +A.sAutoCFast = fread(fh, 1, 'uint8=>uint8');% = 259; (* BYTE *) A.sAutoCSlow = fread(fh, 1, 'uint8=>uint8');% = 260; (* BYTE *) A.sHasVmonX100 = fread(fh, 1, 'uint8=>uint8');% = 261; (* BYTE *) A.sTestDacOn = fread(fh, 1, 'uint8=>uint8');% = 262; (* BYTE *) @@ -881,24 +885,20 @@ A.sVmonFactor = fread(fh, 1, 'double=>double');% = 336; (* LONGREAL *) A.sCalibDate = fread(fh, 2, 'double=>double');% = 344; (* 16 = SizeCalibDate *) A.sVmonOffset = fread(fh, 1, 'double=>double');% = 360; (* LONGREAL *) -A.sEEPROMKind = fread(fh, 1, 'uint8=>uint8'); = 368; (* BYTE *) -A.sVrefX2 = fread(fh, 1, 'uint8=>uint8'); = 369; (* BYTE *) -A.sHasVrefX2AndF2Vmon = fread(fh, 1, 'uint8=>uint8'); = 370; (* BYTE *) -A.sSpare1 = 371; (* BYTE *) -A.sSpare2 = 372; (* BYTE *) -A.sSpare3 = 373; (* BYTE *) -A.sSpare4 = 374; (* BYTE *) -A.sSpare5 = 375; (* BYTE *) - - sCCStimDacScale = 376; (* LONGREAL *) - sVmonFiltBandwidth = 384; (* LONGREAL *) - sVmonFiltFrequency = 392; (* LONGREAL *) - AmplifierStateSize = 400; (* = 50 * 8 *) - - +A.sEEPROMKind = fread(fh, 1, 'uint8=>uint8');% = 368; (* BYTE *) +A.sVrefX2 = fread(fh, 1, 'uint8=>uint8');% = 369; (* BYTE *) +A.sHasVrefX2AndF2Vmon = fread(fh, 1, 'uint8=>uint8');% = 370; (* BYTE *) +A.sSpare1 = fread(fh, 1, 'uint8=>uint8');% = 371; (* BYTE *) +A.sSpare2 = fread(fh, 1, 'uint8=>uint8');% = 372; (* BYTE *) +A.sSpare3 = fread(fh, 1, 'uint8=>uint8');% = 373; (* BYTE *) +A.sSpare4 = fread(fh, 1, 'uint8=>uint8');% = 374; (* BYTE *) +A.sSpare5 = fread(fh, 1, 'uint8=>uint8');% = 375; (* BYTE *) +A.sCCStimDacScale = fread(fh, 1, 'double=>double');% = 376; (* LONGREAL *) +A.sVmonFiltBandwidth = fread(fh, 1, 'double=>double');% = 384; (* LONGREAL *) +A.sVmonFiltFrequency = fread(fh, 1, 'double=>double');% = 392; (* LONGREAL *) +A.AmplifierStateSize = 400;% (* = 50 * 8 *) -A.AmplifierStateSize = 400; fseek(fh, offset+A.AmplifierStateSize, 'bof'); end diff --git a/@HEKA_Importer/HI_ImportHEKAtoMat.m b/@HEKA_Importer/HI_ImportHEKAtoMat.m index e289e90..9430ddd 100644 --- a/@HEKA_Importer/HI_ImportHEKAtoMat.m +++ b/@HEKA_Importer/HI_ImportHEKAtoMat.m @@ -749,19 +749,21 @@ function L=getSeLockInParams(fh) %-------------------------------------------------------------------------- offset=ftell(fh); -L.loExtCalPhase=fread(fh, 1, 'double=>double') ;% = 0; (* LONGREAL *) -L.loExtCalAtten=fread(fh, 1, 'double=>double') ;% = 8; (* LONGREAL *) -L.loPLPhase=fread(fh, 1, 'double=>double') ;% = 16; (* LONGREAL *) -L.loPLPhaseY1=fread(fh, 1, 'double=>double') ;% = 24; (* LONGREAL *) -L.loPLPhaseY2=fread(fh, 1, 'double=>double') ;% = 32; (* LONGREAL *) -L.loUsedPhaseShift=fread(fh, 1, 'double=>double') ;% = 40; (* LONGREAL *) -L.loUsedAttenuation=fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) -L.loFiller1=fread(fh, 1, 'double=>double'); -L.loExtCalValid=fread(fh, 1, 'uint8=>logical') ;% = 64; (* BOOLEAN *) -L.loPLPhaseValid=fread(fh, 1, 'uint8=>logical') ;% = 65; (* BOOLEAN *) -L.loLockInMode=fread(fh, 1, 'uint8=>uint8') ;% = 66; (* BYTE *) -L.loCalMode=fread(fh, 1, 'uint8=>uint8') ;% = 67; (* BYTE *) -L.LockInParamsSize=96; +L.loExtCalPhase = fread(fh, 1, 'double=>double');% = 0; (* LONGREAL *) +L.loExtCalAtten = fread(fh, 1, 'double=>double');% = 8; (* LONGREAL *) +L.loPLPhase = fread(fh, 1, 'double=>double');% = 16; (* LONGREAL *) +L.loPLPhaseY1 = fread(fh, 1, 'double=>double');% = 24; (* LONGREAL *) +L.loPLPhaseY2 = fread(fh, 1, 'double=>double');% = 32; (* LONGREAL *) +L.loUsedPhaseShift = fread(fh, 1, 'double=>double');% = 40; (* LONGREAL *) +L.loUsedAttenuation = fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) + L.loSpare = fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) +L.loExtCalValid = fread(fh, 1, 'uint8=>logical');% = 64; (* BOOLEAN *) +L.loPLPhaseValid = fread(fh, 1, 'uint8=>logical');% = 65; (* BOOLEAN *) +L.loLockInMode = fread(fh, 1, 'uint8=>uint8');% = 66; (* BYTE *) +L.loCalMode = fread(fh, 1, 'uint8=>uint8');% = 67; (* BYTE *) + L.loSpare2 = fread(fh, 7, 'int32=>in32');% = 68; (* remaining *) +L.LockInParamsSize = 96; + fseek(fh, offset+L.LockInParamsSize, 'bof'); end @@ -893,8 +895,7 @@ A.sCCStimDacScale = fread(fh, 1, 'double=>double');% = 376; (* LONGREAL *) A.sVmonFiltBandwidth = fread(fh, 1, 'double=>double');% = 384; (* LONGREAL *) A.sVmonFiltFrequency = fread(fh, 1, 'double=>double');% = 392; (* LONGREAL *) -A.AmplifierStateSize = 400;% (* = 50 * 8 *) - +A.AmplifierStateSize = 400;% (* = 50 * 8 *) fseek(fh, offset+A.AmplifierStateSize, 'bof'); From 3ceababfc5aa5c373fedb0c0c0fea9d04d8a20f2 Mon Sep 17 00:00:00 2001 From: ChristianKeine Date: Sun, 23 Jun 2019 13:09:25 -0500 Subject: [PATCH 13/39] restructuring input to classes --- @HEKA_Importer/HEKA_Importer.m | 11 +- @HEKA_Importer/HI_ImportHEKAtoMat.asv | 730 +---------------------- @HEKA_Importer/HI_ImportHEKAtoMat.m | 737 +----------------------- @HEKA_Importer/HI_extractHEKADataTree.m | 2 +- @HEKA_Importer/HI_time2date.m | 12 + @HEKA_Importer/readAmplifierFileHEKA.m | 241 ++++++++ @HEKA_Importer/readPulseFileHEKA.asv | 447 ++++++++++++++ @HEKA_Importer/readPulseFileHEKA.m | 418 ++++++++++++++ @HEKA_Importer/readSolutionFileHEKA.m | 74 +++ @HEKA_Importer/readStimulusFileHEKA.m | 202 +++++++ 10 files changed, 1445 insertions(+), 1429 deletions(-) create mode 100644 @HEKA_Importer/HI_time2date.m create mode 100644 @HEKA_Importer/readAmplifierFileHEKA.m create mode 100644 @HEKA_Importer/readPulseFileHEKA.asv create mode 100644 @HEKA_Importer/readPulseFileHEKA.m create mode 100644 @HEKA_Importer/readSolutionFileHEKA.m create mode 100644 @HEKA_Importer/readStimulusFileHEKA.m diff --git a/@HEKA_Importer/HEKA_Importer.m b/@HEKA_Importer/HEKA_Importer.m index b1162cc..5c45646 100644 --- a/@HEKA_Importer/HEKA_Importer.m +++ b/@HEKA_Importer/HEKA_Importer.m @@ -83,7 +83,7 @@ opt RecTable % contains recordings in table with various parameters, e.g. Rs, Cm, nSweeps ect. solutions = [] - + fileData = []; end @@ -128,8 +128,13 @@ HI_extractHEKADataTree(obj); HI_extractHEKAStimTree(obj); HI_extractHEKASolutionTree(obj); - - end + str = HI_time2date(obj,t); + + readPulseFileHEKA(obj) + [Tree, Position, Counter, nchild]=readStimulusFileHEKA(obj,fh, Tree, Sizes, Level, Position, Counter) + [Tree, Position, Counter, nchild]=readAmplifierFileHEKA(obj,fh, Tree, Sizes, Level, Position, Counter) + [Tree, Position, Counter, nchild]=readSolutionFileHEKA(obj,fh, Tree, Sizes, Level, Position, Counter) + end %% Hide some of the handle class member functions for ease of use. methods (Hidden=true) diff --git a/@HEKA_Importer/HI_ImportHEKAtoMat.asv b/@HEKA_Importer/HI_ImportHEKAtoMat.asv index 6a6f83f..545fce8 100644 --- a/@HEKA_Importer/HI_ImportHEKAtoMat.asv +++ b/@HEKA_Importer/HI_ImportHEKAtoMat.asv @@ -54,8 +54,8 @@ end %% GET DATA, STIM AND SOLUTION TREE -fileExt = {'.pul','.pgf','.sol'}; -treeName = {'dataTree','stimTree','solTree'}; +fileExt = {'.pul','.pgf','.sol','.amp'}; +treeName = {'dataTree','stimTree','solTree','ampTree'}; for iidx = fileExt fileExist = true; @@ -88,7 +88,11 @@ for iidx = fileExt Position=ftell(fh); % Get the tree structures form the file sections - obj.trees.(treeName{strcmp(iidx, fileExt)})=getTree(fh, Sizes, Position, iidx{1}); + obj.tempData.fh = fh; + obj.tempData.Sizes = Sizes; + + + obj.trees.(treeName{strcmp(iidx, fileExt)})=getTree(fh, Sizes, Position, iidx{1},obj); else obj.trees.(treeName{strcmp(iidx, fileExt)}) = []; end @@ -136,7 +140,6 @@ end obj.RecTable.dataRaw = vertcat(dataRaw{:}); obj.RecTable = struct2table(obj.RecTable); - end %-------------------------------------------------------------------------- @@ -185,723 +188,36 @@ end %-------------------------------------------------------------------------- -function [Tree, Counter]=getTree(fh, Sizes, Position, ext) +function [Tree, Counter]=getTree(fh, Sizes, Position, ext,obj) %-------------------------------------------------------------------------- % Main entry point for loading tree -[Tree, Counter]=getTreeReentrant(fh, {}, Sizes, 0, Position, 0, ext); +[Tree, Counter]=getTreeReentrant(fh, {}, Sizes, 0, Position, 0, ext,obj); end -function [Tree, Position, Counter]=getTreeReentrant(fh, Tree, Sizes, Level, Position, Counter, ext) +function [Tree, Position, Counter]=getTreeReentrant(fh, Tree, Sizes, Level, Position, Counter, ext,obj) %-------------------------------------------------------------------------- % Recursive routine called from LoadTree switch ext case '.pul' - [Tree, Position, Counter, nchild]=getOneDataLevel(fh, Tree, Sizes, Level, Position, Counter); + [Tree, Position, Counter, nchild]=obj.readPulseFileHEKA(fh, Tree, Sizes, Level, Position, Counter); case '.pgf' - [Tree, Position, Counter, nchild]=getOneStimLevel(fh, Tree, Sizes, Level, Position, Counter); + [Tree, Position, Counter, nchild]=obj.readStimulusFileHEKA(fh, Tree, Sizes, Level, Position, Counter); case '.sol' - [Tree, Position, Counter, nchild]=getOneSolutionLevel(fh, Tree, Sizes, Level, Position, Counter); -end - -for k=1:double(nchild) - [Tree, Position, Counter]=getTreeReentrant(fh, Tree, Sizes, Level+1, Position, Counter, ext); -end - -end - - -%-------------------------------------------------------------------------- -function [Tree, Position, Counter, nchild]=getOneDataLevel(fh, Tree, Sizes, Level, Position, Counter) -%-------------------------------------------------------------------------- -% Gets one record of the tree and the number of children -[s, Counter]=getOneRecord(fh, Level, Counter); -Tree{Counter, Level+1}=s; -Position=Position+Sizes(Level+1); -fseek(fh, Position, 'bof'); -nchild=fread(fh, 1, 'int32=>int32'); -Position=ftell(fh); -end + [Tree, Position, Counter, nchild]=obj.readSolutionFileHEKA(fh, Tree, Sizes, Level, Position, Counter); + case '.amp' + [Tree, Position, Counter, nchild]=obj.readAmplifierFileHEKA(fh, Tree, Sizes, Level, Position, Counter); -%-------------------------------------------------------------------------- -function [rec, Counter]=getOneRecord(fh, Level, Counter) -%-------------------------------------------------------------------------- -% Gets one record -Counter=Counter+1; -switch Level - case 0 - rec=getRoot(fh); - case 1 - rec=getGroup(fh); - case 2 - rec=getSeries(fh); - case 3 - rec=getSweep(fh); - case 4 - rec=getTrace(fh); - otherwise - error('Unexpected Level'); -end end -% The functions below return data as defined by the HEKA PatchMaster -% specification - -%-------------------------------------------------------------------------- -function p=getRoot(fh) -%-------------------------------------------------------------------------- -p.RoVersion=fread(fh, 1, 'int32=>int32'); -p.RoMark=fread(fh, 1, 'int32=>int32');% = 4; (* INT32 *) -p.RoVersionName=deblank(fread(fh, 32, 'uint8=>char')');% = 8; (* String32Type *) -p.RoAuxFileName=deblank(fread(fh, 80, 'uint8=>char')');% = 40; (* String80Type *) -p.RoRootText=deblank(fread(fh, 400, 'uint8=>char')');% (* String400Type *) -p.RoStartTime=fread(fh, 1, 'double=>double') ;% = 520; (* LONGREAL *) -p.RoStartTimeMATLAB=time2date(p.RoStartTime); -p.RoMaxSamples=fread(fh, 1, 'int32=>int32'); % = 528; (* INT32 *) -p.RoCRC=fread(fh, 1, 'int32=>int32'); % = 532; (* CARD32 *) -p.RoFeatures=fread(fh, 1, 'int16=>int16'); % = 536; (* SET16 *) -p.RoFiller1=fread(fh, 1, 'int16=>int16');% = 538; (* INT16 *) -p.RoFiller2=fread(fh, 1, 'int32=>int32');% = 540; (* INT32 *) -p.RootRecSize= 544; -p=orderfields(p); - -end - -%-------------------------------------------------------------------------- -function g=getGroup(fh) -%-------------------------------------------------------------------------- -% Group -g.GrMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) -g.GrLabel=deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Size *) -g.GrText=deblank(fread(fh, 80, 'uint8=>char')');% = 36; (* String80Size *) -g.GrExperimentNumber=fread(fh, 1, 'int32=>int32');% = 116; (* INT32 *) -g.GrGroupCount=fread(fh, 1, 'int32=>int32');% = 120; (* INT32 *) -g.GrCRC=fread(fh, 1, 'int32=>int32');% = 124; (* CARD32 *) -g.GroupRecSize=128;% (* = 16 * 8 *) -g=orderfields(g); - -end - -%-------------------------------------------------------------------------- -function s=getSeries(fh) -%-------------------------------------------------------------------------- -s.SeMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) -s.SeLabel=deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Type *) -s.SeComment=deblank(fread(fh, 80, 'uint8=>char')');% = 36; (* String80Type *) -s.SeSeriesCount=fread(fh, 1, 'int32=>int32');% = 116; (* INT32 *) -s.SeNumbersw=fread(fh, 1, 'int32=>int32');% = 120; (* INT32 *) -s.SeAmplStateOffset=fread(fh, 1, 'int32=>int32');% = 124; (* INT32 *) -s.SeAmplStateSeries=fread(fh, 1, 'int32=>int32');% = 128; (* INT32 *) -s.SeSeriesType=fread(fh, 1, 'uint8=>uint8');% = 132; (* BYTE *) - -% Added 15.08.2012 -s.SeUseXStart=logical(fread(fh, 1, 'uint8=>uint8'));% = 133; (* BYTE *) - -s.SeFiller2=fread(fh, 1, 'uint8=>uint8');% = 134; (* BYTE *) -s.SeFiller3=fread(fh, 1, 'uint8=>uint8');% = 135; (* BYTE *) -s.SeTime=fread(fh, 1, 'double=>double') ;% = 136; (* LONGREAL *) -s.SeTimeMATLAB=time2date(s.SeTime); -s.SePageWidth=fread(fh, 1, 'double=>double') ;% = 144; (* LONGREAL *) -for k=1:4 - s.SeSwUserParamDescr(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% - s.SeSwUserParamDescr(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% -end -s.SeFiller4=fread(fh, 32, 'uint8=>uint8');% = 312; (* 32 BYTE *) -s.SeSeUserParams=fread(fh, 4, 'double=>double');% = 344; (* ARRAY[0..3] OF LONGREAL *) -s.SeLockInParams=getSeLockInParams(fh);% = 376; (* SeLockInSize = 96, see "Pulsed.de" *) -s.SeAmplifierState=getAmplifierState(fh);% = 472; (* AmplifierStateSize = 400 *) -s.SeUsername=deblank(fread(fh, 80, 'uint8=>char')');% = 872; (* String80Type *) -for k=1:4 - s.SeSeUserParamDescr(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% (* ARRAY[0..3] OF UserParamDescrType = 4*40 *) - s.SeSeUserParamDescr(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% -end -s.SeFiller5=fread(fh, 1, 'int32=>int32');% = 1112; (* INT32 *) -s.SeCRC=fread(fh, 1, 'int32=>int32');% = 1116; (* CARD32 *) - -% Added 15.08.2012 -s.SeSeUserParams2=fread(fh, 4, 'double=>double'); -for k=1:4 - s.SeSeUserParamDescr2(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% - s.SeSeUserParamDescr2(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% -end -s.SeScanParams=fread(fh, 96, 'uint8=>uint8'); -s.SeriesRecSize=1408;% (* = 176 * 8 *) -s=orderfields(s); -s.Sweeps = []; % used to store all the sweeps within the recording structure later on - -end - -%-------------------------------------------------------------------------- -function sw=getSweep(fh) -%-------------------------------------------------------------------------- -sw.SwMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) -sw.SwLabel=deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Type *) -sw.SwAuxDataFileOffset=fread(fh, 1, 'int32=>int32');% = 36; (* INT32 *) -sw.SwStimCount=fread(fh, 1, 'int32=>int32');% = 40; (* INT32 *) -sw.SwSweepCount=fread(fh, 1, 'int32=>int32');% = 44; (* INT32 *) -sw.SwTime=fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) -sw.SwTimeMATLAB=time2date(sw.SwTime);% Also add in MATLAB datenum format -sw.SwTimer=fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) -sw.SwSwUserParams=fread(fh, 4, 'double=>double');% = 64; (* ARRAY[0..3] OF LONGREAL *) -sw.SwTemperature=fread(fh, 1, 'double=>double');% = 96; (* LONGREAL *) -sw.SwOldIntSol=fread(fh, 1, 'int32=>int32');% = 104; (* INT32 *) -sw.SwOldExtSol=fread(fh, 1, 'int32=>int32');% = 108; (* INT32 *) -sw.SwDigitalIn=fread(fh, 1, 'int16=>int16');% = 112; (* SET16 *) -sw.SwSweepKind=fread(fh, 1, 'int16=>int16');% = 114; (* SET16 *) -sw.SwFiller1=fread(fh, 1, 'int32=>int32');% = 116; (* INT32 *) -sw.SwMarkers=fread(fh, 4, 'double=>double');% = 120; (* ARRAY[0..3] OF LONGREAL *) -sw.SwFiller2=fread(fh, 1, 'int32=>int32');% = 152; (* INT32 *) -sw.SwCRC=fread(fh, 1, 'int32=>int32');% = 156; (* CARD32 *) -sw.SwSwHolding = fread(fh,16,'double=>double');% = 160; (* ARRAY[0..15] OF LONGREAL, see SwHoldingNo *) -sw.SweepRecSize = 288;% (* = 36*8) -% % added in v1000 -% sw.SwSwUserParamEx = fread(fh,8,'double=>double'); % = (* ARRAY[0..7] OF LONGREAL *) -% sw.SweepRecSize = 352;% (* = 36*8) - - - - -sw=orderfields(sw); -sw.Traces = []; % used to store all the traces/channels within the sweep structure later on - - - -end - -%-------------------------------------------------------------------------- -function tr=getTrace(fh) -%-------------------------------------------------------------------------- - -% identical between v9 and v1000 - -tr.TrMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) -tr.TrLabel=deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Type *) -tr.TrTraceCount=fread(fh, 1, 'int32=>int32');% = 36; (* INT32 *) -tr.TrData=fread(fh, 1, 'int32=>int32');% = 40; (* INT32 *) -tr.TrDataPoints=fread(fh, 1, 'int32=>int32');% = 44; (* INT32 *) -tr.TrInternalSolution=fread(fh, 1, 'int32=>int32');% = 48; (* INT32 *) -tr.TrAverageCount=fread(fh, 1, 'int32=>int32');% = 52; (* INT32 *) -tr.TrLeakCount=fread(fh, 1, 'int32=>int32');% = 56; (* INT32 *) -tr.TrLeakTraces=fread(fh, 1, 'int32=>int32');% = 60; (* INT32 *) -tr.TrDataKind=fread(fh, 1, 'uint16=>uint16');% = 64; (* SET16 *) NB Stored unsigned -tr.TrFiller1=fread(fh, 1, 'int16=>int16');% = 66; (* SET16 *) -tr.TrRecordingMode=fread(fh, 1, 'uint8=>uint8');% = 68; (* BYTE *) -tr.TrAmplIndex=fread(fh, 1, 'uint8=>uint8');% = 69; (* CHAR *) -tr.TrDataFormat=fread(fh, 1, 'uint8=>uint8');% = 70; (* BYTE *) -tr.TrDataAbscissa=fread(fh, 1, 'uint8=>uint8');% = 71; (* BYTE *) -tr.TrDataScaler=fread(fh, 1, 'double=>double');% = 72; (* LONGREAL *) -tr.TrTimeOffset=fread(fh, 1, 'double=>double');% = 80; (* LONGREAL *) -tr.TrZeroData=fread(fh, 1, 'double=>double');% = 88; (* LONGREAL *) -tr.TrYUnit=deblank(fread(fh, 8, 'uint8=>char')');% = 96; (* String8Type *) -tr.TrXInterval=fread(fh, 1, 'double=>double');% = 104; (* LONGREAL *) -tr.TrXStart=fread(fh, 1, 'double=>double');% = 112; (* LONGREAL *) -% 17.04.10 TrXUnit bytes may include some trailing characters after NULL -% byte -tr.TrXUnit=deblank(fread(fh, 8, 'uint8=>char')');% = 120; (* String8Type *) -tr.TrYRange=fread(fh, 1, 'double=>double');% = 128; (* LONGREAL *) -tr.TrYOffset=fread(fh, 1, 'double=>double');% = 136; (* LONGREAL *) -tr.TrBandwidth=fread(fh, 1, 'double=>double');% = 144; (* LONGREAL *) -tr.TrPipetteResistance=fread(fh, 1, 'double=>double');% = 152; (* LONGREAL *) -tr.TrCellPotential=fread(fh, 1, 'double=>double');% = 160; (* LONGREAL *) -tr.TrSealResistance=fread(fh, 1, 'double=>double');% = 168; (* LONGREAL *) -tr.TrCSlow=fread(fh, 1, 'double=>double');% = 176; (* LONGREAL *) -tr.TrGSeries=fread(fh, 1, 'double=>double');% = 184; (* LONGREAL *) -tr.TrRsValue=fread(fh, 1, 'double=>double');% = 192; (* LONGREAL *) -tr.TrGLeak=fread(fh, 1, 'double=>double');% = 200; (* LONGREAL *) -tr.TrMConductance=fread(fh, 1, 'double=>double');% = 208; (* LONGREAL *) -tr.TrLinkDAChannel=fread(fh, 1, 'int32=>int32');% = 216; (* INT32 *) -tr.TrValidYrange=fread(fh, 1, 'uint8=>logical');% = 220; (* BOOLEAN *) -tr.TrAdcMode=fread(fh, 1, 'uint8=>uint8');% = 221; (* CHAR *) -tr.TrAdcChannel=fread(fh, 1, 'int16=>int16');% = 222; (* INT16 *) -tr.TrYmin=fread(fh, 1, 'double=>double');% = 224; (* LONGREAL *) -tr.TrYmax=fread(fh, 1, 'double=>double');% = 232; (* LONGREAL *) -tr.TrSourceChannel=fread(fh, 1, 'int32=>int32');% = 240; (* INT32 *) -tr.TrExternalSolution=fread(fh, 1, 'int32=>int32');% = 244; (* INT32 *) -tr.TrCM=fread(fh, 1, 'double=>double');% = 248; (* LONGREAL *) -tr.TrGM=fread(fh, 1, 'double=>double');% = 256; (* LONGREAL *) -tr.TrPhase=fread(fh, 1, 'double=>double');% = 264; (* LONGREAL *) -tr.TrDataCRC=fread(fh, 1, 'int32=>int32');% = 272; (* CARD32 *) -tr.TrCRC=fread(fh, 1, 'int32=>int32');% = 276; (* CARD32 *) -tr.TrGS=fread(fh, 1, 'double=>double');% = 280; (* LONGREAL *) -tr.TrSelfChannel=fread(fh, 1, 'int32=>int32');% = 288; (* INT32 *) - -% Added 15.08.2012 -tr.TrInterleaveSize=fread(fh, 1, 'int32=>int32');% = 292; (* INT32 *) -tr.TrInterleaveSkip=fread(fh, 1, 'int32=>int32');% = 296; (* INT32 *) -tr.TrImageIndex=fread(fh, 1, 'int32=>int32');% = 300; (* INT32 *) -tr.TrMarkers=fread(fh, 10, 'double=>double');% = 304; (* ARRAY[0..9] OF LONGREAL *) -tr.TrSECM_X=fread(fh, 1, 'double=>double');% = 384; (* LONGREAL *) -tr.TrSECM_Y=fread(fh, 1, 'double=>double');% = 392; (* LONGREAL *) -tr.TrSECM_Z=fread(fh, 1, 'double=>double');% = 400; (* LONGREAL *) - -% added 06/2019 -tr.TrTrHolding = fread(fh, 1, 'double=>double');% = 408; (* LONGREAL *) -tr.TrTcEnumerator = fread(fh, 1, 'int32=>int32');% = 416; (* INT32 *) -tr.TrXTrace = fread(fh, 1, 'int32=>int32');% = 420; (* INT32 *) -tr.TrIntSolValue = fread(fh, 1, 'double=>double');% = 424; (* LONGREAL *) -tr.TrExtSolValue = fread(fh, 1, 'double=>double');% = 432; (* LONGREAL *) -tr.TrIntSolName = deblank(fread(fh, 32, 'uint8=>char')');% = 440; (* String32Size *) -tr.TrExtSolName = deblank(fread(fh, 32, 'uint8=>char')');% = 472; (* String32Size *) -tr.TrDataPedestal = fread(fh, 1, 'double=>double');% = 504; (* LONGREAL *) - -tr.TraceRecSize=512; - -tr=orderfields(tr); - -end - -%% GET SOLUTION TREE -%-------------------------------------------------------------------------- -function [Tree, Position, Counter, nchild]=getOneSolutionLevel(fh, Tree, Sizes, Level, Position, Counter) -%-------------------------------------------------------------------------- -% Gets one record of the tree and the number of children -[s, Counter]=getOneSolutionRecord(fh, Level, Counter); -Tree{Counter, Level+1}=s; -Position=Position+Sizes(Level+1); -fseek(fh, Position, 'bof'); -nchild=fread(fh, 1, 'int32=>int32'); -Position=ftell(fh); - -end - -%-------------------------------------------------------------------------- -function [rec, Counter]=getOneSolutionRecord(fh, Level, Counter) -%-------------------------------------------------------------------------- -% Gets one record -Counter=Counter+1; -switch Level - case 0 - rec=getSolutionRoot(fh); - case 1 - rec=getSolution(fh); - case 2 - rec=getChemical(fh); - - otherwise - error('Unexpected Level'); -end - -end - -%-------------------------------------------------------------------------- -function p=getSolutionRoot(fh) -%-------------------------------------------------------------------------- -p.RoVersion=fread(fh, 1, 'int16=>int16'); % = 0; (* INT16 *) -p.RoDataBaseName=deblank(fread(fh, 80, 'uint8=>char')');% = 2; (* SolutionNameSize *) -p.RoSpare1=fread(fh, 1, 'int16=>int16');% = 82; (* INT16 *) -p.RoCRC=fread(fh, 1, 'int32=>int32'); % = 84; (* CARD32 *) -p.RootSize = 88;% = 88 - -p=orderfields(p); - -% in v1000: -% (* RootRecord = RECORD *) -% RoVersion = 0; (* INT32 *) -% RoDataBaseName = 4; (* SolutionNameSize *) -% RoCRC = 84; (* CARD32 *) -% RootSize = 88; - - -end - - -function s=getSolution(fh) -%-------------------------------------------------------------------------- -% Stimulus level -s.SoNumber=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) -s.SoName=deblank(fread(fh, 80, 'uint8=>char')');% = 4; (* SolutionNameSize *) -s.SoNumeric=fread(fh, 1, 'real*4=>double');% = 84; (* REAL *) *) -s.SoNumericName=deblank(fread(fh, 30, 'uint8=>char')');% = 88; (* ChemicalNameSize *) -s.SoPH=fread(fh, 1, 'real*4=>double');% = 118; (* REAL *) -s.SopHCompound=deblank(fread(fh, 30, 'uint8=>char')');% = 122; (* ChemicalNameSize *) -s.soOsmol=fread(fh, 1, 'real*4=>double'); %152; (* REAL *) -s.SoCRC=fread(fh, 1, 'int32=>int32') ;% = 156; (* CARD32 *) -s.SolutionSize=160;% = 160 - -s=orderfields(s); - -end - -%-------------------------------------------------------------------------- -function c=getChemical(fh) -%-------------------------------------------------------------------------- -c.ChConcentration=fread(fh, 1, 'real*4=>double');% = 0; (* REAL *) -c.ChName=deblank(fread(fh, 30, 'uint8=>char')');% = 4; (* ChemicalNameSize *) -c.ChSpare1=fread(fh, 1, 'int16=>int16');% = 34; (* INT16 *) -c.ChCRC=fread(fh, 1, 'int32=>int32')';% 36; (* CARD32 *) -c.ChemicalSize=40;% = 40 - -c=orderfields(c); - -end - - -%% GET STIMULUS TREE -%-------------------------------------------------------------------------- -function [Tree, Position, Counter, nchild]=getOneStimLevel(fh, Tree, Sizes, Level, Position, Counter) -%-------------------------------------------------------------------------- -% Gets one record of the tree and the number of children -[s, Counter]=getOneStimRecord(fh, Level, Counter); -Tree{Counter, Level+1}=s; -Position=Position+Sizes(Level+1); -fseek(fh, Position, 'bof'); -nchild=fread(fh, 1, 'int32=>int32'); -Position=ftell(fh); - -end - -%-------------------------------------------------------------------------- -function [rec, Counter]=getOneStimRecord(fh, Level, Counter) -%-------------------------------------------------------------------------- -% Gets one record -Counter=Counter+1; -switch Level - case 0 - rec=getStimRoot(fh); - case 1 - rec=getStimulation(fh); - case 2 - rec=getChannel(fh); - case 3 - rec=getStimSegment(fh); - otherwise - error('Unexpected Level'); -end - -end - -% The functions below return data as defined by the HEKA PatchMaster -% specification - -%-------------------------------------------------------------------------- -function p=getStimRoot(fh) -%-------------------------------------------------------------------------- -p.RoVersion=fread(fh, 1, 'int32=>int32'); -p.RoMark=fread(fh, 1, 'int32=>int32');% = 4; (* INT32 *) -p.RoVersionName=deblank(fread(fh, 32, 'uint8=>char')');% = 8; (* String32Type *) -p.RoMaxSamples=fread(fh, 1, 'int32=>int32'); % = 40; (* INT32 *) -p.RoFiller1 = fread(fh, 1, 'int32=>int32');% = 44; (* INT32 *) -p.RoParams = fread(fh, 10, 'double=>double');% = 48; (* ARRAY[0..9] OF LONGREAL *) -for k=1:10 - p.RoParamText{k}=deblank(fread(fh, 32, 'uint8=>char')');% = 128; (* ARRAY[0..9],[0..31]OF CHAR *) -end -p.RoReserved = fread(fh, 32, 'int32=>int32');% = 448; (* INT32 *) -p.RoFiller2= fread(fh, 1, 'int32=>int32');% = 576; (* INT32 *) -p.RoCRC= fread(fh, 1, 'int32=>int32');% = 580; (* CARD32 *) -p.RootRecSize= 584; % (* = 73 * 8 *) -p=orderfields(p); - -end - -%-------------------------------------------------------------------------- -function s=getStimulation(fh) -%-------------------------------------------------------------------------- -% Stimulus level -s.stMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) -s.stEntryName=deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Type *) -s.stFileName=deblank(fread(fh, 32, 'uint8=>char')');% = 36; (* String32Type *) -s.stAnalName=deblank(fread(fh, 32, 'uint8=>char')');% = 68; (* String32Type *) -s.stDataStartSegment=fread(fh, 1, 'int32=>int32');% = 100; (* INT32 *) -s.stDataStartTime=fread(fh, 1, 'double=>double') ;% = 104; (* LONGREAL *) -s.stDataStartTimeMATLAB=time2date(s.stDataStartTime); -s.stSampleInterval=fread(fh, 1, 'double=>double') ;% = 112; (* LONGREAL *) -s.stSweepInterval=fread(fh, 1, 'double=>double') ;% = 120; (* LONGREAL *) -s.stLeakDelay=fread(fh, 1, 'double=>double') ;% = 128; (* LONGREAL *) -s.stFilterFactor=fread(fh, 1, 'double=>double') ;% = 136; (* LONGREAL *) -s.stNumberSweeps=fread(fh, 1, 'int32=>int32');% = 144; (* INT32 *) -s.stNumberLeaks=fread(fh, 1, 'int32=>int32');% = 148; (* INT32 *) -s.stNumberAverages=fread(fh, 1, 'int32=>int32');% = 152; (* INT32 *) -s.stActualAdcChannels=fread(fh, 1, 'int32=>int32');% = 156; (* INT32 *) -s.stActualDacChannels=fread(fh, 1, 'int32=>int32');% = 160; (* INT32 *) -s.stExtTrigger=fread(fh, 1, 'uint8=>uint8');% = 164; (* BYTE *) -s.stNoStartWait=fread(fh, 1, 'uint8=>logical');% = 165; (* BOOLEAN *) -s.stUseScanRates=fread(fh, 1, 'uint8=>logical');% = 166; (* BOOLEAN *) -s.stNoContAq=fread(fh, 1, 'uint8=>logical');% = 167; (* BOOLEAN *) -s.stHasLockIn=fread(fh, 1, 'uint8=>logical');% = 168; (* BOOLEAN *) -s.stOldStartMacKind=fread(fh, 1, 'uint8=>char');% = 169; (* CHAR *) -s.stOldEndMacKind=fread(fh, 1, 'uint8=>logical');% = 170; (* BOOLEAN *) -s.stAutoRange=fread(fh, 1, 'uint8=>uint8');% = 171; (* BYTE *) -s.stBreakNext=fread(fh, 1, 'uint8=>logical');% = 172; (* BOOLEAN *) -s.stIsExpanded=fread(fh, 1, 'uint8=>logical');% = 173; (* BOOLEAN *) -s.stLeakCompMode=fread(fh, 1, 'uint8=>logical');% = 174; (* BOOLEAN *) -s.stHasChirp=fread(fh, 1, 'uint8=>logical');% = 175; (* BOOLEAN *) -s.stOldStartMacro=deblank(fread(fh, 32, 'uint8=>char')');% = 176; (* String32Type *) -s.stOldEndMacro=deblank(fread(fh, 32, 'uint8=>char')');% = 208; (* String32Type *) -s.sIsGapFree=fread(fh, 1, 'uint8=>logical');% = 240; (* BOOLEAN *) -s.sHandledExternally=fread(fh, 1, 'uint8=>logical');% = 241; (* BOOLEAN *) -s.stFiller1=fread(fh, 1, 'uint8=>logical');% = 242; (* BOOLEAN *) -s.stFiller2=fread(fh, 1, 'uint8=>logical');% = 243; (* BOOLEAN *) -s.stCRC=fread(fh, 1, 'int32=>int32'); % = 244; (* CARD32 *) -s.stTag=deblank(fread(fh, 32, 'uint8=>char')');% = 248; (* String32Type *) -s.StimulationRecSize = 280;% (* = 35 * 8 *) - -s=orderfields(s); - -end - -%-------------------------------------------------------------------------- -function c=getChannel(fh) -%-------------------------------------------------------------------------- -c.chMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) -c.chLinkedChannel=fread(fh, 1, 'int32=>int32');% = 4; (* INT32 *) -c.chCompressionFactor=fread(fh, 1, 'int32=>int32');% = 8; (* INT32 *) -c.chYUnit=deblank(fread(fh, 8, 'uint8=>char')');% = 12; (* String8Type *) -c.chAdcChannel=fread(fh, 1, 'int16=>int16');% = 20; (* INT16 *) -c.chAdcMode=fread(fh, 1, 'uint8=>uint8');% = 22; (* BYTE *) -c.chDoWrite=fread(fh, 1, 'uint8=>logical');% = 23; (* BOOLEAN *) -c.stLeakStore=fread(fh, 1, 'uint8=>uint8');% = 24; (* BYTE *) -c.chAmplMode=fread(fh, 1, 'uint8=>uint8');% = 25; (* BYTE *) -c.chOwnSegTime=fread(fh, 1, 'uint8=>logical');% = 26; (* BOOLEAN *) -c.chSetLastSegVmemb=fread(fh, 1, 'uint8=>logical');% = 27; (* BOOLEAN *) -c.chDacChannel=fread(fh, 1, 'int16=>int16');% = 28; (* INT16 *) -c.chDacMode=fread(fh, 1, 'uint8=>uint8');% = 30; (* BYTE *) -c.chHasLockInSquare=fread(fh, 1, 'uint8=>uint8');% = 31; (* BYTE *) -c.chRelevantXSegment=fread(fh, 1, 'int32=>int32');% = 32; (* INT32 *) -c.chRelevantYSegment=fread(fh, 1, 'int32=>int32');% = 36; (* INT32 *) -c.chDacUnit=deblank(fread(fh, 8, 'uint8=>char')');% = 40; (* String8Type *) -c.chHolding=fread(fh, 1, 'double=>double') ;% = 48; (* LONGREAL *) -c.chLeakHolding=fread(fh, 1, 'double=>double') ;% = 56; (* LONGREAL *) -c.chLeakSize=fread(fh, 1, 'double=>double') ;% = 64; (* LONGREAL *) -c.chLeakHoldMode=fread(fh, 1, 'uint8=>uint8');% = 72; (* BYTE *) -c.chLeakAlternate=fread(fh, 1, 'uint8=>logical');% = 73; (* BOOLEAN *) -c.chAltLeakAveraging=fread(fh, 1, 'uint8=>logical');% = 74; (* BOOLEAN *) -c.chLeakPulseOn=fread(fh, 1, 'uint8=>logical');% = 75; (* BOOLEAN *) -c.chStimToDacID=fread(fh, 1, 'int16=>int16');% = 76; (* SET16 *) -c.chCompressionMode=fread(fh, 1, 'int16=>int16');% = 78; (* SET16 *) -c.chCompressionSkip=fread(fh, 1, 'int32=>int32');% = 80; (* INT32 *) -c.chDacBit=fread(fh, 1, 'int16=>int16');% = 84; (* INT16 *) -c.chHasLockInSine=fread(fh, 1, 'uint8=>logical');% = 86; (* BOOLEAN *) -c.chBreakMode=fread(fh, 1, 'uint8=>uint8');% = 87; (* BYTE *) -c.chZeroSeg=fread(fh, 1, 'int32=>int32');% = 88; (* INT32 *) -c.chFiller1=fread(fh, 1, 'int32=>int32');% = 92; (* INT32 *) -c.chSine_Cycle=fread(fh, 1, 'double=>double') ;% = 96; (* LONGREAL *) -c.chSine_Amplitude=fread(fh, 1, 'double=>double') ;% = 104; (* LONGREAL *) -c.chLockIn_VReversal=fread(fh, 1, 'double=>double') ;% = 112; (* LONGREAL *) -c.chChirp_StartFreq=fread(fh, 1, 'double=>double') ;% = 120; (* LONGREAL *) -c.chChirp_EndFreq=fread(fh, 1, 'double=>double') ;% = 128; (* LONGREAL *) -c.chChirp_MinPoints=fread(fh, 1, 'double=>double') ;% = 136; (* LONGREAL *) -c.chSquare_NegAmpl=fread(fh, 1, 'double=>double') ;% = 144; (* LONGREAL *) -c.chSquare_DurFactor=fread(fh, 1, 'double=>double') ;% = 152; (* LONGREAL *) -c.chLockIn_Skip=fread(fh, 1, 'int32=>int32');% = 160; (* INT32 *) -c.chPhoto_MaxCycles=fread(fh, 1, 'int32=>int32');% = 164; (* INT32 *) -c.chPhoto_SegmentNo=fread(fh, 1, 'int32=>int32');% = 168; (* INT32 *) -c.chLockIn_AvgCycles=fread(fh, 1, 'int32=>int32');% = 172; (* INT32 *) -c.chImaging_RoiNo=fread(fh, 1, 'int32=>int32');% = 176; (* INT32 *) -c.chChirp_Skip=fread(fh, 1, 'int32=>int32');% = 180; (* INT32 *) -c.chChirp_Amplitude=fread(fh, 1, 'double=>double') ;% = 184; (* LONGREAL *) -c.chPhoto_Adapt=fread(fh, 1, 'uint8=>uint8');% = 192; (* BYTE *) -c.chSine_Kind=fread(fh, 1, 'uint8=>uint8');% = 193; (* BYTE *) -c.chChirp_PreChirp=fread(fh, 1, 'uint8=>uint8');% = 194; (* BYTE *) -c.chSine_Source=fread(fh, 1, 'uint8=>uint8');% = 195; (* BYTE *) -c.chSquare_NegSource=fread(fh, 1, 'uint8=>uint8');% = 196; (* BYTE *) -c.chSquare_PosSource=fread(fh, 1, 'uint8=>uint8');% = 197; (* BYTE *) -c.chChirp_Kind=fread(fh, 1, 'uint8=>uint8');% = 198; (* BYTE *) -c.chChirp_Source=fread(fh, 1, 'uint8=>uint8');% = 199; (* BYTE *) -c.chDacOffset=fread(fh, 1, 'double=>double') ;% = 200; (* LONGREAL *) -c.chAdcOffset=fread(fh, 1, 'double=>double') ;% = 208; (* LONGREAL *) -c.chTraceMathFormat=fread(fh, 1, 'uint8=>uint8');% = 216; (* BYTE *) -c.chHasChirp=fread(fh, 1, 'uint8=>logical');% = 217; (* BOOLEAN *) -c.chSquare_Kind=fread(fh, 1, 'uint8=>uint8');% = 218; (* BYTE *) -c.chFiller2=fread(fh,13,'uint8=>char');% = 219; (* ARRAY[0..13] OF CHAR *) -c.chSquare_Cycle=fread(fh, 1, 'double=>double') ;% = 232; (* LONGREAL *) -c.chSquare_PosAmpl=fread(fh, 1, 'double=>double') ;% = 240; (* LONGREAL *) -c.chCompressionOffset=fread(fh, 1, 'int32=>int32');% = 248; (* INT32 *) -c.chPhotoMode=fread(fh, 1, 'int32=>int32');% = 252; (* INT32 *) -c.chBreakLevel=fread(fh, 1, 'double=>double') ;% = 256; (* LONGREAL *) -c.chTraceMath=deblank(fread(fh,128,'uint8=>char')');% = 264; (* String128Type *) -c.chOldCRC=fread(fh, 1, 'int32=>int32');% = 268; (* CARD32 *) -c.chFiller3=fread(fh, 1, 'int32=>int32');% = 392; (* INT32 *) -c.chCRC=fread(fh, 1, 'int32=>int32');% = 396; (* CARD32 *) -c.ChannelRecSize = 400;% (* = 50 * 8 *) -c=orderfields(c); - -end - -%-------------------------------------------------------------------------- -function ss=getStimSegment(fh) -%-------------------------------------------------------------------------- -ss.seMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) -ss.seClass=fread(fh, 1, 'uint8=>uint8');% = 4; (* BYTE *) -ss.seDoStore=fread(fh, 1, 'uint8=>logical');% = 5; (* BOOLEAN *) -ss.seVoltageIncMode=fread(fh, 1, 'uint8=>uint8');% = 6; (* BYTE *) -ss.seDurationIncMode=fread(fh, 1, 'uint8=>uint8');% = 7; (* BYTE *) -ss.seVoltage=fread(fh, 1, 'double=>double');% = 8; (* LONGREAL *) -ss.seVoltageSource=fread(fh, 1, 'int32=>int32');% = 16; (* INT32 *) -ss.seDeltaVFactor=fread(fh, 1, 'double=>double');% = 20; (* LONGREAL *) -ss.seDeltaVIncrement=fread(fh, 1, 'double=>double');% = 28; (* LONGREAL *) -ss.seDuration=fread(fh, 1, 'double=>double');% = 36; (* LONGREAL *) -ss.seDurationSource=fread(fh, 1, 'int32=>int32');% = 44; (* INT32 *) -ss.seDeltaTFactor=fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) -ss.seDeltaTIncrement=fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) -ss.seFiller1=fread(fh, 1, 'int32=>int32');% = 64; (* INT32 *) -ss.seCRC=fread(fh, 1, 'int32=>int32');% = 68; (* CARD32 *) -ss.seScanRate=fread(fh, 1, 'double=>double');% = 72; (* LONGREAL *) -ss.StimSegmentRecSize = 80;% (* = 10 * 8 *) -ss=orderfields(ss); - +for k=1:double(nchild) + [Tree, Position, Counter]=getTreeReentrant(fh, Tree, Sizes, Level+1, Position, Counter, ext, obj); end - - -%% GET AMPLIFIER DATA -%-------------------------------------------------------------------------- -function L=getSeLockInParams(fh) -%-------------------------------------------------------------------------- -offset=ftell(fh); -L.loExtCalPhase = fread(fh, 1, 'double=>double');% = 0; (* LONGREAL *) -L.loExtCalAtten = fread(fh, 1, 'double=>double');% = 8; (* LONGREAL *) -L.loPLPhase = fread(fh, 1, 'double=>double');% = 16; (* LONGREAL *) -L.loPLPhaseY1 = fread(fh, 1, 'double=>double');% = 24; (* LONGREAL *) -L.loPLPhaseY2 = fread(fh, 1, 'double=>double');% = 32; (* LONGREAL *) -L.loUsedPhaseShift = fread(fh, 1, 'double=>double');% = 40; (* LONGREAL *) -L.loUsedAttenuation = fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) - L.loSpare = fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) -L.loExtCalValid = fread(fh, 1, 'uint8=>logical');% = 64; (* BOOLEAN *) -L.loPLPhaseValid = fread(fh, 1, 'uint8=>logical');% = 65; (* BOOLEAN *) -L.loLockInMode = fread(fh, 1, 'uint8=>uint8');% = 66; (* BYTE *) -L.loCalMode = fread(fh, 1, 'uint8=>uint8');% = 67; (* BYTE *) - L.loSpare2 = fread(fh, 3, 'double=>double');% = 68; (* LONGREAL *) - L.loSpare3 = fread(fh, 3, 'double=>double');% = 68; (* LONGREAL *) - L.loSpare3 = fread(fh, 3, 'double=>double'); -L.LockInParamsSize = 96; - -fseek(fh, offset+L.LockInParamsSize, 'bof'); - end -%-------------------------------------------------------------------------- -function A=getAmplifierState(fh) -%-------------------------------------------------------------------------- -offset=ftell(fh); -A.sStateVersion = fread(fh, 1, 'double=>double');% = 0; (* 8 = SizeStateVersion *) -A.sCurrentGain = fread(fh, 1, 'double=>double');% = 8; (* LONGREAL *) -A.sF2Bandwidth = fread(fh, 1, 'double=>double');% = 16; (* LONGREAL *) -A.sF2Frequency = fread(fh, 1, 'double=>double');% = 24; (* LONGREAL *) -A.sRsValue = fread(fh, 1, 'double=>double');% = 32; (* LONGREAL *) -A.sRsFraction = fread(fh, 1, 'double=>double');% = 40; (* LONGREAL *) -A.sGLeak = fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) -A.sCFastAmp1 = fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) -A.sCFastAmp2 = fread(fh, 1, 'double=>double');% = 64; (* LONGREAL *) -A.sCFastTau = fread(fh, 1, 'double=>double');% = 72; (* LONGREAL *) -A.sCSlow = fread(fh, 1, 'double=>double');% = 80; (* LONGREAL *) -A.sGSeries = fread(fh, 1, 'double=>double');% = 88; (* LONGREAL *) -A.sVCStimDacScale = fread(fh, 1, 'double=>double');% = 96; (* LONGREAL *) -A.sCCStimScale = fread(fh, 1, 'double=>double');% = 104; (* LONGREAL *) -A.sVHold = fread(fh, 1, 'double=>double');% = 112; (* LONGREAL *) -A.sLastVHold = fread(fh, 1, 'double=>double');% = 120; (* LONGREAL *) -A.sVpOffset = fread(fh, 1, 'double=>double');% = 128; (* LONGREAL *) -A.sVLiquidJunction = fread(fh, 1, 'double=>double');% = 136; (* LONGREAL *) -A.sCCIHold = fread(fh, 1, 'double=>double');% = 144; (* LONGREAL *) -A.sCSlowStimVolts = fread(fh, 1, 'double=>double');% = 152; (* LONGREAL *) -A.sCCTrackVHold = fread(fh, 1, 'double=>double');% = 160; (* LONGREAL *) -A.sTimeoutCSlow = fread(fh, 1, 'double=>double');% = 168; (* LONGREAL *) -A.sSearchDelay = fread(fh, 1, 'double=>double');% = 176; (* LONGREAL *) -A.sMConductance = fread(fh, 1, 'double=>double');% = 184; (* LONGREAL *) -A.sMCapacitance = fread(fh, 1, 'double=>double');% = 192; (* LONGREAL *) -A.sSerialNumber = fread(fh, 1, 'double=>double');% = 200; (* 8 = SizeSerialNumber *) - -A.sE9Boards = fread(fh, 1, 'int16=>int16');% = 208; (* INT16 *) -A.sCSlowCycles = fread(fh, 1, 'int16=>int16');% = 210; (* INT16 *) -A.sIMonAdc = fread(fh, 1, 'int16=>int16');% = 212; (* INT16 *) -A.sVMonAdc = fread(fh, 1, 'int16=>int16');% = 214; (* INT16 *) - -A.sMuxAdc = fread(fh, 1, 'int16=>int16');% = 216; (* INT16 *) -A.sTestDac = fread(fh, 1, 'int16=>int16');% = 218; (* INT16 *) -A.sStimDac = fread(fh, 1, 'int16=>int16');% = 220; (* INT16 *) -A.sStimDacOffset = fread(fh, 1, 'int16=>int16');% = 222; (* INT16 *) - -A.sMaxDigitalBit = fread(fh, 1, 'int16=>int16');% = 224; (* INT16 *) -A.sHasCFastHigh = fread(fh, 1, 'uint8=>uint8');% = 226; (* BYTE *) -A.sCFastHigh = fread(fh, 1, 'uint8=>uint8');% = 227; (* BYTE *) -A.sHasBathSense = fread(fh, 1, 'uint8=>uint8');% = 228; (* BYTE *) -A.sBathSense = fread(fh, 1, 'uint8=>uint8');% = 229; (* BYTE *) -A.sHasF2Bypass = fread(fh, 1, 'uint8=>uint8');% = 230; (* BYTE *) -A.sF2Mode = fread(fh, 1, 'uint8=>uint8');% = 231; (* BYTE *) - -A.sAmplKind = fread(fh, 1, 'uint8=>uint8');% = 232; (* BYTE *) -A.sIsEpc9N = fread(fh, 1, 'uint8=>uint8');% = 233; (* BYTE *) -A.sADBoard = fread(fh, 1, 'uint8=>uint8');% = 234; (* BYTE *) -A.sBoardVersion = fread(fh, 1, 'uint8=>uint8');% = 235; (* BYTE *) -A.sActiveE9Board = fread(fh, 1, 'uint8=>uint8');% = 236; (* BYTE *) -A.sMode = fread(fh, 1, 'uint8=>uint8');% = 237; (* BYTE *) -A.sRange = fread(fh, 1, 'uint8=>uint8');% = 238; (* BYTE *) -A.sF2Response = fread(fh, 1, 'uint8=>uint8');% = 239; (* BYTE *) - -A.sRsOn = fread(fh, 1, 'uint8=>uint8');% = 240; (* BYTE *) -A.sCSlowRange = fread(fh, 1, 'uint8=>uint8');% = 241; (* BYTE *) -A.sCCRange = fread(fh, 1, 'uint8=>uint8');% = 242; (* BYTE *) -A.sCCGain = fread(fh, 1, 'uint8=>uint8');% = 243; (* BYTE *) -A.sCSlowToTestDac = fread(fh, 1, 'uint8=>uint8');% = 244; (* BYTE *) -A.sStimPath = fread(fh, 1, 'uint8=>uint8');% = 245; (* BYTE *) -A.sCCTrackTau = fread(fh, 1, 'uint8=>uint8');% = 246; (* BYTE *) -A.sWasClipping = fread(fh, 1, 'uint8=>uint8');% = 247; (* BYTE *) - -A.sRepetitiveCSlow = fread(fh, 1, 'uint8=>uint8');% = 248; (* BYTE *) -A.sLastCSlowRange = fread(fh, 1, 'uint8=>uint8');% = 249; (* BYTE *) - A.sOld1 = fread(fh, 1, 'uint8=>uint8');% = 250; (* BYTE *) -A.sCanCCFast = fread(fh, 1, 'uint8=>uint8');% = 251; (* BYTE *) -A.sCanLowCCRange = fread(fh, 1, 'uint8=>uint8');% = 252; (* BYTE *) -A.sCanHighCCRange = fread(fh, 1, 'uint8=>uint8');% = 253; (* BYTE *) -A.sCanCCTrackingg = fread(fh, 1, 'uint8=>uint8');% = 254; (* BYTE *) -A.sCHasVmonPath = fread(fh, 1, 'uint8=>uint8');% = 255; (* BYTE *) - -A.sHasNewCCMode = fread(fh, 1, 'uint8=>uint8');% = 256; (* BYTE *) -A.sSelector = fread(fh, 1, 'uint8=>char');% = 257; (* CHAR *) -A.sHoldInverted = fread(fh, 1, 'uint8=>uint8');% = 258; (* BYTE *) -A.sAutoCFast = fread(fh, 1, 'uint8=>uint8');% = 259; (* BYTE *) -A.sAutoCSlow = fread(fh, 1, 'uint8=>uint8');% = 260; (* BYTE *) -A.sHasVmonX100 = fread(fh, 1, 'uint8=>uint8');% = 261; (* BYTE *) -A.sTestDacOn = fread(fh, 1, 'uint8=>uint8');% = 262; (* BYTE *) -A.sQMuxAdcOn = fread(fh, 1, 'uint8=>uint8');% = 263; (* BYTE *) - -A.sImon1Bandwidth = fread(fh, 1, 'double=>double');% = 264; (* LONGREAL *) -A.sStimScale = fread(fh, 1, 'double=>double');% = 272; (* LONGREAL *) - -A.sGain = fread(fh, 1, 'uint8=>uint8');% = 280; (* BYTE *) -A.sFilter1 = fread(fh, 1, 'uint8=>uint8');% = 281; (* BYTE *) -A.sStimFilterOn = fread(fh, 1, 'uint8=>uint8');% = 282; (* BYTE *) -A.sRsSlow = fread(fh, 1, 'uint8=>uint8');% = 283; (* BYTE *) - A.sOld2 = fread(fh, 1, 'uint8=>uint8');% = 284; (* BYTE *) -A.sCCCFastOn = fread(fh, 1, 'uint8=>uint8');% = 285; (* BYTE *) -A.sCCFastSpeed = fread(fh, 1, 'uint8=>uint8');% = 286; (* BYTE *) -A.sF2Source = fread(fh, 1, 'uint8=>uint8');% = 287; (* BYTE *) - -A.sTestRange = fread(fh, 1, 'uint8=>uint8');% = 288; (* BYTE *) -A.sTestDacPath = fread(fh, 1, 'uint8=>uint8');% = 289; (* BYTE *) -A.sMuxChannel = fread(fh, 1, 'uint8=>uint8');% = 290; (* BYTE *) -A.sMuxGain64 = fread(fh, 1, 'uint8=>uint8');% = 291; (* BYTE *) -A.sVmonX100 = fread(fh, 1, 'uint8=>uint8');% = 292; (* BYTE *) -A.sIsQuadro = fread(fh, 1, 'uint8=>uint8');% = 293; (* BYTE *) -A.sF1Mode = fread(fh, 1, 'uint8=>uint8');% = 294; (* BYTE *) - A.sOld3 = fread(fh, 1, 'uint8=>uint8');% = 295; (* BYTE *) -A.sStimFilterHz = fread(fh, 1, 'double=>double');% = 296; (* LONGREAL *) -A.sRsTau = fread(fh, 1, 'double=>double');% = 304; (* LONGREAL *) -A.sDacToAdcDelay = fread(fh, 1, 'double=>double');% = 312; (* LONGREAL *) -A.sInputFilterTau = fread(fh, 1, 'double=>double');% = 320; (* LONGREAL *) -A.sOutputFilterTau = fread(fh, 1, 'double=>double');% = 328; (* LONGREAL *) -A.sVmonFactor = fread(fh, 1, 'double=>double');% = 336; (* LONGREAL *) -A.sCalibDate = fread(fh, 2, 'double=>double');% = 344; (* 16 = SizeCalibDate *) -A.sVmonOffset = fread(fh, 1, 'double=>double');% = 360; (* LONGREAL *) - -A.sEEPROMKind = fread(fh, 1, 'uint8=>uint8');% = 368; (* BYTE *) -A.sVrefX2 = fread(fh, 1, 'uint8=>uint8');% = 369; (* BYTE *) -A.sHasVrefX2AndF2Vmon = fread(fh, 1, 'uint8=>uint8');% = 370; (* BYTE *) -A.sSpare1 = fread(fh, 1, 'uint8=>uint8');% = 371; (* BYTE *) -A.sSpare2 = fread(fh, 1, 'uint8=>uint8');% = 372; (* BYTE *) -A.sSpare3 = fread(fh, 1, 'uint8=>uint8');% = 373; (* BYTE *) -A.sSpare4 = fread(fh, 1, 'uint8=>uint8');% = 374; (* BYTE *) -A.sSpare5 = fread(fh, 1, 'uint8=>uint8');% = 375; (* BYTE *) - -A.sCCStimDacScale = fread(fh, 1, 'double=>double');% = 376; (* LONGREAL *) -A.sVmonFiltBandwidth = fread(fh, 1, 'double=>double');% = 384; (* LONGREAL *) -A.sVmonFiltFrequency = fread(fh, 1, 'double=>double');% = 392; (* LONGREAL *) -A.AmplifierStateSize = 400;% (* = 50 * 8 *) - -fseek(fh, offset+A.AmplifierStateSize, 'bof'); - -end %-------------------------------------------------------------------------- function matData2=LocalImportGroup(fh, dataTree, grp, grp_row) @@ -1153,15 +469,3 @@ end return end -%-------------------------------------------------------------------------- -function str=time2date(t) -%-------------------------------------------------------------------------- -t=t-1580970496; -if t<0 - t=t+4294967296; -end -t=t+9561652096; -str=datestr(t/(24*60*60)+datenum(1601,1,1)); -return -end -%-------------------------------------------------------------------------- \ No newline at end of file diff --git a/@HEKA_Importer/HI_ImportHEKAtoMat.m b/@HEKA_Importer/HI_ImportHEKAtoMat.m index 9430ddd..28a1031 100644 --- a/@HEKA_Importer/HI_ImportHEKAtoMat.m +++ b/@HEKA_Importer/HI_ImportHEKAtoMat.m @@ -54,8 +54,8 @@ %% GET DATA, STIM AND SOLUTION TREE -fileExt = {'.pul','.pgf','.sol'}; -treeName = {'dataTree','stimTree','solTree'}; +fileExt = {'.pul','.pgf','.sol','.amp'}; +treeName = {'dataTree','stimTree','solTree','ampTree'}; for iidx = fileExt fileExist = true; @@ -88,7 +88,12 @@ Position=ftell(fh); % Get the tree structures form the file sections - obj.trees.(treeName{strcmp(iidx, fileExt)})=getTree(fh, Sizes, Position, iidx{1}); + obj.fileData.fh = fh; + obj.fileData.Sizes = Sizes; + obj.fileData.Position = Position; + obj.fileData.fileExt = iidx{1}; + + obj.trees.(treeName{strcmp(iidx, fileExt)})=getTree(fh, Sizes, Position, iidx{1},obj); else obj.trees.(treeName{strcmp(iidx, fileExt)}) = []; end @@ -136,7 +141,6 @@ obj.RecTable.dataRaw = vertcat(dataRaw{:}); obj.RecTable = struct2table(obj.RecTable); - end %-------------------------------------------------------------------------- @@ -185,721 +189,42 @@ %-------------------------------------------------------------------------- -function [Tree, Counter]=getTree(fh, Sizes, Position, ext) +function [Tree, Counter]=getTree(fh, Sizes, Position, ext,obj) %-------------------------------------------------------------------------- % Main entry point for loading tree -[Tree, Counter]=getTreeReentrant(fh, {}, Sizes, 0, Position, 0, ext); + +obj.fileData.Counter = 0; +obj.fileData.Tree = {}; +obj.fileData.Level = 0; + +[Tree, Counter] = getTreeReentrant(obj); end -function [Tree, Position, Counter]=getTreeReentrant(fh, Tree, Sizes, Level, Position, Counter, ext) +function [Tree, Position, Counter]=getTreeReentrant(obj) %-------------------------------------------------------------------------- % Recursive routine called from LoadTree -switch ext +switch obj.fileData.fileExt case '.pul' - [Tree, Position, Counter, nchild]=getOneDataLevel(fh, Tree, Sizes, Level, Position, Counter); + obj.readPulseFileHEKA; case '.pgf' - [Tree, Position, Counter, nchild]=getOneStimLevel(fh, Tree, Sizes, Level, Position, Counter); + obj.readStimulusFileHEKA; case '.sol' - [Tree, Position, Counter, nchild]=getOneSolutionLevel(fh, Tree, Sizes, Level, Position, Counter); -end - -for k=1:double(nchild) - [Tree, Position, Counter]=getTreeReentrant(fh, Tree, Sizes, Level+1, Position, Counter, ext); -end - -end - - -%-------------------------------------------------------------------------- -function [Tree, Position, Counter, nchild]=getOneDataLevel(fh, Tree, Sizes, Level, Position, Counter) -%-------------------------------------------------------------------------- -% Gets one record of the tree and the number of children -[s, Counter]=getOneRecord(fh, Level, Counter); -Tree{Counter, Level+1}=s; -Position=Position+Sizes(Level+1); -fseek(fh, Position, 'bof'); -nchild=fread(fh, 1, 'int32=>int32'); -Position=ftell(fh); -end - -%-------------------------------------------------------------------------- -function [rec, Counter]=getOneRecord(fh, Level, Counter) -%-------------------------------------------------------------------------- -% Gets one record -Counter=Counter+1; -switch Level - case 0 - rec=getRoot(fh); - case 1 - rec=getGroup(fh); - case 2 - rec=getSeries(fh); - case 3 - rec=getSweep(fh); - case 4 - rec=getTrace(fh); - otherwise - error('Unexpected Level'); -end -end - -% The functions below return data as defined by the HEKA PatchMaster -% specification - -%-------------------------------------------------------------------------- -function p=getRoot(fh) -%-------------------------------------------------------------------------- -p.RoVersion=fread(fh, 1, 'int32=>int32'); -p.RoMark=fread(fh, 1, 'int32=>int32');% = 4; (* INT32 *) -p.RoVersionName=deblank(fread(fh, 32, 'uint8=>char')');% = 8; (* String32Type *) -p.RoAuxFileName=deblank(fread(fh, 80, 'uint8=>char')');% = 40; (* String80Type *) -p.RoRootText=deblank(fread(fh, 400, 'uint8=>char')');% (* String400Type *) -p.RoStartTime=fread(fh, 1, 'double=>double') ;% = 520; (* LONGREAL *) -p.RoStartTimeMATLAB=time2date(p.RoStartTime); -p.RoMaxSamples=fread(fh, 1, 'int32=>int32'); % = 528; (* INT32 *) -p.RoCRC=fread(fh, 1, 'int32=>int32'); % = 532; (* CARD32 *) -p.RoFeatures=fread(fh, 1, 'int16=>int16'); % = 536; (* SET16 *) -p.RoFiller1=fread(fh, 1, 'int16=>int16');% = 538; (* INT16 *) -p.RoFiller2=fread(fh, 1, 'int32=>int32');% = 540; (* INT32 *) -p.RootRecSize= 544; -p=orderfields(p); - -end - -%-------------------------------------------------------------------------- -function g=getGroup(fh) -%-------------------------------------------------------------------------- -% Group -g.GrMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) -g.GrLabel=deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Size *) -g.GrText=deblank(fread(fh, 80, 'uint8=>char')');% = 36; (* String80Size *) -g.GrExperimentNumber=fread(fh, 1, 'int32=>int32');% = 116; (* INT32 *) -g.GrGroupCount=fread(fh, 1, 'int32=>int32');% = 120; (* INT32 *) -g.GrCRC=fread(fh, 1, 'int32=>int32');% = 124; (* CARD32 *) -g.GroupRecSize=128;% (* = 16 * 8 *) -g=orderfields(g); - -end - -%-------------------------------------------------------------------------- -function s=getSeries(fh) -%-------------------------------------------------------------------------- -s.SeMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) -s.SeLabel=deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Type *) -s.SeComment=deblank(fread(fh, 80, 'uint8=>char')');% = 36; (* String80Type *) -s.SeSeriesCount=fread(fh, 1, 'int32=>int32');% = 116; (* INT32 *) -s.SeNumbersw=fread(fh, 1, 'int32=>int32');% = 120; (* INT32 *) -s.SeAmplStateOffset=fread(fh, 1, 'int32=>int32');% = 124; (* INT32 *) -s.SeAmplStateSeries=fread(fh, 1, 'int32=>int32');% = 128; (* INT32 *) -s.SeSeriesType=fread(fh, 1, 'uint8=>uint8');% = 132; (* BYTE *) - -% Added 15.08.2012 -s.SeUseXStart=logical(fread(fh, 1, 'uint8=>uint8'));% = 133; (* BYTE *) - -s.SeFiller2=fread(fh, 1, 'uint8=>uint8');% = 134; (* BYTE *) -s.SeFiller3=fread(fh, 1, 'uint8=>uint8');% = 135; (* BYTE *) -s.SeTime=fread(fh, 1, 'double=>double') ;% = 136; (* LONGREAL *) -s.SeTimeMATLAB=time2date(s.SeTime); -s.SePageWidth=fread(fh, 1, 'double=>double') ;% = 144; (* LONGREAL *) -for k=1:4 - s.SeSwUserParamDescr(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% - s.SeSwUserParamDescr(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% -end -s.SeFiller4=fread(fh, 32, 'uint8=>uint8');% = 312; (* 32 BYTE *) -s.SeSeUserParams=fread(fh, 4, 'double=>double');% = 344; (* ARRAY[0..3] OF LONGREAL *) -s.SeLockInParams=getSeLockInParams(fh);% = 376; (* SeLockInSize = 96, see "Pulsed.de" *) -s.SeAmplifierState=getAmplifierState(fh);% = 472; (* AmplifierStateSize = 400 *) -s.SeUsername=deblank(fread(fh, 80, 'uint8=>char')');% = 872; (* String80Type *) -for k=1:4 - s.SeSeUserParamDescr(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% (* ARRAY[0..3] OF UserParamDescrType = 4*40 *) - s.SeSeUserParamDescr(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% -end -s.SeFiller5=fread(fh, 1, 'int32=>int32');% = 1112; (* INT32 *) -s.SeCRC=fread(fh, 1, 'int32=>int32');% = 1116; (* CARD32 *) - -% Added 15.08.2012 -s.SeSeUserParams2=fread(fh, 4, 'double=>double'); -for k=1:4 - s.SeSeUserParamDescr2(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% - s.SeSeUserParamDescr2(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% -end -s.SeScanParams=fread(fh, 96, 'uint8=>uint8'); -s.SeriesRecSize=1408;% (* = 176 * 8 *) -s=orderfields(s); -s.Sweeps = []; % used to store all the sweeps within the recording structure later on - -end - -%-------------------------------------------------------------------------- -function sw=getSweep(fh) -%-------------------------------------------------------------------------- -sw.SwMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) -sw.SwLabel=deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Type *) -sw.SwAuxDataFileOffset=fread(fh, 1, 'int32=>int32');% = 36; (* INT32 *) -sw.SwStimCount=fread(fh, 1, 'int32=>int32');% = 40; (* INT32 *) -sw.SwSweepCount=fread(fh, 1, 'int32=>int32');% = 44; (* INT32 *) -sw.SwTime=fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) -sw.SwTimeMATLAB=time2date(sw.SwTime);% Also add in MATLAB datenum format -sw.SwTimer=fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) -sw.SwSwUserParams=fread(fh, 4, 'double=>double');% = 64; (* ARRAY[0..3] OF LONGREAL *) -sw.SwTemperature=fread(fh, 1, 'double=>double');% = 96; (* LONGREAL *) -sw.SwOldIntSol=fread(fh, 1, 'int32=>int32');% = 104; (* INT32 *) -sw.SwOldExtSol=fread(fh, 1, 'int32=>int32');% = 108; (* INT32 *) -sw.SwDigitalIn=fread(fh, 1, 'int16=>int16');% = 112; (* SET16 *) -sw.SwSweepKind=fread(fh, 1, 'int16=>int16');% = 114; (* SET16 *) -sw.SwFiller1=fread(fh, 1, 'int32=>int32');% = 116; (* INT32 *) -sw.SwMarkers=fread(fh, 4, 'double=>double');% = 120; (* ARRAY[0..3] OF LONGREAL *) -sw.SwFiller2=fread(fh, 1, 'int32=>int32');% = 152; (* INT32 *) -sw.SwCRC=fread(fh, 1, 'int32=>int32');% = 156; (* CARD32 *) -sw.SwSwHolding = fread(fh,16,'double=>double');% = 160; (* ARRAY[0..15] OF LONGREAL, see SwHoldingNo *) -sw.SweepRecSize = 288;% (* = 36*8) -% % added in v1000 -% sw.SwSwUserParamEx = fread(fh,8,'double=>double'); % = (* ARRAY[0..7] OF LONGREAL *) -% sw.SweepRecSize = 352;% (* = 36*8) - - - - -sw=orderfields(sw); -sw.Traces = []; % used to store all the traces/channels within the sweep structure later on - - - -end - -%-------------------------------------------------------------------------- -function tr=getTrace(fh) -%-------------------------------------------------------------------------- - -% identical between v9 and v1000 - -tr.TrMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) -tr.TrLabel=deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Type *) -tr.TrTraceCount=fread(fh, 1, 'int32=>int32');% = 36; (* INT32 *) -tr.TrData=fread(fh, 1, 'int32=>int32');% = 40; (* INT32 *) -tr.TrDataPoints=fread(fh, 1, 'int32=>int32');% = 44; (* INT32 *) -tr.TrInternalSolution=fread(fh, 1, 'int32=>int32');% = 48; (* INT32 *) -tr.TrAverageCount=fread(fh, 1, 'int32=>int32');% = 52; (* INT32 *) -tr.TrLeakCount=fread(fh, 1, 'int32=>int32');% = 56; (* INT32 *) -tr.TrLeakTraces=fread(fh, 1, 'int32=>int32');% = 60; (* INT32 *) -tr.TrDataKind=fread(fh, 1, 'uint16=>uint16');% = 64; (* SET16 *) NB Stored unsigned -tr.TrFiller1=fread(fh, 1, 'int16=>int16');% = 66; (* SET16 *) -tr.TrRecordingMode=fread(fh, 1, 'uint8=>uint8');% = 68; (* BYTE *) -tr.TrAmplIndex=fread(fh, 1, 'uint8=>uint8');% = 69; (* CHAR *) -tr.TrDataFormat=fread(fh, 1, 'uint8=>uint8');% = 70; (* BYTE *) -tr.TrDataAbscissa=fread(fh, 1, 'uint8=>uint8');% = 71; (* BYTE *) -tr.TrDataScaler=fread(fh, 1, 'double=>double');% = 72; (* LONGREAL *) -tr.TrTimeOffset=fread(fh, 1, 'double=>double');% = 80; (* LONGREAL *) -tr.TrZeroData=fread(fh, 1, 'double=>double');% = 88; (* LONGREAL *) -tr.TrYUnit=deblank(fread(fh, 8, 'uint8=>char')');% = 96; (* String8Type *) -tr.TrXInterval=fread(fh, 1, 'double=>double');% = 104; (* LONGREAL *) -tr.TrXStart=fread(fh, 1, 'double=>double');% = 112; (* LONGREAL *) -% 17.04.10 TrXUnit bytes may include some trailing characters after NULL -% byte -tr.TrXUnit=deblank(fread(fh, 8, 'uint8=>char')');% = 120; (* String8Type *) -tr.TrYRange=fread(fh, 1, 'double=>double');% = 128; (* LONGREAL *) -tr.TrYOffset=fread(fh, 1, 'double=>double');% = 136; (* LONGREAL *) -tr.TrBandwidth=fread(fh, 1, 'double=>double');% = 144; (* LONGREAL *) -tr.TrPipetteResistance=fread(fh, 1, 'double=>double');% = 152; (* LONGREAL *) -tr.TrCellPotential=fread(fh, 1, 'double=>double');% = 160; (* LONGREAL *) -tr.TrSealResistance=fread(fh, 1, 'double=>double');% = 168; (* LONGREAL *) -tr.TrCSlow=fread(fh, 1, 'double=>double');% = 176; (* LONGREAL *) -tr.TrGSeries=fread(fh, 1, 'double=>double');% = 184; (* LONGREAL *) -tr.TrRsValue=fread(fh, 1, 'double=>double');% = 192; (* LONGREAL *) -tr.TrGLeak=fread(fh, 1, 'double=>double');% = 200; (* LONGREAL *) -tr.TrMConductance=fread(fh, 1, 'double=>double');% = 208; (* LONGREAL *) -tr.TrLinkDAChannel=fread(fh, 1, 'int32=>int32');% = 216; (* INT32 *) -tr.TrValidYrange=fread(fh, 1, 'uint8=>logical');% = 220; (* BOOLEAN *) -tr.TrAdcMode=fread(fh, 1, 'uint8=>uint8');% = 221; (* CHAR *) -tr.TrAdcChannel=fread(fh, 1, 'int16=>int16');% = 222; (* INT16 *) -tr.TrYmin=fread(fh, 1, 'double=>double');% = 224; (* LONGREAL *) -tr.TrYmax=fread(fh, 1, 'double=>double');% = 232; (* LONGREAL *) -tr.TrSourceChannel=fread(fh, 1, 'int32=>int32');% = 240; (* INT32 *) -tr.TrExternalSolution=fread(fh, 1, 'int32=>int32');% = 244; (* INT32 *) -tr.TrCM=fread(fh, 1, 'double=>double');% = 248; (* LONGREAL *) -tr.TrGM=fread(fh, 1, 'double=>double');% = 256; (* LONGREAL *) -tr.TrPhase=fread(fh, 1, 'double=>double');% = 264; (* LONGREAL *) -tr.TrDataCRC=fread(fh, 1, 'int32=>int32');% = 272; (* CARD32 *) -tr.TrCRC=fread(fh, 1, 'int32=>int32');% = 276; (* CARD32 *) -tr.TrGS=fread(fh, 1, 'double=>double');% = 280; (* LONGREAL *) -tr.TrSelfChannel=fread(fh, 1, 'int32=>int32');% = 288; (* INT32 *) - -% Added 15.08.2012 -tr.TrInterleaveSize=fread(fh, 1, 'int32=>int32');% = 292; (* INT32 *) -tr.TrInterleaveSkip=fread(fh, 1, 'int32=>int32');% = 296; (* INT32 *) -tr.TrImageIndex=fread(fh, 1, 'int32=>int32');% = 300; (* INT32 *) -tr.TrMarkers=fread(fh, 10, 'double=>double');% = 304; (* ARRAY[0..9] OF LONGREAL *) -tr.TrSECM_X=fread(fh, 1, 'double=>double');% = 384; (* LONGREAL *) -tr.TrSECM_Y=fread(fh, 1, 'double=>double');% = 392; (* LONGREAL *) -tr.TrSECM_Z=fread(fh, 1, 'double=>double');% = 400; (* LONGREAL *) - -% added 06/2019 -tr.TrTrHolding = fread(fh, 1, 'double=>double');% = 408; (* LONGREAL *) -tr.TrTcEnumerator = fread(fh, 1, 'int32=>int32');% = 416; (* INT32 *) -tr.TrXTrace = fread(fh, 1, 'int32=>int32');% = 420; (* INT32 *) -tr.TrIntSolValue = fread(fh, 1, 'double=>double');% = 424; (* LONGREAL *) -tr.TrExtSolValue = fread(fh, 1, 'double=>double');% = 432; (* LONGREAL *) -tr.TrIntSolName = deblank(fread(fh, 32, 'uint8=>char')');% = 440; (* String32Size *) -tr.TrExtSolName = deblank(fread(fh, 32, 'uint8=>char')');% = 472; (* String32Size *) -tr.TrDataPedestal = fread(fh, 1, 'double=>double');% = 504; (* LONGREAL *) - -tr.TraceRecSize=512; - -tr=orderfields(tr); - -end - -%% GET SOLUTION TREE -%-------------------------------------------------------------------------- -function [Tree, Position, Counter, nchild]=getOneSolutionLevel(fh, Tree, Sizes, Level, Position, Counter) -%-------------------------------------------------------------------------- -% Gets one record of the tree and the number of children -[s, Counter]=getOneSolutionRecord(fh, Level, Counter); -Tree{Counter, Level+1}=s; -Position=Position+Sizes(Level+1); -fseek(fh, Position, 'bof'); -nchild=fread(fh, 1, 'int32=>int32'); -Position=ftell(fh); - -end - -%-------------------------------------------------------------------------- -function [rec, Counter]=getOneSolutionRecord(fh, Level, Counter) -%-------------------------------------------------------------------------- -% Gets one record -Counter=Counter+1; -switch Level - case 0 - rec=getSolutionRoot(fh); - case 1 - rec=getSolution(fh); - case 2 - rec=getChemical(fh); - - otherwise - error('Unexpected Level'); -end - -end - -%-------------------------------------------------------------------------- -function p=getSolutionRoot(fh) -%-------------------------------------------------------------------------- -p.RoVersion=fread(fh, 1, 'int16=>int16'); % = 0; (* INT16 *) -p.RoDataBaseName=deblank(fread(fh, 80, 'uint8=>char')');% = 2; (* SolutionNameSize *) -p.RoSpare1=fread(fh, 1, 'int16=>int16');% = 82; (* INT16 *) -p.RoCRC=fread(fh, 1, 'int32=>int32'); % = 84; (* CARD32 *) -p.RootSize = 88;% = 88 - -p=orderfields(p); - -% in v1000: -% (* RootRecord = RECORD *) -% RoVersion = 0; (* INT32 *) -% RoDataBaseName = 4; (* SolutionNameSize *) -% RoCRC = 84; (* CARD32 *) -% RootSize = 88; - - -end - - -function s=getSolution(fh) -%-------------------------------------------------------------------------- -% Stimulus level -s.SoNumber=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) -s.SoName=deblank(fread(fh, 80, 'uint8=>char')');% = 4; (* SolutionNameSize *) -s.SoNumeric=fread(fh, 1, 'real*4=>double');% = 84; (* REAL *) *) -s.SoNumericName=deblank(fread(fh, 30, 'uint8=>char')');% = 88; (* ChemicalNameSize *) -s.SoPH=fread(fh, 1, 'real*4=>double');% = 118; (* REAL *) -s.SopHCompound=deblank(fread(fh, 30, 'uint8=>char')');% = 122; (* ChemicalNameSize *) -s.soOsmol=fread(fh, 1, 'real*4=>double'); %152; (* REAL *) -s.SoCRC=fread(fh, 1, 'int32=>int32') ;% = 156; (* CARD32 *) -s.SolutionSize=160;% = 160 - -s=orderfields(s); - -end - -%-------------------------------------------------------------------------- -function c=getChemical(fh) -%-------------------------------------------------------------------------- -c.ChConcentration=fread(fh, 1, 'real*4=>double');% = 0; (* REAL *) -c.ChName=deblank(fread(fh, 30, 'uint8=>char')');% = 4; (* ChemicalNameSize *) -c.ChSpare1=fread(fh, 1, 'int16=>int16');% = 34; (* INT16 *) -c.ChCRC=fread(fh, 1, 'int32=>int32')';% 36; (* CARD32 *) -c.ChemicalSize=40;% = 40 - -c=orderfields(c); - -end - - -%% GET STIMULUS TREE -%-------------------------------------------------------------------------- -function [Tree, Position, Counter, nchild]=getOneStimLevel(fh, Tree, Sizes, Level, Position, Counter) -%-------------------------------------------------------------------------- -% Gets one record of the tree and the number of children -[s, Counter]=getOneStimRecord(fh, Level, Counter); -Tree{Counter, Level+1}=s; -Position=Position+Sizes(Level+1); -fseek(fh, Position, 'bof'); -nchild=fread(fh, 1, 'int32=>int32'); -Position=ftell(fh); - -end - -%-------------------------------------------------------------------------- -function [rec, Counter]=getOneStimRecord(fh, Level, Counter) -%-------------------------------------------------------------------------- -% Gets one record -Counter=Counter+1; -switch Level - case 0 - rec=getStimRoot(fh); - case 1 - rec=getStimulation(fh); - case 2 - rec=getChannel(fh); - case 3 - rec=getStimSegment(fh); - otherwise - error('Unexpected Level'); -end - -end - -% The functions below return data as defined by the HEKA PatchMaster -% specification - -%-------------------------------------------------------------------------- -function p=getStimRoot(fh) -%-------------------------------------------------------------------------- -p.RoVersion=fread(fh, 1, 'int32=>int32'); -p.RoMark=fread(fh, 1, 'int32=>int32');% = 4; (* INT32 *) -p.RoVersionName=deblank(fread(fh, 32, 'uint8=>char')');% = 8; (* String32Type *) -p.RoMaxSamples=fread(fh, 1, 'int32=>int32'); % = 40; (* INT32 *) -p.RoFiller1 = fread(fh, 1, 'int32=>int32');% = 44; (* INT32 *) -p.RoParams = fread(fh, 10, 'double=>double');% = 48; (* ARRAY[0..9] OF LONGREAL *) -for k=1:10 - p.RoParamText{k}=deblank(fread(fh, 32, 'uint8=>char')');% = 128; (* ARRAY[0..9],[0..31]OF CHAR *) -end -p.RoReserved = fread(fh, 32, 'int32=>int32');% = 448; (* INT32 *) -p.RoFiller2= fread(fh, 1, 'int32=>int32');% = 576; (* INT32 *) -p.RoCRC= fread(fh, 1, 'int32=>int32');% = 580; (* CARD32 *) -p.RootRecSize= 584; % (* = 73 * 8 *) -p=orderfields(p); + obj.readSolutionFileHEKA; + case '.amp' + obj.readAmplifierFileHEKA; end -%-------------------------------------------------------------------------- -function s=getStimulation(fh) -%-------------------------------------------------------------------------- -% Stimulus level -s.stMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) -s.stEntryName=deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Type *) -s.stFileName=deblank(fread(fh, 32, 'uint8=>char')');% = 36; (* String32Type *) -s.stAnalName=deblank(fread(fh, 32, 'uint8=>char')');% = 68; (* String32Type *) -s.stDataStartSegment=fread(fh, 1, 'int32=>int32');% = 100; (* INT32 *) -s.stDataStartTime=fread(fh, 1, 'double=>double') ;% = 104; (* LONGREAL *) -s.stDataStartTimeMATLAB=time2date(s.stDataStartTime); -s.stSampleInterval=fread(fh, 1, 'double=>double') ;% = 112; (* LONGREAL *) -s.stSweepInterval=fread(fh, 1, 'double=>double') ;% = 120; (* LONGREAL *) -s.stLeakDelay=fread(fh, 1, 'double=>double') ;% = 128; (* LONGREAL *) -s.stFilterFactor=fread(fh, 1, 'double=>double') ;% = 136; (* LONGREAL *) -s.stNumberSweeps=fread(fh, 1, 'int32=>int32');% = 144; (* INT32 *) -s.stNumberLeaks=fread(fh, 1, 'int32=>int32');% = 148; (* INT32 *) -s.stNumberAverages=fread(fh, 1, 'int32=>int32');% = 152; (* INT32 *) -s.stActualAdcChannels=fread(fh, 1, 'int32=>int32');% = 156; (* INT32 *) -s.stActualDacChannels=fread(fh, 1, 'int32=>int32');% = 160; (* INT32 *) -s.stExtTrigger=fread(fh, 1, 'uint8=>uint8');% = 164; (* BYTE *) -s.stNoStartWait=fread(fh, 1, 'uint8=>logical');% = 165; (* BOOLEAN *) -s.stUseScanRates=fread(fh, 1, 'uint8=>logical');% = 166; (* BOOLEAN *) -s.stNoContAq=fread(fh, 1, 'uint8=>logical');% = 167; (* BOOLEAN *) -s.stHasLockIn=fread(fh, 1, 'uint8=>logical');% = 168; (* BOOLEAN *) -s.stOldStartMacKind=fread(fh, 1, 'uint8=>char');% = 169; (* CHAR *) -s.stOldEndMacKind=fread(fh, 1, 'uint8=>logical');% = 170; (* BOOLEAN *) -s.stAutoRange=fread(fh, 1, 'uint8=>uint8');% = 171; (* BYTE *) -s.stBreakNext=fread(fh, 1, 'uint8=>logical');% = 172; (* BOOLEAN *) -s.stIsExpanded=fread(fh, 1, 'uint8=>logical');% = 173; (* BOOLEAN *) -s.stLeakCompMode=fread(fh, 1, 'uint8=>logical');% = 174; (* BOOLEAN *) -s.stHasChirp=fread(fh, 1, 'uint8=>logical');% = 175; (* BOOLEAN *) -s.stOldStartMacro=deblank(fread(fh, 32, 'uint8=>char')');% = 176; (* String32Type *) -s.stOldEndMacro=deblank(fread(fh, 32, 'uint8=>char')');% = 208; (* String32Type *) -s.sIsGapFree=fread(fh, 1, 'uint8=>logical');% = 240; (* BOOLEAN *) -s.sHandledExternally=fread(fh, 1, 'uint8=>logical');% = 241; (* BOOLEAN *) -s.stFiller1=fread(fh, 1, 'uint8=>logical');% = 242; (* BOOLEAN *) -s.stFiller2=fread(fh, 1, 'uint8=>logical');% = 243; (* BOOLEAN *) -s.stCRC=fread(fh, 1, 'int32=>int32'); % = 244; (* CARD32 *) -s.stTag=deblank(fread(fh, 32, 'uint8=>char')');% = 248; (* String32Type *) -s.StimulationRecSize = 280;% (* = 35 * 8 *) - -s=orderfields(s); - +for k=1:double(obj.fileData.nchild) + obj.fileData.Level = obj.fileData.Level+1; + getTreeReentrant(obj); end -%-------------------------------------------------------------------------- -function c=getChannel(fh) -%-------------------------------------------------------------------------- -c.chMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) -c.chLinkedChannel=fread(fh, 1, 'int32=>int32');% = 4; (* INT32 *) -c.chCompressionFactor=fread(fh, 1, 'int32=>int32');% = 8; (* INT32 *) -c.chYUnit=deblank(fread(fh, 8, 'uint8=>char')');% = 12; (* String8Type *) -c.chAdcChannel=fread(fh, 1, 'int16=>int16');% = 20; (* INT16 *) -c.chAdcMode=fread(fh, 1, 'uint8=>uint8');% = 22; (* BYTE *) -c.chDoWrite=fread(fh, 1, 'uint8=>logical');% = 23; (* BOOLEAN *) -c.stLeakStore=fread(fh, 1, 'uint8=>uint8');% = 24; (* BYTE *) -c.chAmplMode=fread(fh, 1, 'uint8=>uint8');% = 25; (* BYTE *) -c.chOwnSegTime=fread(fh, 1, 'uint8=>logical');% = 26; (* BOOLEAN *) -c.chSetLastSegVmemb=fread(fh, 1, 'uint8=>logical');% = 27; (* BOOLEAN *) -c.chDacChannel=fread(fh, 1, 'int16=>int16');% = 28; (* INT16 *) -c.chDacMode=fread(fh, 1, 'uint8=>uint8');% = 30; (* BYTE *) -c.chHasLockInSquare=fread(fh, 1, 'uint8=>uint8');% = 31; (* BYTE *) -c.chRelevantXSegment=fread(fh, 1, 'int32=>int32');% = 32; (* INT32 *) -c.chRelevantYSegment=fread(fh, 1, 'int32=>int32');% = 36; (* INT32 *) -c.chDacUnit=deblank(fread(fh, 8, 'uint8=>char')');% = 40; (* String8Type *) -c.chHolding=fread(fh, 1, 'double=>double') ;% = 48; (* LONGREAL *) -c.chLeakHolding=fread(fh, 1, 'double=>double') ;% = 56; (* LONGREAL *) -c.chLeakSize=fread(fh, 1, 'double=>double') ;% = 64; (* LONGREAL *) -c.chLeakHoldMode=fread(fh, 1, 'uint8=>uint8');% = 72; (* BYTE *) -c.chLeakAlternate=fread(fh, 1, 'uint8=>logical');% = 73; (* BOOLEAN *) -c.chAltLeakAveraging=fread(fh, 1, 'uint8=>logical');% = 74; (* BOOLEAN *) -c.chLeakPulseOn=fread(fh, 1, 'uint8=>logical');% = 75; (* BOOLEAN *) -c.chStimToDacID=fread(fh, 1, 'int16=>int16');% = 76; (* SET16 *) -c.chCompressionMode=fread(fh, 1, 'int16=>int16');% = 78; (* SET16 *) -c.chCompressionSkip=fread(fh, 1, 'int32=>int32');% = 80; (* INT32 *) -c.chDacBit=fread(fh, 1, 'int16=>int16');% = 84; (* INT16 *) -c.chHasLockInSine=fread(fh, 1, 'uint8=>logical');% = 86; (* BOOLEAN *) -c.chBreakMode=fread(fh, 1, 'uint8=>uint8');% = 87; (* BYTE *) -c.chZeroSeg=fread(fh, 1, 'int32=>int32');% = 88; (* INT32 *) -c.chFiller1=fread(fh, 1, 'int32=>int32');% = 92; (* INT32 *) -c.chSine_Cycle=fread(fh, 1, 'double=>double') ;% = 96; (* LONGREAL *) -c.chSine_Amplitude=fread(fh, 1, 'double=>double') ;% = 104; (* LONGREAL *) -c.chLockIn_VReversal=fread(fh, 1, 'double=>double') ;% = 112; (* LONGREAL *) -c.chChirp_StartFreq=fread(fh, 1, 'double=>double') ;% = 120; (* LONGREAL *) -c.chChirp_EndFreq=fread(fh, 1, 'double=>double') ;% = 128; (* LONGREAL *) -c.chChirp_MinPoints=fread(fh, 1, 'double=>double') ;% = 136; (* LONGREAL *) -c.chSquare_NegAmpl=fread(fh, 1, 'double=>double') ;% = 144; (* LONGREAL *) -c.chSquare_DurFactor=fread(fh, 1, 'double=>double') ;% = 152; (* LONGREAL *) -c.chLockIn_Skip=fread(fh, 1, 'int32=>int32');% = 160; (* INT32 *) -c.chPhoto_MaxCycles=fread(fh, 1, 'int32=>int32');% = 164; (* INT32 *) -c.chPhoto_SegmentNo=fread(fh, 1, 'int32=>int32');% = 168; (* INT32 *) -c.chLockIn_AvgCycles=fread(fh, 1, 'int32=>int32');% = 172; (* INT32 *) -c.chImaging_RoiNo=fread(fh, 1, 'int32=>int32');% = 176; (* INT32 *) -c.chChirp_Skip=fread(fh, 1, 'int32=>int32');% = 180; (* INT32 *) -c.chChirp_Amplitude=fread(fh, 1, 'double=>double') ;% = 184; (* LONGREAL *) -c.chPhoto_Adapt=fread(fh, 1, 'uint8=>uint8');% = 192; (* BYTE *) -c.chSine_Kind=fread(fh, 1, 'uint8=>uint8');% = 193; (* BYTE *) -c.chChirp_PreChirp=fread(fh, 1, 'uint8=>uint8');% = 194; (* BYTE *) -c.chSine_Source=fread(fh, 1, 'uint8=>uint8');% = 195; (* BYTE *) -c.chSquare_NegSource=fread(fh, 1, 'uint8=>uint8');% = 196; (* BYTE *) -c.chSquare_PosSource=fread(fh, 1, 'uint8=>uint8');% = 197; (* BYTE *) -c.chChirp_Kind=fread(fh, 1, 'uint8=>uint8');% = 198; (* BYTE *) -c.chChirp_Source=fread(fh, 1, 'uint8=>uint8');% = 199; (* BYTE *) -c.chDacOffset=fread(fh, 1, 'double=>double') ;% = 200; (* LONGREAL *) -c.chAdcOffset=fread(fh, 1, 'double=>double') ;% = 208; (* LONGREAL *) -c.chTraceMathFormat=fread(fh, 1, 'uint8=>uint8');% = 216; (* BYTE *) -c.chHasChirp=fread(fh, 1, 'uint8=>logical');% = 217; (* BOOLEAN *) -c.chSquare_Kind=fread(fh, 1, 'uint8=>uint8');% = 218; (* BYTE *) -c.chFiller2=fread(fh,13,'uint8=>char');% = 219; (* ARRAY[0..13] OF CHAR *) -c.chSquare_Cycle=fread(fh, 1, 'double=>double') ;% = 232; (* LONGREAL *) -c.chSquare_PosAmpl=fread(fh, 1, 'double=>double') ;% = 240; (* LONGREAL *) -c.chCompressionOffset=fread(fh, 1, 'int32=>int32');% = 248; (* INT32 *) -c.chPhotoMode=fread(fh, 1, 'int32=>int32');% = 252; (* INT32 *) -c.chBreakLevel=fread(fh, 1, 'double=>double') ;% = 256; (* LONGREAL *) -c.chTraceMath=deblank(fread(fh,128,'uint8=>char')');% = 264; (* String128Type *) -c.chOldCRC=fread(fh, 1, 'int32=>int32');% = 268; (* CARD32 *) -c.chFiller3=fread(fh, 1, 'int32=>int32');% = 392; (* INT32 *) -c.chCRC=fread(fh, 1, 'int32=>int32');% = 396; (* CARD32 *) -c.ChannelRecSize = 400;% (* = 50 * 8 *) -c=orderfields(c); - end -%-------------------------------------------------------------------------- -function ss=getStimSegment(fh) -%-------------------------------------------------------------------------- -ss.seMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) -ss.seClass=fread(fh, 1, 'uint8=>uint8');% = 4; (* BYTE *) -ss.seDoStore=fread(fh, 1, 'uint8=>logical');% = 5; (* BOOLEAN *) -ss.seVoltageIncMode=fread(fh, 1, 'uint8=>uint8');% = 6; (* BYTE *) -ss.seDurationIncMode=fread(fh, 1, 'uint8=>uint8');% = 7; (* BYTE *) -ss.seVoltage=fread(fh, 1, 'double=>double');% = 8; (* LONGREAL *) -ss.seVoltageSource=fread(fh, 1, 'int32=>int32');% = 16; (* INT32 *) -ss.seDeltaVFactor=fread(fh, 1, 'double=>double');% = 20; (* LONGREAL *) -ss.seDeltaVIncrement=fread(fh, 1, 'double=>double');% = 28; (* LONGREAL *) -ss.seDuration=fread(fh, 1, 'double=>double');% = 36; (* LONGREAL *) -ss.seDurationSource=fread(fh, 1, 'int32=>int32');% = 44; (* INT32 *) -ss.seDeltaTFactor=fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) -ss.seDeltaTIncrement=fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) -ss.seFiller1=fread(fh, 1, 'int32=>int32');% = 64; (* INT32 *) -ss.seCRC=fread(fh, 1, 'int32=>int32');% = 68; (* CARD32 *) -ss.seScanRate=fread(fh, 1, 'double=>double');% = 72; (* LONGREAL *) -ss.StimSegmentRecSize = 80;% (* = 10 * 8 *) -ss=orderfields(ss); - -end - - - -%% GET AMPLIFIER DATA -%-------------------------------------------------------------------------- -function L=getSeLockInParams(fh) -%-------------------------------------------------------------------------- -offset=ftell(fh); -L.loExtCalPhase = fread(fh, 1, 'double=>double');% = 0; (* LONGREAL *) -L.loExtCalAtten = fread(fh, 1, 'double=>double');% = 8; (* LONGREAL *) -L.loPLPhase = fread(fh, 1, 'double=>double');% = 16; (* LONGREAL *) -L.loPLPhaseY1 = fread(fh, 1, 'double=>double');% = 24; (* LONGREAL *) -L.loPLPhaseY2 = fread(fh, 1, 'double=>double');% = 32; (* LONGREAL *) -L.loUsedPhaseShift = fread(fh, 1, 'double=>double');% = 40; (* LONGREAL *) -L.loUsedAttenuation = fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) - L.loSpare = fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) -L.loExtCalValid = fread(fh, 1, 'uint8=>logical');% = 64; (* BOOLEAN *) -L.loPLPhaseValid = fread(fh, 1, 'uint8=>logical');% = 65; (* BOOLEAN *) -L.loLockInMode = fread(fh, 1, 'uint8=>uint8');% = 66; (* BYTE *) -L.loCalMode = fread(fh, 1, 'uint8=>uint8');% = 67; (* BYTE *) - L.loSpare2 = fread(fh, 7, 'int32=>in32');% = 68; (* remaining *) -L.LockInParamsSize = 96; - -fseek(fh, offset+L.LockInParamsSize, 'bof'); - -end - -%-------------------------------------------------------------------------- -function A=getAmplifierState(fh) -%-------------------------------------------------------------------------- -offset=ftell(fh); -A.sStateVersion = fread(fh, 1, 'double=>double');% = 0; (* 8 = SizeStateVersion *) -A.sCurrentGain = fread(fh, 1, 'double=>double');% = 8; (* LONGREAL *) -A.sF2Bandwidth = fread(fh, 1, 'double=>double');% = 16; (* LONGREAL *) -A.sF2Frequency = fread(fh, 1, 'double=>double');% = 24; (* LONGREAL *) -A.sRsValue = fread(fh, 1, 'double=>double');% = 32; (* LONGREAL *) -A.sRsFraction = fread(fh, 1, 'double=>double');% = 40; (* LONGREAL *) -A.sGLeak = fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) -A.sCFastAmp1 = fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) -A.sCFastAmp2 = fread(fh, 1, 'double=>double');% = 64; (* LONGREAL *) -A.sCFastTau = fread(fh, 1, 'double=>double');% = 72; (* LONGREAL *) -A.sCSlow = fread(fh, 1, 'double=>double');% = 80; (* LONGREAL *) -A.sGSeries = fread(fh, 1, 'double=>double');% = 88; (* LONGREAL *) -A.sVCStimDacScale = fread(fh, 1, 'double=>double');% = 96; (* LONGREAL *) -A.sCCStimScale = fread(fh, 1, 'double=>double');% = 104; (* LONGREAL *) -A.sVHold = fread(fh, 1, 'double=>double');% = 112; (* LONGREAL *) -A.sLastVHold = fread(fh, 1, 'double=>double');% = 120; (* LONGREAL *) -A.sVpOffset = fread(fh, 1, 'double=>double');% = 128; (* LONGREAL *) -A.sVLiquidJunction = fread(fh, 1, 'double=>double');% = 136; (* LONGREAL *) -A.sCCIHold = fread(fh, 1, 'double=>double');% = 144; (* LONGREAL *) -A.sCSlowStimVolts = fread(fh, 1, 'double=>double');% = 152; (* LONGREAL *) -A.sCCTrackVHold = fread(fh, 1, 'double=>double');% = 160; (* LONGREAL *) -A.sTimeoutCSlow = fread(fh, 1, 'double=>double');% = 168; (* LONGREAL *) -A.sSearchDelay = fread(fh, 1, 'double=>double');% = 176; (* LONGREAL *) -A.sMConductance = fread(fh, 1, 'double=>double');% = 184; (* LONGREAL *) -A.sMCapacitance = fread(fh, 1, 'double=>double');% = 192; (* LONGREAL *) -A.sSerialNumber = fread(fh, 1, 'double=>double');% = 200; (* 8 = SizeSerialNumber *) - -A.sE9Boards = fread(fh, 1, 'int16=>int16');% = 208; (* INT16 *) -A.sCSlowCycles = fread(fh, 1, 'int16=>int16');% = 210; (* INT16 *) -A.sIMonAdc = fread(fh, 1, 'int16=>int16');% = 212; (* INT16 *) -A.sVMonAdc = fread(fh, 1, 'int16=>int16');% = 214; (* INT16 *) - -A.sMuxAdc = fread(fh, 1, 'int16=>int16');% = 216; (* INT16 *) -A.sTestDac = fread(fh, 1, 'int16=>int16');% = 218; (* INT16 *) -A.sStimDac = fread(fh, 1, 'int16=>int16');% = 220; (* INT16 *) -A.sStimDacOffset = fread(fh, 1, 'int16=>int16');% = 222; (* INT16 *) - -A.sMaxDigitalBit = fread(fh, 1, 'int16=>int16');% = 224; (* INT16 *) -A.sHasCFastHigh = fread(fh, 1, 'uint8=>uint8');% = 226; (* BYTE *) -A.sCFastHigh = fread(fh, 1, 'uint8=>uint8');% = 227; (* BYTE *) -A.sHasBathSense = fread(fh, 1, 'uint8=>uint8');% = 228; (* BYTE *) -A.sBathSense = fread(fh, 1, 'uint8=>uint8');% = 229; (* BYTE *) -A.sHasF2Bypass = fread(fh, 1, 'uint8=>uint8');% = 230; (* BYTE *) -A.sF2Mode = fread(fh, 1, 'uint8=>uint8');% = 231; (* BYTE *) - -A.sAmplKind = fread(fh, 1, 'uint8=>uint8');% = 232; (* BYTE *) -A.sIsEpc9N = fread(fh, 1, 'uint8=>uint8');% = 233; (* BYTE *) -A.sADBoard = fread(fh, 1, 'uint8=>uint8');% = 234; (* BYTE *) -A.sBoardVersion = fread(fh, 1, 'uint8=>uint8');% = 235; (* BYTE *) -A.sActiveE9Board = fread(fh, 1, 'uint8=>uint8');% = 236; (* BYTE *) -A.sMode = fread(fh, 1, 'uint8=>uint8');% = 237; (* BYTE *) -A.sRange = fread(fh, 1, 'uint8=>uint8');% = 238; (* BYTE *) -A.sF2Response = fread(fh, 1, 'uint8=>uint8');% = 239; (* BYTE *) - -A.sRsOn = fread(fh, 1, 'uint8=>uint8');% = 240; (* BYTE *) -A.sCSlowRange = fread(fh, 1, 'uint8=>uint8');% = 241; (* BYTE *) -A.sCCRange = fread(fh, 1, 'uint8=>uint8');% = 242; (* BYTE *) -A.sCCGain = fread(fh, 1, 'uint8=>uint8');% = 243; (* BYTE *) -A.sCSlowToTestDac = fread(fh, 1, 'uint8=>uint8');% = 244; (* BYTE *) -A.sStimPath = fread(fh, 1, 'uint8=>uint8');% = 245; (* BYTE *) -A.sCCTrackTau = fread(fh, 1, 'uint8=>uint8');% = 246; (* BYTE *) -A.sWasClipping = fread(fh, 1, 'uint8=>uint8');% = 247; (* BYTE *) - -A.sRepetitiveCSlow = fread(fh, 1, 'uint8=>uint8');% = 248; (* BYTE *) -A.sLastCSlowRange = fread(fh, 1, 'uint8=>uint8');% = 249; (* BYTE *) - A.sOld1 = fread(fh, 1, 'uint8=>uint8');% = 250; (* BYTE *) -A.sCanCCFast = fread(fh, 1, 'uint8=>uint8');% = 251; (* BYTE *) -A.sCanLowCCRange = fread(fh, 1, 'uint8=>uint8');% = 252; (* BYTE *) -A.sCanHighCCRange = fread(fh, 1, 'uint8=>uint8');% = 253; (* BYTE *) -A.sCanCCTrackingg = fread(fh, 1, 'uint8=>uint8');% = 254; (* BYTE *) -A.sCHasVmonPath = fread(fh, 1, 'uint8=>uint8');% = 255; (* BYTE *) - -A.sHasNewCCMode = fread(fh, 1, 'uint8=>uint8');% = 256; (* BYTE *) -A.sSelector = fread(fh, 1, 'uint8=>char');% = 257; (* CHAR *) -A.sHoldInverted = fread(fh, 1, 'uint8=>uint8');% = 258; (* BYTE *) -A.sAutoCFast = fread(fh, 1, 'uint8=>uint8');% = 259; (* BYTE *) -A.sAutoCSlow = fread(fh, 1, 'uint8=>uint8');% = 260; (* BYTE *) -A.sHasVmonX100 = fread(fh, 1, 'uint8=>uint8');% = 261; (* BYTE *) -A.sTestDacOn = fread(fh, 1, 'uint8=>uint8');% = 262; (* BYTE *) -A.sQMuxAdcOn = fread(fh, 1, 'uint8=>uint8');% = 263; (* BYTE *) - -A.sImon1Bandwidth = fread(fh, 1, 'double=>double');% = 264; (* LONGREAL *) -A.sStimScale = fread(fh, 1, 'double=>double');% = 272; (* LONGREAL *) - -A.sGain = fread(fh, 1, 'uint8=>uint8');% = 280; (* BYTE *) -A.sFilter1 = fread(fh, 1, 'uint8=>uint8');% = 281; (* BYTE *) -A.sStimFilterOn = fread(fh, 1, 'uint8=>uint8');% = 282; (* BYTE *) -A.sRsSlow = fread(fh, 1, 'uint8=>uint8');% = 283; (* BYTE *) - A.sOld2 = fread(fh, 1, 'uint8=>uint8');% = 284; (* BYTE *) -A.sCCCFastOn = fread(fh, 1, 'uint8=>uint8');% = 285; (* BYTE *) -A.sCCFastSpeed = fread(fh, 1, 'uint8=>uint8');% = 286; (* BYTE *) -A.sF2Source = fread(fh, 1, 'uint8=>uint8');% = 287; (* BYTE *) - -A.sTestRange = fread(fh, 1, 'uint8=>uint8');% = 288; (* BYTE *) -A.sTestDacPath = fread(fh, 1, 'uint8=>uint8');% = 289; (* BYTE *) -A.sMuxChannel = fread(fh, 1, 'uint8=>uint8');% = 290; (* BYTE *) -A.sMuxGain64 = fread(fh, 1, 'uint8=>uint8');% = 291; (* BYTE *) -A.sVmonX100 = fread(fh, 1, 'uint8=>uint8');% = 292; (* BYTE *) -A.sIsQuadro = fread(fh, 1, 'uint8=>uint8');% = 293; (* BYTE *) -A.sF1Mode = fread(fh, 1, 'uint8=>uint8');% = 294; (* BYTE *) - A.sOld3 = fread(fh, 1, 'uint8=>uint8');% = 295; (* BYTE *) -A.sStimFilterHz = fread(fh, 1, 'double=>double');% = 296; (* LONGREAL *) -A.sRsTau = fread(fh, 1, 'double=>double');% = 304; (* LONGREAL *) -A.sDacToAdcDelay = fread(fh, 1, 'double=>double');% = 312; (* LONGREAL *) -A.sInputFilterTau = fread(fh, 1, 'double=>double');% = 320; (* LONGREAL *) -A.sOutputFilterTau = fread(fh, 1, 'double=>double');% = 328; (* LONGREAL *) -A.sVmonFactor = fread(fh, 1, 'double=>double');% = 336; (* LONGREAL *) -A.sCalibDate = fread(fh, 2, 'double=>double');% = 344; (* 16 = SizeCalibDate *) -A.sVmonOffset = fread(fh, 1, 'double=>double');% = 360; (* LONGREAL *) - -A.sEEPROMKind = fread(fh, 1, 'uint8=>uint8');% = 368; (* BYTE *) -A.sVrefX2 = fread(fh, 1, 'uint8=>uint8');% = 369; (* BYTE *) -A.sHasVrefX2AndF2Vmon = fread(fh, 1, 'uint8=>uint8');% = 370; (* BYTE *) -A.sSpare1 = fread(fh, 1, 'uint8=>uint8');% = 371; (* BYTE *) -A.sSpare2 = fread(fh, 1, 'uint8=>uint8');% = 372; (* BYTE *) -A.sSpare3 = fread(fh, 1, 'uint8=>uint8');% = 373; (* BYTE *) -A.sSpare4 = fread(fh, 1, 'uint8=>uint8');% = 374; (* BYTE *) -A.sSpare5 = fread(fh, 1, 'uint8=>uint8');% = 375; (* BYTE *) - -A.sCCStimDacScale = fread(fh, 1, 'double=>double');% = 376; (* LONGREAL *) -A.sVmonFiltBandwidth = fread(fh, 1, 'double=>double');% = 384; (* LONGREAL *) -A.sVmonFiltFrequency = fread(fh, 1, 'double=>double');% = 392; (* LONGREAL *) -A.AmplifierStateSize = 400;% (* = 50 * 8 *) - -fseek(fh, offset+A.AmplifierStateSize, 'bof'); - -end %-------------------------------------------------------------------------- function matData2=LocalImportGroup(fh, dataTree, grp, grp_row) @@ -1151,15 +476,3 @@ return end -%-------------------------------------------------------------------------- -function str=time2date(t) -%-------------------------------------------------------------------------- -t=t-1580970496; -if t<0 - t=t+4294967296; -end -t=t+9561652096; -str=datestr(t/(24*60*60)+datenum(1601,1,1)); -return -end -%-------------------------------------------------------------------------- \ No newline at end of file diff --git a/@HEKA_Importer/HI_extractHEKADataTree.m b/@HEKA_Importer/HI_extractHEKADataTree.m index 89a36a7..6c97564 100644 --- a/@HEKA_Importer/HI_extractHEKADataTree.m +++ b/@HEKA_Importer/HI_extractHEKADataTree.m @@ -80,7 +80,7 @@ function HI_extractHEKADataTree(obj) % nSweeps = reshape([Recs(:).SeNumbersw],numel(Recs),1); %EXTRACT INFORMATION FROM AMPLIFIER STATE, LEVEL 3 -AmpState = [Recs(:).SeAmplifierState]; +% AmpState = [Recs(:).SeAmplifierState]; % THIS ONLY READS OUT THE Rs/Cm VALUES FOR FIRST SWEEP % RsFractionComp = reshape([AmpState(:).E9RsFraction],numel(AmpState),1); diff --git a/@HEKA_Importer/HI_time2date.m b/@HEKA_Importer/HI_time2date.m new file mode 100644 index 0000000..c5a9139 --- /dev/null +++ b/@HEKA_Importer/HI_time2date.m @@ -0,0 +1,12 @@ +%-------------------------------------------------------------------------- +function str=HI_time2date(obj,t) +%-------------------------------------------------------------------------- +t=t-1580970496; +if t<0 + t=t+4294967296; +end +t=t+9561652096; +str=datestr(t/(24*60*60)+datenum(1601,1,1)); +return +end +%-------------------------------------------------------------------------- \ No newline at end of file diff --git a/@HEKA_Importer/readAmplifierFileHEKA.m b/@HEKA_Importer/readAmplifierFileHEKA.m new file mode 100644 index 0000000..35fa910 --- /dev/null +++ b/@HEKA_Importer/readAmplifierFileHEKA.m @@ -0,0 +1,241 @@ +function [Tree, Position, Counter, nchild]=readAmplifierFileHEKA(obj,fh, Tree, Sizes, Level, Position, Counter) +%-------------------------------------------------------------------------- +% Gets one record of the tree and the number of children + + + +[s, Counter]=getOneAmplifierRecord(fh, Level, Counter); +Tree{Counter, Level+1}=s; +Position=Position+Sizes(Level+1); +fseek(fh, Position, 'bof'); +nchild=fread(fh, 1, 'int32=>int32'); +Position=ftell(fh); + +end + +%-------------------------------------------------------------------------- +function [rec, Counter]=getOneAmplifierRecord(fh, Level, Counter) +%-------------------------------------------------------------------------- +% Gets one record +Counter=Counter+1; +switch Level + case 0 + rec=getAmplifierRootRecord(fh); + case 1 + rec=getAmplifierSeriesRecord(fh); + case 2 + rec=getAmplifierStateRecord(fh); + + otherwise + error('Unexpected Level'); +end + +end + +%-------------------------------------------------------------------------- +function p=getAmplifierRootRecord(fh) +%-------------------------------------------------------------------------- +p.RoVersion = fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) +p.RoMark = fread(fh, 1, 'int32=>int32');% = 4; (* INT32 *) +p.RoVersionName = deblank(fread(fh, 32, 'uint8=>char')');% = 8; (* String32Type *) +p.RoAmplifierName = deblank(fread(fh, 32, 'uint8=>char')');% = 40; (* String32Type *) +p.RoAmplifier = fread(fh,1,'uint8=>uint8');% = 72; (* CHAR *) +p.RoADBoard = fread(fh,1,'uint8=>uint8');% = 73; (* CHAR *) +p.RoCreator = fread(fh,1,'uint8=>uint8');% = 74; (* CHAR *) + p.RoFiller1 = fread(fh, 1, 'uint8=>uint8');% = 75; (* BYTE *) +p.RoCRC = fread(fh, 1, 'int32=>int32');% = 76; (* CARD32 *) +p.RootRecSize = 80;% (* = 10 * 8 *) + +p=orderfields(p); + +end + +%-------------------------------------------------------------------------- +function s=getAmplifierSeriesRecord(fh) +%-------------------------------------------------------------------------- +s.SeMark = fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) +s.SeSeriesCount = fread(fh, 1, 'int32=>int32');% = 4; (* INT32 *) +s.SeFiller1 = fread(fh, 1, 'int32=>int32');% = 8; (* INT32 *) +s.SeCRC = fread(fh, 1, 'int32=>int32');% = 12; (* CARD32 *) +s.SeriesRecSize = 16;% (* = 2 * 8 *) + +s=orderfields(s); + +end + +%% +function a=getAmplifierStateRecord(fh) + +a.AmMark = fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) +a.AmStateCount = fread(fh, 1, 'int32=>int32');% = 4; (* INT32 *) +a.AmStateVersion = fread(fh,1,'uint8=>uint8');% = 8; (* CHAR *) + a.AmFiller1 = fread(fh, 1, 'uint8=>uint8');% = 9; (* BYTE *) + a.AmFiller2 = fread(fh, 1, 'uint8=>uint8');% = 10; (* BYTE *) + a.AmFiller3 = fread(fh, 1, 'uint8=>uint8');% = 11; (* BYTE *) + a.AmFiller4 = fread(fh, 1, 'int32=>int32');% = 12; (* INT32 *) +a.AmLockInParams = getSeLockInParams(fh);% = 16; (* LockInParamsSize = 96 *) +a.AmAmplifierState = getAmplifierState(fh);% = 112; (* AmplifierStateSize = 400 *) +a.AmIntSol = fread(fh, 1, 'int32=>int32');% = 512; (* INT32 *) +a.AmExtSol = fread(fh, 1, 'int32=>int32');% = 516; (* INT32 *) + a.AmFiller5 = fread(fh, 36, 'uint8=>uint8');% = 520; (* spares: 36 bytes *) +a.AmCRC = fread(fh, 1, 'int32=>int32');% = 556; (* CARD32 *) +a.StateRecSize = 560;% (* = 70 * 8 *) + +a = orderfields(a); + +end + +function L=getSeLockInParams(fh) +%-------------------------------------------------------------------------- +offset=ftell(fh); +L.loExtCalPhase = fread(fh, 1, 'double=>double');% = 0; (* LONGREAL *) +L.loExtCalAtten = fread(fh, 1, 'double=>double');% = 8; (* LONGREAL *) +L.loPLPhase = fread(fh, 1, 'double=>double');% = 16; (* LONGREAL *) +L.loPLPhaseY1 = fread(fh, 1, 'double=>double');% = 24; (* LONGREAL *) +L.loPLPhaseY2 = fread(fh, 1, 'double=>double');% = 32; (* LONGREAL *) +L.loUsedPhaseShift = fread(fh, 1, 'double=>double');% = 40; (* LONGREAL *) +L.loUsedAttenuation = fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) + L.loSpare = fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) +L.loExtCalValid = fread(fh, 1, 'uint8=>logical');% = 64; (* BOOLEAN *) +L.loPLPhaseValid = fread(fh, 1, 'uint8=>logical');% = 65; (* BOOLEAN *) +L.loLockInMode = fread(fh, 1, 'uint8=>uint8');% = 66; (* BYTE *) +L.loCalMode = fread(fh, 1, 'uint8=>uint8');% = 67; (* BYTE *) + L.loSpare2 = fread(fh, 7, 'int32=>in32');% = 68; (* remaining *) +L.LockInParamsSize = 96; + +fseek(fh, offset+L.LockInParamsSize, 'bof'); + +end + +%-------------------------------------------------------------------------- +function A=getAmplifierState(fh) +%-------------------------------------------------------------------------- +offset=ftell(fh); +A.sStateVersion = fread(fh, 1, 'double=>double');% = 0; (* 8 = SizeStateVersion *) +A.sCurrentGain = fread(fh, 1, 'double=>double');% = 8; (* LONGREAL *) +A.sF2Bandwidth = fread(fh, 1, 'double=>double');% = 16; (* LONGREAL *) +A.sF2Frequency = fread(fh, 1, 'double=>double');% = 24; (* LONGREAL *) +A.sRsValue = fread(fh, 1, 'double=>double');% = 32; (* LONGREAL *) +A.sRsFraction = fread(fh, 1, 'double=>double');% = 40; (* LONGREAL *) +A.sGLeak = fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) +A.sCFastAmp1 = fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) +A.sCFastAmp2 = fread(fh, 1, 'double=>double');% = 64; (* LONGREAL *) +A.sCFastTau = fread(fh, 1, 'double=>double');% = 72; (* LONGREAL *) +A.sCSlow = fread(fh, 1, 'double=>double');% = 80; (* LONGREAL *) +A.sGSeries = fread(fh, 1, 'double=>double');% = 88; (* LONGREAL *) +A.sVCStimDacScale = fread(fh, 1, 'double=>double');% = 96; (* LONGREAL *) +A.sCCStimScale = fread(fh, 1, 'double=>double');% = 104; (* LONGREAL *) +A.sVHold = fread(fh, 1, 'double=>double');% = 112; (* LONGREAL *) +A.sLastVHold = fread(fh, 1, 'double=>double');% = 120; (* LONGREAL *) +A.sVpOffset = fread(fh, 1, 'double=>double');% = 128; (* LONGREAL *) +A.sVLiquidJunction = fread(fh, 1, 'double=>double');% = 136; (* LONGREAL *) +A.sCCIHold = fread(fh, 1, 'double=>double');% = 144; (* LONGREAL *) +A.sCSlowStimVolts = fread(fh, 1, 'double=>double');% = 152; (* LONGREAL *) +A.sCCTrackVHold = fread(fh, 1, 'double=>double');% = 160; (* LONGREAL *) +A.sTimeoutCSlow = fread(fh, 1, 'double=>double');% = 168; (* LONGREAL *) +A.sSearchDelay = fread(fh, 1, 'double=>double');% = 176; (* LONGREAL *) +A.sMConductance = fread(fh, 1, 'double=>double');% = 184; (* LONGREAL *) +A.sMCapacitance = fread(fh, 1, 'double=>double');% = 192; (* LONGREAL *) +A.sSerialNumber = fread(fh, 1, 'double=>double');% = 200; (* 8 = SizeSerialNumber *) + +A.sE9Boards = fread(fh, 1, 'int16=>int16');% = 208; (* INT16 *) +A.sCSlowCycles = fread(fh, 1, 'int16=>int16');% = 210; (* INT16 *) +A.sIMonAdc = fread(fh, 1, 'int16=>int16');% = 212; (* INT16 *) +A.sVMonAdc = fread(fh, 1, 'int16=>int16');% = 214; (* INT16 *) + +A.sMuxAdc = fread(fh, 1, 'int16=>int16');% = 216; (* INT16 *) +A.sTestDac = fread(fh, 1, 'int16=>int16');% = 218; (* INT16 *) +A.sStimDac = fread(fh, 1, 'int16=>int16');% = 220; (* INT16 *) +A.sStimDacOffset = fread(fh, 1, 'int16=>int16');% = 222; (* INT16 *) + +A.sMaxDigitalBit = fread(fh, 1, 'int16=>int16');% = 224; (* INT16 *) +A.sHasCFastHigh = fread(fh, 1, 'uint8=>uint8');% = 226; (* BYTE *) +A.sCFastHigh = fread(fh, 1, 'uint8=>uint8');% = 227; (* BYTE *) +A.sHasBathSense = fread(fh, 1, 'uint8=>uint8');% = 228; (* BYTE *) +A.sBathSense = fread(fh, 1, 'uint8=>uint8');% = 229; (* BYTE *) +A.sHasF2Bypass = fread(fh, 1, 'uint8=>uint8');% = 230; (* BYTE *) +A.sF2Mode = fread(fh, 1, 'uint8=>uint8');% = 231; (* BYTE *) + +A.sAmplKind = fread(fh, 1, 'uint8=>uint8');% = 232; (* BYTE *) +A.sIsEpc9N = fread(fh, 1, 'uint8=>uint8');% = 233; (* BYTE *) +A.sADBoard = fread(fh, 1, 'uint8=>uint8');% = 234; (* BYTE *) +A.sBoardVersion = fread(fh, 1, 'uint8=>uint8');% = 235; (* BYTE *) +A.sActiveE9Board = fread(fh, 1, 'uint8=>uint8');% = 236; (* BYTE *) +A.sMode = fread(fh, 1, 'uint8=>uint8');% = 237; (* BYTE *) +A.sRange = fread(fh, 1, 'uint8=>uint8');% = 238; (* BYTE *) +A.sF2Response = fread(fh, 1, 'uint8=>uint8');% = 239; (* BYTE *) + +A.sRsOn = fread(fh, 1, 'uint8=>uint8');% = 240; (* BYTE *) +A.sCSlowRange = fread(fh, 1, 'uint8=>uint8');% = 241; (* BYTE *) +A.sCCRange = fread(fh, 1, 'uint8=>uint8');% = 242; (* BYTE *) +A.sCCGain = fread(fh, 1, 'uint8=>uint8');% = 243; (* BYTE *) +A.sCSlowToTestDac = fread(fh, 1, 'uint8=>uint8');% = 244; (* BYTE *) +A.sStimPath = fread(fh, 1, 'uint8=>uint8');% = 245; (* BYTE *) +A.sCCTrackTau = fread(fh, 1, 'uint8=>uint8');% = 246; (* BYTE *) +A.sWasClipping = fread(fh, 1, 'uint8=>uint8');% = 247; (* BYTE *) + +A.sRepetitiveCSlow = fread(fh, 1, 'uint8=>uint8');% = 248; (* BYTE *) +A.sLastCSlowRange = fread(fh, 1, 'uint8=>uint8');% = 249; (* BYTE *) + A.sOld1 = fread(fh, 1, 'uint8=>uint8');% = 250; (* BYTE *) +A.sCanCCFast = fread(fh, 1, 'uint8=>uint8');% = 251; (* BYTE *) +A.sCanLowCCRange = fread(fh, 1, 'uint8=>uint8');% = 252; (* BYTE *) +A.sCanHighCCRange = fread(fh, 1, 'uint8=>uint8');% = 253; (* BYTE *) +A.sCanCCTrackingg = fread(fh, 1, 'uint8=>uint8');% = 254; (* BYTE *) +A.sCHasVmonPath = fread(fh, 1, 'uint8=>uint8');% = 255; (* BYTE *) + +A.sHasNewCCMode = fread(fh, 1, 'uint8=>uint8');% = 256; (* BYTE *) +A.sSelector = fread(fh, 1, 'uint8=>char');% = 257; (* CHAR *) +A.sHoldInverted = fread(fh, 1, 'uint8=>uint8');% = 258; (* BYTE *) +A.sAutoCFast = fread(fh, 1, 'uint8=>uint8');% = 259; (* BYTE *) +A.sAutoCSlow = fread(fh, 1, 'uint8=>uint8');% = 260; (* BYTE *) +A.sHasVmonX100 = fread(fh, 1, 'uint8=>uint8');% = 261; (* BYTE *) +A.sTestDacOn = fread(fh, 1, 'uint8=>uint8');% = 262; (* BYTE *) +A.sQMuxAdcOn = fread(fh, 1, 'uint8=>uint8');% = 263; (* BYTE *) + +A.sImon1Bandwidth = fread(fh, 1, 'double=>double');% = 264; (* LONGREAL *) +A.sStimScale = fread(fh, 1, 'double=>double');% = 272; (* LONGREAL *) + +A.sGain = fread(fh, 1, 'uint8=>uint8');% = 280; (* BYTE *) +A.sFilter1 = fread(fh, 1, 'uint8=>uint8');% = 281; (* BYTE *) +A.sStimFilterOn = fread(fh, 1, 'uint8=>uint8');% = 282; (* BYTE *) +A.sRsSlow = fread(fh, 1, 'uint8=>uint8');% = 283; (* BYTE *) + A.sOld2 = fread(fh, 1, 'uint8=>uint8');% = 284; (* BYTE *) +A.sCCCFastOn = fread(fh, 1, 'uint8=>uint8');% = 285; (* BYTE *) +A.sCCFastSpeed = fread(fh, 1, 'uint8=>uint8');% = 286; (* BYTE *) +A.sF2Source = fread(fh, 1, 'uint8=>uint8');% = 287; (* BYTE *) + +A.sTestRange = fread(fh, 1, 'uint8=>uint8');% = 288; (* BYTE *) +A.sTestDacPath = fread(fh, 1, 'uint8=>uint8');% = 289; (* BYTE *) +A.sMuxChannel = fread(fh, 1, 'uint8=>uint8');% = 290; (* BYTE *) +A.sMuxGain64 = fread(fh, 1, 'uint8=>uint8');% = 291; (* BYTE *) +A.sVmonX100 = fread(fh, 1, 'uint8=>uint8');% = 292; (* BYTE *) +A.sIsQuadro = fread(fh, 1, 'uint8=>uint8');% = 293; (* BYTE *) +A.sF1Mode = fread(fh, 1, 'uint8=>uint8');% = 294; (* BYTE *) + A.sOld3 = fread(fh, 1, 'uint8=>uint8');% = 295; (* BYTE *) + +A.sStimFilterHz = fread(fh, 1, 'double=>double');% = 296; (* LONGREAL *) +A.sRsTau = fread(fh, 1, 'double=>double');% = 304; (* LONGREAL *) +A.sDacToAdcDelay = fread(fh, 1, 'double=>double');% = 312; (* LONGREAL *) +A.sInputFilterTau = fread(fh, 1, 'double=>double');% = 320; (* LONGREAL *) +A.sOutputFilterTau = fread(fh, 1, 'double=>double');% = 328; (* LONGREAL *) +A.sVmonFactor = fread(fh, 1, 'double=>double');% = 336; (* LONGREAL *) +A.sCalibDate = fread(fh, 2, 'double=>double');% = 344; (* 16 = SizeCalibDate *) +A.sVmonOffset = fread(fh, 1, 'double=>double');% = 360; (* LONGREAL *) + +A.sEEPROMKind = fread(fh, 1, 'uint8=>uint8');% = 368; (* BYTE *) +A.sVrefX2 = fread(fh, 1, 'uint8=>uint8');% = 369; (* BYTE *) +A.sHasVrefX2AndF2Vmon = fread(fh, 1, 'uint8=>uint8');% = 370; (* BYTE *) +A.sSpare1 = fread(fh, 1, 'uint8=>uint8');% = 371; (* BYTE *) +A.sSpare2 = fread(fh, 1, 'uint8=>uint8');% = 372; (* BYTE *) +A.sSpare3 = fread(fh, 1, 'uint8=>uint8');% = 373; (* BYTE *) +A.sSpare4 = fread(fh, 1, 'uint8=>uint8');% = 374; (* BYTE *) +A.sSpare5 = fread(fh, 1, 'uint8=>uint8');% = 375; (* BYTE *) + +A.sCCStimDacScale = fread(fh, 1, 'double=>double');% = 376; (* LONGREAL *) +A.sVmonFiltBandwidth = fread(fh, 1, 'double=>double');% = 384; (* LONGREAL *) +A.sVmonFiltFrequency = fread(fh, 1, 'double=>double');% = 392; (* LONGREAL *) +A.AmplifierStateSize = 400;% (* = 50 * 8 *) + +fseek(fh, offset+A.AmplifierStateSize, 'bof'); + +end diff --git a/@HEKA_Importer/readPulseFileHEKA.asv b/@HEKA_Importer/readPulseFileHEKA.asv new file mode 100644 index 0000000..023c8f6 --- /dev/null +++ b/@HEKA_Importer/readPulseFileHEKA.asv @@ -0,0 +1,447 @@ +function [Tree, Position, Counter, nchild]=readPulseFileHEKA(obj,fh, Tree, Sizes, Level, Position, Counter) +%-------------------------------------------------------------------------- +% Gets one record of the tree and the number of children + + + + +[s, Counter]=getOneRecord(fh, Level, Counter,obj); +Tree{Counter, Level+1}=s; +Position=Position+Sizes(Level+1); +fseek(fh, Position, 'bof'); +nchild=fread(fh, 1, 'int32=>int32'); +Position=ftell(fh); +end + +%-------------------------------------------------------------------------- +function [rec, Counter]=getOneRecord(fh, Level, Counter,obj) +%-------------------------------------------------------------------------- +% Gets one record +% Counter=Counter+1; +obj.fileData.Counter = obj.fileData.Counter+1 + +switch Level + case 0 + rec=getRoot(fh,obj); + case 1 + rec=getGroup(fh,obj); + case 2 + rec=getSeries(fh,obj); + case 3 + rec=getSweep(fh,obj); + case 4 + rec=getTrace(fh,obj); + otherwise + error('Unexpected Level'); +end +end + +% The functions below return data as defined by the HEKA PatchMaster +% specification + +%-------------------------------------------------------------------------- +function p=getRoot(fh,obj) +%-------------------------------------------------------------------------- +p.RoVersion=fread(fh, 1, 'int32=>int32'); +p.RoMark=fread(fh, 1, 'int32=>int32');% = 4; (* INT32 *) +p.RoVersionName=deblank(fread(fh, 32, 'uint8=>char')');% = 8; (* String32Type *) +p.RoAuxFileName=deblank(fread(fh, 80, 'uint8=>char')');% = 40; (* String80Type *) +p.RoRootText=deblank(fread(fh, 400, 'uint8=>char')');% (* String400Type *) +p.RoStartTime=fread(fh, 1, 'double=>double') ;% = 520; (* LONGREAL *) +p.RoStartTimeMATLAB=obj.HI_time2date(p.RoStartTime); +p.RoMaxSamples=fread(fh, 1, 'int32=>int32'); % = 528; (* INT32 *) +p.RoCRC=fread(fh, 1, 'int32=>int32'); % = 532; (* CARD32 *) +p.RoFeatures=fread(fh, 1, 'int16=>int16'); % = 536; (* SET16 *) +p.RoFiller1=fread(fh, 1, 'int16=>int16');% = 538; (* INT16 *) +p.RoFiller2=fread(fh, 1, 'int32=>int32');% = 540; (* INT32 *) +p.RoTcEnumerator = fread(fh,32,'int16=>int16');% = 544; (* ARRAY[0..Max_TcKind_M1] OF INT16 *) +p.RoTcKind = fread(fh,32,'int8=>int8');% = 608; (* ARRAY[0..Max_TcKind_M1] OF INT8 *) +p.RootRecSize = 640; % (* = 80 * 8 *); +p=orderfields(p); + +end + +%-------------------------------------------------------------------------- +function g=getGroup(fh,obj) +%-------------------------------------------------------------------------- +% Group +g.GrMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) +g.GrLabel=deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Size *) +g.GrText=deblank(fread(fh, 80, 'uint8=>char')');% = 36; (* String80Size *) +g.GrExperimentNumber=fread(fh, 1, 'int32=>int32');% = 116; (* INT32 *) +g.GrGroupCount=fread(fh, 1, 'int32=>int32');% = 120; (* INT32 *) +g.GrCRC=fread(fh, 1, 'int32=>int32');% = 124; (* CARD32 *) +g.GrMatrixWidth = fread(fh,1,'double=>double');% = 128; (* LONGREAL *) +g.GrMatrixHeight = fread(fh,1,'double=>double');% = 136; (* LONGREAL *) +g.GroupRecSize = 144; % (* = 18 * 8 *) + +% g.GroupRecSize=128;% (* = 16 * 8 *) +g=orderfields(g); + +end + +%-------------------------------------------------------------------------- +function s=getSeries(fh,obj) +%-------------------------------------------------------------------------- +s.SeMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) +s.SeLabel=deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Type *) +s.SeComment=deblank(fread(fh, 80, 'uint8=>char')');% = 36; (* String80Type *) +s.SeSeriesCount=fread(fh, 1, 'int32=>int32');% = 116; (* INT32 *) +s.SeNumbersw=fread(fh, 1, 'int32=>int32');% = 120; (* INT32 *) + +%% +s.SeAmplStateFlag = fread(fh,1,'int32=>int32');% = 124; (* INT32 *) // flag > 0 => load local oldAmpState, otherwise load from .amp File. +s.SeAmplStateRef = fread(fh,1,'int32=>int32'); % = 128; (* INT32 *) // ref = 0 => use local oldAmpState +s.SeMethodTag = fread(fh,1,'int32=>int32'); % = 132; (* INT32 *) +s.SeTime = fread(fh,1,'double=>double'); % = 136; (* LONGREAL *) +s.SeTimeMATLAB=obj.HI_time2date(s.SeTime); +s.SePageWidth=fread(fh, 1, 'double=>double') ;% = 144; (* LONGREAL *) +for k=1:2 % = 152; (* ARRAY[0..1] OF UserParamDescrType = 2*40 *) + s.SeSwUserParamDescr(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% + s.SeSwUserParamDescr(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% +end +s.SeFiller1 = deblank(fread(fh,80,'uint8=>char')'); % = 232; (* ARRAY[0..1] OF UserParamDescrType = 2*40 *) +s.SeMethodName = deblank(fread(fh,32,'uint8=>char')');% = 312; (* String32Type *) +% + +s.SePhotoParams1 = fread(fh, 4, 'double=>double'); %= 344; (* ARRAY[0..3] OF LONGREAL = 4*8 *) +s.SeOldLockInParams=getSeLockInParams(fh);% = 376; (* SeLockInSize = 96, see "Pulsed.de" *) +s.SeOldAmplifierState=getAmplifierState(fh);% = 472; (* AmplifierStateSize = 400 *) +s.SeUsername=deblank(fread(fh, 80, 'uint8=>char')');% + +for k=1:4 + s.SeSeUserParamDescr(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% (* ARRAY[0..3] OF UserParamDescrType = 4*40 *) + s.SeSeUserParamDescr(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% +end + +% s.SeOldLockInParams = fread(fh,96); % = 376; (* SeOldLockInSize = 96, see "Pulsed.de" *) +% s.SeOldAmpState = fread(fh,400); % = 472; (* SeOldAmpState = 400 -> the AmplStateRecord is now stored in the .amp file *) +% s.SeUsername = deblank(fread(fh,80,'uint8=>char')); % = 872; (* String80Type *) + +s.SePhotoParams2 = deblank(fread(fh,160,'uint8=>char')'); %= 952; (* ARRAY[0..3] OF UserParamDescrType = 4*40 *) +s.SeFiller1=fread(fh, 1, 'int32=>int32');% = 1112; (* INT32 *) +s.SeCRC=fread(fh, 1, 'int32=>int32');% = 1116; (* CARD32 *) + +s.SeSeUserParams2=fread(fh, 4, 'double=>double'); %= 1120; (* ARRAY[0..3] OF LONGREAL *) +for k=1:4 %= 1152; (* ARRAY[0..3] OF UserParamDescrType = 4*40 *) + s.SeSeUserParamDescr2(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% + s.SeSeUserParamDescr2(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% +end +s.SeScanParams=fread(fh, 96, 'uint8=>uint8'); %= 1312; (* ScanParamsSize = 96 (ElProScan Extension) *) + +for k=1:8 %= 1408; (* ARRAY[0..7] OF UserParamDescrType = 8*40 *) + s.SeSeUserDescr2(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% + s.SeSeUserDescr2(k).Unit=deblank(fread(fh, 8, 'uint8=>char')'); +end +s.SeriesRecSize=1728;% = 1728; + +%= 1116; (* CARD32 *) +% s.SeSeUserParams2 = fread(fh,) %= 1120; (* ARRAY[0..3] OF LONGREAL *) +% SeSeUserParamDescr2 %= 1152; (* ARRAY[0..3] OF UserParamDescrType = 4*40 *) +% SeScanParams %= 1312; (* ScanParamsSize = 96 (ElProScan Extension) *) +% SeUserDescr2 %= 1408; (* ARRAY[0..7] OF UserParamDescrType = 8*40 *) +% SeriesRecSize %= 1728; + +%% +% s.SeAmplStateOffset=fread(fh, 1, 'int32=>int32');% = 124; (* INT32 *) +% s.SeAmplStateSeries=fread(fh, 1, 'int32=>int32');% = 128; (* INT32 *) +% s.SeSeriesType=fread(fh, 1, 'uint8=>uint8');% = 132; (* BYTE *) +% +% % Added 15.08.2012 +% s.SeUseXStart=logical(fread(fh, 1, 'uint8=>uint8'));% = 133; (* BYTE *) +% +% s.SeFiller2=fread(fh, 1, 'uint8=>uint8');% = 134; (* BYTE *) +% s.SeFiller3=fread(fh, 1, 'uint8=>uint8');% = 135; (* BYTE *) +% s.SeTime=fread(fh, 1, 'double=>double') ;% = 136; (* LONGREAL *) +% s.SeTimeMATLAB=time2date(s.SeTime); +% s.SePageWidth=fread(fh, 1, 'double=>double') ;% = 144; (* LONGREAL *) +% for k=1:4 +% s.SeSwUserParamDescr(k).Name=deblank(fread(fh, 32, 'uint8=>')');% +% s.SeSwUserParamDescr(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% +% end +% s.SeFiller4=fread(fh, 32, 'uint8=>uint8');% = 312; (* 32 BYTE *) +% s.SeSeUserParams=fread(fh, 4, 'double=>double');% = 344; (* ARRAY[0..3] OF LONGREAL *) +% s.SeLockInParams=getSeLockInParams(fh);% = 376; (* SeLockInSize = 96, see "Pulsed.de" *) +% s.SeAmplifierState=getAmplifierState(fh);% = 472; (* AmplifierStateSize = 400 *) +% s.SeUsername=deblank(fread(fh, 80, 'uint8=>char')');% = 872; (* String80Type *) +% for k=1:4 +% s.SeSeUserParamDescr(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% (* ARRAY[0..3] OF UserParamDescrType = 4*40 *) +% s.SeSeUserParamDescr(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% +% end +% s.SeFiller5=fread(fh, 1, 'int32=>int32');% = 1112; (* INT32 *) +% s.SeCRC=fread(fh, 1, 'int32=>int32');% = 1116; (* CARD32 *) +% +% % Added 15.08.2012 +% s.SeSeUserParams2=fread(fh, 4, 'double=>double'); +% for k=1:4 +% s.SeSeUserParamDescr2(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% +% s.SeSeUserParamDescr2(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% +% end +% s.SeScanParams=fread(fh, 96, 'uint8=>uint8'); +% s.SeriesRecSize=1408;% (* = 176 * 8 *) +s=orderfields(s); +s.Sweeps = []; % used to store all the sweeps within the recording structure later on + +end + +%-------------------------------------------------------------------------- +function sw=getSweep(fh,obj) +%-------------------------------------------------------------------------- +sw.SwMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) +sw.SwLabel=deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Type *) +sw.SwAuxDataFileOffset=fread(fh, 1, 'int32=>int32');% = 36; (* INT32 *) +sw.SwStimCount=fread(fh, 1, 'int32=>int32');% = 40; (* INT32 *) +sw.SwSweepCount=fread(fh, 1, 'int32=>int32');% = 44; (* INT32 *) +sw.SwTime=fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) +sw.SwTimeMATLAB=obj.HI_time2date(sw.SwTime);% Also add in MATLAB datenum format +sw.SwTimer=fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) +sw.SwSwUserParams=fread(fh, 2, 'double=>double');% = 64; (* ARRAY[0..1] OF LONGREAL *) +sw.SwPipPressure=fread(fh, 2, 'double=>double'); % = 80; (* LONGREAL * +sw.SwRMSNoise=fread(fh,2,'double=>double'); % = 88; (* LONGREAL *) +sw.SwTemperature=fread(fh, 1, 'double=>double');% = 96; (* LONGREAL *) +sw.SwOldIntSol=fread(fh, 1, 'int32=>int32');% = 104; (* INT32 *) +sw.SwOldExtSol=fread(fh, 1, 'int32=>int32');% = 108; (* INT32 *) +sw.SwDigitalIn=fread(fh, 1, 'int16=>int16');% = 112; (* SET16 *) +sw.SwSweepKind=fread(fh, 1, 'int16=>int16');% = 114; (* SET16 *) +sw.SwDigitalOut=fread(fh,1, 'int16=>int16'); % = 116; (* SET16 *) +sw.SwFiller1=fread(fh, 1, 'int16=>int16');% = 118; (* INT32 *) +sw.SwMarkers=fread(fh, 4, 'double=>double');% = 120; (* ARRAY[0..3] OF LONGREAL, see SwMarkersNo *) +sw.SwFiller2=fread(fh, 1, 'int32=>int32');% = 152; (* INT32 *) +sw.SwCRC=fread(fh, 1, 'int32=>int32');% = 156; (* CARD32 *) +sw.SwSwHolding=fread(fh,16,'double=>double'); % = 160; (* ARRAY[0..15] OF LONGREAL, see SwHoldingNo *) +sw.SwSwUserParamEx=fread(fh,8,'double=>double'); % = 288; (* ARRAY[0..7] OF LONGREAL *) +sw.SweepRecSize = 352;% +sw=orderfields(sw); +sw.Traces = []; % used to store all the traces/channels within the sweep structure later on +end + +%-------------------------------------------------------------------------- +function tr=getTrace(fh,obj) +%-------------------------------------------------------------------------- +tr.TrMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) +tr.TrLabel=deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Type *) +tr.TrTraceCount=fread(fh, 1, 'int32=>int32');% = 36; (* INT32 *) +tr.TrData=fread(fh, 1, 'int32=>int32');% = 40; (* INT32 *) +tr.TrDataPoints=fread(fh, 1, 'int32=>int32');% = 44; (* INT32 *) +tr.TrInternalSolution=fread(fh, 1, 'int32=>int32');% = 48; (* INT32 *) +tr.TrAverageCount=fread(fh, 1, 'int32=>int32');% = 52; (* INT32 *) +tr.TrLeakCount=fread(fh, 1, 'int32=>int32');% = 56; (* INT32 *) +tr.TrLeakTraces=fread(fh, 1, 'int32=>int32');% = 60; (* INT32 *) +tr.TrDataKind=fread(fh, 1, 'uint16=>uint16');% = 64; (* SET16 *) NB Stored unsigned +tr.TrFiller1=fread(fh, 1, 'int16=>int16');% = 66; (* SET16 *) +tr.TrRecordingMode=fread(fh, 1, 'uint8=>uint8');% = 68; (* BYTE *) +tr.TrAmplIndex=fread(fh, 1, 'uint8=>uint8');% = 69; (* CHAR *) +tr.TrDataFormat=fread(fh, 1, 'uint8=>uint8');% = 70; (* BYTE *) +tr.TrDataAbscissa=fread(fh, 1, 'uint8=>uint8');% = 71; (* BYTE *) +tr.TrDataScaler=fread(fh, 1, 'double=>double');% = 72; (* LONGREAL *) +tr.TrTimeOffset=fread(fh, 1, 'double=>double');% = 80; (* LONGREAL *) +tr.TrZeroData=fread(fh, 1, 'double=>double');% = 88; (* LONGREAL *) +tr.TrYUnit=deblank(fread(fh, 8, 'uint8=>char')');% = 96; (* String8Type *) +tr.TrXInterval=fread(fh, 1, 'double=>double');% = 104; (* LONGREAL *) +tr.TrXStart=fread(fh, 1, 'double=>double');% = 112; (* LONGREAL *) +% 17.04.10 TrXUnit bytes may include some trailing characters after NULL +% byte +tr.TrXUnit=deblank(fread(fh, 8, 'uint8=>char')');% = 120; (* String8Type *) +tr.TrYRange=fread(fh, 1, 'double=>double');% = 128; (* LONGREAL *) +tr.TrYOffset=fread(fh, 1, 'double=>double');% = 136; (* LONGREAL *) +tr.TrBandwidth=fread(fh, 1, 'double=>double');% = 144; (* LONGREAL *) +tr.TrPipetteResistance=fread(fh, 1, 'double=>double');% = 152; (* LONGREAL *) +tr.TrCellPotential=fread(fh, 1, 'double=>double');% = 160; (* LONGREAL *) +tr.TrSealResistance=fread(fh, 1, 'double=>double');% = 168; (* LONGREAL *) +tr.TrCSlow=fread(fh, 1, 'double=>double');% = 176; (* LONGREAL *) +tr.TrGSeries=fread(fh, 1, 'double=>double');% = 184; (* LONGREAL *) +tr.TrRsValue=fread(fh, 1, 'double=>double');% = 192; (* LONGREAL *) +tr.TrGLeak=fread(fh, 1, 'double=>double');% = 200; (* LONGREAL *) +tr.TrMConductance=fread(fh, 1, 'double=>double');% = 208; (* LONGREAL *) +tr.TrLinkDAChannel=fread(fh, 1, 'int32=>int32');% = 216; (* INT32 *) +tr.TrValidYrange=fread(fh, 1, 'uint8=>logical');% = 220; (* BOOLEAN *) +tr.TrAdcMode=fread(fh, 1, 'uint8=>uint8');% = 221; (* CHAR *) +tr.TrAdcChannel=fread(fh, 1, 'int16=>int16');% = 222; (* INT16 *) +tr.TrYmin=fread(fh, 1, 'double=>double');% = 224; (* LONGREAL *) +tr.TrYmax=fread(fh, 1, 'double=>double');% = 232; (* LONGREAL *) +tr.TrSourceChannel=fread(fh, 1, 'int32=>int32');% = 240; (* INT32 *) +tr.TrExternalSolution=fread(fh, 1, 'int32=>int32');% = 244; (* INT32 *) +tr.TrCM=fread(fh, 1, 'double=>double');% = 248; (* LONGREAL *) +tr.TrGM=fread(fh, 1, 'double=>double');% = 256; (* LONGREAL *) +tr.TrPhase=fread(fh, 1, 'double=>double');% = 264; (* LONGREAL *) +tr.TrDataCRC=fread(fh, 1, 'int32=>int32');% = 272; (* CARD32 *) +tr.TrCRC=fread(fh, 1, 'int32=>int32');% = 276; (* CARD32 *) +tr.TrGS=fread(fh, 1, 'double=>double');% = 280; (* LONGREAL *) +tr.TrSelfChannel=fread(fh, 1, 'int32=>int32');% = 288; (* INT32 *) + +% Added 15.08.2012 +tr.TrInterleaveSize=fread(fh, 1, 'int32=>int32');% = 292; (* INT32 *) +tr.TrInterleaveSkip=fread(fh, 1, 'int32=>int32');% = 296; (* INT32 *) +tr.TrImageIndex=fread(fh, 1, 'int32=>int32');% = 300; (* INT32 *) +tr.TrMarkers=fread(fh, 10, 'double=>double');% = 304; (* ARRAY[0..9] OF LONGREAL *) +tr.TrSECM_X=fread(fh, 1, 'double=>double');% = 384; (* LONGREAL *) +tr.TrSECM_Y=fread(fh, 1, 'double=>double');% = 392; (* LONGREAL *) +tr.TrSECM_Z=fread(fh, 1, 'double=>double');% = 400; (* LONGREAL *) +tr.TrTrHolding = fread(fh, 1, 'double=>double');% = 408; (* LONGREAL *) +tr.TrTcEnumerator = fread(fh, 1, 'int32=>int32');% = 416; (* INT32 *) +tr.TrXTrace = fread(fh, 1, 'int32=>int32');% = 420; (* INT32 *) +tr.TrIntSolValue = fread(fh, 1, 'double=>double');% = 424; (* LONGREAL *) +tr.TrExtSolValue = fread(fh, 1, 'double=>double');% = 432; (* LONGREAL *) +tr.TrIntSolName = deblank(fread(fh, 32, 'uint8=>char')');% = 440; (* String32Size *) +tr.TrExtSolName = deblank(fread(fh, 32, 'uint8=>char')');% = 472; (* String32Size *) +tr.TrDataPedestal = fread(fh, 1, 'double=>double');% = 504; (* LONGREAL *) + +tr.TraceRecSize=512; %(* = 64 * 8 *) + +tr=orderfields(tr); + +end +function L=getSeLockInParams(fh) +%-------------------------------------------------------------------------- +offset=ftell(fh); +L.loExtCalPhase = fread(fh, 1, 'double=>double');% = 0; (* LONGREAL *) +L.loExtCalAtten = fread(fh, 1, 'double=>double');% = 8; (* LONGREAL *) +L.loPLPhase = fread(fh, 1, 'double=>double');% = 16; (* LONGREAL *) +L.loPLPhaseY1 = fread(fh, 1, 'double=>double');% = 24; (* LONGREAL *) +L.loPLPhaseY2 = fread(fh, 1, 'double=>double');% = 32; (* LONGREAL *) +L.loUsedPhaseShift = fread(fh, 1, 'double=>double');% = 40; (* LONGREAL *) +L.loUsedAttenuation = fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) + L.loSpare = fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) +L.loExtCalValid = fread(fh, 1, 'uint8=>logical');% = 64; (* BOOLEAN *) +L.loPLPhaseValid = fread(fh, 1, 'uint8=>logical');% = 65; (* BOOLEAN *) +L.loLockInMode = fread(fh, 1, 'uint8=>uint8');% = 66; (* BYTE *) +L.loCalMode = fread(fh, 1, 'uint8=>uint8');% = 67; (* BYTE *) + L.loSpare2 = fread(fh, 7, 'int32=>in32');% = 68; (* remaining *) +L.LockInParamsSize = 96; + +fseek(fh, offset+L.LockInParamsSize, 'bof'); + +end + +%-------------------------------------------------------------------------- +function A=getAmplifierState(fh) +%-------------------------------------------------------------------------- +offset=ftell(fh); +A.sStateVersion = fread(fh, 1, 'double=>double');% = 0; (* 8 = SizeStateVersion *) +A.sCurrentGain = fread(fh, 1, 'double=>double');% = 8; (* LONGREAL *) +A.sF2Bandwidth = fread(fh, 1, 'double=>double');% = 16; (* LONGREAL *) +A.sF2Frequency = fread(fh, 1, 'double=>double');% = 24; (* LONGREAL *) +A.sRsValue = fread(fh, 1, 'double=>double');% = 32; (* LONGREAL *) +A.sRsFraction = fread(fh, 1, 'double=>double');% = 40; (* LONGREAL *) +A.sGLeak = fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) +A.sCFastAmp1 = fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) +A.sCFastAmp2 = fread(fh, 1, 'double=>double');% = 64; (* LONGREAL *) +A.sCFastTau = fread(fh, 1, 'double=>double');% = 72; (* LONGREAL *) +A.sCSlow = fread(fh, 1, 'double=>double');% = 80; (* LONGREAL *) +A.sGSeries = fread(fh, 1, 'double=>double');% = 88; (* LONGREAL *) +A.sVCStimDacScale = fread(fh, 1, 'double=>double');% = 96; (* LONGREAL *) +A.sCCStimScale = fread(fh, 1, 'double=>double');% = 104; (* LONGREAL *) +A.sVHold = fread(fh, 1, 'double=>double');% = 112; (* LONGREAL *) +A.sLastVHold = fread(fh, 1, 'double=>double');% = 120; (* LONGREAL *) +A.sVpOffset = fread(fh, 1, 'double=>double');% = 128; (* LONGREAL *) +A.sVLiquidJunction = fread(fh, 1, 'double=>double');% = 136; (* LONGREAL *) +A.sCCIHold = fread(fh, 1, 'double=>double');% = 144; (* LONGREAL *) +A.sCSlowStimVolts = fread(fh, 1, 'double=>double');% = 152; (* LONGREAL *) +A.sCCTrackVHold = fread(fh, 1, 'double=>double');% = 160; (* LONGREAL *) +A.sTimeoutCSlow = fread(fh, 1, 'double=>double');% = 168; (* LONGREAL *) +A.sSearchDelay = fread(fh, 1, 'double=>double');% = 176; (* LONGREAL *) +A.sMConductance = fread(fh, 1, 'double=>double');% = 184; (* LONGREAL *) +A.sMCapacitance = fread(fh, 1, 'double=>double');% = 192; (* LONGREAL *) +A.sSerialNumber = fread(fh, 1, 'double=>double');% = 200; (* 8 = SizeSerialNumber *) + +A.sE9Boards = fread(fh, 1, 'int16=>int16');% = 208; (* INT16 *) +A.sCSlowCycles = fread(fh, 1, 'int16=>int16');% = 210; (* INT16 *) +A.sIMonAdc = fread(fh, 1, 'int16=>int16');% = 212; (* INT16 *) +A.sVMonAdc = fread(fh, 1, 'int16=>int16');% = 214; (* INT16 *) + +A.sMuxAdc = fread(fh, 1, 'int16=>int16');% = 216; (* INT16 *) +A.sTestDac = fread(fh, 1, 'int16=>int16');% = 218; (* INT16 *) +A.sStimDac = fread(fh, 1, 'int16=>int16');% = 220; (* INT16 *) +A.sStimDacOffset = fread(fh, 1, 'int16=>int16');% = 222; (* INT16 *) + +A.sMaxDigitalBit = fread(fh, 1, 'int16=>int16');% = 224; (* INT16 *) +A.sHasCFastHigh = fread(fh, 1, 'uint8=>uint8');% = 226; (* BYTE *) +A.sCFastHigh = fread(fh, 1, 'uint8=>uint8');% = 227; (* BYTE *) +A.sHasBathSense = fread(fh, 1, 'uint8=>uint8');% = 228; (* BYTE *) +A.sBathSense = fread(fh, 1, 'uint8=>uint8');% = 229; (* BYTE *) +A.sHasF2Bypass = fread(fh, 1, 'uint8=>uint8');% = 230; (* BYTE *) +A.sF2Mode = fread(fh, 1, 'uint8=>uint8');% = 231; (* BYTE *) + +A.sAmplKind = fread(fh, 1, 'uint8=>uint8');% = 232; (* BYTE *) +A.sIsEpc9N = fread(fh, 1, 'uint8=>uint8');% = 233; (* BYTE *) +A.sADBoard = fread(fh, 1, 'uint8=>uint8');% = 234; (* BYTE *) +A.sBoardVersion = fread(fh, 1, 'uint8=>uint8');% = 235; (* BYTE *) +A.sActiveE9Board = fread(fh, 1, 'uint8=>uint8');% = 236; (* BYTE *) +A.sMode = fread(fh, 1, 'uint8=>uint8');% = 237; (* BYTE *) +A.sRange = fread(fh, 1, 'uint8=>uint8');% = 238; (* BYTE *) +A.sF2Response = fread(fh, 1, 'uint8=>uint8');% = 239; (* BYTE *) + +A.sRsOn = fread(fh, 1, 'uint8=>uint8');% = 240; (* BYTE *) +A.sCSlowRange = fread(fh, 1, 'uint8=>uint8');% = 241; (* BYTE *) +A.sCCRange = fread(fh, 1, 'uint8=>uint8');% = 242; (* BYTE *) +A.sCCGain = fread(fh, 1, 'uint8=>uint8');% = 243; (* BYTE *) +A.sCSlowToTestDac = fread(fh, 1, 'uint8=>uint8');% = 244; (* BYTE *) +A.sStimPath = fread(fh, 1, 'uint8=>uint8');% = 245; (* BYTE *) +A.sCCTrackTau = fread(fh, 1, 'uint8=>uint8');% = 246; (* BYTE *) +A.sWasClipping = fread(fh, 1, 'uint8=>uint8');% = 247; (* BYTE *) + +A.sRepetitiveCSlow = fread(fh, 1, 'uint8=>uint8');% = 248; (* BYTE *) +A.sLastCSlowRange = fread(fh, 1, 'uint8=>uint8');% = 249; (* BYTE *) + A.sOld1 = fread(fh, 1, 'uint8=>uint8');% = 250; (* BYTE *) +A.sCanCCFast = fread(fh, 1, 'uint8=>uint8');% = 251; (* BYTE *) +A.sCanLowCCRange = fread(fh, 1, 'uint8=>uint8');% = 252; (* BYTE *) +A.sCanHighCCRange = fread(fh, 1, 'uint8=>uint8');% = 253; (* BYTE *) +A.sCanCCTrackingg = fread(fh, 1, 'uint8=>uint8');% = 254; (* BYTE *) +A.sCHasVmonPath = fread(fh, 1, 'uint8=>uint8');% = 255; (* BYTE *) + +A.sHasNewCCMode = fread(fh, 1, 'uint8=>uint8');% = 256; (* BYTE *) +A.sSelector = fread(fh, 1, 'uint8=>char');% = 257; (* CHAR *) +A.sHoldInverted = fread(fh, 1, 'uint8=>uint8');% = 258; (* BYTE *) +A.sAutoCFast = fread(fh, 1, 'uint8=>uint8');% = 259; (* BYTE *) +A.sAutoCSlow = fread(fh, 1, 'uint8=>uint8');% = 260; (* BYTE *) +A.sHasVmonX100 = fread(fh, 1, 'uint8=>uint8');% = 261; (* BYTE *) +A.sTestDacOn = fread(fh, 1, 'uint8=>uint8');% = 262; (* BYTE *) +A.sQMuxAdcOn = fread(fh, 1, 'uint8=>uint8');% = 263; (* BYTE *) + +A.sImon1Bandwidth = fread(fh, 1, 'double=>double');% = 264; (* LONGREAL *) +A.sStimScale = fread(fh, 1, 'double=>double');% = 272; (* LONGREAL *) + +A.sGain = fread(fh, 1, 'uint8=>uint8');% = 280; (* BYTE *) +A.sFilter1 = fread(fh, 1, 'uint8=>uint8');% = 281; (* BYTE *) +A.sStimFilterOn = fread(fh, 1, 'uint8=>uint8');% = 282; (* BYTE *) +A.sRsSlow = fread(fh, 1, 'uint8=>uint8');% = 283; (* BYTE *) + A.sOld2 = fread(fh, 1, 'uint8=>uint8');% = 284; (* BYTE *) +A.sCCCFastOn = fread(fh, 1, 'uint8=>uint8');% = 285; (* BYTE *) +A.sCCFastSpeed = fread(fh, 1, 'uint8=>uint8');% = 286; (* BYTE *) +A.sF2Source = fread(fh, 1, 'uint8=>uint8');% = 287; (* BYTE *) + +A.sTestRange = fread(fh, 1, 'uint8=>uint8');% = 288; (* BYTE *) +A.sTestDacPath = fread(fh, 1, 'uint8=>uint8');% = 289; (* BYTE *) +A.sMuxChannel = fread(fh, 1, 'uint8=>uint8');% = 290; (* BYTE *) +A.sMuxGain64 = fread(fh, 1, 'uint8=>uint8');% = 291; (* BYTE *) +A.sVmonX100 = fread(fh, 1, 'uint8=>uint8');% = 292; (* BYTE *) +A.sIsQuadro = fread(fh, 1, 'uint8=>uint8');% = 293; (* BYTE *) +A.sF1Mode = fread(fh, 1, 'uint8=>uint8');% = 294; (* BYTE *) + A.sOld3 = fread(fh, 1, 'uint8=>uint8');% = 295; (* BYTE *) + +A.sStimFilterHz = fread(fh, 1, 'double=>double');% = 296; (* LONGREAL *) +A.sRsTau = fread(fh, 1, 'double=>double');% = 304; (* LONGREAL *) +A.sDacToAdcDelay = fread(fh, 1, 'double=>double');% = 312; (* LONGREAL *) +A.sInputFilterTau = fread(fh, 1, 'double=>double');% = 320; (* LONGREAL *) +A.sOutputFilterTau = fread(fh, 1, 'double=>double');% = 328; (* LONGREAL *) +A.sVmonFactor = fread(fh, 1, 'double=>double');% = 336; (* LONGREAL *) +A.sCalibDate = fread(fh, 2, 'double=>double');% = 344; (* 16 = SizeCalibDate *) +A.sVmonOffset = fread(fh, 1, 'double=>double');% = 360; (* LONGREAL *) + +A.sEEPROMKind = fread(fh, 1, 'uint8=>uint8');% = 368; (* BYTE *) +A.sVrefX2 = fread(fh, 1, 'uint8=>uint8');% = 369; (* BYTE *) +A.sHasVrefX2AndF2Vmon = fread(fh, 1, 'uint8=>uint8');% = 370; (* BYTE *) +A.sSpare1 = fread(fh, 1, 'uint8=>uint8');% = 371; (* BYTE *) +A.sSpare2 = fread(fh, 1, 'uint8=>uint8');% = 372; (* BYTE *) +A.sSpare3 = fread(fh, 1, 'uint8=>uint8');% = 373; (* BYTE *) +A.sSpare4 = fread(fh, 1, 'uint8=>uint8');% = 374; (* BYTE *) +A.sSpare5 = fread(fh, 1, 'uint8=>uint8');% = 375; (* BYTE *) + +A.sCCStimDacScale = fread(fh, 1, 'double=>double');% = 376; (* LONGREAL *) +A.sVmonFiltBandwidth = fread(fh, 1, 'double=>double');% = 384; (* LONGREAL *) +A.sVmonFiltFrequency = fread(fh, 1, 'double=>double');% = 392; (* LONGREAL *) +A.AmplifierStateSize = 400;% (* = 50 * 8 *) + +fseek(fh, offset+A.AmplifierStateSize, 'bof'); + +end \ No newline at end of file diff --git a/@HEKA_Importer/readPulseFileHEKA.m b/@HEKA_Importer/readPulseFileHEKA.m new file mode 100644 index 0000000..435b7e4 --- /dev/null +++ b/@HEKA_Importer/readPulseFileHEKA.m @@ -0,0 +1,418 @@ +function readPulseFileHEKA(obj) +%-------------------------------------------------------------------------- +% Gets one record of the tree and the number of children + + + + +s = getOneRecord(obj); +obj.fileData.Tree{obj.fileData.Counter, obj.fileData.Level+1} = s; + +obj.fileData.Position = obj.fileData.Position+obj.fileData.Sizes(obj.fileData.Level+1); +fseek(obj.fileData.fh, obj.fileData.Position, 'bof'); +obj.fileData.nchild=fread(obj.fileData.fh, 1, 'int32=>int32'); +obj.fileData.Position=ftell(obj.fileData.fh); + +end + +%-------------------------------------------------------------------------- +function rec=getOneRecord(obj) +%-------------------------------------------------------------------------- +% Gets one record +% Counter=Counter+1; +obj.fileData.Counter = obj.fileData.Counter+1; + +switch obj.fileData.Level + case 0 + rec=getRoot(obj); + case 1 + rec=getGroup(obj); + case 2 + rec=getSeries(obj); + case 3 + rec=getSweep(obj); + case 4 + rec=getTrace(obj); + otherwise + error('Unexpected Level'); +end +end + +% The functions below return data as defined by the HEKA PatchMaster +% specification + +%-------------------------------------------------------------------------- +function p=getRoot(obj) +%-------------------------------------------------------------------------- +fh = obj.fileData.fh; + +p.RoVersion=fread(fh, 1, 'int32=>int32'); +p.RoMark=fread(fh, 1, 'int32=>int32');% = 4; (* INT32 *) +p.RoVersionName=deblank(fread(fh, 32, 'uint8=>char')');% = 8; (* String32Type *) +p.RoAuxFileName=deblank(fread(fh, 80, 'uint8=>char')');% = 40; (* String80Type *) +p.RoRootText=deblank(fread(fh, 400, 'uint8=>char')');% (* String400Type *) +p.RoStartTime=fread(fh, 1, 'double=>double') ;% = 520; (* LONGREAL *) +p.RoStartTimeMATLAB=obj.HI_time2date(p.RoStartTime); +p.RoMaxSamples=fread(fh, 1, 'int32=>int32'); % = 528; (* INT32 *) +p.RoCRC=fread(fh, 1, 'int32=>int32'); % = 532; (* CARD32 *) +p.RoFeatures=fread(fh, 1, 'int16=>int16'); % = 536; (* SET16 *) +p.RoFiller1=fread(fh, 1, 'int16=>int16');% = 538; (* INT16 *) +p.RoFiller2=fread(fh, 1, 'int32=>int32');% = 540; (* INT32 *) +p.RoTcEnumerator = fread(fh,32,'int16=>int16');% = 544; (* ARRAY[0..Max_TcKind_M1] OF INT16 *) +p.RoTcKind = fread(fh,32,'int8=>int8');% = 608; (* ARRAY[0..Max_TcKind_M1] OF INT8 *) +p.RootRecSize = 640; % (* = 80 * 8 *); +p=orderfields(p); + +end + +%-------------------------------------------------------------------------- +function g=getGroup(obj) +%-------------------------------------------------------------------------- +% Group +fh = obj.fileData.fh; + + +g.GrMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) +g.GrLabel=deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Size *) +g.GrText=deblank(fread(fh, 80, 'uint8=>char')');% = 36; (* String80Size *) +g.GrExperimentNumber=fread(fh, 1, 'int32=>int32');% = 116; (* INT32 *) +g.GrGroupCount=fread(fh, 1, 'int32=>int32');% = 120; (* INT32 *) +g.GrCRC=fread(fh, 1, 'int32=>int32');% = 124; (* CARD32 *) +g.GrMatrixWidth = fread(fh,1,'double=>double');% = 128; (* LONGREAL *) +g.GrMatrixHeight = fread(fh,1,'double=>double');% = 136; (* LONGREAL *) +g.GroupRecSize = 144; % (* = 18 * 8 *) + +% g.GroupRecSize=128;% (* = 16 * 8 *) +g=orderfields(g); + +end + +%-------------------------------------------------------------------------- +function s=getSeries(obj) +%-------------------------------------------------------------------------- +fh = obj.fileData.fh; + +s.SeMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) +s.SeLabel=deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Type *) +s.SeComment=deblank(fread(fh, 80, 'uint8=>char')');% = 36; (* String80Type *) +s.SeSeriesCount=fread(fh, 1, 'int32=>int32');% = 116; (* INT32 *) +s.SeNumbersw=fread(fh, 1, 'int32=>int32');% = 120; (* INT32 *) + +%% +s.SeAmplStateFlag = fread(fh,1,'int32=>int32');% = 124; (* INT32 *) // flag > 0 => load local oldAmpState, otherwise load from .amp File. +s.SeAmplStateRef = fread(fh,1,'int32=>int32'); % = 128; (* INT32 *) // ref = 0 => use local oldAmpState +s.SeMethodTag = fread(fh,1,'int32=>int32'); % = 132; (* INT32 *) +s.SeTime = fread(fh,1,'double=>double'); % = 136; (* LONGREAL *) +s.SeTimeMATLAB=obj.HI_time2date(s.SeTime); +s.SePageWidth=fread(fh, 1, 'double=>double') ;% = 144; (* LONGREAL *) +for k=1:2 % = 152; (* ARRAY[0..1] OF UserParamDescrType = 2*40 *) + s.SeSwUserParamDescr(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% + s.SeSwUserParamDescr(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% +end +s.SeFiller1 = deblank(fread(fh,80,'uint8=>char')'); % = 232; (* ARRAY[0..1] OF UserParamDescrType = 2*40 *) +s.SeMethodName = deblank(fread(fh,32,'uint8=>char')');% = 312; (* String32Type *) +% + +s.SePhotoParams1 = fread(fh, 4, 'double=>double'); %= 344; (* ARRAY[0..3] OF LONGREAL = 4*8 *) +s.SeOldLockInParams=getSeLockInParams(fh);% = 376; (* SeLockInSize = 96, see "Pulsed.de" *) +s.SeOldAmplifierState=getAmplifierState(fh);% = 472; (* AmplifierStateSize = 400 *) +s.SeUsername=deblank(fread(fh, 80, 'uint8=>char')');% + +for k=1:4 + s.SeSeUserParamDescr(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% (* ARRAY[0..3] OF UserParamDescrType = 4*40 *) + s.SeSeUserParamDescr(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% +end + +% s.SeOldLockInParams = fread(fh,96); % = 376; (* SeOldLockInSize = 96, see "Pulsed.de" *) +% s.SeOldAmpState = fread(fh,400); % = 472; (* SeOldAmpState = 400 -> the AmplStateRecord is now stored in the .amp file *) +% s.SeUsername = deblank(fread(fh,80,'uint8=>char')); % = 872; (* String80Type *) + +s.SePhotoParams2 = deblank(fread(fh,160,'uint8=>char')'); %= 952; (* ARRAY[0..3] OF UserParamDescrType = 4*40 *) +s.SeFiller1=fread(fh, 1, 'int32=>int32');% = 1112; (* INT32 *) +s.SeCRC=fread(fh, 1, 'int32=>int32');% = 1116; (* CARD32 *) + +s.SeSeUserParams2=fread(fh, 4, 'double=>double'); %= 1120; (* ARRAY[0..3] OF LONGREAL *) +for k=1:4 %= 1152; (* ARRAY[0..3] OF UserParamDescrType = 4*40 *) + s.SeSeUserParamDescr2(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% + s.SeSeUserParamDescr2(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% +end +s.SeScanParams=fread(fh, 96, 'uint8=>uint8'); %= 1312; (* ScanParamsSize = 96 (ElProScan Extension) *) + +for k=1:8 %= 1408; (* ARRAY[0..7] OF UserParamDescrType = 8*40 *) + s.SeSeUserDescr2(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% + s.SeSeUserDescr2(k).Unit=deblank(fread(fh, 8, 'uint8=>char')'); +end +s.SeriesRecSize=1728;% = 1728; + +s=orderfields(s); +s.Sweeps = []; % used to store all the sweeps within the recording structure later on + +end + +%-------------------------------------------------------------------------- +function sw=getSweep(obj) +%-------------------------------------------------------------------------- + +fh = obj.fileData.fh; + +sw.SwMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) +sw.SwLabel=deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Type *) +sw.SwAuxDataFileOffset=fread(fh, 1, 'int32=>int32');% = 36; (* INT32 *) +sw.SwStimCount=fread(fh, 1, 'int32=>int32');% = 40; (* INT32 *) +sw.SwSweepCount=fread(fh, 1, 'int32=>int32');% = 44; (* INT32 *) +sw.SwTime=fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) +sw.SwTimeMATLAB=obj.HI_time2date(sw.SwTime);% Also add in MATLAB datenum format +sw.SwTimer=fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) +sw.SwSwUserParams=fread(fh, 2, 'double=>double');% = 64; (* ARRAY[0..1] OF LONGREAL *) +sw.SwPipPressure=fread(fh, 2, 'double=>double'); % = 80; (* LONGREAL * +sw.SwRMSNoise=fread(fh,2,'double=>double'); % = 88; (* LONGREAL *) +sw.SwTemperature=fread(fh, 1, 'double=>double');% = 96; (* LONGREAL *) +sw.SwOldIntSol=fread(fh, 1, 'int32=>int32');% = 104; (* INT32 *) +sw.SwOldExtSol=fread(fh, 1, 'int32=>int32');% = 108; (* INT32 *) +sw.SwDigitalIn=fread(fh, 1, 'int16=>int16');% = 112; (* SET16 *) +sw.SwSweepKind=fread(fh, 1, 'int16=>int16');% = 114; (* SET16 *) +sw.SwDigitalOut=fread(fh,1, 'int16=>int16'); % = 116; (* SET16 *) +sw.SwFiller1=fread(fh, 1, 'int16=>int16');% = 118; (* INT32 *) +sw.SwMarkers=fread(fh, 4, 'double=>double');% = 120; (* ARRAY[0..3] OF LONGREAL, see SwMarkersNo *) +sw.SwFiller2=fread(fh, 1, 'int32=>int32');% = 152; (* INT32 *) +sw.SwCRC=fread(fh, 1, 'int32=>int32');% = 156; (* CARD32 *) +sw.SwSwHolding=fread(fh,16,'double=>double'); % = 160; (* ARRAY[0..15] OF LONGREAL, see SwHoldingNo *) +sw.SwSwUserParamEx=fread(fh,8,'double=>double'); % = 288; (* ARRAY[0..7] OF LONGREAL *) +sw.SweepRecSize = 352;% +sw=orderfields(sw); +sw.Traces = []; % used to store all the traces/channels within the sweep structure later on +end + +%-------------------------------------------------------------------------- +function tr=getTrace(obj) +%-------------------------------------------------------------------------- +fh = obj.fileData.fh; + +tr.TrMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) +tr.TrLabel=deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Type *) +tr.TrTraceCount=fread(fh, 1, 'int32=>int32');% = 36; (* INT32 *) +tr.TrData=fread(fh, 1, 'int32=>int32');% = 40; (* INT32 *) +tr.TrDataPoints=fread(fh, 1, 'int32=>int32');% = 44; (* INT32 *) +tr.TrInternalSolution=fread(fh, 1, 'int32=>int32');% = 48; (* INT32 *) +tr.TrAverageCount=fread(fh, 1, 'int32=>int32');% = 52; (* INT32 *) +tr.TrLeakCount=fread(fh, 1, 'int32=>int32');% = 56; (* INT32 *) +tr.TrLeakTraces=fread(fh, 1, 'int32=>int32');% = 60; (* INT32 *) +tr.TrDataKind=fread(fh, 1, 'uint16=>uint16');% = 64; (* SET16 *) NB Stored unsigned +tr.TrFiller1=fread(fh, 1, 'int16=>int16');% = 66; (* SET16 *) +tr.TrRecordingMode=fread(fh, 1, 'uint8=>uint8');% = 68; (* BYTE *) +tr.TrAmplIndex=fread(fh, 1, 'uint8=>uint8');% = 69; (* CHAR *) +tr.TrDataFormat=fread(fh, 1, 'uint8=>uint8');% = 70; (* BYTE *) +tr.TrDataAbscissa=fread(fh, 1, 'uint8=>uint8');% = 71; (* BYTE *) +tr.TrDataScaler=fread(fh, 1, 'double=>double');% = 72; (* LONGREAL *) +tr.TrTimeOffset=fread(fh, 1, 'double=>double');% = 80; (* LONGREAL *) +tr.TrZeroData=fread(fh, 1, 'double=>double');% = 88; (* LONGREAL *) +tr.TrYUnit=deblank(fread(fh, 8, 'uint8=>char')');% = 96; (* String8Type *) +tr.TrXInterval=fread(fh, 1, 'double=>double');% = 104; (* LONGREAL *) +tr.TrXStart=fread(fh, 1, 'double=>double');% = 112; (* LONGREAL *) +% 17.04.10 TrXUnit bytes may include some trailing characters after NULL +% byte +tr.TrXUnit=deblank(fread(fh, 8, 'uint8=>char')');% = 120; (* String8Type *) +tr.TrYRange=fread(fh, 1, 'double=>double');% = 128; (* LONGREAL *) +tr.TrYOffset=fread(fh, 1, 'double=>double');% = 136; (* LONGREAL *) +tr.TrBandwidth=fread(fh, 1, 'double=>double');% = 144; (* LONGREAL *) +tr.TrPipetteResistance=fread(fh, 1, 'double=>double');% = 152; (* LONGREAL *) +tr.TrCellPotential=fread(fh, 1, 'double=>double');% = 160; (* LONGREAL *) +tr.TrSealResistance=fread(fh, 1, 'double=>double');% = 168; (* LONGREAL *) +tr.TrCSlow=fread(fh, 1, 'double=>double');% = 176; (* LONGREAL *) +tr.TrGSeries=fread(fh, 1, 'double=>double');% = 184; (* LONGREAL *) +tr.TrRsValue=fread(fh, 1, 'double=>double');% = 192; (* LONGREAL *) +tr.TrGLeak=fread(fh, 1, 'double=>double');% = 200; (* LONGREAL *) +tr.TrMConductance=fread(fh, 1, 'double=>double');% = 208; (* LONGREAL *) +tr.TrLinkDAChannel=fread(fh, 1, 'int32=>int32');% = 216; (* INT32 *) +tr.TrValidYrange=fread(fh, 1, 'uint8=>logical');% = 220; (* BOOLEAN *) +tr.TrAdcMode=fread(fh, 1, 'uint8=>uint8');% = 221; (* CHAR *) +tr.TrAdcChannel=fread(fh, 1, 'int16=>int16');% = 222; (* INT16 *) +tr.TrYmin=fread(fh, 1, 'double=>double');% = 224; (* LONGREAL *) +tr.TrYmax=fread(fh, 1, 'double=>double');% = 232; (* LONGREAL *) +tr.TrSourceChannel=fread(fh, 1, 'int32=>int32');% = 240; (* INT32 *) +tr.TrExternalSolution=fread(fh, 1, 'int32=>int32');% = 244; (* INT32 *) +tr.TrCM=fread(fh, 1, 'double=>double');% = 248; (* LONGREAL *) +tr.TrGM=fread(fh, 1, 'double=>double');% = 256; (* LONGREAL *) +tr.TrPhase=fread(fh, 1, 'double=>double');% = 264; (* LONGREAL *) +tr.TrDataCRC=fread(fh, 1, 'int32=>int32');% = 272; (* CARD32 *) +tr.TrCRC=fread(fh, 1, 'int32=>int32');% = 276; (* CARD32 *) +tr.TrGS=fread(fh, 1, 'double=>double');% = 280; (* LONGREAL *) +tr.TrSelfChannel=fread(fh, 1, 'int32=>int32');% = 288; (* INT32 *) + +% Added 15.08.2012 +tr.TrInterleaveSize=fread(fh, 1, 'int32=>int32');% = 292; (* INT32 *) +tr.TrInterleaveSkip=fread(fh, 1, 'int32=>int32');% = 296; (* INT32 *) +tr.TrImageIndex=fread(fh, 1, 'int32=>int32');% = 300; (* INT32 *) +tr.TrMarkers=fread(fh, 10, 'double=>double');% = 304; (* ARRAY[0..9] OF LONGREAL *) +tr.TrSECM_X=fread(fh, 1, 'double=>double');% = 384; (* LONGREAL *) +tr.TrSECM_Y=fread(fh, 1, 'double=>double');% = 392; (* LONGREAL *) +tr.TrSECM_Z=fread(fh, 1, 'double=>double');% = 400; (* LONGREAL *) +tr.TrTrHolding = fread(fh, 1, 'double=>double');% = 408; (* LONGREAL *) +tr.TrTcEnumerator = fread(fh, 1, 'int32=>int32');% = 416; (* INT32 *) +tr.TrXTrace = fread(fh, 1, 'int32=>int32');% = 420; (* INT32 *) +tr.TrIntSolValue = fread(fh, 1, 'double=>double');% = 424; (* LONGREAL *) +tr.TrExtSolValue = fread(fh, 1, 'double=>double');% = 432; (* LONGREAL *) +tr.TrIntSolName = deblank(fread(fh, 32, 'uint8=>char')');% = 440; (* String32Size *) +tr.TrExtSolName = deblank(fread(fh, 32, 'uint8=>char')');% = 472; (* String32Size *) +tr.TrDataPedestal = fread(fh, 1, 'double=>double');% = 504; (* LONGREAL *) + +tr.TraceRecSize=512; %(* = 64 * 8 *) + +tr=orderfields(tr); + +end + +function L=getSeLockInParams(fh) +%-------------------------------------------------------------------------- +offset=ftell(fh); +L.loExtCalPhase = fread(fh, 1, 'double=>double');% = 0; (* LONGREAL *) +L.loExtCalAtten = fread(fh, 1, 'double=>double');% = 8; (* LONGREAL *) +L.loPLPhase = fread(fh, 1, 'double=>double');% = 16; (* LONGREAL *) +L.loPLPhaseY1 = fread(fh, 1, 'double=>double');% = 24; (* LONGREAL *) +L.loPLPhaseY2 = fread(fh, 1, 'double=>double');% = 32; (* LONGREAL *) +L.loUsedPhaseShift = fread(fh, 1, 'double=>double');% = 40; (* LONGREAL *) +L.loUsedAttenuation = fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) + L.loSpare = fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) +L.loExtCalValid = fread(fh, 1, 'uint8=>logical');% = 64; (* BOOLEAN *) +L.loPLPhaseValid = fread(fh, 1, 'uint8=>logical');% = 65; (* BOOLEAN *) +L.loLockInMode = fread(fh, 1, 'uint8=>uint8');% = 66; (* BYTE *) +L.loCalMode = fread(fh, 1, 'uint8=>uint8');% = 67; (* BYTE *) + L.loSpare2 = fread(fh, 7, 'int32=>in32');% = 68; (* remaining *) +L.LockInParamsSize = 96; + +fseek(fh, offset+L.LockInParamsSize, 'bof'); + +end + +%-------------------------------------------------------------------------- +function A=getAmplifierState(fh) +%-------------------------------------------------------------------------- +offset=ftell(fh); +A.sStateVersion = fread(fh, 1, 'double=>double');% = 0; (* 8 = SizeStateVersion *) +A.sCurrentGain = fread(fh, 1, 'double=>double');% = 8; (* LONGREAL *) +A.sF2Bandwidth = fread(fh, 1, 'double=>double');% = 16; (* LONGREAL *) +A.sF2Frequency = fread(fh, 1, 'double=>double');% = 24; (* LONGREAL *) +A.sRsValue = fread(fh, 1, 'double=>double');% = 32; (* LONGREAL *) +A.sRsFraction = fread(fh, 1, 'double=>double');% = 40; (* LONGREAL *) +A.sGLeak = fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) +A.sCFastAmp1 = fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) +A.sCFastAmp2 = fread(fh, 1, 'double=>double');% = 64; (* LONGREAL *) +A.sCFastTau = fread(fh, 1, 'double=>double');% = 72; (* LONGREAL *) +A.sCSlow = fread(fh, 1, 'double=>double');% = 80; (* LONGREAL *) +A.sGSeries = fread(fh, 1, 'double=>double');% = 88; (* LONGREAL *) +A.sVCStimDacScale = fread(fh, 1, 'double=>double');% = 96; (* LONGREAL *) +A.sCCStimScale = fread(fh, 1, 'double=>double');% = 104; (* LONGREAL *) +A.sVHold = fread(fh, 1, 'double=>double');% = 112; (* LONGREAL *) +A.sLastVHold = fread(fh, 1, 'double=>double');% = 120; (* LONGREAL *) +A.sVpOffset = fread(fh, 1, 'double=>double');% = 128; (* LONGREAL *) +A.sVLiquidJunction = fread(fh, 1, 'double=>double');% = 136; (* LONGREAL *) +A.sCCIHold = fread(fh, 1, 'double=>double');% = 144; (* LONGREAL *) +A.sCSlowStimVolts = fread(fh, 1, 'double=>double');% = 152; (* LONGREAL *) +A.sCCTrackVHold = fread(fh, 1, 'double=>double');% = 160; (* LONGREAL *) +A.sTimeoutCSlow = fread(fh, 1, 'double=>double');% = 168; (* LONGREAL *) +A.sSearchDelay = fread(fh, 1, 'double=>double');% = 176; (* LONGREAL *) +A.sMConductance = fread(fh, 1, 'double=>double');% = 184; (* LONGREAL *) +A.sMCapacitance = fread(fh, 1, 'double=>double');% = 192; (* LONGREAL *) +A.sSerialNumber = fread(fh, 1, 'double=>double');% = 200; (* 8 = SizeSerialNumber *) + +A.sE9Boards = fread(fh, 1, 'int16=>int16');% = 208; (* INT16 *) +A.sCSlowCycles = fread(fh, 1, 'int16=>int16');% = 210; (* INT16 *) +A.sIMonAdc = fread(fh, 1, 'int16=>int16');% = 212; (* INT16 *) +A.sVMonAdc = fread(fh, 1, 'int16=>int16');% = 214; (* INT16 *) + +A.sMuxAdc = fread(fh, 1, 'int16=>int16');% = 216; (* INT16 *) +A.sTestDac = fread(fh, 1, 'int16=>int16');% = 218; (* INT16 *) +A.sStimDac = fread(fh, 1, 'int16=>int16');% = 220; (* INT16 *) +A.sStimDacOffset = fread(fh, 1, 'int16=>int16');% = 222; (* INT16 *) + +A.sMaxDigitalBit = fread(fh, 1, 'int16=>int16');% = 224; (* INT16 *) +A.sHasCFastHigh = fread(fh, 1, 'uint8=>uint8');% = 226; (* BYTE *) +A.sCFastHigh = fread(fh, 1, 'uint8=>uint8');% = 227; (* BYTE *) +A.sHasBathSense = fread(fh, 1, 'uint8=>uint8');% = 228; (* BYTE *) +A.sBathSense = fread(fh, 1, 'uint8=>uint8');% = 229; (* BYTE *) +A.sHasF2Bypass = fread(fh, 1, 'uint8=>uint8');% = 230; (* BYTE *) +A.sF2Mode = fread(fh, 1, 'uint8=>uint8');% = 231; (* BYTE *) + +A.sAmplKind = fread(fh, 1, 'uint8=>uint8');% = 232; (* BYTE *) +A.sIsEpc9N = fread(fh, 1, 'uint8=>uint8');% = 233; (* BYTE *) +A.sADBoard = fread(fh, 1, 'uint8=>uint8');% = 234; (* BYTE *) +A.sBoardVersion = fread(fh, 1, 'uint8=>uint8');% = 235; (* BYTE *) +A.sActiveE9Board = fread(fh, 1, 'uint8=>uint8');% = 236; (* BYTE *) +A.sMode = fread(fh, 1, 'uint8=>uint8');% = 237; (* BYTE *) +A.sRange = fread(fh, 1, 'uint8=>uint8');% = 238; (* BYTE *) +A.sF2Response = fread(fh, 1, 'uint8=>uint8');% = 239; (* BYTE *) + +A.sRsOn = fread(fh, 1, 'uint8=>uint8');% = 240; (* BYTE *) +A.sCSlowRange = fread(fh, 1, 'uint8=>uint8');% = 241; (* BYTE *) +A.sCCRange = fread(fh, 1, 'uint8=>uint8');% = 242; (* BYTE *) +A.sCCGain = fread(fh, 1, 'uint8=>uint8');% = 243; (* BYTE *) +A.sCSlowToTestDac = fread(fh, 1, 'uint8=>uint8');% = 244; (* BYTE *) +A.sStimPath = fread(fh, 1, 'uint8=>uint8');% = 245; (* BYTE *) +A.sCCTrackTau = fread(fh, 1, 'uint8=>uint8');% = 246; (* BYTE *) +A.sWasClipping = fread(fh, 1, 'uint8=>uint8');% = 247; (* BYTE *) + +A.sRepetitiveCSlow = fread(fh, 1, 'uint8=>uint8');% = 248; (* BYTE *) +A.sLastCSlowRange = fread(fh, 1, 'uint8=>uint8');% = 249; (* BYTE *) + A.sOld1 = fread(fh, 1, 'uint8=>uint8');% = 250; (* BYTE *) +A.sCanCCFast = fread(fh, 1, 'uint8=>uint8');% = 251; (* BYTE *) +A.sCanLowCCRange = fread(fh, 1, 'uint8=>uint8');% = 252; (* BYTE *) +A.sCanHighCCRange = fread(fh, 1, 'uint8=>uint8');% = 253; (* BYTE *) +A.sCanCCTrackingg = fread(fh, 1, 'uint8=>uint8');% = 254; (* BYTE *) +A.sCHasVmonPath = fread(fh, 1, 'uint8=>uint8');% = 255; (* BYTE *) + +A.sHasNewCCMode = fread(fh, 1, 'uint8=>uint8');% = 256; (* BYTE *) +A.sSelector = fread(fh, 1, 'uint8=>char');% = 257; (* CHAR *) +A.sHoldInverted = fread(fh, 1, 'uint8=>uint8');% = 258; (* BYTE *) +A.sAutoCFast = fread(fh, 1, 'uint8=>uint8');% = 259; (* BYTE *) +A.sAutoCSlow = fread(fh, 1, 'uint8=>uint8');% = 260; (* BYTE *) +A.sHasVmonX100 = fread(fh, 1, 'uint8=>uint8');% = 261; (* BYTE *) +A.sTestDacOn = fread(fh, 1, 'uint8=>uint8');% = 262; (* BYTE *) +A.sQMuxAdcOn = fread(fh, 1, 'uint8=>uint8');% = 263; (* BYTE *) + +A.sImon1Bandwidth = fread(fh, 1, 'double=>double');% = 264; (* LONGREAL *) +A.sStimScale = fread(fh, 1, 'double=>double');% = 272; (* LONGREAL *) + +A.sGain = fread(fh, 1, 'uint8=>uint8');% = 280; (* BYTE *) +A.sFilter1 = fread(fh, 1, 'uint8=>uint8');% = 281; (* BYTE *) +A.sStimFilterOn = fread(fh, 1, 'uint8=>uint8');% = 282; (* BYTE *) +A.sRsSlow = fread(fh, 1, 'uint8=>uint8');% = 283; (* BYTE *) + A.sOld2 = fread(fh, 1, 'uint8=>uint8');% = 284; (* BYTE *) +A.sCCCFastOn = fread(fh, 1, 'uint8=>uint8');% = 285; (* BYTE *) +A.sCCFastSpeed = fread(fh, 1, 'uint8=>uint8');% = 286; (* BYTE *) +A.sF2Source = fread(fh, 1, 'uint8=>uint8');% = 287; (* BYTE *) + +A.sTestRange = fread(fh, 1, 'uint8=>uint8');% = 288; (* BYTE *) +A.sTestDacPath = fread(fh, 1, 'uint8=>uint8');% = 289; (* BYTE *) +A.sMuxChannel = fread(fh, 1, 'uint8=>uint8');% = 290; (* BYTE *) +A.sMuxGain64 = fread(fh, 1, 'uint8=>uint8');% = 291; (* BYTE *) +A.sVmonX100 = fread(fh, 1, 'uint8=>uint8');% = 292; (* BYTE *) +A.sIsQuadro = fread(fh, 1, 'uint8=>uint8');% = 293; (* BYTE *) +A.sF1Mode = fread(fh, 1, 'uint8=>uint8');% = 294; (* BYTE *) + A.sOld3 = fread(fh, 1, 'uint8=>uint8');% = 295; (* BYTE *) + +A.sStimFilterHz = fread(fh, 1, 'double=>double');% = 296; (* LONGREAL *) +A.sRsTau = fread(fh, 1, 'double=>double');% = 304; (* LONGREAL *) +A.sDacToAdcDelay = fread(fh, 1, 'double=>double');% = 312; (* LONGREAL *) +A.sInputFilterTau = fread(fh, 1, 'double=>double');% = 320; (* LONGREAL *) +A.sOutputFilterTau = fread(fh, 1, 'double=>double');% = 328; (* LONGREAL *) +A.sVmonFactor = fread(fh, 1, 'double=>double');% = 336; (* LONGREAL *) +A.sCalibDate = fread(fh, 2, 'double=>double');% = 344; (* 16 = SizeCalibDate *) +A.sVmonOffset = fread(fh, 1, 'double=>double');% = 360; (* LONGREAL *) + +A.sEEPROMKind = fread(fh, 1, 'uint8=>uint8');% = 368; (* BYTE *) +A.sVrefX2 = fread(fh, 1, 'uint8=>uint8');% = 369; (* BYTE *) +A.sHasVrefX2AndF2Vmon = fread(fh, 1, 'uint8=>uint8');% = 370; (* BYTE *) +A.sSpare1 = fread(fh, 1, 'uint8=>uint8');% = 371; (* BYTE *) +A.sSpare2 = fread(fh, 1, 'uint8=>uint8');% = 372; (* BYTE *) +A.sSpare3 = fread(fh, 1, 'uint8=>uint8');% = 373; (* BYTE *) +A.sSpare4 = fread(fh, 1, 'uint8=>uint8');% = 374; (* BYTE *) +A.sSpare5 = fread(fh, 1, 'uint8=>uint8');% = 375; (* BYTE *) + +A.sCCStimDacScale = fread(fh, 1, 'double=>double');% = 376; (* LONGREAL *) +A.sVmonFiltBandwidth = fread(fh, 1, 'double=>double');% = 384; (* LONGREAL *) +A.sVmonFiltFrequency = fread(fh, 1, 'double=>double');% = 392; (* LONGREAL *) +A.AmplifierStateSize = 400;% (* = 50 * 8 *) + +fseek(fh, offset+A.AmplifierStateSize, 'bof'); + +end \ No newline at end of file diff --git a/@HEKA_Importer/readSolutionFileHEKA.m b/@HEKA_Importer/readSolutionFileHEKA.m new file mode 100644 index 0000000..2481076 --- /dev/null +++ b/@HEKA_Importer/readSolutionFileHEKA.m @@ -0,0 +1,74 @@ +function [Tree, Position, Counter, nchild]=readSolutionFileHEKA(obj,fh, Tree, Sizes, Level, Position, Counter) +%-------------------------------------------------------------------------- +% Gets one record of the tree and the number of children +[s, Counter]=getOneSolutionRecord(fh, Level, Counter); +Tree{Counter, Level+1}=s; +Position=Position+Sizes(Level+1); +fseek(fh, Position, 'bof'); +nchild=fread(fh, 1, 'int32=>int32'); +Position=ftell(fh); + +end + + +%-------------------------------------------------------------------------- +function [rec, Counter]=getOneSolutionRecord(fh, Level, Counter) +%-------------------------------------------------------------------------- +% Gets one record +Counter=Counter+1; +switch Level + case 0 + rec=getSolutionRoot(fh); + case 1 + rec=getSolutionRecord(fh); + case 2 + rec=getChemicalRecord(fh); + + otherwise + error('Unexpected Level'); +end + +end + +%-------------------------------------------------------------------------- +function p=getSolutionRoot(fh) +%-------------------------------------------------------------------------- +p.RoVersion = fread(fh, 1, 'int16=>int16'); % = 0; (* INT16 *) +p.RoDataBaseName = deblank(fread(fh, 80, 'uint8=>char')');% = 2; (* SolutionNameSize *) +p.RoSpare1 = fread(fh, 1, 'int16=>int16');% = 82; (* INT16 *) +p.RoCRC = fread(fh, 1, 'int32=>int32'); % = 84; (* CARD32 *) +p.RootSize = 88;% = 88 + +p=orderfields(p); + +end + + +function s=getSolutionRecord(fh) +%-------------------------------------------------------------------------- +s.SoNumber = fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) +s.SoName = deblank(fread(fh, 80, 'uint8=>char')');% = 4; (* SolutionNameSize *) +s.SoNumeric = fread(fh, 1, 'real*4=>double');% = 84; (* REAL *) *) +s.SoNumericName = deblank(fread(fh, 30, 'uint8=>char')');% = 88; (* ChemicalNameSize *) +s.SoPH = fread(fh, 1, 'real*4=>double');% = 118; (* REAL *) +s.SopHCompound = deblank(fread(fh, 30, 'uint8=>char')');% = 122; (* ChemicalNameSize *) +s.soOsmol = fread(fh, 1, 'real*4=>double');% = 152; (* REAL *) +s.SoCRC = fread(fh, 1, 'int32=>int32') ;% = 156; (* CARD32 *) +s.SolutionSize = 160;% = 160 + +s=orderfields(s); + +end + +%-------------------------------------------------------------------------- +function c=getChemicalRecord(fh) +%-------------------------------------------------------------------------- +c.ChConcentration = fread(fh, 1, 'real*4=>double');% = 0; (* REAL *) +c.ChName = deblank(fread(fh, 30, 'uint8=>char')');% = 4; (* ChemicalNameSize *) +c.ChSpare1 = fread(fh, 1, 'int16=>int16');% = 34; (* INT16 *) +c.ChCRC = fread(fh, 1, 'int32=>int32')';% = 36; (* CARD32 *) +c.ChemicalSize = 40;% = 40 + +c=orderfields(c); + +end diff --git a/@HEKA_Importer/readStimulusFileHEKA.m b/@HEKA_Importer/readStimulusFileHEKA.m new file mode 100644 index 0000000..4a9a23d --- /dev/null +++ b/@HEKA_Importer/readStimulusFileHEKA.m @@ -0,0 +1,202 @@ +function [Tree, Position, Counter, nchild]=readStimulusFileHEKA(obj,fh, Tree, Sizes, Level, Position, Counter) +%-------------------------------------------------------------------------- +% Gets one record of the tree and the number of children +[s, Counter]=getOneStimRecord(fh, Level, Counter,obj); +Tree{Counter, Level+1}=s; +Position=Position+Sizes(Level+1); +fseek(fh, Position, 'bof'); +nchild=fread(fh, 1, 'int32=>int32'); +Position=ftell(fh); + +end + +%-------------------------------------------------------------------------- +function [rec, Counter]=getOneStimRecord(fh, Level, Counter,obj) +%-------------------------------------------------------------------------- +% Gets one record +Counter=Counter+1; +switch Level + case 0 + rec=getStimRoot(fh,obj); + case 1 + rec=getStimulation(fh,obj); + case 2 + rec=getChannel(fh,obj); + case 3 + rec=getStimSegment(fh,obj); + otherwise + error('Unexpected Level'); +end + +end + +% The functions below return data as defined by the HEKA PatchMaster +% specification + +%-------------------------------------------------------------------------- +function p=getStimRoot(fh,obj) +%-------------------------------------------------------------------------- +p.RoVersion=fread(fh, 1, 'int32=>int32'); +p.RoMark=fread(fh, 1, 'int32=>int32');% = 4; (* INT32 *) +p.RoVersionName=deblank(fread(fh, 32, 'uint8=>char')');% = 8; (* String32Type *) +p.RoMaxSamples=fread(fh, 1, 'int32=>int32'); % = 40; (* INT32 *) +p.RoFiller1 = fread(fh, 1, 'int32=>int32');% = 44; (* INT32 *) +p.RoParams = fread(fh, 10, 'double=>double');% = 48; (* ARRAY[0..9] OF LONGREAL *) +for k=1:10 + p.RoParamText{k}=deblank(fread(fh, 32, 'uint8=>char')');% = 128; (* ARRAY[0..9],[0..31]OF CHAR *) +end +p.RoReserved = fread(fh, 32, 'int32=>int32');% = 448; (* INT32 *) +p.RoFiller2= fread(fh, 1, 'int32=>int32');% = 576; (* INT32 *) +p.RoCRC= fread(fh, 1, 'int32=>int32');% = 580; (* CARD32 *) +p.RootRecSize= 584; % (* = 73 * 8 *) +p=orderfields(p); + +end + +%-------------------------------------------------------------------------- +function s=getStimulation(fh,obj) +%-------------------------------------------------------------------------- +% Stimulus level +s.stMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) +s.stEntryName=deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Type *) +s.stFileName=deblank(fread(fh, 32, 'uint8=>char')');% = 36; (* String32Type *) +s.stAnalName=deblank(fread(fh, 32, 'uint8=>char')');% = 68; (* String32Type *) +s.stDataStartSegment=fread(fh, 1, 'int32=>int32');% = 100; (* INT32 *) +s.stDataStartTime=fread(fh, 1, 'double=>double') ;% = 104; (* LONGREAL *) +s.stDataStartTimeMATLAB=obj.HI_time2date(s.stDataStartTime); +s.stSampleInterval=fread(fh, 1, 'double=>double') ;% = 112; (* LONGREAL *) +s.stSweepInterval=fread(fh, 1, 'double=>double') ;% = 120; (* LONGREAL *) +s.stLeakDelay=fread(fh, 1, 'double=>double') ;% = 128; (* LONGREAL *) +s.stFilterFactor=fread(fh, 1, 'double=>double') ;% = 136; (* LONGREAL *) +s.stNumberSweeps=fread(fh, 1, 'int32=>int32');% = 144; (* INT32 *) +s.stNumberLeaks=fread(fh, 1, 'int32=>int32');% = 148; (* INT32 *) +s.stNumberAverages=fread(fh, 1, 'int32=>int32');% = 152; (* INT32 *) +s.stActualAdcChannels=fread(fh, 1, 'int32=>int32');% = 156; (* INT32 *) +s.stActualDacChannels=fread(fh, 1, 'int32=>int32');% = 160; (* INT32 *) +s.stExtTrigger=fread(fh, 1, 'uint8=>uint8');% = 164; (* BYTE *) +s.stNoStartWait=fread(fh, 1, 'uint8=>logical');% = 165; (* BOOLEAN *) +s.stUseScanRates=fread(fh, 1, 'uint8=>logical');% = 166; (* BOOLEAN *) +s.stNoContAq=fread(fh, 1, 'uint8=>logical');% = 167; (* BOOLEAN *) +s.stHasLockIn=fread(fh, 1, 'uint8=>logical');% = 168; (* BOOLEAN *) +s.stOldStartMacKind=fread(fh, 1, 'uint8=>char');% = 169; (* CHAR *) +s.stOldEndMacKind=fread(fh, 1, 'uint8=>logical');% = 170; (* BOOLEAN *) +s.stAutoRange=fread(fh, 1, 'uint8=>uint8');% = 171; (* BYTE *) +s.stBreakNext=fread(fh, 1, 'uint8=>logical');% = 172; (* BOOLEAN *) +s.stIsExpanded=fread(fh, 1, 'uint8=>logical');% = 173; (* BOOLEAN *) +s.stLeakCompMode=fread(fh, 1, 'uint8=>logical');% = 174; (* BOOLEAN *) +s.stHasChirp=fread(fh, 1, 'uint8=>logical');% = 175; (* BOOLEAN *) +s.stOldStartMacro=deblank(fread(fh, 32, 'uint8=>char')');% = 176; (* String32Type *) +s.stOldEndMacro=deblank(fread(fh, 32, 'uint8=>char')');% = 208; (* String32Type *) +s.sIsGapFree=fread(fh, 1, 'uint8=>logical');% = 240; (* BOOLEAN *) +s.sHandledExternally=fread(fh, 1, 'uint8=>logical');% = 241; (* BOOLEAN *) +s.stFiller1=fread(fh, 1, 'uint8=>logical');% = 242; (* BOOLEAN *) +s.stFiller2=fread(fh, 1, 'uint8=>logical');% = 243; (* BOOLEAN *) +s.stCRC=fread(fh, 1, 'int32=>int32'); % = 244; (* CARD32 *) +s.stTag=deblank(fread(fh, 32, 'uint8=>char')');% = 248; (* String32Type *) +s.StimulationRecSize = 280;% (* = 35 * 8 *) + +s=orderfields(s); + +end + +%-------------------------------------------------------------------------- +function c=getChannel(fh,obj) +%-------------------------------------------------------------------------- +c.chMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) +c.chLinkedChannel=fread(fh, 1, 'int32=>int32');% = 4; (* INT32 *) +c.chCompressionFactor=fread(fh, 1, 'int32=>int32');% = 8; (* INT32 *) +c.chYUnit=deblank(fread(fh, 8, 'uint8=>char')');% = 12; (* String8Type *) +c.chAdcChannel=fread(fh, 1, 'int16=>int16');% = 20; (* INT16 *) +c.chAdcMode=fread(fh, 1, 'uint8=>uint8');% = 22; (* BYTE *) +c.chDoWrite=fread(fh, 1, 'uint8=>logical');% = 23; (* BOOLEAN *) +c.stLeakStore=fread(fh, 1, 'uint8=>uint8');% = 24; (* BYTE *) +c.chAmplMode=fread(fh, 1, 'uint8=>uint8');% = 25; (* BYTE *) +c.chOwnSegTime=fread(fh, 1, 'uint8=>logical');% = 26; (* BOOLEAN *) +c.chSetLastSegVmemb=fread(fh, 1, 'uint8=>logical');% = 27; (* BOOLEAN *) +c.chDacChannel=fread(fh, 1, 'int16=>int16');% = 28; (* INT16 *) +c.chDacMode=fread(fh, 1, 'uint8=>uint8');% = 30; (* BYTE *) +c.chHasLockInSquare=fread(fh, 1, 'uint8=>uint8');% = 31; (* BYTE *) +c.chRelevantXSegment=fread(fh, 1, 'int32=>int32');% = 32; (* INT32 *) +c.chRelevantYSegment=fread(fh, 1, 'int32=>int32');% = 36; (* INT32 *) +c.chDacUnit=deblank(fread(fh, 8, 'uint8=>char')');% = 40; (* String8Type *) +c.chHolding=fread(fh, 1, 'double=>double') ;% = 48; (* LONGREAL *) +c.chLeakHolding=fread(fh, 1, 'double=>double') ;% = 56; (* LONGREAL *) +c.chLeakSize=fread(fh, 1, 'double=>double') ;% = 64; (* LONGREAL *) +c.chLeakHoldMode=fread(fh, 1, 'uint8=>uint8');% = 72; (* BYTE *) +c.chLeakAlternate=fread(fh, 1, 'uint8=>logical');% = 73; (* BOOLEAN *) +c.chAltLeakAveraging=fread(fh, 1, 'uint8=>logical');% = 74; (* BOOLEAN *) +c.chLeakPulseOn=fread(fh, 1, 'uint8=>logical');% = 75; (* BOOLEAN *) +c.chStimToDacID=fread(fh, 1, 'int16=>int16');% = 76; (* SET16 *) +c.chCompressionMode=fread(fh, 1, 'int16=>int16');% = 78; (* SET16 *) +c.chCompressionSkip=fread(fh, 1, 'int32=>int32');% = 80; (* INT32 *) +c.chDacBit=fread(fh, 1, 'int16=>int16');% = 84; (* INT16 *) +c.chHasLockInSine=fread(fh, 1, 'uint8=>logical');% = 86; (* BOOLEAN *) +c.chBreakMode=fread(fh, 1, 'uint8=>uint8');% = 87; (* BYTE *) +c.chZeroSeg=fread(fh, 1, 'int32=>int32');% = 88; (* INT32 *) +c.chFiller1=fread(fh, 1, 'int32=>int32');% = 92; (* INT32 *) +c.chSine_Cycle=fread(fh, 1, 'double=>double') ;% = 96; (* LONGREAL *) +c.chSine_Amplitude=fread(fh, 1, 'double=>double') ;% = 104; (* LONGREAL *) +c.chLockIn_VReversal=fread(fh, 1, 'double=>double') ;% = 112; (* LONGREAL *) +c.chChirp_StartFreq=fread(fh, 1, 'double=>double') ;% = 120; (* LONGREAL *) +c.chChirp_EndFreq=fread(fh, 1, 'double=>double') ;% = 128; (* LONGREAL *) +c.chChirp_MinPoints=fread(fh, 1, 'double=>double') ;% = 136; (* LONGREAL *) +c.chSquare_NegAmpl=fread(fh, 1, 'double=>double') ;% = 144; (* LONGREAL *) +c.chSquare_DurFactor=fread(fh, 1, 'double=>double') ;% = 152; (* LONGREAL *) +c.chLockIn_Skip=fread(fh, 1, 'int32=>int32');% = 160; (* INT32 *) +c.chPhoto_MaxCycles=fread(fh, 1, 'int32=>int32');% = 164; (* INT32 *) +c.chPhoto_SegmentNo=fread(fh, 1, 'int32=>int32');% = 168; (* INT32 *) +c.chLockIn_AvgCycles=fread(fh, 1, 'int32=>int32');% = 172; (* INT32 *) +c.chImaging_RoiNo=fread(fh, 1, 'int32=>int32');% = 176; (* INT32 *) +c.chChirp_Skip=fread(fh, 1, 'int32=>int32');% = 180; (* INT32 *) +c.chChirp_Amplitude=fread(fh, 1, 'double=>double') ;% = 184; (* LONGREAL *) +c.chPhoto_Adapt=fread(fh, 1, 'uint8=>uint8');% = 192; (* BYTE *) +c.chSine_Kind=fread(fh, 1, 'uint8=>uint8');% = 193; (* BYTE *) +c.chChirp_PreChirp=fread(fh, 1, 'uint8=>uint8');% = 194; (* BYTE *) +c.chSine_Source=fread(fh, 1, 'uint8=>uint8');% = 195; (* BYTE *) +c.chSquare_NegSource=fread(fh, 1, 'uint8=>uint8');% = 196; (* BYTE *) +c.chSquare_PosSource=fread(fh, 1, 'uint8=>uint8');% = 197; (* BYTE *) +c.chChirp_Kind=fread(fh, 1, 'uint8=>uint8');% = 198; (* BYTE *) +c.chChirp_Source=fread(fh, 1, 'uint8=>uint8');% = 199; (* BYTE *) +c.chDacOffset=fread(fh, 1, 'double=>double') ;% = 200; (* LONGREAL *) +c.chAdcOffset=fread(fh, 1, 'double=>double') ;% = 208; (* LONGREAL *) +c.chTraceMathFormat=fread(fh, 1, 'uint8=>uint8');% = 216; (* BYTE *) +c.chHasChirp=fread(fh, 1, 'uint8=>logical');% = 217; (* BOOLEAN *) +c.chSquare_Kind=fread(fh, 1, 'uint8=>uint8');% = 218; (* BYTE *) +c.chFiller2=fread(fh,13,'uint8=>char');% = 219; (* ARRAY[0..13] OF CHAR *) +c.chSquare_Cycle=fread(fh, 1, 'double=>double') ;% = 232; (* LONGREAL *) +c.chSquare_PosAmpl=fread(fh, 1, 'double=>double') ;% = 240; (* LONGREAL *) +c.chCompressionOffset=fread(fh, 1, 'int32=>int32');% = 248; (* INT32 *) +c.chPhotoMode=fread(fh, 1, 'int32=>int32');% = 252; (* INT32 *) +c.chBreakLevel=fread(fh, 1, 'double=>double') ;% = 256; (* LONGREAL *) +c.chTraceMath=deblank(fread(fh,128,'uint8=>char')');% = 264; (* String128Type *) +c.chOldCRC=fread(fh, 1, 'int32=>int32');% = 268; (* CARD32 *) +c.chFiller3=fread(fh, 1, 'int32=>int32');% = 392; (* INT32 *) +c.chCRC=fread(fh, 1, 'int32=>int32');% = 396; (* CARD32 *) +c.ChannelRecSize = 400;% (* = 50 * 8 *) +c=orderfields(c); + +end + +%-------------------------------------------------------------------------- +function ss=getStimSegment(fh,obj) +%-------------------------------------------------------------------------- +ss.seMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) +ss.seClass=fread(fh, 1, 'uint8=>uint8');% = 4; (* BYTE *) +ss.seDoStore=fread(fh, 1, 'uint8=>logical');% = 5; (* BOOLEAN *) +ss.seVoltageIncMode=fread(fh, 1, 'uint8=>uint8');% = 6; (* BYTE *) +ss.seDurationIncMode=fread(fh, 1, 'uint8=>uint8');% = 7; (* BYTE *) +ss.seVoltage=fread(fh, 1, 'double=>double');% = 8; (* LONGREAL *) +ss.seVoltageSource=fread(fh, 1, 'int32=>int32');% = 16; (* INT32 *) +ss.seDeltaVFactor=fread(fh, 1, 'double=>double');% = 20; (* LONGREAL *) +ss.seDeltaVIncrement=fread(fh, 1, 'double=>double');% = 28; (* LONGREAL *) +ss.seDuration=fread(fh, 1, 'double=>double');% = 36; (* LONGREAL *) +ss.seDurationSource=fread(fh, 1, 'int32=>int32');% = 44; (* INT32 *) +ss.seDeltaTFactor=fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) +ss.seDeltaTIncrement=fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) +ss.seFiller1=fread(fh, 1, 'int32=>int32');% = 64; (* INT32 *) +ss.seCRC=fread(fh, 1, 'int32=>int32');% = 68; (* CARD32 *) +ss.seScanRate=fread(fh, 1, 'double=>double');% = 72; (* LONGREAL *) +ss.StimSegmentRecSize = 80;% (* = 10 * 8 *) +ss=orderfields(ss); + +end From 3e6a5789c00f13d247db13018c3444f6c2701e37 Mon Sep 17 00:00:00 2001 From: ChristianKeine Date: Sun, 23 Jun 2019 13:13:31 -0500 Subject: [PATCH 14/39] updating to class --- @HEKA_Importer/HEKA_Importer.m | 9 +- @HEKA_Importer/readAmplifierFileHEKA.asv | 240 +++++++++++++++++++++++ @HEKA_Importer/readAmplifierFileHEKA.m | 26 ++- @HEKA_Importer/readStimulusFileHEKA.m | 46 +++-- 4 files changed, 284 insertions(+), 37 deletions(-) create mode 100644 @HEKA_Importer/readAmplifierFileHEKA.asv diff --git a/@HEKA_Importer/HEKA_Importer.m b/@HEKA_Importer/HEKA_Importer.m index 5c45646..3641f1f 100644 --- a/@HEKA_Importer/HEKA_Importer.m +++ b/@HEKA_Importer/HEKA_Importer.m @@ -130,10 +130,11 @@ HI_extractHEKASolutionTree(obj); str = HI_time2date(obj,t); - readPulseFileHEKA(obj) - [Tree, Position, Counter, nchild]=readStimulusFileHEKA(obj,fh, Tree, Sizes, Level, Position, Counter) - [Tree, Position, Counter, nchild]=readAmplifierFileHEKA(obj,fh, Tree, Sizes, Level, Position, Counter) - [Tree, Position, Counter, nchild]=readSolutionFileHEKA(obj,fh, Tree, Sizes, Level, Position, Counter) + readPulseFileHEKA(obj); + readStimulusFileHEKA(obj); + readAmplifierFileHEKA(obj); + readSolutionFileHEKA(obj); + end %% Hide some of the handle class member functions for ease of use. diff --git a/@HEKA_Importer/readAmplifierFileHEKA.asv b/@HEKA_Importer/readAmplifierFileHEKA.asv new file mode 100644 index 0000000..71f6803 --- /dev/null +++ b/@HEKA_Importer/readAmplifierFileHEKA.asv @@ -0,0 +1,240 @@ +function readAmplifierFileHEKA(obj) +%-------------------------------------------------------------------------- +% Gets one record of the tree and the number of children + +s = getOneRecord(obj); +obj.fileData.Tree{obj.fileData.Counter, obj.fileData.Level+1} = s; + +obj.fileData.Position = obj.fileData.Position+obj.fileData.Sizes(obj.fileData.Level+1); +fseek(obj.fileData.fh, obj.fileData.Position, 'bof'); +obj.fileData.nchild=fread(obj.fileData.fh, 1, 'int32=>int32'); +obj.fileData.Position=ftell(obj.fileData.fh); + +end + +%-------------------------------------------------------------------------- +function [rec, Counter]=getOneAmplifierRecord(fh, Level, Counter) +%-------------------------------------------------------------------------- +% Gets one record +Counter=Counter+1; +switch Level + case 0 + rec=getAmplifierRootRecord(fh); + case 1 + rec=getAmplifierSeriesRecord(fh); + case 2 + rec=getAmplifierStateRecord(fh); + + otherwise + error('Unexpected Level'); +end + +end + +%-------------------------------------------------------------------------- +function p=getAmplifierRootRecord(fh) +%-------------------------------------------------------------------------- +p.RoVersion = fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) +p.RoMark = fread(fh, 1, 'int32=>int32');% = 4; (* INT32 *) +p.RoVersionName = deblank(fread(fh, 32, 'uint8=>char')');% = 8; (* String32Type *) +p.RoAmplifierName = deblank(fread(fh, 32, 'uint8=>char')');% = 40; (* String32Type *) +p.RoAmplifier = fread(fh,1,'uint8=>uint8');% = 72; (* CHAR *) +p.RoADBoard = fread(fh,1,'uint8=>uint8');% = 73; (* CHAR *) +p.RoCreator = fread(fh,1,'uint8=>uint8');% = 74; (* CHAR *) + p.RoFiller1 = fread(fh, 1, 'uint8=>uint8');% = 75; (* BYTE *) +p.RoCRC = fread(fh, 1, 'int32=>int32');% = 76; (* CARD32 *) +p.RootRecSize = 80;% (* = 10 * 8 *) + +p=orderfields(p); + +end + +%-------------------------------------------------------------------------- +function s=getAmplifierSeriesRecord(fh) +%-------------------------------------------------------------------------- +s.SeMark = fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) +s.SeSeriesCount = fread(fh, 1, 'int32=>int32');% = 4; (* INT32 *) +s.SeFiller1 = fread(fh, 1, 'int32=>int32');% = 8; (* INT32 *) +s.SeCRC = fread(fh, 1, 'int32=>int32');% = 12; (* CARD32 *) +s.SeriesRecSize = 16;% (* = 2 * 8 *) + +s=orderfields(s); + +end + +%% +function a=getAmplifierStateRecord(fh) + +a.AmMark = fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) +a.AmStateCount = fread(fh, 1, 'int32=>int32');% = 4; (* INT32 *) +a.AmStateVersion = fread(fh,1,'uint8=>uint8');% = 8; (* CHAR *) + a.AmFiller1 = fread(fh, 1, 'uint8=>uint8');% = 9; (* BYTE *) + a.AmFiller2 = fread(fh, 1, 'uint8=>uint8');% = 10; (* BYTE *) + a.AmFiller3 = fread(fh, 1, 'uint8=>uint8');% = 11; (* BYTE *) + a.AmFiller4 = fread(fh, 1, 'int32=>int32');% = 12; (* INT32 *) +a.AmLockInParams = getSeLockInParams(fh);% = 16; (* LockInParamsSize = 96 *) +a.AmAmplifierState = getAmplifierState(fh);% = 112; (* AmplifierStateSize = 400 *) +a.AmIntSol = fread(fh, 1, 'int32=>int32');% = 512; (* INT32 *) +a.AmExtSol = fread(fh, 1, 'int32=>int32');% = 516; (* INT32 *) + a.AmFiller5 = fread(fh, 36, 'uint8=>uint8');% = 520; (* spares: 36 bytes *) +a.AmCRC = fread(fh, 1, 'int32=>int32');% = 556; (* CARD32 *) +a.StateRecSize = 560;% (* = 70 * 8 *) + +a = orderfields(a); + +end + +function L=getSeLockInParams(fh) +%-------------------------------------------------------------------------- +offset=ftell(fh); +L.loExtCalPhase = fread(fh, 1, 'double=>double');% = 0; (* LONGREAL *) +L.loExtCalAtten = fread(fh, 1, 'double=>double');% = 8; (* LONGREAL *) +L.loPLPhase = fread(fh, 1, 'double=>double');% = 16; (* LONGREAL *) +L.loPLPhaseY1 = fread(fh, 1, 'double=>double');% = 24; (* LONGREAL *) +L.loPLPhaseY2 = fread(fh, 1, 'double=>double');% = 32; (* LONGREAL *) +L.loUsedPhaseShift = fread(fh, 1, 'double=>double');% = 40; (* LONGREAL *) +L.loUsedAttenuation = fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) + L.loSpare = fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) +L.loExtCalValid = fread(fh, 1, 'uint8=>logical');% = 64; (* BOOLEAN *) +L.loPLPhaseValid = fread(fh, 1, 'uint8=>logical');% = 65; (* BOOLEAN *) +L.loLockInMode = fread(fh, 1, 'uint8=>uint8');% = 66; (* BYTE *) +L.loCalMode = fread(fh, 1, 'uint8=>uint8');% = 67; (* BYTE *) + L.loSpare2 = fread(fh, 7, 'int32=>in32');% = 68; (* remaining *) +L.LockInParamsSize = 96; + +fseek(fh, offset+L.LockInParamsSize, 'bof'); + +end + +%-------------------------------------------------------------------------- +function A=getAmplifierState(fh) +%-------------------------------------------------------------------------- +offset=ftell(fh); +A.sStateVersion = fread(fh, 1, 'double=>double');% = 0; (* 8 = SizeStateVersion *) +A.sCurrentGain = fread(fh, 1, 'double=>double');% = 8; (* LONGREAL *) +A.sF2Bandwidth = fread(fh, 1, 'double=>double');% = 16; (* LONGREAL *) +A.sF2Frequency = fread(fh, 1, 'double=>double');% = 24; (* LONGREAL *) +A.sRsValue = fread(fh, 1, 'double=>double');% = 32; (* LONGREAL *) +A.sRsFraction = fread(fh, 1, 'double=>double');% = 40; (* LONGREAL *) +A.sGLeak = fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) +A.sCFastAmp1 = fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) +A.sCFastAmp2 = fread(fh, 1, 'double=>double');% = 64; (* LONGREAL *) +A.sCFastTau = fread(fh, 1, 'double=>double');% = 72; (* LONGREAL *) +A.sCSlow = fread(fh, 1, 'double=>double');% = 80; (* LONGREAL *) +A.sGSeries = fread(fh, 1, 'double=>double');% = 88; (* LONGREAL *) +A.sVCStimDacScale = fread(fh, 1, 'double=>double');% = 96; (* LONGREAL *) +A.sCCStimScale = fread(fh, 1, 'double=>double');% = 104; (* LONGREAL *) +A.sVHold = fread(fh, 1, 'double=>double');% = 112; (* LONGREAL *) +A.sLastVHold = fread(fh, 1, 'double=>double');% = 120; (* LONGREAL *) +A.sVpOffset = fread(fh, 1, 'double=>double');% = 128; (* LONGREAL *) +A.sVLiquidJunction = fread(fh, 1, 'double=>double');% = 136; (* LONGREAL *) +A.sCCIHold = fread(fh, 1, 'double=>double');% = 144; (* LONGREAL *) +A.sCSlowStimVolts = fread(fh, 1, 'double=>double');% = 152; (* LONGREAL *) +A.sCCTrackVHold = fread(fh, 1, 'double=>double');% = 160; (* LONGREAL *) +A.sTimeoutCSlow = fread(fh, 1, 'double=>double');% = 168; (* LONGREAL *) +A.sSearchDelay = fread(fh, 1, 'double=>double');% = 176; (* LONGREAL *) +A.sMConductance = fread(fh, 1, 'double=>double');% = 184; (* LONGREAL *) +A.sMCapacitance = fread(fh, 1, 'double=>double');% = 192; (* LONGREAL *) +A.sSerialNumber = fread(fh, 1, 'double=>double');% = 200; (* 8 = SizeSerialNumber *) + +A.sE9Boards = fread(fh, 1, 'int16=>int16');% = 208; (* INT16 *) +A.sCSlowCycles = fread(fh, 1, 'int16=>int16');% = 210; (* INT16 *) +A.sIMonAdc = fread(fh, 1, 'int16=>int16');% = 212; (* INT16 *) +A.sVMonAdc = fread(fh, 1, 'int16=>int16');% = 214; (* INT16 *) + +A.sMuxAdc = fread(fh, 1, 'int16=>int16');% = 216; (* INT16 *) +A.sTestDac = fread(fh, 1, 'int16=>int16');% = 218; (* INT16 *) +A.sStimDac = fread(fh, 1, 'int16=>int16');% = 220; (* INT16 *) +A.sStimDacOffset = fread(fh, 1, 'int16=>int16');% = 222; (* INT16 *) + +A.sMaxDigitalBit = fread(fh, 1, 'int16=>int16');% = 224; (* INT16 *) +A.sHasCFastHigh = fread(fh, 1, 'uint8=>uint8');% = 226; (* BYTE *) +A.sCFastHigh = fread(fh, 1, 'uint8=>uint8');% = 227; (* BYTE *) +A.sHasBathSense = fread(fh, 1, 'uint8=>uint8');% = 228; (* BYTE *) +A.sBathSense = fread(fh, 1, 'uint8=>uint8');% = 229; (* BYTE *) +A.sHasF2Bypass = fread(fh, 1, 'uint8=>uint8');% = 230; (* BYTE *) +A.sF2Mode = fread(fh, 1, 'uint8=>uint8');% = 231; (* BYTE *) + +A.sAmplKind = fread(fh, 1, 'uint8=>uint8');% = 232; (* BYTE *) +A.sIsEpc9N = fread(fh, 1, 'uint8=>uint8');% = 233; (* BYTE *) +A.sADBoard = fread(fh, 1, 'uint8=>uint8');% = 234; (* BYTE *) +A.sBoardVersion = fread(fh, 1, 'uint8=>uint8');% = 235; (* BYTE *) +A.sActiveE9Board = fread(fh, 1, 'uint8=>uint8');% = 236; (* BYTE *) +A.sMode = fread(fh, 1, 'uint8=>uint8');% = 237; (* BYTE *) +A.sRange = fread(fh, 1, 'uint8=>uint8');% = 238; (* BYTE *) +A.sF2Response = fread(fh, 1, 'uint8=>uint8');% = 239; (* BYTE *) + +A.sRsOn = fread(fh, 1, 'uint8=>uint8');% = 240; (* BYTE *) +A.sCSlowRange = fread(fh, 1, 'uint8=>uint8');% = 241; (* BYTE *) +A.sCCRange = fread(fh, 1, 'uint8=>uint8');% = 242; (* BYTE *) +A.sCCGain = fread(fh, 1, 'uint8=>uint8');% = 243; (* BYTE *) +A.sCSlowToTestDac = fread(fh, 1, 'uint8=>uint8');% = 244; (* BYTE *) +A.sStimPath = fread(fh, 1, 'uint8=>uint8');% = 245; (* BYTE *) +A.sCCTrackTau = fread(fh, 1, 'uint8=>uint8');% = 246; (* BYTE *) +A.sWasClipping = fread(fh, 1, 'uint8=>uint8');% = 247; (* BYTE *) + +A.sRepetitiveCSlow = fread(fh, 1, 'uint8=>uint8');% = 248; (* BYTE *) +A.sLastCSlowRange = fread(fh, 1, 'uint8=>uint8');% = 249; (* BYTE *) + A.sOld1 = fread(fh, 1, 'uint8=>uint8');% = 250; (* BYTE *) +A.sCanCCFast = fread(fh, 1, 'uint8=>uint8');% = 251; (* BYTE *) +A.sCanLowCCRange = fread(fh, 1, 'uint8=>uint8');% = 252; (* BYTE *) +A.sCanHighCCRange = fread(fh, 1, 'uint8=>uint8');% = 253; (* BYTE *) +A.sCanCCTrackingg = fread(fh, 1, 'uint8=>uint8');% = 254; (* BYTE *) +A.sCHasVmonPath = fread(fh, 1, 'uint8=>uint8');% = 255; (* BYTE *) + +A.sHasNewCCMode = fread(fh, 1, 'uint8=>uint8');% = 256; (* BYTE *) +A.sSelector = fread(fh, 1, 'uint8=>char');% = 257; (* CHAR *) +A.sHoldInverted = fread(fh, 1, 'uint8=>uint8');% = 258; (* BYTE *) +A.sAutoCFast = fread(fh, 1, 'uint8=>uint8');% = 259; (* BYTE *) +A.sAutoCSlow = fread(fh, 1, 'uint8=>uint8');% = 260; (* BYTE *) +A.sHasVmonX100 = fread(fh, 1, 'uint8=>uint8');% = 261; (* BYTE *) +A.sTestDacOn = fread(fh, 1, 'uint8=>uint8');% = 262; (* BYTE *) +A.sQMuxAdcOn = fread(fh, 1, 'uint8=>uint8');% = 263; (* BYTE *) + +A.sImon1Bandwidth = fread(fh, 1, 'double=>double');% = 264; (* LONGREAL *) +A.sStimScale = fread(fh, 1, 'double=>double');% = 272; (* LONGREAL *) + +A.sGain = fread(fh, 1, 'uint8=>uint8');% = 280; (* BYTE *) +A.sFilter1 = fread(fh, 1, 'uint8=>uint8');% = 281; (* BYTE *) +A.sStimFilterOn = fread(fh, 1, 'uint8=>uint8');% = 282; (* BYTE *) +A.sRsSlow = fread(fh, 1, 'uint8=>uint8');% = 283; (* BYTE *) + A.sOld2 = fread(fh, 1, 'uint8=>uint8');% = 284; (* BYTE *) +A.sCCCFastOn = fread(fh, 1, 'uint8=>uint8');% = 285; (* BYTE *) +A.sCCFastSpeed = fread(fh, 1, 'uint8=>uint8');% = 286; (* BYTE *) +A.sF2Source = fread(fh, 1, 'uint8=>uint8');% = 287; (* BYTE *) + +A.sTestRange = fread(fh, 1, 'uint8=>uint8');% = 288; (* BYTE *) +A.sTestDacPath = fread(fh, 1, 'uint8=>uint8');% = 289; (* BYTE *) +A.sMuxChannel = fread(fh, 1, 'uint8=>uint8');% = 290; (* BYTE *) +A.sMuxGain64 = fread(fh, 1, 'uint8=>uint8');% = 291; (* BYTE *) +A.sVmonX100 = fread(fh, 1, 'uint8=>uint8');% = 292; (* BYTE *) +A.sIsQuadro = fread(fh, 1, 'uint8=>uint8');% = 293; (* BYTE *) +A.sF1Mode = fread(fh, 1, 'uint8=>uint8');% = 294; (* BYTE *) + A.sOld3 = fread(fh, 1, 'uint8=>uint8');% = 295; (* BYTE *) + +A.sStimFilterHz = fread(fh, 1, 'double=>double');% = 296; (* LONGREAL *) +A.sRsTau = fread(fh, 1, 'double=>double');% = 304; (* LONGREAL *) +A.sDacToAdcDelay = fread(fh, 1, 'double=>double');% = 312; (* LONGREAL *) +A.sInputFilterTau = fread(fh, 1, 'double=>double');% = 320; (* LONGREAL *) +A.sOutputFilterTau = fread(fh, 1, 'double=>double');% = 328; (* LONGREAL *) +A.sVmonFactor = fread(fh, 1, 'double=>double');% = 336; (* LONGREAL *) +A.sCalibDate = fread(fh, 2, 'double=>double');% = 344; (* 16 = SizeCalibDate *) +A.sVmonOffset = fread(fh, 1, 'double=>double');% = 360; (* LONGREAL *) + +A.sEEPROMKind = fread(fh, 1, 'uint8=>uint8');% = 368; (* BYTE *) +A.sVrefX2 = fread(fh, 1, 'uint8=>uint8');% = 369; (* BYTE *) +A.sHasVrefX2AndF2Vmon = fread(fh, 1, 'uint8=>uint8');% = 370; (* BYTE *) +A.sSpare1 = fread(fh, 1, 'uint8=>uint8');% = 371; (* BYTE *) +A.sSpare2 = fread(fh, 1, 'uint8=>uint8');% = 372; (* BYTE *) +A.sSpare3 = fread(fh, 1, 'uint8=>uint8');% = 373; (* BYTE *) +A.sSpare4 = fread(fh, 1, 'uint8=>uint8');% = 374; (* BYTE *) +A.sSpare5 = fread(fh, 1, 'uint8=>uint8');% = 375; (* BYTE *) + +A.sCCStimDacScale = fread(fh, 1, 'double=>double');% = 376; (* LONGREAL *) +A.sVmonFiltBandwidth = fread(fh, 1, 'double=>double');% = 384; (* LONGREAL *) +A.sVmonFiltFrequency = fread(fh, 1, 'double=>double');% = 392; (* LONGREAL *) +A.AmplifierStateSize = 400;% (* = 50 * 8 *) + +fseek(fh, offset+A.AmplifierStateSize, 'bof'); + +end diff --git a/@HEKA_Importer/readAmplifierFileHEKA.m b/@HEKA_Importer/readAmplifierFileHEKA.m index 35fa910..ceaa2c2 100644 --- a/@HEKA_Importer/readAmplifierFileHEKA.m +++ b/@HEKA_Importer/readAmplifierFileHEKA.m @@ -1,31 +1,29 @@ -function [Tree, Position, Counter, nchild]=readAmplifierFileHEKA(obj,fh, Tree, Sizes, Level, Position, Counter) +function readAmplifierFileHEKA(obj) %-------------------------------------------------------------------------- % Gets one record of the tree and the number of children +s = getOneAmplifierRecord(obj); +obj.fileData.Tree{obj.fileData.Counter, obj.fileData.Level+1} = s; - -[s, Counter]=getOneAmplifierRecord(fh, Level, Counter); -Tree{Counter, Level+1}=s; -Position=Position+Sizes(Level+1); -fseek(fh, Position, 'bof'); -nchild=fread(fh, 1, 'int32=>int32'); -Position=ftell(fh); +obj.fileData.Position = obj.fileData.Position+obj.fileData.Sizes(obj.fileData.Level+1); +fseek(obj.fileData.fh, obj.fileData.Position, 'bof'); +obj.fileData.nchild=fread(obj.fileData.fh, 1, 'int32=>int32'); +obj.fileData.Position=ftell(obj.fileData.fh); end %-------------------------------------------------------------------------- -function [rec, Counter]=getOneAmplifierRecord(fh, Level, Counter) +function rec=getOneAmplifierRecord(obj) %-------------------------------------------------------------------------- % Gets one record -Counter=Counter+1; +obj.fileData.Counter = obj.fileData.Counter+1; switch Level case 0 - rec=getAmplifierRootRecord(fh); + rec=getAmplifierRootRecord(obj); case 1 - rec=getAmplifierSeriesRecord(fh); + rec=getAmplifierSeriesRecord(obj); case 2 - rec=getAmplifierStateRecord(fh); - + rec=getAmplifierStateRecord(obj); otherwise error('Unexpected Level'); end diff --git a/@HEKA_Importer/readStimulusFileHEKA.m b/@HEKA_Importer/readStimulusFileHEKA.m index 4a9a23d..e7e345b 100644 --- a/@HEKA_Importer/readStimulusFileHEKA.m +++ b/@HEKA_Importer/readStimulusFileHEKA.m @@ -1,29 +1,29 @@ -function [Tree, Position, Counter, nchild]=readStimulusFileHEKA(obj,fh, Tree, Sizes, Level, Position, Counter) +function readStimulusFileHEKA(obj) %-------------------------------------------------------------------------- % Gets one record of the tree and the number of children -[s, Counter]=getOneStimRecord(fh, Level, Counter,obj); -Tree{Counter, Level+1}=s; -Position=Position+Sizes(Level+1); -fseek(fh, Position, 'bof'); -nchild=fread(fh, 1, 'int32=>int32'); -Position=ftell(fh); - +s = getOneStimRecord(obj); +obj.fileData.Tree{obj.fileData.Counter, obj.fileData.Level+1} = s; +obj.fileData.Position = obj.fileData.Position+obj.fileData.Sizes(obj.fileData.Level+1); +fseek(obj.fileData.fh, obj.fileData.Position, 'bof'); +obj.fileData.nchild=fread(obj.fileData.fh, 1, 'int32=>int32'); +obj.fileData.Position=ftell(obj.fileData.fh); end + %-------------------------------------------------------------------------- -function [rec, Counter]=getOneStimRecord(fh, Level, Counter,obj) +function rec=getOneStimRecord(obj) %-------------------------------------------------------------------------- % Gets one record -Counter=Counter+1; -switch Level +obj.fileData.Counter = obj.fileData.Counter+1; +switch obj.fileData.Level case 0 - rec=getStimRoot(fh,obj); + rec=getStimRoot(obj); case 1 - rec=getStimulation(fh,obj); + rec=getStimulation(obj); case 2 - rec=getChannel(fh,obj); + rec=getChannel(obj); case 3 - rec=getStimSegment(fh,obj); + rec=getStimSegment(obj); otherwise error('Unexpected Level'); end @@ -34,8 +34,10 @@ % specification %-------------------------------------------------------------------------- -function p=getStimRoot(fh,obj) +function p=getStimRoot(obj) %-------------------------------------------------------------------------- +fh = obj.fileData.fh; + p.RoVersion=fread(fh, 1, 'int32=>int32'); p.RoMark=fread(fh, 1, 'int32=>int32');% = 4; (* INT32 *) p.RoVersionName=deblank(fread(fh, 32, 'uint8=>char')');% = 8; (* String32Type *) @@ -54,8 +56,10 @@ end %-------------------------------------------------------------------------- -function s=getStimulation(fh,obj) +function s=getStimulation(obj) %-------------------------------------------------------------------------- +fh = obj.fileData.fh; + % Stimulus level s.stMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) s.stEntryName=deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Type *) @@ -100,8 +104,10 @@ end %-------------------------------------------------------------------------- -function c=getChannel(fh,obj) +function c=getChannel(obj) %-------------------------------------------------------------------------- +fh = obj.fileData.fh; + c.chMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) c.chLinkedChannel=fread(fh, 1, 'int32=>int32');% = 4; (* INT32 *) c.chCompressionFactor=fread(fh, 1, 'int32=>int32');% = 8; (* INT32 *) @@ -178,8 +184,10 @@ end %-------------------------------------------------------------------------- -function ss=getStimSegment(fh,obj) +function ss=getStimSegment(obj) %-------------------------------------------------------------------------- +fh = obj.fileData.fh; + ss.seMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) ss.seClass=fread(fh, 1, 'uint8=>uint8');% = 4; (* BYTE *) ss.seDoStore=fread(fh, 1, 'uint8=>logical');% = 5; (* BOOLEAN *) From 94747373b1e20add9c55a6f6e517d77e8fd0191d Mon Sep 17 00:00:00 2001 From: ChristianKeine Date: Sun, 23 Jun 2019 13:22:53 -0500 Subject: [PATCH 15/39] update import --- @HEKA_Importer/HI_ImportHEKAtoMat.m | 2 +- @HEKA_Importer/readAmplifierFileHEKA.m | 14 ++++++--- @HEKA_Importer/readSolutionFileHEKA.m | 39 +++++++++++++++----------- 3 files changed, 34 insertions(+), 21 deletions(-) diff --git a/@HEKA_Importer/HI_ImportHEKAtoMat.m b/@HEKA_Importer/HI_ImportHEKAtoMat.m index 28a1031..251f484 100644 --- a/@HEKA_Importer/HI_ImportHEKAtoMat.m +++ b/@HEKA_Importer/HI_ImportHEKAtoMat.m @@ -217,8 +217,8 @@ end + obj.fileData.Level = obj.fileData.Level+1; %% This counts too high for k=1:double(obj.fileData.nchild) - obj.fileData.Level = obj.fileData.Level+1; getTreeReentrant(obj); end diff --git a/@HEKA_Importer/readAmplifierFileHEKA.m b/@HEKA_Importer/readAmplifierFileHEKA.m index ceaa2c2..a7c4e1b 100644 --- a/@HEKA_Importer/readAmplifierFileHEKA.m +++ b/@HEKA_Importer/readAmplifierFileHEKA.m @@ -31,8 +31,10 @@ function readAmplifierFileHEKA(obj) end %-------------------------------------------------------------------------- -function p=getAmplifierRootRecord(fh) +function p=getAmplifierRootRecord(obj) %-------------------------------------------------------------------------- +fh = obj.fileData.fh; + p.RoVersion = fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) p.RoMark = fread(fh, 1, 'int32=>int32');% = 4; (* INT32 *) p.RoVersionName = deblank(fread(fh, 32, 'uint8=>char')');% = 8; (* String32Type *) @@ -49,8 +51,10 @@ function readAmplifierFileHEKA(obj) end %-------------------------------------------------------------------------- -function s=getAmplifierSeriesRecord(fh) +function s=getAmplifierSeriesRecord(obj) %-------------------------------------------------------------------------- +fh = obj.fileData.fh; + s.SeMark = fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) s.SeSeriesCount = fread(fh, 1, 'int32=>int32');% = 4; (* INT32 *) s.SeFiller1 = fread(fh, 1, 'int32=>int32');% = 8; (* INT32 *) @@ -61,8 +65,10 @@ function readAmplifierFileHEKA(obj) end -%% -function a=getAmplifierStateRecord(fh) +%-------------------------------------------------------------------------- +function a=getAmplifierStateRecord(obj) +%-------------------------------------------------------------------------- +fh = obj.fileData.fh; a.AmMark = fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) a.AmStateCount = fread(fh, 1, 'int32=>int32');% = 4; (* INT32 *) diff --git a/@HEKA_Importer/readSolutionFileHEKA.m b/@HEKA_Importer/readSolutionFileHEKA.m index 2481076..26880a4 100644 --- a/@HEKA_Importer/readSolutionFileHEKA.m +++ b/@HEKA_Importer/readSolutionFileHEKA.m @@ -1,28 +1,29 @@ -function [Tree, Position, Counter, nchild]=readSolutionFileHEKA(obj,fh, Tree, Sizes, Level, Position, Counter) +function readSolutionFileHEKA(obj) %-------------------------------------------------------------------------- % Gets one record of the tree and the number of children -[s, Counter]=getOneSolutionRecord(fh, Level, Counter); -Tree{Counter, Level+1}=s; -Position=Position+Sizes(Level+1); -fseek(fh, Position, 'bof'); -nchild=fread(fh, 1, 'int32=>int32'); -Position=ftell(fh); +s = getOneSolutionRecord(obj); +obj.fileData.Tree{obj.fileData.Counter, obj.fileData.Level+1} = s; + +obj.fileData.Position = obj.fileData.Position+obj.fileData.Sizes(obj.fileData.Level+1); +fseek(obj.fileData.fh, obj.fileData.Position, 'bof'); +obj.fileData.nchild=fread(obj.fileData.fh, 1, 'int32=>int32'); +obj.fileData.Position=ftell(obj.fileData.fh); end %-------------------------------------------------------------------------- -function [rec, Counter]=getOneSolutionRecord(fh, Level, Counter) +function rec=getOneSolutionRecord(obj) %-------------------------------------------------------------------------- % Gets one record -Counter=Counter+1; +obj.fileData.Counter = obj.fileData.Counter+1; switch Level case 0 - rec=getSolutionRoot(fh); + rec=getSolutionRoot(obj); case 1 - rec=getSolutionRecord(fh); + rec=getSolutionRecord(obj); case 2 - rec=getChemicalRecord(fh); + rec=getChemicalRecord(obj); otherwise error('Unexpected Level'); @@ -31,8 +32,10 @@ end %-------------------------------------------------------------------------- -function p=getSolutionRoot(fh) +function p=getSolutionRoot(obj) %-------------------------------------------------------------------------- +fh = obj.fileData.fh; + p.RoVersion = fread(fh, 1, 'int16=>int16'); % = 0; (* INT16 *) p.RoDataBaseName = deblank(fread(fh, 80, 'uint8=>char')');% = 2; (* SolutionNameSize *) p.RoSpare1 = fread(fh, 1, 'int16=>int16');% = 82; (* INT16 *) @@ -43,9 +46,11 @@ end - -function s=getSolutionRecord(fh) %-------------------------------------------------------------------------- +function s=getSolutionRecord(obj) +%-------------------------------------------------------------------------- +fh = obj.fileData.fh; + s.SoNumber = fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) s.SoName = deblank(fread(fh, 80, 'uint8=>char')');% = 4; (* SolutionNameSize *) s.SoNumeric = fread(fh, 1, 'real*4=>double');% = 84; (* REAL *) *) @@ -61,8 +66,10 @@ end %-------------------------------------------------------------------------- -function c=getChemicalRecord(fh) +function c=getChemicalRecord(obj) %-------------------------------------------------------------------------- +fh = obj.fileData.fh; + c.ChConcentration = fread(fh, 1, 'real*4=>double');% = 0; (* REAL *) c.ChName = deblank(fread(fh, 30, 'uint8=>char')');% = 4; (* ChemicalNameSize *) c.ChSpare1 = fread(fh, 1, 'int16=>int16');% = 34; (* INT16 *) From b03810c7cff08339584e96710d9101eae6851710 Mon Sep 17 00:00:00 2001 From: ChristianKeine Date: Sun, 23 Jun 2019 22:45:20 -0500 Subject: [PATCH 16/39] update import --- @HEKA_Importer/HEKA_Importer.m | 8 +- @HEKA_Importer/HI_ImportHEKAtoMat.asv | 53 +-- @HEKA_Importer/HI_ImportHEKAtoMat.m | 40 +- @HEKA_Importer/readAmplifierFileHEKA.asv | 33 +- @HEKA_Importer/readAmplifierFileHEKA.m | 10 +- @HEKA_Importer/readPulseFileHEKA.asv | 447 ----------------------- @HEKA_Importer/readPulseFileHEKA.m | 13 +- @HEKA_Importer/readSolutionFileHEKA.m | 8 +- @HEKA_Importer/readStimulusFileHEKA.m | 12 +- 9 files changed, 96 insertions(+), 528 deletions(-) delete mode 100644 @HEKA_Importer/readPulseFileHEKA.asv diff --git a/@HEKA_Importer/HEKA_Importer.m b/@HEKA_Importer/HEKA_Importer.m index 3641f1f..4d60477 100644 --- a/@HEKA_Importer/HEKA_Importer.m +++ b/@HEKA_Importer/HEKA_Importer.m @@ -130,10 +130,10 @@ HI_extractHEKASolutionTree(obj); str = HI_time2date(obj,t); - readPulseFileHEKA(obj); - readStimulusFileHEKA(obj); - readAmplifierFileHEKA(obj); - readSolutionFileHEKA(obj); + readPulseFileHEKA(obj,Level); + readStimulusFileHEKA(obj,Level); + readAmplifierFileHEKA(obj,Level); + readSolutionFileHEKA(obj,Level); end diff --git a/@HEKA_Importer/HI_ImportHEKAtoMat.asv b/@HEKA_Importer/HI_ImportHEKAtoMat.asv index 545fce8..683a4ee 100644 --- a/@HEKA_Importer/HI_ImportHEKAtoMat.asv +++ b/@HEKA_Importer/HI_ImportHEKAtoMat.asv @@ -88,11 +88,13 @@ for iidx = fileExt Position=ftell(fh); % Get the tree structures form the file sections - obj.tempData.fh = fh; - obj.tempData.Sizes = Sizes; - + obj.fileData.fh = fh; + obj.fileData.Sizes = Sizes; + obj.fileData.Position = Position; + obj.fileData.fileExt = iidx{1}; obj.trees.(treeName{strcmp(iidx, fileExt)})=getTree(fh, Sizes, Position, iidx{1},obj); + else obj.trees.(treeName{strcmp(iidx, fileExt)}) = []; end @@ -160,11 +162,11 @@ switch h.oSignature isBundled=false; case {'DAT1' 'DAT2'} % Newer format - h.oVersion=fread(fh, 32, 'uint8=>char')'; - h.oTime=fread(fh, 1, 'double'); - h.oItems=fread(fh, 1, 'int32=>int32'); - h.oIsLittleEndian=fread(fh, 1, 'uint8=>logical'); - h.BundleHeaderSize=256; + h.oVersion = fread(fh, 32, 'uint8=>char')'; + h.oTime = fread(fh, 1, 'double'); + h.oItems = fread(fh, 1, 'int32=>int32'); + h.oIsLittleEndian = fread(fh, 1, 'uint8=>logical'); + h.BundleHeaderSize = 256; switch h.oSignature case 'DAT1' h.oBundleItems=[]; @@ -172,10 +174,10 @@ switch h.oSignature case {'DAT2'} fseek(fh, 64, 'bof'); for k=1:12 - h.oBundleItems(k).oStart=fread(fh, 1, 'int32=>int32'); - h.oBundleItems(k).oLength=fread(fh, 1, 'int32=>int32'); - h.oBundleItems(k).oExtension=deblank(fread(fh, 8, 'uint8=>char')'); - h.oBundleItems(k).BundleItemSize=16; + h.oBundleItems(k).oStart = fread(fh, 1, 'int32=>int32'); + h.oBundleItems(k).oLength = fread(fh, 1, 'int32=>int32'); + h.oBundleItems(k).oExtension = deblank(fread(fh, 8, 'uint8=>char')'); + h.oBundleItems(k).BundleItemSize = 16; end isBundled=true; end @@ -188,33 +190,40 @@ end %-------------------------------------------------------------------------- -function [Tree, Counter]=getTree(fh, Sizes, Position, ext,obj) +function Tree=getTree(fh, Sizes, Position, ext,obj) %-------------------------------------------------------------------------- % Main entry point for loading tree -[Tree, Counter]=getTreeReentrant(fh, {}, Sizes, 0, Position, 0, ext,obj); + +obj.fileData.Counter = 0; +obj.fileData.Tree = {}; +obj.fileData.Level = 0; + +Tree = getTreeReentrant(obj,0); end -function [Tree, Position, Counter]=getTreeReentrant(fh, Tree, Sizes, Level, Position, Counter, ext,obj) +function Tree=getTreeReentrant(obj,Level) %-------------------------------------------------------------------------- % Recursive routine called from LoadTree -switch ext +switch obj.fileData.fileExt case '.pul' - [Tree, Position, Counter, nchild]=obj.readPulseFileHEKA(fh, Tree, Sizes, Level, Position, Counter); + obj.readPulseFileHEKA(Level); case '.pgf' - [Tree, Position, Counter, nchild]=obj.readStimulusFileHEKA(fh, Tree, Sizes, Level, Position, Counter); + obj.readStimulusFileHEKA; case '.sol' - [Tree, Position, Counter, nchild]=obj.readSolutionFileHEKA(fh, Tree, Sizes, Level, Position, Counter); + obj.readSolutionFileHEKA; case '.amp' - [Tree, Position, Counter, nchild]=obj.readAmplifierFileHEKA(fh, Tree, Sizes, Level, Position, Counter); + obj.readAmplifierFileHEKA; end -for k=1:double(nchild) - [Tree, Position, Counter]=getTreeReentrant(fh, Tree, Sizes, Level+1, Position, Counter, ext, obj); +for k=1:double(obj.fileData.nchild) + getTreeReentrant(obj,Level+1); end +Tree = obj.fileData.Tree; + end diff --git a/@HEKA_Importer/HI_ImportHEKAtoMat.m b/@HEKA_Importer/HI_ImportHEKAtoMat.m index 251f484..a1f9329 100644 --- a/@HEKA_Importer/HI_ImportHEKAtoMat.m +++ b/@HEKA_Importer/HI_ImportHEKAtoMat.m @@ -93,7 +93,8 @@ obj.fileData.Position = Position; obj.fileData.fileExt = iidx{1}; - obj.trees.(treeName{strcmp(iidx, fileExt)})=getTree(fh, Sizes, Position, iidx{1},obj); + obj.trees.(treeName{strcmp(iidx, fileExt)})=getTree(obj); + else obj.trees.(treeName{strcmp(iidx, fileExt)}) = []; end @@ -161,11 +162,11 @@ isBundled=false; case {'DAT1' 'DAT2'} % Newer format - h.oVersion=fread(fh, 32, 'uint8=>char')'; - h.oTime=fread(fh, 1, 'double'); - h.oItems=fread(fh, 1, 'int32=>int32'); - h.oIsLittleEndian=fread(fh, 1, 'uint8=>logical'); - h.BundleHeaderSize=256; + h.oVersion = fread(fh, 32, 'uint8=>char')'; + h.oTime = fread(fh, 1, 'double'); + h.oItems = fread(fh, 1, 'int32=>int32'); + h.oIsLittleEndian = fread(fh, 1, 'uint8=>logical'); + h.BundleHeaderSize = 256; switch h.oSignature case 'DAT1' h.oBundleItems=[]; @@ -173,10 +174,10 @@ case {'DAT2'} fseek(fh, 64, 'bof'); for k=1:12 - h.oBundleItems(k).oStart=fread(fh, 1, 'int32=>int32'); - h.oBundleItems(k).oLength=fread(fh, 1, 'int32=>int32'); - h.oBundleItems(k).oExtension=deblank(fread(fh, 8, 'uint8=>char')'); - h.oBundleItems(k).BundleItemSize=16; + h.oBundleItems(k).oStart = fread(fh, 1, 'int32=>int32'); + h.oBundleItems(k).oLength = fread(fh, 1, 'int32=>int32'); + h.oBundleItems(k).oExtension = deblank(fread(fh, 8, 'uint8=>char')'); + h.oBundleItems(k).BundleItemSize = 16; end isBundled=true; end @@ -189,7 +190,7 @@ %-------------------------------------------------------------------------- -function [Tree, Counter]=getTree(fh, Sizes, Position, ext,obj) +function Tree=getTree(obj) %-------------------------------------------------------------------------- % Main entry point for loading tree @@ -197,31 +198,32 @@ obj.fileData.Tree = {}; obj.fileData.Level = 0; -[Tree, Counter] = getTreeReentrant(obj); +Tree = getTreeReentrant(obj,0); end -function [Tree, Position, Counter]=getTreeReentrant(obj) +function Tree=getTreeReentrant(obj,Level) %-------------------------------------------------------------------------- % Recursive routine called from LoadTree switch obj.fileData.fileExt case '.pul' - obj.readPulseFileHEKA; + obj.readPulseFileHEKA(Level); case '.pgf' - obj.readStimulusFileHEKA; + obj.readStimulusFileHEKA(Level); case '.sol' - obj.readSolutionFileHEKA; + obj.readSolutionFileHEKA(Level); case '.amp' - obj.readAmplifierFileHEKA; + obj.readAmplifierFileHEKA(Level); end - obj.fileData.Level = obj.fileData.Level+1; %% This counts too high for k=1:double(obj.fileData.nchild) - getTreeReentrant(obj); + getTreeReentrant(obj,Level+1); end +Tree = obj.fileData.Tree; + end diff --git a/@HEKA_Importer/readAmplifierFileHEKA.asv b/@HEKA_Importer/readAmplifierFileHEKA.asv index 71f6803..04ee255 100644 --- a/@HEKA_Importer/readAmplifierFileHEKA.asv +++ b/@HEKA_Importer/readAmplifierFileHEKA.asv @@ -1,11 +1,11 @@ -function readAmplifierFileHEKA(obj) +function readAmplifierFileHEKA(obj,Level) %-------------------------------------------------------------------------- % Gets one record of the tree and the number of children -s = getOneRecord(obj); -obj.fileData.Tree{obj.fileData.Counter, obj.fileData.Level+1} = s; +s = getOneAmplifierRecord(obj,Level); +obj.fileData.Tree{obj.fileData.Counter, Level+1} = s; -obj.fileData.Position = obj.fileData.Position+obj.fileData.Sizes(obj.fileData.Level+1); +obj.fileData.Position = obj.fileData.Position+obj.fileData.Sizes(Level+1); fseek(obj.fileData.fh, obj.fileData.Position, 'bof'); obj.fileData.nchild=fread(obj.fileData.fh, 1, 'int32=>int32'); obj.fileData.Position=ftell(obj.fileData.fh); @@ -13,18 +13,17 @@ obj.fileData.Position=ftell(obj.fileData.fh); end %-------------------------------------------------------------------------- -function [rec, Counter]=getOneAmplifierRecord(fh, Level, Counter) +function rec=getOneAmplifierRecord(obj,Level) %-------------------------------------------------------------------------- % Gets one record -Counter=Counter+1; +obj.fileData.Counter = obj.fileData.Counter+1; switch Level case 0 - rec=getAmplifierRootRecord(fh); + rec=getAmplifierRootRecord(obj); case 1 - rec=getAmplifierSeriesRecord(fh); + rec=getAmplifierSeriesRecord(obj); case 2 - rec=getAmplifierStateRecord(fh); - + rec=getAmplifierStateRecord(obj); otherwise error('Unexpected Level'); end @@ -32,8 +31,10 @@ end end %-------------------------------------------------------------------------- -function p=getAmplifierRootRecord(fh) +function p=getAmplifierRootRecord(obj) %-------------------------------------------------------------------------- +fh = obj.fileData.fh; + p.RoVersion = fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) p.RoMark = fread(fh, 1, 'int32=>int32');% = 4; (* INT32 *) p.RoVersionName = deblank(fread(fh, 32, 'uint8=>char')');% = 8; (* String32Type *) @@ -50,8 +51,10 @@ p=orderfields(p); end %-------------------------------------------------------------------------- -function s=getAmplifierSeriesRecord(fh) +function s=getAmplifierSeriesRecord(obj) %-------------------------------------------------------------------------- +fh = obj.fileData.fh; + s.SeMark = fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) s.SeSeriesCount = fread(fh, 1, 'int32=>int32');% = 4; (* INT32 *) s.SeFiller1 = fread(fh, 1, 'int32=>int32');% = 8; (* INT32 *) @@ -62,8 +65,10 @@ s=orderfields(s); end -%% -function a=getAmplifierStateRecord(fh) +%-------------------------------------------------------------------------- +function a=getAmplifierStateRecord(obj) +%-------------------------------------------------------------------------- +fh = obj.fileData.fh; a.AmMark = fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) a.AmStateCount = fread(fh, 1, 'int32=>int32');% = 4; (* INT32 *) diff --git a/@HEKA_Importer/readAmplifierFileHEKA.m b/@HEKA_Importer/readAmplifierFileHEKA.m index a7c4e1b..04ee255 100644 --- a/@HEKA_Importer/readAmplifierFileHEKA.m +++ b/@HEKA_Importer/readAmplifierFileHEKA.m @@ -1,11 +1,11 @@ -function readAmplifierFileHEKA(obj) +function readAmplifierFileHEKA(obj,Level) %-------------------------------------------------------------------------- % Gets one record of the tree and the number of children -s = getOneAmplifierRecord(obj); -obj.fileData.Tree{obj.fileData.Counter, obj.fileData.Level+1} = s; +s = getOneAmplifierRecord(obj,Level); +obj.fileData.Tree{obj.fileData.Counter, Level+1} = s; -obj.fileData.Position = obj.fileData.Position+obj.fileData.Sizes(obj.fileData.Level+1); +obj.fileData.Position = obj.fileData.Position+obj.fileData.Sizes(Level+1); fseek(obj.fileData.fh, obj.fileData.Position, 'bof'); obj.fileData.nchild=fread(obj.fileData.fh, 1, 'int32=>int32'); obj.fileData.Position=ftell(obj.fileData.fh); @@ -13,7 +13,7 @@ function readAmplifierFileHEKA(obj) end %-------------------------------------------------------------------------- -function rec=getOneAmplifierRecord(obj) +function rec=getOneAmplifierRecord(obj,Level) %-------------------------------------------------------------------------- % Gets one record obj.fileData.Counter = obj.fileData.Counter+1; diff --git a/@HEKA_Importer/readPulseFileHEKA.asv b/@HEKA_Importer/readPulseFileHEKA.asv deleted file mode 100644 index 023c8f6..0000000 --- a/@HEKA_Importer/readPulseFileHEKA.asv +++ /dev/null @@ -1,447 +0,0 @@ -function [Tree, Position, Counter, nchild]=readPulseFileHEKA(obj,fh, Tree, Sizes, Level, Position, Counter) -%-------------------------------------------------------------------------- -% Gets one record of the tree and the number of children - - - - -[s, Counter]=getOneRecord(fh, Level, Counter,obj); -Tree{Counter, Level+1}=s; -Position=Position+Sizes(Level+1); -fseek(fh, Position, 'bof'); -nchild=fread(fh, 1, 'int32=>int32'); -Position=ftell(fh); -end - -%-------------------------------------------------------------------------- -function [rec, Counter]=getOneRecord(fh, Level, Counter,obj) -%-------------------------------------------------------------------------- -% Gets one record -% Counter=Counter+1; -obj.fileData.Counter = obj.fileData.Counter+1 - -switch Level - case 0 - rec=getRoot(fh,obj); - case 1 - rec=getGroup(fh,obj); - case 2 - rec=getSeries(fh,obj); - case 3 - rec=getSweep(fh,obj); - case 4 - rec=getTrace(fh,obj); - otherwise - error('Unexpected Level'); -end -end - -% The functions below return data as defined by the HEKA PatchMaster -% specification - -%-------------------------------------------------------------------------- -function p=getRoot(fh,obj) -%-------------------------------------------------------------------------- -p.RoVersion=fread(fh, 1, 'int32=>int32'); -p.RoMark=fread(fh, 1, 'int32=>int32');% = 4; (* INT32 *) -p.RoVersionName=deblank(fread(fh, 32, 'uint8=>char')');% = 8; (* String32Type *) -p.RoAuxFileName=deblank(fread(fh, 80, 'uint8=>char')');% = 40; (* String80Type *) -p.RoRootText=deblank(fread(fh, 400, 'uint8=>char')');% (* String400Type *) -p.RoStartTime=fread(fh, 1, 'double=>double') ;% = 520; (* LONGREAL *) -p.RoStartTimeMATLAB=obj.HI_time2date(p.RoStartTime); -p.RoMaxSamples=fread(fh, 1, 'int32=>int32'); % = 528; (* INT32 *) -p.RoCRC=fread(fh, 1, 'int32=>int32'); % = 532; (* CARD32 *) -p.RoFeatures=fread(fh, 1, 'int16=>int16'); % = 536; (* SET16 *) -p.RoFiller1=fread(fh, 1, 'int16=>int16');% = 538; (* INT16 *) -p.RoFiller2=fread(fh, 1, 'int32=>int32');% = 540; (* INT32 *) -p.RoTcEnumerator = fread(fh,32,'int16=>int16');% = 544; (* ARRAY[0..Max_TcKind_M1] OF INT16 *) -p.RoTcKind = fread(fh,32,'int8=>int8');% = 608; (* ARRAY[0..Max_TcKind_M1] OF INT8 *) -p.RootRecSize = 640; % (* = 80 * 8 *); -p=orderfields(p); - -end - -%-------------------------------------------------------------------------- -function g=getGroup(fh,obj) -%-------------------------------------------------------------------------- -% Group -g.GrMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) -g.GrLabel=deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Size *) -g.GrText=deblank(fread(fh, 80, 'uint8=>char')');% = 36; (* String80Size *) -g.GrExperimentNumber=fread(fh, 1, 'int32=>int32');% = 116; (* INT32 *) -g.GrGroupCount=fread(fh, 1, 'int32=>int32');% = 120; (* INT32 *) -g.GrCRC=fread(fh, 1, 'int32=>int32');% = 124; (* CARD32 *) -g.GrMatrixWidth = fread(fh,1,'double=>double');% = 128; (* LONGREAL *) -g.GrMatrixHeight = fread(fh,1,'double=>double');% = 136; (* LONGREAL *) -g.GroupRecSize = 144; % (* = 18 * 8 *) - -% g.GroupRecSize=128;% (* = 16 * 8 *) -g=orderfields(g); - -end - -%-------------------------------------------------------------------------- -function s=getSeries(fh,obj) -%-------------------------------------------------------------------------- -s.SeMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) -s.SeLabel=deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Type *) -s.SeComment=deblank(fread(fh, 80, 'uint8=>char')');% = 36; (* String80Type *) -s.SeSeriesCount=fread(fh, 1, 'int32=>int32');% = 116; (* INT32 *) -s.SeNumbersw=fread(fh, 1, 'int32=>int32');% = 120; (* INT32 *) - -%% -s.SeAmplStateFlag = fread(fh,1,'int32=>int32');% = 124; (* INT32 *) // flag > 0 => load local oldAmpState, otherwise load from .amp File. -s.SeAmplStateRef = fread(fh,1,'int32=>int32'); % = 128; (* INT32 *) // ref = 0 => use local oldAmpState -s.SeMethodTag = fread(fh,1,'int32=>int32'); % = 132; (* INT32 *) -s.SeTime = fread(fh,1,'double=>double'); % = 136; (* LONGREAL *) -s.SeTimeMATLAB=obj.HI_time2date(s.SeTime); -s.SePageWidth=fread(fh, 1, 'double=>double') ;% = 144; (* LONGREAL *) -for k=1:2 % = 152; (* ARRAY[0..1] OF UserParamDescrType = 2*40 *) - s.SeSwUserParamDescr(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% - s.SeSwUserParamDescr(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% -end -s.SeFiller1 = deblank(fread(fh,80,'uint8=>char')'); % = 232; (* ARRAY[0..1] OF UserParamDescrType = 2*40 *) -s.SeMethodName = deblank(fread(fh,32,'uint8=>char')');% = 312; (* String32Type *) -% - -s.SePhotoParams1 = fread(fh, 4, 'double=>double'); %= 344; (* ARRAY[0..3] OF LONGREAL = 4*8 *) -s.SeOldLockInParams=getSeLockInParams(fh);% = 376; (* SeLockInSize = 96, see "Pulsed.de" *) -s.SeOldAmplifierState=getAmplifierState(fh);% = 472; (* AmplifierStateSize = 400 *) -s.SeUsername=deblank(fread(fh, 80, 'uint8=>char')');% - -for k=1:4 - s.SeSeUserParamDescr(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% (* ARRAY[0..3] OF UserParamDescrType = 4*40 *) - s.SeSeUserParamDescr(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% -end - -% s.SeOldLockInParams = fread(fh,96); % = 376; (* SeOldLockInSize = 96, see "Pulsed.de" *) -% s.SeOldAmpState = fread(fh,400); % = 472; (* SeOldAmpState = 400 -> the AmplStateRecord is now stored in the .amp file *) -% s.SeUsername = deblank(fread(fh,80,'uint8=>char')); % = 872; (* String80Type *) - -s.SePhotoParams2 = deblank(fread(fh,160,'uint8=>char')'); %= 952; (* ARRAY[0..3] OF UserParamDescrType = 4*40 *) -s.SeFiller1=fread(fh, 1, 'int32=>int32');% = 1112; (* INT32 *) -s.SeCRC=fread(fh, 1, 'int32=>int32');% = 1116; (* CARD32 *) - -s.SeSeUserParams2=fread(fh, 4, 'double=>double'); %= 1120; (* ARRAY[0..3] OF LONGREAL *) -for k=1:4 %= 1152; (* ARRAY[0..3] OF UserParamDescrType = 4*40 *) - s.SeSeUserParamDescr2(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% - s.SeSeUserParamDescr2(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% -end -s.SeScanParams=fread(fh, 96, 'uint8=>uint8'); %= 1312; (* ScanParamsSize = 96 (ElProScan Extension) *) - -for k=1:8 %= 1408; (* ARRAY[0..7] OF UserParamDescrType = 8*40 *) - s.SeSeUserDescr2(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% - s.SeSeUserDescr2(k).Unit=deblank(fread(fh, 8, 'uint8=>char')'); -end -s.SeriesRecSize=1728;% = 1728; - -%= 1116; (* CARD32 *) -% s.SeSeUserParams2 = fread(fh,) %= 1120; (* ARRAY[0..3] OF LONGREAL *) -% SeSeUserParamDescr2 %= 1152; (* ARRAY[0..3] OF UserParamDescrType = 4*40 *) -% SeScanParams %= 1312; (* ScanParamsSize = 96 (ElProScan Extension) *) -% SeUserDescr2 %= 1408; (* ARRAY[0..7] OF UserParamDescrType = 8*40 *) -% SeriesRecSize %= 1728; - -%% -% s.SeAmplStateOffset=fread(fh, 1, 'int32=>int32');% = 124; (* INT32 *) -% s.SeAmplStateSeries=fread(fh, 1, 'int32=>int32');% = 128; (* INT32 *) -% s.SeSeriesType=fread(fh, 1, 'uint8=>uint8');% = 132; (* BYTE *) -% -% % Added 15.08.2012 -% s.SeUseXStart=logical(fread(fh, 1, 'uint8=>uint8'));% = 133; (* BYTE *) -% -% s.SeFiller2=fread(fh, 1, 'uint8=>uint8');% = 134; (* BYTE *) -% s.SeFiller3=fread(fh, 1, 'uint8=>uint8');% = 135; (* BYTE *) -% s.SeTime=fread(fh, 1, 'double=>double') ;% = 136; (* LONGREAL *) -% s.SeTimeMATLAB=time2date(s.SeTime); -% s.SePageWidth=fread(fh, 1, 'double=>double') ;% = 144; (* LONGREAL *) -% for k=1:4 -% s.SeSwUserParamDescr(k).Name=deblank(fread(fh, 32, 'uint8=>')');% -% s.SeSwUserParamDescr(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% -% end -% s.SeFiller4=fread(fh, 32, 'uint8=>uint8');% = 312; (* 32 BYTE *) -% s.SeSeUserParams=fread(fh, 4, 'double=>double');% = 344; (* ARRAY[0..3] OF LONGREAL *) -% s.SeLockInParams=getSeLockInParams(fh);% = 376; (* SeLockInSize = 96, see "Pulsed.de" *) -% s.SeAmplifierState=getAmplifierState(fh);% = 472; (* AmplifierStateSize = 400 *) -% s.SeUsername=deblank(fread(fh, 80, 'uint8=>char')');% = 872; (* String80Type *) -% for k=1:4 -% s.SeSeUserParamDescr(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% (* ARRAY[0..3] OF UserParamDescrType = 4*40 *) -% s.SeSeUserParamDescr(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% -% end -% s.SeFiller5=fread(fh, 1, 'int32=>int32');% = 1112; (* INT32 *) -% s.SeCRC=fread(fh, 1, 'int32=>int32');% = 1116; (* CARD32 *) -% -% % Added 15.08.2012 -% s.SeSeUserParams2=fread(fh, 4, 'double=>double'); -% for k=1:4 -% s.SeSeUserParamDescr2(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% -% s.SeSeUserParamDescr2(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% -% end -% s.SeScanParams=fread(fh, 96, 'uint8=>uint8'); -% s.SeriesRecSize=1408;% (* = 176 * 8 *) -s=orderfields(s); -s.Sweeps = []; % used to store all the sweeps within the recording structure later on - -end - -%-------------------------------------------------------------------------- -function sw=getSweep(fh,obj) -%-------------------------------------------------------------------------- -sw.SwMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) -sw.SwLabel=deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Type *) -sw.SwAuxDataFileOffset=fread(fh, 1, 'int32=>int32');% = 36; (* INT32 *) -sw.SwStimCount=fread(fh, 1, 'int32=>int32');% = 40; (* INT32 *) -sw.SwSweepCount=fread(fh, 1, 'int32=>int32');% = 44; (* INT32 *) -sw.SwTime=fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) -sw.SwTimeMATLAB=obj.HI_time2date(sw.SwTime);% Also add in MATLAB datenum format -sw.SwTimer=fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) -sw.SwSwUserParams=fread(fh, 2, 'double=>double');% = 64; (* ARRAY[0..1] OF LONGREAL *) -sw.SwPipPressure=fread(fh, 2, 'double=>double'); % = 80; (* LONGREAL * -sw.SwRMSNoise=fread(fh,2,'double=>double'); % = 88; (* LONGREAL *) -sw.SwTemperature=fread(fh, 1, 'double=>double');% = 96; (* LONGREAL *) -sw.SwOldIntSol=fread(fh, 1, 'int32=>int32');% = 104; (* INT32 *) -sw.SwOldExtSol=fread(fh, 1, 'int32=>int32');% = 108; (* INT32 *) -sw.SwDigitalIn=fread(fh, 1, 'int16=>int16');% = 112; (* SET16 *) -sw.SwSweepKind=fread(fh, 1, 'int16=>int16');% = 114; (* SET16 *) -sw.SwDigitalOut=fread(fh,1, 'int16=>int16'); % = 116; (* SET16 *) -sw.SwFiller1=fread(fh, 1, 'int16=>int16');% = 118; (* INT32 *) -sw.SwMarkers=fread(fh, 4, 'double=>double');% = 120; (* ARRAY[0..3] OF LONGREAL, see SwMarkersNo *) -sw.SwFiller2=fread(fh, 1, 'int32=>int32');% = 152; (* INT32 *) -sw.SwCRC=fread(fh, 1, 'int32=>int32');% = 156; (* CARD32 *) -sw.SwSwHolding=fread(fh,16,'double=>double'); % = 160; (* ARRAY[0..15] OF LONGREAL, see SwHoldingNo *) -sw.SwSwUserParamEx=fread(fh,8,'double=>double'); % = 288; (* ARRAY[0..7] OF LONGREAL *) -sw.SweepRecSize = 352;% -sw=orderfields(sw); -sw.Traces = []; % used to store all the traces/channels within the sweep structure later on -end - -%-------------------------------------------------------------------------- -function tr=getTrace(fh,obj) -%-------------------------------------------------------------------------- -tr.TrMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) -tr.TrLabel=deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Type *) -tr.TrTraceCount=fread(fh, 1, 'int32=>int32');% = 36; (* INT32 *) -tr.TrData=fread(fh, 1, 'int32=>int32');% = 40; (* INT32 *) -tr.TrDataPoints=fread(fh, 1, 'int32=>int32');% = 44; (* INT32 *) -tr.TrInternalSolution=fread(fh, 1, 'int32=>int32');% = 48; (* INT32 *) -tr.TrAverageCount=fread(fh, 1, 'int32=>int32');% = 52; (* INT32 *) -tr.TrLeakCount=fread(fh, 1, 'int32=>int32');% = 56; (* INT32 *) -tr.TrLeakTraces=fread(fh, 1, 'int32=>int32');% = 60; (* INT32 *) -tr.TrDataKind=fread(fh, 1, 'uint16=>uint16');% = 64; (* SET16 *) NB Stored unsigned -tr.TrFiller1=fread(fh, 1, 'int16=>int16');% = 66; (* SET16 *) -tr.TrRecordingMode=fread(fh, 1, 'uint8=>uint8');% = 68; (* BYTE *) -tr.TrAmplIndex=fread(fh, 1, 'uint8=>uint8');% = 69; (* CHAR *) -tr.TrDataFormat=fread(fh, 1, 'uint8=>uint8');% = 70; (* BYTE *) -tr.TrDataAbscissa=fread(fh, 1, 'uint8=>uint8');% = 71; (* BYTE *) -tr.TrDataScaler=fread(fh, 1, 'double=>double');% = 72; (* LONGREAL *) -tr.TrTimeOffset=fread(fh, 1, 'double=>double');% = 80; (* LONGREAL *) -tr.TrZeroData=fread(fh, 1, 'double=>double');% = 88; (* LONGREAL *) -tr.TrYUnit=deblank(fread(fh, 8, 'uint8=>char')');% = 96; (* String8Type *) -tr.TrXInterval=fread(fh, 1, 'double=>double');% = 104; (* LONGREAL *) -tr.TrXStart=fread(fh, 1, 'double=>double');% = 112; (* LONGREAL *) -% 17.04.10 TrXUnit bytes may include some trailing characters after NULL -% byte -tr.TrXUnit=deblank(fread(fh, 8, 'uint8=>char')');% = 120; (* String8Type *) -tr.TrYRange=fread(fh, 1, 'double=>double');% = 128; (* LONGREAL *) -tr.TrYOffset=fread(fh, 1, 'double=>double');% = 136; (* LONGREAL *) -tr.TrBandwidth=fread(fh, 1, 'double=>double');% = 144; (* LONGREAL *) -tr.TrPipetteResistance=fread(fh, 1, 'double=>double');% = 152; (* LONGREAL *) -tr.TrCellPotential=fread(fh, 1, 'double=>double');% = 160; (* LONGREAL *) -tr.TrSealResistance=fread(fh, 1, 'double=>double');% = 168; (* LONGREAL *) -tr.TrCSlow=fread(fh, 1, 'double=>double');% = 176; (* LONGREAL *) -tr.TrGSeries=fread(fh, 1, 'double=>double');% = 184; (* LONGREAL *) -tr.TrRsValue=fread(fh, 1, 'double=>double');% = 192; (* LONGREAL *) -tr.TrGLeak=fread(fh, 1, 'double=>double');% = 200; (* LONGREAL *) -tr.TrMConductance=fread(fh, 1, 'double=>double');% = 208; (* LONGREAL *) -tr.TrLinkDAChannel=fread(fh, 1, 'int32=>int32');% = 216; (* INT32 *) -tr.TrValidYrange=fread(fh, 1, 'uint8=>logical');% = 220; (* BOOLEAN *) -tr.TrAdcMode=fread(fh, 1, 'uint8=>uint8');% = 221; (* CHAR *) -tr.TrAdcChannel=fread(fh, 1, 'int16=>int16');% = 222; (* INT16 *) -tr.TrYmin=fread(fh, 1, 'double=>double');% = 224; (* LONGREAL *) -tr.TrYmax=fread(fh, 1, 'double=>double');% = 232; (* LONGREAL *) -tr.TrSourceChannel=fread(fh, 1, 'int32=>int32');% = 240; (* INT32 *) -tr.TrExternalSolution=fread(fh, 1, 'int32=>int32');% = 244; (* INT32 *) -tr.TrCM=fread(fh, 1, 'double=>double');% = 248; (* LONGREAL *) -tr.TrGM=fread(fh, 1, 'double=>double');% = 256; (* LONGREAL *) -tr.TrPhase=fread(fh, 1, 'double=>double');% = 264; (* LONGREAL *) -tr.TrDataCRC=fread(fh, 1, 'int32=>int32');% = 272; (* CARD32 *) -tr.TrCRC=fread(fh, 1, 'int32=>int32');% = 276; (* CARD32 *) -tr.TrGS=fread(fh, 1, 'double=>double');% = 280; (* LONGREAL *) -tr.TrSelfChannel=fread(fh, 1, 'int32=>int32');% = 288; (* INT32 *) - -% Added 15.08.2012 -tr.TrInterleaveSize=fread(fh, 1, 'int32=>int32');% = 292; (* INT32 *) -tr.TrInterleaveSkip=fread(fh, 1, 'int32=>int32');% = 296; (* INT32 *) -tr.TrImageIndex=fread(fh, 1, 'int32=>int32');% = 300; (* INT32 *) -tr.TrMarkers=fread(fh, 10, 'double=>double');% = 304; (* ARRAY[0..9] OF LONGREAL *) -tr.TrSECM_X=fread(fh, 1, 'double=>double');% = 384; (* LONGREAL *) -tr.TrSECM_Y=fread(fh, 1, 'double=>double');% = 392; (* LONGREAL *) -tr.TrSECM_Z=fread(fh, 1, 'double=>double');% = 400; (* LONGREAL *) -tr.TrTrHolding = fread(fh, 1, 'double=>double');% = 408; (* LONGREAL *) -tr.TrTcEnumerator = fread(fh, 1, 'int32=>int32');% = 416; (* INT32 *) -tr.TrXTrace = fread(fh, 1, 'int32=>int32');% = 420; (* INT32 *) -tr.TrIntSolValue = fread(fh, 1, 'double=>double');% = 424; (* LONGREAL *) -tr.TrExtSolValue = fread(fh, 1, 'double=>double');% = 432; (* LONGREAL *) -tr.TrIntSolName = deblank(fread(fh, 32, 'uint8=>char')');% = 440; (* String32Size *) -tr.TrExtSolName = deblank(fread(fh, 32, 'uint8=>char')');% = 472; (* String32Size *) -tr.TrDataPedestal = fread(fh, 1, 'double=>double');% = 504; (* LONGREAL *) - -tr.TraceRecSize=512; %(* = 64 * 8 *) - -tr=orderfields(tr); - -end -function L=getSeLockInParams(fh) -%-------------------------------------------------------------------------- -offset=ftell(fh); -L.loExtCalPhase = fread(fh, 1, 'double=>double');% = 0; (* LONGREAL *) -L.loExtCalAtten = fread(fh, 1, 'double=>double');% = 8; (* LONGREAL *) -L.loPLPhase = fread(fh, 1, 'double=>double');% = 16; (* LONGREAL *) -L.loPLPhaseY1 = fread(fh, 1, 'double=>double');% = 24; (* LONGREAL *) -L.loPLPhaseY2 = fread(fh, 1, 'double=>double');% = 32; (* LONGREAL *) -L.loUsedPhaseShift = fread(fh, 1, 'double=>double');% = 40; (* LONGREAL *) -L.loUsedAttenuation = fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) - L.loSpare = fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) -L.loExtCalValid = fread(fh, 1, 'uint8=>logical');% = 64; (* BOOLEAN *) -L.loPLPhaseValid = fread(fh, 1, 'uint8=>logical');% = 65; (* BOOLEAN *) -L.loLockInMode = fread(fh, 1, 'uint8=>uint8');% = 66; (* BYTE *) -L.loCalMode = fread(fh, 1, 'uint8=>uint8');% = 67; (* BYTE *) - L.loSpare2 = fread(fh, 7, 'int32=>in32');% = 68; (* remaining *) -L.LockInParamsSize = 96; - -fseek(fh, offset+L.LockInParamsSize, 'bof'); - -end - -%-------------------------------------------------------------------------- -function A=getAmplifierState(fh) -%-------------------------------------------------------------------------- -offset=ftell(fh); -A.sStateVersion = fread(fh, 1, 'double=>double');% = 0; (* 8 = SizeStateVersion *) -A.sCurrentGain = fread(fh, 1, 'double=>double');% = 8; (* LONGREAL *) -A.sF2Bandwidth = fread(fh, 1, 'double=>double');% = 16; (* LONGREAL *) -A.sF2Frequency = fread(fh, 1, 'double=>double');% = 24; (* LONGREAL *) -A.sRsValue = fread(fh, 1, 'double=>double');% = 32; (* LONGREAL *) -A.sRsFraction = fread(fh, 1, 'double=>double');% = 40; (* LONGREAL *) -A.sGLeak = fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) -A.sCFastAmp1 = fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) -A.sCFastAmp2 = fread(fh, 1, 'double=>double');% = 64; (* LONGREAL *) -A.sCFastTau = fread(fh, 1, 'double=>double');% = 72; (* LONGREAL *) -A.sCSlow = fread(fh, 1, 'double=>double');% = 80; (* LONGREAL *) -A.sGSeries = fread(fh, 1, 'double=>double');% = 88; (* LONGREAL *) -A.sVCStimDacScale = fread(fh, 1, 'double=>double');% = 96; (* LONGREAL *) -A.sCCStimScale = fread(fh, 1, 'double=>double');% = 104; (* LONGREAL *) -A.sVHold = fread(fh, 1, 'double=>double');% = 112; (* LONGREAL *) -A.sLastVHold = fread(fh, 1, 'double=>double');% = 120; (* LONGREAL *) -A.sVpOffset = fread(fh, 1, 'double=>double');% = 128; (* LONGREAL *) -A.sVLiquidJunction = fread(fh, 1, 'double=>double');% = 136; (* LONGREAL *) -A.sCCIHold = fread(fh, 1, 'double=>double');% = 144; (* LONGREAL *) -A.sCSlowStimVolts = fread(fh, 1, 'double=>double');% = 152; (* LONGREAL *) -A.sCCTrackVHold = fread(fh, 1, 'double=>double');% = 160; (* LONGREAL *) -A.sTimeoutCSlow = fread(fh, 1, 'double=>double');% = 168; (* LONGREAL *) -A.sSearchDelay = fread(fh, 1, 'double=>double');% = 176; (* LONGREAL *) -A.sMConductance = fread(fh, 1, 'double=>double');% = 184; (* LONGREAL *) -A.sMCapacitance = fread(fh, 1, 'double=>double');% = 192; (* LONGREAL *) -A.sSerialNumber = fread(fh, 1, 'double=>double');% = 200; (* 8 = SizeSerialNumber *) - -A.sE9Boards = fread(fh, 1, 'int16=>int16');% = 208; (* INT16 *) -A.sCSlowCycles = fread(fh, 1, 'int16=>int16');% = 210; (* INT16 *) -A.sIMonAdc = fread(fh, 1, 'int16=>int16');% = 212; (* INT16 *) -A.sVMonAdc = fread(fh, 1, 'int16=>int16');% = 214; (* INT16 *) - -A.sMuxAdc = fread(fh, 1, 'int16=>int16');% = 216; (* INT16 *) -A.sTestDac = fread(fh, 1, 'int16=>int16');% = 218; (* INT16 *) -A.sStimDac = fread(fh, 1, 'int16=>int16');% = 220; (* INT16 *) -A.sStimDacOffset = fread(fh, 1, 'int16=>int16');% = 222; (* INT16 *) - -A.sMaxDigitalBit = fread(fh, 1, 'int16=>int16');% = 224; (* INT16 *) -A.sHasCFastHigh = fread(fh, 1, 'uint8=>uint8');% = 226; (* BYTE *) -A.sCFastHigh = fread(fh, 1, 'uint8=>uint8');% = 227; (* BYTE *) -A.sHasBathSense = fread(fh, 1, 'uint8=>uint8');% = 228; (* BYTE *) -A.sBathSense = fread(fh, 1, 'uint8=>uint8');% = 229; (* BYTE *) -A.sHasF2Bypass = fread(fh, 1, 'uint8=>uint8');% = 230; (* BYTE *) -A.sF2Mode = fread(fh, 1, 'uint8=>uint8');% = 231; (* BYTE *) - -A.sAmplKind = fread(fh, 1, 'uint8=>uint8');% = 232; (* BYTE *) -A.sIsEpc9N = fread(fh, 1, 'uint8=>uint8');% = 233; (* BYTE *) -A.sADBoard = fread(fh, 1, 'uint8=>uint8');% = 234; (* BYTE *) -A.sBoardVersion = fread(fh, 1, 'uint8=>uint8');% = 235; (* BYTE *) -A.sActiveE9Board = fread(fh, 1, 'uint8=>uint8');% = 236; (* BYTE *) -A.sMode = fread(fh, 1, 'uint8=>uint8');% = 237; (* BYTE *) -A.sRange = fread(fh, 1, 'uint8=>uint8');% = 238; (* BYTE *) -A.sF2Response = fread(fh, 1, 'uint8=>uint8');% = 239; (* BYTE *) - -A.sRsOn = fread(fh, 1, 'uint8=>uint8');% = 240; (* BYTE *) -A.sCSlowRange = fread(fh, 1, 'uint8=>uint8');% = 241; (* BYTE *) -A.sCCRange = fread(fh, 1, 'uint8=>uint8');% = 242; (* BYTE *) -A.sCCGain = fread(fh, 1, 'uint8=>uint8');% = 243; (* BYTE *) -A.sCSlowToTestDac = fread(fh, 1, 'uint8=>uint8');% = 244; (* BYTE *) -A.sStimPath = fread(fh, 1, 'uint8=>uint8');% = 245; (* BYTE *) -A.sCCTrackTau = fread(fh, 1, 'uint8=>uint8');% = 246; (* BYTE *) -A.sWasClipping = fread(fh, 1, 'uint8=>uint8');% = 247; (* BYTE *) - -A.sRepetitiveCSlow = fread(fh, 1, 'uint8=>uint8');% = 248; (* BYTE *) -A.sLastCSlowRange = fread(fh, 1, 'uint8=>uint8');% = 249; (* BYTE *) - A.sOld1 = fread(fh, 1, 'uint8=>uint8');% = 250; (* BYTE *) -A.sCanCCFast = fread(fh, 1, 'uint8=>uint8');% = 251; (* BYTE *) -A.sCanLowCCRange = fread(fh, 1, 'uint8=>uint8');% = 252; (* BYTE *) -A.sCanHighCCRange = fread(fh, 1, 'uint8=>uint8');% = 253; (* BYTE *) -A.sCanCCTrackingg = fread(fh, 1, 'uint8=>uint8');% = 254; (* BYTE *) -A.sCHasVmonPath = fread(fh, 1, 'uint8=>uint8');% = 255; (* BYTE *) - -A.sHasNewCCMode = fread(fh, 1, 'uint8=>uint8');% = 256; (* BYTE *) -A.sSelector = fread(fh, 1, 'uint8=>char');% = 257; (* CHAR *) -A.sHoldInverted = fread(fh, 1, 'uint8=>uint8');% = 258; (* BYTE *) -A.sAutoCFast = fread(fh, 1, 'uint8=>uint8');% = 259; (* BYTE *) -A.sAutoCSlow = fread(fh, 1, 'uint8=>uint8');% = 260; (* BYTE *) -A.sHasVmonX100 = fread(fh, 1, 'uint8=>uint8');% = 261; (* BYTE *) -A.sTestDacOn = fread(fh, 1, 'uint8=>uint8');% = 262; (* BYTE *) -A.sQMuxAdcOn = fread(fh, 1, 'uint8=>uint8');% = 263; (* BYTE *) - -A.sImon1Bandwidth = fread(fh, 1, 'double=>double');% = 264; (* LONGREAL *) -A.sStimScale = fread(fh, 1, 'double=>double');% = 272; (* LONGREAL *) - -A.sGain = fread(fh, 1, 'uint8=>uint8');% = 280; (* BYTE *) -A.sFilter1 = fread(fh, 1, 'uint8=>uint8');% = 281; (* BYTE *) -A.sStimFilterOn = fread(fh, 1, 'uint8=>uint8');% = 282; (* BYTE *) -A.sRsSlow = fread(fh, 1, 'uint8=>uint8');% = 283; (* BYTE *) - A.sOld2 = fread(fh, 1, 'uint8=>uint8');% = 284; (* BYTE *) -A.sCCCFastOn = fread(fh, 1, 'uint8=>uint8');% = 285; (* BYTE *) -A.sCCFastSpeed = fread(fh, 1, 'uint8=>uint8');% = 286; (* BYTE *) -A.sF2Source = fread(fh, 1, 'uint8=>uint8');% = 287; (* BYTE *) - -A.sTestRange = fread(fh, 1, 'uint8=>uint8');% = 288; (* BYTE *) -A.sTestDacPath = fread(fh, 1, 'uint8=>uint8');% = 289; (* BYTE *) -A.sMuxChannel = fread(fh, 1, 'uint8=>uint8');% = 290; (* BYTE *) -A.sMuxGain64 = fread(fh, 1, 'uint8=>uint8');% = 291; (* BYTE *) -A.sVmonX100 = fread(fh, 1, 'uint8=>uint8');% = 292; (* BYTE *) -A.sIsQuadro = fread(fh, 1, 'uint8=>uint8');% = 293; (* BYTE *) -A.sF1Mode = fread(fh, 1, 'uint8=>uint8');% = 294; (* BYTE *) - A.sOld3 = fread(fh, 1, 'uint8=>uint8');% = 295; (* BYTE *) - -A.sStimFilterHz = fread(fh, 1, 'double=>double');% = 296; (* LONGREAL *) -A.sRsTau = fread(fh, 1, 'double=>double');% = 304; (* LONGREAL *) -A.sDacToAdcDelay = fread(fh, 1, 'double=>double');% = 312; (* LONGREAL *) -A.sInputFilterTau = fread(fh, 1, 'double=>double');% = 320; (* LONGREAL *) -A.sOutputFilterTau = fread(fh, 1, 'double=>double');% = 328; (* LONGREAL *) -A.sVmonFactor = fread(fh, 1, 'double=>double');% = 336; (* LONGREAL *) -A.sCalibDate = fread(fh, 2, 'double=>double');% = 344; (* 16 = SizeCalibDate *) -A.sVmonOffset = fread(fh, 1, 'double=>double');% = 360; (* LONGREAL *) - -A.sEEPROMKind = fread(fh, 1, 'uint8=>uint8');% = 368; (* BYTE *) -A.sVrefX2 = fread(fh, 1, 'uint8=>uint8');% = 369; (* BYTE *) -A.sHasVrefX2AndF2Vmon = fread(fh, 1, 'uint8=>uint8');% = 370; (* BYTE *) -A.sSpare1 = fread(fh, 1, 'uint8=>uint8');% = 371; (* BYTE *) -A.sSpare2 = fread(fh, 1, 'uint8=>uint8');% = 372; (* BYTE *) -A.sSpare3 = fread(fh, 1, 'uint8=>uint8');% = 373; (* BYTE *) -A.sSpare4 = fread(fh, 1, 'uint8=>uint8');% = 374; (* BYTE *) -A.sSpare5 = fread(fh, 1, 'uint8=>uint8');% = 375; (* BYTE *) - -A.sCCStimDacScale = fread(fh, 1, 'double=>double');% = 376; (* LONGREAL *) -A.sVmonFiltBandwidth = fread(fh, 1, 'double=>double');% = 384; (* LONGREAL *) -A.sVmonFiltFrequency = fread(fh, 1, 'double=>double');% = 392; (* LONGREAL *) -A.AmplifierStateSize = 400;% (* = 50 * 8 *) - -fseek(fh, offset+A.AmplifierStateSize, 'bof'); - -end \ No newline at end of file diff --git a/@HEKA_Importer/readPulseFileHEKA.m b/@HEKA_Importer/readPulseFileHEKA.m index 435b7e4..c261c67 100644 --- a/@HEKA_Importer/readPulseFileHEKA.m +++ b/@HEKA_Importer/readPulseFileHEKA.m @@ -1,14 +1,13 @@ -function readPulseFileHEKA(obj) +function readPulseFileHEKA(obj,Level) %-------------------------------------------------------------------------- % Gets one record of the tree and the number of children +s = getOneRecord(obj,Level); +obj.fileData.Tree{obj.fileData.Counter, Level+1} = s; -s = getOneRecord(obj); -obj.fileData.Tree{obj.fileData.Counter, obj.fileData.Level+1} = s; - -obj.fileData.Position = obj.fileData.Position+obj.fileData.Sizes(obj.fileData.Level+1); +obj.fileData.Position = obj.fileData.Position+obj.fileData.Sizes(Level+1); fseek(obj.fileData.fh, obj.fileData.Position, 'bof'); obj.fileData.nchild=fread(obj.fileData.fh, 1, 'int32=>int32'); obj.fileData.Position=ftell(obj.fileData.fh); @@ -16,13 +15,13 @@ function readPulseFileHEKA(obj) end %-------------------------------------------------------------------------- -function rec=getOneRecord(obj) +function rec=getOneRecord(obj,Level) %-------------------------------------------------------------------------- % Gets one record % Counter=Counter+1; obj.fileData.Counter = obj.fileData.Counter+1; -switch obj.fileData.Level +switch Level case 0 rec=getRoot(obj); case 1 diff --git a/@HEKA_Importer/readSolutionFileHEKA.m b/@HEKA_Importer/readSolutionFileHEKA.m index 26880a4..547a737 100644 --- a/@HEKA_Importer/readSolutionFileHEKA.m +++ b/@HEKA_Importer/readSolutionFileHEKA.m @@ -1,10 +1,10 @@ -function readSolutionFileHEKA(obj) +function readSolutionFileHEKA(obj,Level) %-------------------------------------------------------------------------- % Gets one record of the tree and the number of children s = getOneSolutionRecord(obj); -obj.fileData.Tree{obj.fileData.Counter, obj.fileData.Level+1} = s; +obj.fileData.Tree{obj.fileData.Counter, Level+1} = s; -obj.fileData.Position = obj.fileData.Position+obj.fileData.Sizes(obj.fileData.Level+1); +obj.fileData.Position = obj.fileData.Position+obj.fileData.Sizes(Level+1); fseek(obj.fileData.fh, obj.fileData.Position, 'bof'); obj.fileData.nchild=fread(obj.fileData.fh, 1, 'int32=>int32'); obj.fileData.Position=ftell(obj.fileData.fh); @@ -13,7 +13,7 @@ function readSolutionFileHEKA(obj) %-------------------------------------------------------------------------- -function rec=getOneSolutionRecord(obj) +function rec=getOneSolutionRecord(obj,Level) %-------------------------------------------------------------------------- % Gets one record obj.fileData.Counter = obj.fileData.Counter+1; diff --git a/@HEKA_Importer/readStimulusFileHEKA.m b/@HEKA_Importer/readStimulusFileHEKA.m index e7e345b..e6fee26 100644 --- a/@HEKA_Importer/readStimulusFileHEKA.m +++ b/@HEKA_Importer/readStimulusFileHEKA.m @@ -1,9 +1,9 @@ -function readStimulusFileHEKA(obj) +function readStimulusFileHEKA(obj,Level) %-------------------------------------------------------------------------- % Gets one record of the tree and the number of children -s = getOneStimRecord(obj); -obj.fileData.Tree{obj.fileData.Counter, obj.fileData.Level+1} = s; -obj.fileData.Position = obj.fileData.Position+obj.fileData.Sizes(obj.fileData.Level+1); +s = getOneStimRecord(obj,Level); +obj.fileData.Tree{obj.fileData.Counter, Level+1} = s; +obj.fileData.Position = obj.fileData.Position+obj.fileData.Sizes(Level+1); fseek(obj.fileData.fh, obj.fileData.Position, 'bof'); obj.fileData.nchild=fread(obj.fileData.fh, 1, 'int32=>int32'); obj.fileData.Position=ftell(obj.fileData.fh); @@ -11,11 +11,11 @@ function readStimulusFileHEKA(obj) %-------------------------------------------------------------------------- -function rec=getOneStimRecord(obj) +function rec=getOneStimRecord(obj,Level) %-------------------------------------------------------------------------- % Gets one record obj.fileData.Counter = obj.fileData.Counter+1; -switch obj.fileData.Level +switch Level case 0 rec=getStimRoot(obj); case 1 From 08fe2e02fd0122dd1b293c01ede39ec9b2e66cc3 Mon Sep 17 00:00:00 2001 From: ChristianKeine Date: Mon, 24 Jun 2019 09:04:20 -0500 Subject: [PATCH 17/39] updating import --- @HEKA_Importer/HI_ImportHEKAtoMat.asv | 480 ----------------------- @HEKA_Importer/HI_ImportHEKAtoMat.m | 2 +- @HEKA_Importer/readAmplifierFileHEKA.asv | 245 ------------ @HEKA_Importer/readPulseFileHEKA.asv | 466 ++++++++++++++++++++++ @HEKA_Importer/readPulseFileHEKA.m | 149 ++++--- 5 files changed, 551 insertions(+), 791 deletions(-) delete mode 100644 @HEKA_Importer/HI_ImportHEKAtoMat.asv delete mode 100644 @HEKA_Importer/readAmplifierFileHEKA.asv create mode 100644 @HEKA_Importer/readPulseFileHEKA.asv diff --git a/@HEKA_Importer/HI_ImportHEKAtoMat.asv b/@HEKA_Importer/HI_ImportHEKAtoMat.asv deleted file mode 100644 index 683a4ee..0000000 --- a/@HEKA_Importer/HI_ImportHEKAtoMat.asv +++ /dev/null @@ -1,480 +0,0 @@ -function obj=HI_ImportHEKAtoMat(obj) -% ImportHEKA imports HEKA PatchMaster and ChartMaster .DAT files -% Filepath is taken from the input object. -% -% ImportHEKA has been tested with Windows generated .DAT files on Windows, -% Linux and Mac OS10.4. -% -% Both bundled and unbundled data files are supported. If your files are -% unbundled, they must all be in the same folder. -% -% Details of the HEKA file format are available from -% ftp://server.hekahome.de/pub/FileFormat/Patchmasterv9/ -% -%-------------------------------------------------------------------------- -% Author: Malcolm Lidierth 12/09 -% Copyright © The Author & King's College London 2009- -%-------------------------------------------------------------------------- - -% Revisions -% 17.04.10 TrXUnit: see within -% 28.11.11 TrXUnit: see within -% 15.08.12 Updated to support interleaved channels and PatchMaster 2.60 -% files dated 24-Jan-2011 onwards. -% 19.05.13 Modified by Samata Katta to output Matlab variable containing data -% 12.08.15 Don't save *.kcl file (line 793 commented out). -% 03.07.17 Modified by Samata Katta to read in stimulus parameters from -% .pgf section of .dat file. -% 01.01.2019 Modified by Christian Keine to read solution parameters from -% .sol section of .dat file. -% 04.02.2019: combine readout of dataTree, stimTree and solTree. -% -% See also HEKA_Importer -% HEKA_Importer.HI_loadHEKAFile -% HEKA_Importer.HI_extractHEKASolutionTree -% HEKA_Importer.HI_extractHEKAStimTree -% HEKA_Importer.HI_extractHEKADataTree - - - -[pathname, filename, ext]=fileparts(obj.opt.filepath); - -% Open file and get bundle header. Assume little-endian to begin with -endian='ieee-le'; -fh=fopen(obj.opt.filepath, 'r', endian); -[bundle, littleendianflag, isBundled]=getBundleHeader(fh); - -% Big endian so repeat process -if ~isempty(littleendianflag) && littleendianflag==false - fclose(fh); - endian='ieee-be'; - fh=fopen(obj.opt.filepath, 'r', endian); - bundle=getBundleHeader(fh); -end - -%% GET DATA, STIM AND SOLUTION TREE - -fileExt = {'.pul','.pgf','.sol','.amp'}; -treeName = {'dataTree','stimTree','solTree','ampTree'}; - -for iidx = fileExt - fileExist = true; - if isBundled - % ext = {'.dat','.pul','.pgf','.amp','.sol',[],[],'.mrk','.mth','.onl'}; - ext={bundle.oBundleItems.oExtension}; - % Find the section of the dat file - idx=strcmp(iidx, ext);%15.08.2012 - change from strmatch - if any(idx) % check if section exists, e.g. will be empty when solution base was not active during recordings - start=bundle.oBundleItems(idx).oStart; - else - fileExist = false; - end - else - % Or open pulse file if not bundled - fclose(fh); - start=0; - fh=fopen(fullfile(pathname, [filename, iidx{1}]), 'r', endian); - if fh<0 - fileExist = false; - end - end - - % READ OUT TREE - if fileExist - fseek(fh, start, 'bof'); - Magic = fread(fh, 4, 'uint8=>char'); - Levels=fread(fh, 1, 'int32=>int32'); - Sizes=fread(fh, double(Levels), 'int32=>int32'); - Position=ftell(fh); - - % Get the tree structures form the file sections - obj.fileData.fh = fh; - obj.fileData.Sizes = Sizes; - obj.fileData.Position = Position; - obj.fileData.fileExt = iidx{1}; - - obj.trees.(treeName{strcmp(iidx, fileExt)})=getTree(fh, Sizes, Position, iidx{1},obj); - - else - obj.trees.(treeName{strcmp(iidx, fileExt)}) = []; - end -end - -%% GET DATA -if isBundled - % Set offset for data - idx=strcmp('.dat', ext);%15.08.2012 - change from strmatch - start=bundle.oBundleItems(idx).oStart; -else - % Or open data file if not bundled - fclose(fh); - fh=fopen(obj.opt.filepath, 'r', endian); - start=bundle.BundleHeaderSize; -end - -% Now set pointer to the start of the data the data -fseek(fh, start, 'bof'); - -% Get the group headers into a structure array -ngroup=1; -for k=1:size(obj.trees.dataTree,1) - if ~isempty(obj.trees.dataTree{k, 2}) - grp_row(ngroup)=k; %#ok - ngroup=ngroup+1; - end -end - -% ADD MINIMUM RANDOM NUMBER TO AVOID DISCRETIZATION; ADD TO ALL CHANNELS -addEPS = @(x) x+randn(size(x))*eps; - -% For each group -matData2 = cell(numel(grp_row),1); -dataRaw = cell(numel(grp_row),1); - -for iGr = 1:numel(grp_row) - matData2{iGr}=LocalImportGroup(fh, obj.trees.dataTree, iGr, grp_row); - - for iSer = 1:numel(matData2{iGr}) - dataRaw{iGr,:}{iSer,:} = cellfun(addEPS,matData2{iGr}{iSer},'UniformOutput',false); - end - -end - -obj.RecTable.dataRaw = vertcat(dataRaw{:}); -obj.RecTable = struct2table(obj.RecTable); -end - -%-------------------------------------------------------------------------- -function [h, littleendianflag, isBundled]=getBundleHeader(fh) -%-------------------------------------------------------------------------- -% Get the bundle header from a HEKA .dat file -fseek(fh, 0, 'bof'); -h.oSignature=deblank(fread(fh, 8, 'uint8=>char')'); -switch h.oSignature - case 'DATA' - % Old format: nothing to do - h.oVersion=[]; - h.oTime=[]; - h.oItems=[]; - h.oIsLittleEndian=[]; - h.oBundleItems(1:12)=[]; - h.BundleHeaderSize=0; - isBundled=false; - case {'DAT1' 'DAT2'} - % Newer format - h.oVersion = fread(fh, 32, 'uint8=>char')'; - h.oTime = fread(fh, 1, 'double'); - h.oItems = fread(fh, 1, 'int32=>int32'); - h.oIsLittleEndian = fread(fh, 1, 'uint8=>logical'); - h.BundleHeaderSize = 256; - switch h.oSignature - case 'DAT1' - h.oBundleItems=[]; - isBundled=false; - case {'DAT2'} - fseek(fh, 64, 'bof'); - for k=1:12 - h.oBundleItems(k).oStart = fread(fh, 1, 'int32=>int32'); - h.oBundleItems(k).oLength = fread(fh, 1, 'int32=>int32'); - h.oBundleItems(k).oExtension = deblank(fread(fh, 8, 'uint8=>char')'); - h.oBundleItems(k).BundleItemSize = 16; - end - isBundled=true; - end - otherwise - error('This legacy file format is not supported'); -end -littleendianflag=h.oIsLittleEndian; - -end - - -%-------------------------------------------------------------------------- -function Tree=getTree(fh, Sizes, Position, ext,obj) -%-------------------------------------------------------------------------- -% Main entry point for loading tree - -obj.fileData.Counter = 0; -obj.fileData.Tree = {}; -obj.fileData.Level = 0; - -Tree = getTreeReentrant(obj,0); -end - - -function Tree=getTreeReentrant(obj,Level) -%-------------------------------------------------------------------------- -% Recursive routine called from LoadTree - -switch obj.fileData.fileExt - case '.pul' - obj.readPulseFileHEKA(Level); - case '.pgf' - obj.readStimulusFileHEKA; - case '.sol' - obj.readSolutionFileHEKA; - case '.amp' - obj.readAmplifierFileHEKA; - -end - -for k=1:double(obj.fileData.nchild) - getTreeReentrant(obj,Level+1); -end - -Tree = obj.fileData.Tree; - -end - - - -%-------------------------------------------------------------------------- -function matData2=LocalImportGroup(fh, dataTree, grp, grp_row) -%-------------------------------------------------------------------------- -% Create a structure for the series headers - - -% Pad the indices for last series of last group -grp_row(end+1)=size(dataTree,1); - -% Collect the series headers and row numbers for this group into a -% structure array -[ser_s, ser_row, nseries]=getSeriesHeaders(dataTree, grp_row, grp); - -% Pad for last series -ser_row(nseries+1)=grp_row(grp+1); - -dataoffsets=[]; -% Create the channels - -matData2 = cell(nseries,1); -for ser=1:nseries - - [sw_s, sw_row, nsweeps]=getSweepHeaders(dataTree, ser_row, ser); - - % Make sure the sweeps are in temporal sequence - if any(diff(cell2mat({sw_s.SwTime}))<=0) - % TODO: sort them if this can ever happen. - % For the moment just throw an error - error('Sweeps not in temporal sequence'); - end - - - sw_row(nsweeps+1)=ser_row(ser+1); - % Get the trace headers for this sweep - [tr_row]=getTraceHeaders(dataTree, sw_row); - - - for k=1:size(tr_row, 1) - - [tr_s, isConstantScaling, isConstantFormat, isFramed]=LocalCheckEntries(dataTree, tr_row, k); - - % TODO: Need a better way to do this - % Check whether interleaving is supported with this file version - % Note: HEKA added interleaving Jan 2011. - % TrInterleaveSkip was previously in a filler block, so should always - % be zero with older files. - if tr_s(1).TrInterleaveSize>0 && tr_s(1).TrInterleaveSkip>0 - INTERLEAVE_SUPPORTED=true; - else - INTERLEAVE_SUPPORTED=false; - end - - data=zeros(max(cell2mat({tr_s.TrDataPoints})), size(tr_row,2)); - - for tr=1:size(tr_row,2) - % Disc format - [fmt, nbytes]=LocalFormatToString(tr_s(tr).TrDataFormat); - % Always read into double - readfmt=[fmt '=>double']; - % Skip to start of the data - fseek(fh, dataTree{tr_row(k,tr),5}.TrData, 'bof'); - % Store data offset for later error checks - dataoffsets(end+1)=dataTree{tr_row(k,tr),5}.TrData; %#ok - % Read the data - if ~INTERLEAVE_SUPPORTED || dataTree{tr_row(k,tr),5}.TrInterleaveSize==0 - [data(1:dataTree{tr_row(k,tr),5}.TrDataPoints, tr)]=... - fread(fh, double(dataTree{tr_row(k,tr),5}.TrDataPoints), readfmt); - else - offset=1; - nelements= double(dataTree{tr_row(k,tr),5}.TrInterleaveSize/nbytes); - for nread=1:floor(numel(data)/double(dataTree{tr_row(k,tr),5}.TrInterleaveSize/nbytes)) - [data(offset:offset+nelements-1), N]=fread(fh, nelements, readfmt); - if (N - ser_row(nseries+1)=k; %#ok - nseries=nseries+1; - end -end -return -end - -%-------------------------------------------------------------------------- -function [sw_s, sw_row, nsweeps]=getSweepHeaders(tree, ser_row, ser) -%-------------------------------------------------------------------------- -nsweeps=0; -for k=ser_row(ser)+1:ser_row(ser+1) - if ~isempty(tree{k, 4}) - sw_s(nsweeps+1)=tree{k, 4}; %#ok - sw_row(nsweeps+1)=k; %#ok - nsweeps=nsweeps+1; - end -end -return -end - -%-------------------------------------------------------------------------- -function [tr_row, ntrace]=getTraceHeaders(tree, sw_row) -%-------------------------------------------------------------------------- -ntrace=0; -m=1; -n=1; -for k=sw_row(1)+1:sw_row(end) - if ~isempty(tree{k, 5}) - %tr_s(m,n)=tree{k, 5}; %#ok - tr_row(m,n)=k; %#ok - ntrace=ntrace+1; - m=m+1; - else - m=1; - n=n+1; - end -end -return -end - - -%-------------------------------------------------------------------------- -function [tr_s, isConstantScaling, isConstantFormat, isFramed]=LocalCheckEntries(tree, tr_row, k) -%-------------------------------------------------------------------------- -% Check units are the same for all traces -tr_s=[tree{tr_row(k, :),5}]; - - -if numel(unique({tr_s.TrYUnit}))>1 - error('1002: Waveform units are not constant'); -end - -if numel(unique({tr_s.TrXUnit}))>1 - error('1003: Time units are not constant'); -end - -if numel(unique(cell2mat({tr_s.TrXInterval})))~=1 - error('1004: Unequal sample intervals'); -end - -% Other unexpected conditions - give user freedom to create these but warn -% about them -if numel(unique({tr_s.TrLabel}))>1 - warning('LocalCheckEntries:w2001', 'Different trace labels'); -end - -if numel(unique(cell2mat({tr_s.TrAdcChannel})))>1 - warning('LocalCheckEntries:w2002', 'Data collected from different ADC channels'); -end - -if numel(unique(cell2mat({tr_s.TrRecordingMode})))>1 - warning('LocalCheckEntries:w2003', 'Traces collected using different recording modes'); -end - -if numel(unique(cell2mat({tr_s.TrCellPotential})))>1 - warning('LocalCheckEntries:w2004', 'Traces collected using different Em'); -end - -% Check scaling factor is constant -ScaleFactor=unique(cell2mat({tr_s.TrDataScaler})); -if numel(ScaleFactor)==1 - isConstantScaling=true; -else - isConstantScaling=false; -end - - -%... and data format -if numel(unique(cell2mat({tr_s.TrDataFormat})))==1 - isConstantFormat=true; -else - isConstantFormat=false; -end - -% Do we have constant epoch lengths and offsets? -if numel(unique(cell2mat({tr_s.TrDataPoints})))==1 &&... - numel(unique(cell2mat({tr_s.TrTimeOffset })))==1 - isFramed=true; -else - isFramed=false; -end -return -end - diff --git a/@HEKA_Importer/HI_ImportHEKAtoMat.m b/@HEKA_Importer/HI_ImportHEKAtoMat.m index a1f9329..3aca0fb 100644 --- a/@HEKA_Importer/HI_ImportHEKAtoMat.m +++ b/@HEKA_Importer/HI_ImportHEKAtoMat.m @@ -162,7 +162,7 @@ isBundled=false; case {'DAT1' 'DAT2'} % Newer format - h.oVersion = fread(fh, 32, 'uint8=>char')'; + h.oVersion = fread(fh, 32,'uint8=>char')'; h.oTime = fread(fh, 1, 'double'); h.oItems = fread(fh, 1, 'int32=>int32'); h.oIsLittleEndian = fread(fh, 1, 'uint8=>logical'); diff --git a/@HEKA_Importer/readAmplifierFileHEKA.asv b/@HEKA_Importer/readAmplifierFileHEKA.asv deleted file mode 100644 index 04ee255..0000000 --- a/@HEKA_Importer/readAmplifierFileHEKA.asv +++ /dev/null @@ -1,245 +0,0 @@ -function readAmplifierFileHEKA(obj,Level) -%-------------------------------------------------------------------------- -% Gets one record of the tree and the number of children - -s = getOneAmplifierRecord(obj,Level); -obj.fileData.Tree{obj.fileData.Counter, Level+1} = s; - -obj.fileData.Position = obj.fileData.Position+obj.fileData.Sizes(Level+1); -fseek(obj.fileData.fh, obj.fileData.Position, 'bof'); -obj.fileData.nchild=fread(obj.fileData.fh, 1, 'int32=>int32'); -obj.fileData.Position=ftell(obj.fileData.fh); - -end - -%-------------------------------------------------------------------------- -function rec=getOneAmplifierRecord(obj,Level) -%-------------------------------------------------------------------------- -% Gets one record -obj.fileData.Counter = obj.fileData.Counter+1; -switch Level - case 0 - rec=getAmplifierRootRecord(obj); - case 1 - rec=getAmplifierSeriesRecord(obj); - case 2 - rec=getAmplifierStateRecord(obj); - otherwise - error('Unexpected Level'); -end - -end - -%-------------------------------------------------------------------------- -function p=getAmplifierRootRecord(obj) -%-------------------------------------------------------------------------- -fh = obj.fileData.fh; - -p.RoVersion = fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) -p.RoMark = fread(fh, 1, 'int32=>int32');% = 4; (* INT32 *) -p.RoVersionName = deblank(fread(fh, 32, 'uint8=>char')');% = 8; (* String32Type *) -p.RoAmplifierName = deblank(fread(fh, 32, 'uint8=>char')');% = 40; (* String32Type *) -p.RoAmplifier = fread(fh,1,'uint8=>uint8');% = 72; (* CHAR *) -p.RoADBoard = fread(fh,1,'uint8=>uint8');% = 73; (* CHAR *) -p.RoCreator = fread(fh,1,'uint8=>uint8');% = 74; (* CHAR *) - p.RoFiller1 = fread(fh, 1, 'uint8=>uint8');% = 75; (* BYTE *) -p.RoCRC = fread(fh, 1, 'int32=>int32');% = 76; (* CARD32 *) -p.RootRecSize = 80;% (* = 10 * 8 *) - -p=orderfields(p); - -end - -%-------------------------------------------------------------------------- -function s=getAmplifierSeriesRecord(obj) -%-------------------------------------------------------------------------- -fh = obj.fileData.fh; - -s.SeMark = fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) -s.SeSeriesCount = fread(fh, 1, 'int32=>int32');% = 4; (* INT32 *) -s.SeFiller1 = fread(fh, 1, 'int32=>int32');% = 8; (* INT32 *) -s.SeCRC = fread(fh, 1, 'int32=>int32');% = 12; (* CARD32 *) -s.SeriesRecSize = 16;% (* = 2 * 8 *) - -s=orderfields(s); - -end - -%-------------------------------------------------------------------------- -function a=getAmplifierStateRecord(obj) -%-------------------------------------------------------------------------- -fh = obj.fileData.fh; - -a.AmMark = fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) -a.AmStateCount = fread(fh, 1, 'int32=>int32');% = 4; (* INT32 *) -a.AmStateVersion = fread(fh,1,'uint8=>uint8');% = 8; (* CHAR *) - a.AmFiller1 = fread(fh, 1, 'uint8=>uint8');% = 9; (* BYTE *) - a.AmFiller2 = fread(fh, 1, 'uint8=>uint8');% = 10; (* BYTE *) - a.AmFiller3 = fread(fh, 1, 'uint8=>uint8');% = 11; (* BYTE *) - a.AmFiller4 = fread(fh, 1, 'int32=>int32');% = 12; (* INT32 *) -a.AmLockInParams = getSeLockInParams(fh);% = 16; (* LockInParamsSize = 96 *) -a.AmAmplifierState = getAmplifierState(fh);% = 112; (* AmplifierStateSize = 400 *) -a.AmIntSol = fread(fh, 1, 'int32=>int32');% = 512; (* INT32 *) -a.AmExtSol = fread(fh, 1, 'int32=>int32');% = 516; (* INT32 *) - a.AmFiller5 = fread(fh, 36, 'uint8=>uint8');% = 520; (* spares: 36 bytes *) -a.AmCRC = fread(fh, 1, 'int32=>int32');% = 556; (* CARD32 *) -a.StateRecSize = 560;% (* = 70 * 8 *) - -a = orderfields(a); - -end - -function L=getSeLockInParams(fh) -%-------------------------------------------------------------------------- -offset=ftell(fh); -L.loExtCalPhase = fread(fh, 1, 'double=>double');% = 0; (* LONGREAL *) -L.loExtCalAtten = fread(fh, 1, 'double=>double');% = 8; (* LONGREAL *) -L.loPLPhase = fread(fh, 1, 'double=>double');% = 16; (* LONGREAL *) -L.loPLPhaseY1 = fread(fh, 1, 'double=>double');% = 24; (* LONGREAL *) -L.loPLPhaseY2 = fread(fh, 1, 'double=>double');% = 32; (* LONGREAL *) -L.loUsedPhaseShift = fread(fh, 1, 'double=>double');% = 40; (* LONGREAL *) -L.loUsedAttenuation = fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) - L.loSpare = fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) -L.loExtCalValid = fread(fh, 1, 'uint8=>logical');% = 64; (* BOOLEAN *) -L.loPLPhaseValid = fread(fh, 1, 'uint8=>logical');% = 65; (* BOOLEAN *) -L.loLockInMode = fread(fh, 1, 'uint8=>uint8');% = 66; (* BYTE *) -L.loCalMode = fread(fh, 1, 'uint8=>uint8');% = 67; (* BYTE *) - L.loSpare2 = fread(fh, 7, 'int32=>in32');% = 68; (* remaining *) -L.LockInParamsSize = 96; - -fseek(fh, offset+L.LockInParamsSize, 'bof'); - -end - -%-------------------------------------------------------------------------- -function A=getAmplifierState(fh) -%-------------------------------------------------------------------------- -offset=ftell(fh); -A.sStateVersion = fread(fh, 1, 'double=>double');% = 0; (* 8 = SizeStateVersion *) -A.sCurrentGain = fread(fh, 1, 'double=>double');% = 8; (* LONGREAL *) -A.sF2Bandwidth = fread(fh, 1, 'double=>double');% = 16; (* LONGREAL *) -A.sF2Frequency = fread(fh, 1, 'double=>double');% = 24; (* LONGREAL *) -A.sRsValue = fread(fh, 1, 'double=>double');% = 32; (* LONGREAL *) -A.sRsFraction = fread(fh, 1, 'double=>double');% = 40; (* LONGREAL *) -A.sGLeak = fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) -A.sCFastAmp1 = fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) -A.sCFastAmp2 = fread(fh, 1, 'double=>double');% = 64; (* LONGREAL *) -A.sCFastTau = fread(fh, 1, 'double=>double');% = 72; (* LONGREAL *) -A.sCSlow = fread(fh, 1, 'double=>double');% = 80; (* LONGREAL *) -A.sGSeries = fread(fh, 1, 'double=>double');% = 88; (* LONGREAL *) -A.sVCStimDacScale = fread(fh, 1, 'double=>double');% = 96; (* LONGREAL *) -A.sCCStimScale = fread(fh, 1, 'double=>double');% = 104; (* LONGREAL *) -A.sVHold = fread(fh, 1, 'double=>double');% = 112; (* LONGREAL *) -A.sLastVHold = fread(fh, 1, 'double=>double');% = 120; (* LONGREAL *) -A.sVpOffset = fread(fh, 1, 'double=>double');% = 128; (* LONGREAL *) -A.sVLiquidJunction = fread(fh, 1, 'double=>double');% = 136; (* LONGREAL *) -A.sCCIHold = fread(fh, 1, 'double=>double');% = 144; (* LONGREAL *) -A.sCSlowStimVolts = fread(fh, 1, 'double=>double');% = 152; (* LONGREAL *) -A.sCCTrackVHold = fread(fh, 1, 'double=>double');% = 160; (* LONGREAL *) -A.sTimeoutCSlow = fread(fh, 1, 'double=>double');% = 168; (* LONGREAL *) -A.sSearchDelay = fread(fh, 1, 'double=>double');% = 176; (* LONGREAL *) -A.sMConductance = fread(fh, 1, 'double=>double');% = 184; (* LONGREAL *) -A.sMCapacitance = fread(fh, 1, 'double=>double');% = 192; (* LONGREAL *) -A.sSerialNumber = fread(fh, 1, 'double=>double');% = 200; (* 8 = SizeSerialNumber *) - -A.sE9Boards = fread(fh, 1, 'int16=>int16');% = 208; (* INT16 *) -A.sCSlowCycles = fread(fh, 1, 'int16=>int16');% = 210; (* INT16 *) -A.sIMonAdc = fread(fh, 1, 'int16=>int16');% = 212; (* INT16 *) -A.sVMonAdc = fread(fh, 1, 'int16=>int16');% = 214; (* INT16 *) - -A.sMuxAdc = fread(fh, 1, 'int16=>int16');% = 216; (* INT16 *) -A.sTestDac = fread(fh, 1, 'int16=>int16');% = 218; (* INT16 *) -A.sStimDac = fread(fh, 1, 'int16=>int16');% = 220; (* INT16 *) -A.sStimDacOffset = fread(fh, 1, 'int16=>int16');% = 222; (* INT16 *) - -A.sMaxDigitalBit = fread(fh, 1, 'int16=>int16');% = 224; (* INT16 *) -A.sHasCFastHigh = fread(fh, 1, 'uint8=>uint8');% = 226; (* BYTE *) -A.sCFastHigh = fread(fh, 1, 'uint8=>uint8');% = 227; (* BYTE *) -A.sHasBathSense = fread(fh, 1, 'uint8=>uint8');% = 228; (* BYTE *) -A.sBathSense = fread(fh, 1, 'uint8=>uint8');% = 229; (* BYTE *) -A.sHasF2Bypass = fread(fh, 1, 'uint8=>uint8');% = 230; (* BYTE *) -A.sF2Mode = fread(fh, 1, 'uint8=>uint8');% = 231; (* BYTE *) - -A.sAmplKind = fread(fh, 1, 'uint8=>uint8');% = 232; (* BYTE *) -A.sIsEpc9N = fread(fh, 1, 'uint8=>uint8');% = 233; (* BYTE *) -A.sADBoard = fread(fh, 1, 'uint8=>uint8');% = 234; (* BYTE *) -A.sBoardVersion = fread(fh, 1, 'uint8=>uint8');% = 235; (* BYTE *) -A.sActiveE9Board = fread(fh, 1, 'uint8=>uint8');% = 236; (* BYTE *) -A.sMode = fread(fh, 1, 'uint8=>uint8');% = 237; (* BYTE *) -A.sRange = fread(fh, 1, 'uint8=>uint8');% = 238; (* BYTE *) -A.sF2Response = fread(fh, 1, 'uint8=>uint8');% = 239; (* BYTE *) - -A.sRsOn = fread(fh, 1, 'uint8=>uint8');% = 240; (* BYTE *) -A.sCSlowRange = fread(fh, 1, 'uint8=>uint8');% = 241; (* BYTE *) -A.sCCRange = fread(fh, 1, 'uint8=>uint8');% = 242; (* BYTE *) -A.sCCGain = fread(fh, 1, 'uint8=>uint8');% = 243; (* BYTE *) -A.sCSlowToTestDac = fread(fh, 1, 'uint8=>uint8');% = 244; (* BYTE *) -A.sStimPath = fread(fh, 1, 'uint8=>uint8');% = 245; (* BYTE *) -A.sCCTrackTau = fread(fh, 1, 'uint8=>uint8');% = 246; (* BYTE *) -A.sWasClipping = fread(fh, 1, 'uint8=>uint8');% = 247; (* BYTE *) - -A.sRepetitiveCSlow = fread(fh, 1, 'uint8=>uint8');% = 248; (* BYTE *) -A.sLastCSlowRange = fread(fh, 1, 'uint8=>uint8');% = 249; (* BYTE *) - A.sOld1 = fread(fh, 1, 'uint8=>uint8');% = 250; (* BYTE *) -A.sCanCCFast = fread(fh, 1, 'uint8=>uint8');% = 251; (* BYTE *) -A.sCanLowCCRange = fread(fh, 1, 'uint8=>uint8');% = 252; (* BYTE *) -A.sCanHighCCRange = fread(fh, 1, 'uint8=>uint8');% = 253; (* BYTE *) -A.sCanCCTrackingg = fread(fh, 1, 'uint8=>uint8');% = 254; (* BYTE *) -A.sCHasVmonPath = fread(fh, 1, 'uint8=>uint8');% = 255; (* BYTE *) - -A.sHasNewCCMode = fread(fh, 1, 'uint8=>uint8');% = 256; (* BYTE *) -A.sSelector = fread(fh, 1, 'uint8=>char');% = 257; (* CHAR *) -A.sHoldInverted = fread(fh, 1, 'uint8=>uint8');% = 258; (* BYTE *) -A.sAutoCFast = fread(fh, 1, 'uint8=>uint8');% = 259; (* BYTE *) -A.sAutoCSlow = fread(fh, 1, 'uint8=>uint8');% = 260; (* BYTE *) -A.sHasVmonX100 = fread(fh, 1, 'uint8=>uint8');% = 261; (* BYTE *) -A.sTestDacOn = fread(fh, 1, 'uint8=>uint8');% = 262; (* BYTE *) -A.sQMuxAdcOn = fread(fh, 1, 'uint8=>uint8');% = 263; (* BYTE *) - -A.sImon1Bandwidth = fread(fh, 1, 'double=>double');% = 264; (* LONGREAL *) -A.sStimScale = fread(fh, 1, 'double=>double');% = 272; (* LONGREAL *) - -A.sGain = fread(fh, 1, 'uint8=>uint8');% = 280; (* BYTE *) -A.sFilter1 = fread(fh, 1, 'uint8=>uint8');% = 281; (* BYTE *) -A.sStimFilterOn = fread(fh, 1, 'uint8=>uint8');% = 282; (* BYTE *) -A.sRsSlow = fread(fh, 1, 'uint8=>uint8');% = 283; (* BYTE *) - A.sOld2 = fread(fh, 1, 'uint8=>uint8');% = 284; (* BYTE *) -A.sCCCFastOn = fread(fh, 1, 'uint8=>uint8');% = 285; (* BYTE *) -A.sCCFastSpeed = fread(fh, 1, 'uint8=>uint8');% = 286; (* BYTE *) -A.sF2Source = fread(fh, 1, 'uint8=>uint8');% = 287; (* BYTE *) - -A.sTestRange = fread(fh, 1, 'uint8=>uint8');% = 288; (* BYTE *) -A.sTestDacPath = fread(fh, 1, 'uint8=>uint8');% = 289; (* BYTE *) -A.sMuxChannel = fread(fh, 1, 'uint8=>uint8');% = 290; (* BYTE *) -A.sMuxGain64 = fread(fh, 1, 'uint8=>uint8');% = 291; (* BYTE *) -A.sVmonX100 = fread(fh, 1, 'uint8=>uint8');% = 292; (* BYTE *) -A.sIsQuadro = fread(fh, 1, 'uint8=>uint8');% = 293; (* BYTE *) -A.sF1Mode = fread(fh, 1, 'uint8=>uint8');% = 294; (* BYTE *) - A.sOld3 = fread(fh, 1, 'uint8=>uint8');% = 295; (* BYTE *) - -A.sStimFilterHz = fread(fh, 1, 'double=>double');% = 296; (* LONGREAL *) -A.sRsTau = fread(fh, 1, 'double=>double');% = 304; (* LONGREAL *) -A.sDacToAdcDelay = fread(fh, 1, 'double=>double');% = 312; (* LONGREAL *) -A.sInputFilterTau = fread(fh, 1, 'double=>double');% = 320; (* LONGREAL *) -A.sOutputFilterTau = fread(fh, 1, 'double=>double');% = 328; (* LONGREAL *) -A.sVmonFactor = fread(fh, 1, 'double=>double');% = 336; (* LONGREAL *) -A.sCalibDate = fread(fh, 2, 'double=>double');% = 344; (* 16 = SizeCalibDate *) -A.sVmonOffset = fread(fh, 1, 'double=>double');% = 360; (* LONGREAL *) - -A.sEEPROMKind = fread(fh, 1, 'uint8=>uint8');% = 368; (* BYTE *) -A.sVrefX2 = fread(fh, 1, 'uint8=>uint8');% = 369; (* BYTE *) -A.sHasVrefX2AndF2Vmon = fread(fh, 1, 'uint8=>uint8');% = 370; (* BYTE *) -A.sSpare1 = fread(fh, 1, 'uint8=>uint8');% = 371; (* BYTE *) -A.sSpare2 = fread(fh, 1, 'uint8=>uint8');% = 372; (* BYTE *) -A.sSpare3 = fread(fh, 1, 'uint8=>uint8');% = 373; (* BYTE *) -A.sSpare4 = fread(fh, 1, 'uint8=>uint8');% = 374; (* BYTE *) -A.sSpare5 = fread(fh, 1, 'uint8=>uint8');% = 375; (* BYTE *) - -A.sCCStimDacScale = fread(fh, 1, 'double=>double');% = 376; (* LONGREAL *) -A.sVmonFiltBandwidth = fread(fh, 1, 'double=>double');% = 384; (* LONGREAL *) -A.sVmonFiltFrequency = fread(fh, 1, 'double=>double');% = 392; (* LONGREAL *) -A.AmplifierStateSize = 400;% (* = 50 * 8 *) - -fseek(fh, offset+A.AmplifierStateSize, 'bof'); - -end diff --git a/@HEKA_Importer/readPulseFileHEKA.asv b/@HEKA_Importer/readPulseFileHEKA.asv new file mode 100644 index 0000000..30c1480 --- /dev/null +++ b/@HEKA_Importer/readPulseFileHEKA.asv @@ -0,0 +1,466 @@ +function readPulseFileHEKA(obj,Level) +%-------------------------------------------------------------------------- +% Gets one record of the tree and the number of children + + + +s = getOneRecord(obj,Level); +obj.fileData.Tree{obj.fileData.Counter, Level+1} = s; + +obj.fileData.Position = obj.fileData.Position+obj.fileData.Sizes(Level+1); +fseek(obj.fileData.fh, obj.fileData.Position, 'bof'); +obj.fileData.nchild=fread(obj.fileData.fh, 1, 'int32=>int32'); +obj.fileData.Position=ftell(obj.fileData.fh); + +end + +%-------------------------------------------------------------------------- +function rec=getOneRecord(obj,Level) +%-------------------------------------------------------------------------- +% Gets one record +% Counter=Counter+1; +obj.fileData.Counter = obj.fileData.Counter+1; + +switch Level + case 0 + rec=getRoot(obj); + case 1 + rec=getGroup(obj); + case 2 + rec=getSeries(obj); + case 3 + rec=getSweep(obj); + case 4 + rec=getTrace(obj); + otherwise + error('Unexpected Level'); +end +end + +% The functions below return data as defined by the HEKA PatchMaster +% specification + +%-------------------------------------------------------------------------- +function p=getRoot(obj) +%-------------------------------------------------------------------------- +fh = obj.fileData.fh; + +p.RoVersion = fread(fh, 1, 'int32=>int32');% = 4; (* INT32 *) +p.RoMark = fread(fh, 1, 'int32=>int32');% = 4; (* INT32 *) +p.RoVersionName = deblank(fread(fh, 32, 'uint8=>char')');% = 8; (* String32Type *) +p.RoAuxFileName = deblank(fread(fh, 80, 'uint8=>char')');% = 40; (* String80Type *) +p.RoRootText = deblank(fread(fh, 400, 'uint8=>char')');% (* String400Type *) +p.RoStartTime = fread(fh, 1, 'double=>double') ;% = 520; (* LONGREAL *) +p.RoStartTimeMATLAB = obj.HI_time2date(p.RoStartTime); +p.RoMaxSamples = fread(fh, 1, 'int32=>int32'); % = 528; (* INT32 *) +p.RoCRC = fread(fh, 1, 'int32=>int32'); % = 532; (* CARD32 *) +p.RoFeatures = fread(fh, 1, 'int16=>int16'); % = 536; (* SET16 *) +p.RoFiller1 = fread(fh, 1, 'int16=>int16');% = 538; (* INT16 *) +p.RoFiller2 = fread(fh, 1, 'int32=>int32');% = 540; (* INT32 *) +p.RoTcEnumerator = fread(fh,32,'int16=>int16');% = 544; (* ARRAY[0..Max_TcKind_M1] OF INT16 *) +p.RoTcKind = fread(fh,32,'int8=>int8');% = 608; (* ARRAY[0..Max_TcKind_M1] OF INT8 *) +p.RootRecSize = 640;% (* = 80 * 8 *); +p=orderfields(p); + +obj.fileData.fileVersion = p.RoVersion; +end + +%-------------------------------------------------------------------------- +function g=getGroup(obj) +%-------------------------------------------------------------------------- +% Group +fh = obj.fileData.fh; + +g.GrMark = fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) +g.GrLabel = deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Size *) +g.GrText = deblank(fread(fh, 80, 'uint8=>char')');% = 36; (* String80Size *) +g.GrExperimentNumber = fread(fh, 1, 'int32=>int32');% = 116; (* INT32 *) +g.GrGroupCount = fread(fh, 1, 'int32=>int32');% = 120; (* INT32 *) +g.GrCRC = fread(fh, 1, 'int32=>int32');% = 124; (* CARD32 *) +g.GrMatrixWidth = fread(fh,1,'double=>double');% = 128; (* LONGREAL *) +g.GrMatrixHeight = fread(fh,1,'double=>double');% = 136; (* LONGREAL *) +g.GroupRecSize = 144; % (* = 18 * 8 *) + +g=orderfields(g); + +end + +%-------------------------------------------------------------------------- +function s=getSeries(obj) +%-------------------------------------------------------------------------- +fh = obj.fileData.fh; + +s.SeMark = fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) +s.SeLabel = deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Type *) +s.SeComment = deblank(fread(fh, 80, 'uint8=>char')');% = 36; (* String80Type *) +s.SeSeriesCount = fread(fh, 1, 'int32=>int32');% = 116; (* INT32 *) +s.SeNumbersw = fread(fh, 1, 'int32=>int32');% = 120; (* INT32 *) +switch obj.fileData.fileVersion + case 9 + s.SeAmplStateOffset = fread(fh, 1, 'int32=>int32');% = 124; (* INT32 * + s.SeAmplStateSeries = fread(fh, 1, 'int32=>int32');% = 128; (* INT32 * + case 1000 + s.SeAmplStateFlag = fread(fh,1,'int32=>int32');% = 124; (* INT32 *) // flag > 0 => load local oldAmpState, otherwise load from .amp File. + s.SeAmplStateRef = fread(fh,1,'int32=>int32'); % = 128; (* INT32 *) // ref = 0 => use local oldAmpState +end + +%% +s.SeMethodTag = fread(fh,1,'int32=>int32'); % = 132; (* INT32 *) +s.SeTime = fread(fh,1,'double=>double'); % = 136; (* LONGREAL *) +s.SeTimeMATLAB = obj.HI_time2date(s.SeTime); +s.SePageWidth = fread(fh, 1, 'double=>double') ;% = 144; (* LONGREAL *) + +switch obj.fileData.fileVersion + case 9 + for k=1:4 % = 152; (* ARRAY[0..1] OF UserParamDescrType = 4*40 *) + s.SeSwUserParamDescr(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% + s.SeSwUserParamDescr(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% + end + case 1000 + for k=1:2 % = 152; (* ARRAY[0..1] OF UserParamDescrType = 4*40 *) + s.SeUserDescr1(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% + s.SeUserDescr1(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% + end + s.SeFiller1 = deblank(fread(fh,80,'uint8=>char')'); % = 232; (* ARRAY[0..1] OF UserParamDescrType = 2*40 *) +end + +s.SeMethodName = deblank(fread(fh,32,'uint8=>char')');% = 312; (* String32Type *) + +switch obj.fileData.fileVersion + case 9 + s.SeSeUserParams1 = fread(fh ,4 ,'double=>double'); % = 344; (* ARRAY[0..3] OF LONGREAL *) + s.SeLockInParams = getSeLockInParams(fh);% = 376; (* SeLockInSize = 96, see "Pulsed.de" *) + s.SeAmplifierState = getAmplifierState(fh);% = 472; (* AmplifierStateSize = 400 *) + case 1000 + s.SePhotoParams1 = fread(fh, 4, 'double=>double'); % = 344; (* ARRAY[0..3] OF LONGREAL = 4*8 *) + s.SeOldLockInParams = getSeLockInParams(fh);% = 376; (* SeLockInSize = 96, see "Pulsed.de" *) + s.SeOldAmpState = getAmplifierState(fh);% = 472; (* AmplifierStateSize = 400 *) +end + +s.SeUsername = deblank(fread(fh, 80, 'uint8=>char')');% = 872; (* String80Type *) +switch obj.fileData.fileVersion + case 9 + for k=1:4% = 952; (* ARRAY[0..3] OF UserParamDescrType = 4*40 *) + s.SeSeUserParamDescr(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% + s.SeSeUserParamDescr(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% + end + case 1000 + +end + + + +s.SeFiller1 = fread(fh, 1, 'int32=>int32');% = 1112; (* INT32 *) +s.SeCRC = fread(fh, 1, 'int32=>int32');% = 1116; (* CARD32 *) +s.SeSeUserParams2 = fread(fh, 4, 'double=>double'); %= 1120; (* ARRAY[0..3] OF LONGREAL *) +for k=1:4 %= 1152; (* ARRAY[0..3] OF UserParamDescrType = 4*40 *) + s.SeSeUserParamDescr2(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% + s.SeSeUserParamDescr2(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% +end + +s.SeScanParams = fread(fh, 96, 'uint8=>uint8'); %= 1312; (* ScanParamsSize = 96 (ElProScan Extension) *) +s.SeriesRecSize = 1408;% = 1408; (* = 176 * 8 *) + + + +% s.SePhotoParams1 = fread(fh, 4, 'double=>double'); % = 344; (* ARRAY[0..3] OF LONGREAL = 4*8 *) + +% s.SeUsername = deblank(fread(fh, 80, 'uint8=>char')');% + + + + + +% s.SeLockInParams = fread(fh,96); % = 376; (* SeOldLockInSize = 96, see "Pulsed.de" *) +% s.SeAmplifierState = fread(fh,400); % = 472; (* SeOldAmpState = 400 -> the AmplStateRecord is now stored in the .amp file *) +% % s.SeUsername = deblank(fread(fh,80,'uint8=>char')); % = 872; (* String80Type *) +% +% s.SePhotoParams2 = deblank(fread(fh,160,'uint8=>char')'); %= 952; (* ARRAY[0..3] OF UserParamDescrType = 4*40 *) +% s.SeFiller1 = fread(fh, 1, 'int32=>int32');% = 1112; (* INT32 *) +% s.SeCRC = fread(fh, 1, 'int32=>int32');% = 1116; (* CARD32 *) +% +% s.SeSeUserParams2 = fread(fh, 4, 'double=>double'); %= 1120; (* ARRAY[0..3] OF LONGREAL *) +% for k=1:4 %= 1152; (* ARRAY[0..3] OF UserParamDescrType = 4*40 *) +% s.SeSeUserParamDescr2(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% +% s.SeSeUserParamDescr2(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% +% end +% s.SeScanParams = fread(fh, 96, 'uint8=>uint8'); %= 1312; (* ScanParamsSize = 96 (ElProScan Extension) *) +% +% for k=1:8 %= 1408; (* ARRAY[0..7] OF UserParamDescrType = 8*40 *) +% s.SeSeUserDescr2(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% +% s.SeSeUserDescr2(k).Unit=deblank(fread(fh, 8, 'uint8=>char')'); +% end +% s.SeriesRecSize = 1728;% = 1728; + +s=orderfields(s); +s.Sweeps = []; % used to store all the sweeps within the recording structure later on + +end + +%-------------------------------------------------------------------------- +function sw=getSweep(obj) +%-------------------------------------------------------------------------- + +fh = obj.fileData.fh; + +sw.SwMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) +sw.SwLabel=deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Type *) +sw.SwAuxDataFileOffset=fread(fh, 1, 'int32=>int32');% = 36; (* INT32 *) +sw.SwStimCount=fread(fh, 1, 'int32=>int32');% = 40; (* INT32 *) +sw.SwSweepCount=fread(fh, 1, 'int32=>int32');% = 44; (* INT32 *) +sw.SwTime=fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) +sw.SwTimeMATLAB=obj.HI_time2date(sw.SwTime);% Also add in MATLAB datenum format +sw.SwTimer=fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) +sw.SwSwUserParams=fread(fh, 2, 'double=>double');% = 64; (* ARRAY[0..1] OF LONGREAL *) +sw.SwPipPressure=fread(fh, 2, 'double=>double'); % = 80; (* LONGREAL * +sw.SwRMSNoise=fread(fh,2,'double=>double'); % = 88; (* LONGREAL *) +sw.SwTemperature=fread(fh, 1, 'double=>double');% = 96; (* LONGREAL *) +sw.SwOldIntSol=fread(fh, 1, 'int32=>int32');% = 104; (* INT32 *) +sw.SwOldExtSol=fread(fh, 1, 'int32=>int32');% = 108; (* INT32 *) +sw.SwDigitalIn=fread(fh, 1, 'int16=>int16');% = 112; (* SET16 *) +sw.SwSweepKind=fread(fh, 1, 'int16=>int16');% = 114; (* SET16 *) +sw.SwDigitalOut=fread(fh,1, 'int16=>int16'); % = 116; (* SET16 *) +sw.SwFiller1=fread(fh, 1, 'int16=>int16');% = 118; (* INT32 *) +sw.SwMarkers=fread(fh, 4, 'double=>double');% = 120; (* ARRAY[0..3] OF LONGREAL, see SwMarkersNo *) +sw.SwFiller2=fread(fh, 1, 'int32=>int32');% = 152; (* INT32 *) +sw.SwCRC=fread(fh, 1, 'int32=>int32');% = 156; (* CARD32 *) +sw.SwSwHolding=fread(fh,16,'double=>double'); % = 160; (* ARRAY[0..15] OF LONGREAL, see SwHoldingNo *) +sw.SwSwUserParamEx=fread(fh,8,'double=>double'); % = 288; (* ARRAY[0..7] OF LONGREAL *) +sw.SweepRecSize = 352;% +sw=orderfields(sw); +sw.Traces = []; % used to store all the traces/channels within the sweep structure later on +end + +%-------------------------------------------------------------------------- +function tr=getTrace(obj) +%-------------------------------------------------------------------------- +fh = obj.fileData.fh; + +tr.TrMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) +tr.TrLabel=deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Type *) +tr.TrTraceCount=fread(fh, 1, 'int32=>int32');% = 36; (* INT32 *) +tr.TrData=fread(fh, 1, 'int32=>int32');% = 40; (* INT32 *) +tr.TrDataPoints=fread(fh, 1, 'int32=>int32');% = 44; (* INT32 *) +tr.TrInternalSolution=fread(fh, 1, 'int32=>int32');% = 48; (* INT32 *) +tr.TrAverageCount=fread(fh, 1, 'int32=>int32');% = 52; (* INT32 *) +tr.TrLeakCount=fread(fh, 1, 'int32=>int32');% = 56; (* INT32 *) +tr.TrLeakTraces=fread(fh, 1, 'int32=>int32');% = 60; (* INT32 *) +tr.TrDataKind=fread(fh, 1, 'uint16=>uint16');% = 64; (* SET16 *) NB Stored unsigned +tr.TrFiller1=fread(fh, 1, 'int16=>int16');% = 66; (* SET16 *) +tr.TrRecordingMode=fread(fh, 1, 'uint8=>uint8');% = 68; (* BYTE *) +tr.TrAmplIndex=fread(fh, 1, 'uint8=>uint8');% = 69; (* CHAR *) +tr.TrDataFormat=fread(fh, 1, 'uint8=>uint8');% = 70; (* BYTE *) +tr.TrDataAbscissa=fread(fh, 1, 'uint8=>uint8');% = 71; (* BYTE *) +tr.TrDataScaler=fread(fh, 1, 'double=>double');% = 72; (* LONGREAL *) +tr.TrTimeOffset=fread(fh, 1, 'double=>double');% = 80; (* LONGREAL *) +tr.TrZeroData=fread(fh, 1, 'double=>double');% = 88; (* LONGREAL *) +tr.TrYUnit=deblank(fread(fh, 8, 'uint8=>char')');% = 96; (* String8Type *) +tr.TrXInterval=fread(fh, 1, 'double=>double');% = 104; (* LONGREAL *) +tr.TrXStart=fread(fh, 1, 'double=>double');% = 112; (* LONGREAL *) +% 17.04.10 TrXUnit bytes may include some trailing characters after NULL +% byte +tr.TrXUnit=deblank(fread(fh, 8, 'uint8=>char')');% = 120; (* String8Type *) +tr.TrYRange=fread(fh, 1, 'double=>double');% = 128; (* LONGREAL *) +tr.TrYOffset=fread(fh, 1, 'double=>double');% = 136; (* LONGREAL *) +tr.TrBandwidth=fread(fh, 1, 'double=>double');% = 144; (* LONGREAL *) +tr.TrPipetteResistance=fread(fh, 1, 'double=>double');% = 152; (* LONGREAL *) +tr.TrCellPotential=fread(fh, 1, 'double=>double');% = 160; (* LONGREAL *) +tr.TrSealResistance=fread(fh, 1, 'double=>double');% = 168; (* LONGREAL *) +tr.TrCSlow=fread(fh, 1, 'double=>double');% = 176; (* LONGREAL *) +tr.TrGSeries=fread(fh, 1, 'double=>double');% = 184; (* LONGREAL *) +tr.TrRsValue=fread(fh, 1, 'double=>double');% = 192; (* LONGREAL *) +tr.TrGLeak=fread(fh, 1, 'double=>double');% = 200; (* LONGREAL *) +tr.TrMConductance=fread(fh, 1, 'double=>double');% = 208; (* LONGREAL *) +tr.TrLinkDAChannel=fread(fh, 1, 'int32=>int32');% = 216; (* INT32 *) +tr.TrValidYrange=fread(fh, 1, 'uint8=>logical');% = 220; (* BOOLEAN *) +tr.TrAdcMode=fread(fh, 1, 'uint8=>uint8');% = 221; (* CHAR *) +tr.TrAdcChannel=fread(fh, 1, 'int16=>int16');% = 222; (* INT16 *) +tr.TrYmin=fread(fh, 1, 'double=>double');% = 224; (* LONGREAL *) +tr.TrYmax=fread(fh, 1, 'double=>double');% = 232; (* LONGREAL *) +tr.TrSourceChannel=fread(fh, 1, 'int32=>int32');% = 240; (* INT32 *) +tr.TrExternalSolution=fread(fh, 1, 'int32=>int32');% = 244; (* INT32 *) +tr.TrCM=fread(fh, 1, 'double=>double');% = 248; (* LONGREAL *) +tr.TrGM=fread(fh, 1, 'double=>double');% = 256; (* LONGREAL *) +tr.TrPhase=fread(fh, 1, 'double=>double');% = 264; (* LONGREAL *) +tr.TrDataCRC=fread(fh, 1, 'int32=>int32');% = 272; (* CARD32 *) +tr.TrCRC=fread(fh, 1, 'int32=>int32');% = 276; (* CARD32 *) +tr.TrGS=fread(fh, 1, 'double=>double');% = 280; (* LONGREAL *) +tr.TrSelfChannel=fread(fh, 1, 'int32=>int32');% = 288; (* INT32 *) + +% Added 15.08.2012 +tr.TrInterleaveSize=fread(fh, 1, 'int32=>int32');% = 292; (* INT32 *) +tr.TrInterleaveSkip=fread(fh, 1, 'int32=>int32');% = 296; (* INT32 *) +tr.TrImageIndex=fread(fh, 1, 'int32=>int32');% = 300; (* INT32 *) +tr.TrMarkers=fread(fh, 10, 'double=>double');% = 304; (* ARRAY[0..9] OF LONGREAL *) +tr.TrSECM_X=fread(fh, 1, 'double=>double');% = 384; (* LONGREAL *) +tr.TrSECM_Y=fread(fh, 1, 'double=>double');% = 392; (* LONGREAL *) +tr.TrSECM_Z=fread(fh, 1, 'double=>double');% = 400; (* LONGREAL *) +tr.TrTrHolding = fread(fh, 1, 'double=>double');% = 408; (* LONGREAL *) +tr.TrTcEnumerator = fread(fh, 1, 'int32=>int32');% = 416; (* INT32 *) +tr.TrXTrace = fread(fh, 1, 'int32=>int32');% = 420; (* INT32 *) +tr.TrIntSolValue = fread(fh, 1, 'double=>double');% = 424; (* LONGREAL *) +tr.TrExtSolValue = fread(fh, 1, 'double=>double');% = 432; (* LONGREAL *) +tr.TrIntSolName = deblank(fread(fh, 32, 'uint8=>char')');% = 440; (* String32Size *) +tr.TrExtSolName = deblank(fread(fh, 32, 'uint8=>char')');% = 472; (* String32Size *) +tr.TrDataPedestal = fread(fh, 1, 'double=>double');% = 504; (* LONGREAL *) + +tr.TraceRecSize=512; %(* = 64 * 8 *) + +tr=orderfields(tr); + +end + +function L=getSeLockInParams(fh) +%-------------------------------------------------------------------------- +offset=ftell(fh); +L.loExtCalPhase = fread(fh, 1, 'double=>double');% = 0; (* LONGREAL *) +L.loExtCalAtten = fread(fh, 1, 'double=>double');% = 8; (* LONGREAL *) +L.loPLPhase = fread(fh, 1, 'double=>double');% = 16; (* LONGREAL *) +L.loPLPhaseY1 = fread(fh, 1, 'double=>double');% = 24; (* LONGREAL *) +L.loPLPhaseY2 = fread(fh, 1, 'double=>double');% = 32; (* LONGREAL *) +L.loUsedPhaseShift = fread(fh, 1, 'double=>double');% = 40; (* LONGREAL *) +L.loUsedAttenuation = fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) + L.loSpare = fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) +L.loExtCalValid = fread(fh, 1, 'uint8=>logical');% = 64; (* BOOLEAN *) +L.loPLPhaseValid = fread(fh, 1, 'uint8=>logical');% = 65; (* BOOLEAN *) +L.loLockInMode = fread(fh, 1, 'uint8=>uint8');% = 66; (* BYTE *) +L.loCalMode = fread(fh, 1, 'uint8=>uint8');% = 67; (* BYTE *) + L.loSpare2 = fread(fh, 7, 'int32=>in32');% = 68; (* remaining *) +L.LockInParamsSize = 96; + +fseek(fh, offset+L.LockInParamsSize, 'bof'); + +end + +%-------------------------------------------------------------------------- +function A=getAmplifierState(fh) +%-------------------------------------------------------------------------- +offset=ftell(fh); +A.sStateVersion = fread(fh, 1, 'double=>double');% = 0; (* 8 = SizeStateVersion *) +A.sCurrentGain = fread(fh, 1, 'double=>double');% = 8; (* LONGREAL *) +A.sF2Bandwidth = fread(fh, 1, 'double=>double');% = 16; (* LONGREAL *) +A.sF2Frequency = fread(fh, 1, 'double=>double');% = 24; (* LONGREAL *) +A.sRsValue = fread(fh, 1, 'double=>double');% = 32; (* LONGREAL *) +A.sRsFraction = fread(fh, 1, 'double=>double');% = 40; (* LONGREAL *) +A.sGLeak = fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) +A.sCFastAmp1 = fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) +A.sCFastAmp2 = fread(fh, 1, 'double=>double');% = 64; (* LONGREAL *) +A.sCFastTau = fread(fh, 1, 'double=>double');% = 72; (* LONGREAL *) +A.sCSlow = fread(fh, 1, 'double=>double');% = 80; (* LONGREAL *) +A.sGSeries = fread(fh, 1, 'double=>double');% = 88; (* LONGREAL *) +A.sVCStimDacScale = fread(fh, 1, 'double=>double');% = 96; (* LONGREAL *) +A.sCCStimScale = fread(fh, 1, 'double=>double');% = 104; (* LONGREAL *) +A.sVHold = fread(fh, 1, 'double=>double');% = 112; (* LONGREAL *) +A.sLastVHold = fread(fh, 1, 'double=>double');% = 120; (* LONGREAL *) +A.sVpOffset = fread(fh, 1, 'double=>double');% = 128; (* LONGREAL *) +A.sVLiquidJunction = fread(fh, 1, 'double=>double');% = 136; (* LONGREAL *) +A.sCCIHold = fread(fh, 1, 'double=>double');% = 144; (* LONGREAL *) +A.sCSlowStimVolts = fread(fh, 1, 'double=>double');% = 152; (* LONGREAL *) +A.sCCTrackVHold = fread(fh, 1, 'double=>double');% = 160; (* LONGREAL *) +A.sTimeoutCSlow = fread(fh, 1, 'double=>double');% = 168; (* LONGREAL *) +A.sSearchDelay = fread(fh, 1, 'double=>double');% = 176; (* LONGREAL *) +A.sMConductance = fread(fh, 1, 'double=>double');% = 184; (* LONGREAL *) +A.sMCapacitance = fread(fh, 1, 'double=>double');% = 192; (* LONGREAL *) +A.sSerialNumber = fread(fh, 1, 'double=>double');% = 200; (* 8 = SizeSerialNumber *) + +A.sE9Boards = fread(fh, 1, 'int16=>int16');% = 208; (* INT16 *) +A.sCSlowCycles = fread(fh, 1, 'int16=>int16');% = 210; (* INT16 *) +A.sIMonAdc = fread(fh, 1, 'int16=>int16');% = 212; (* INT16 *) +A.sVMonAdc = fread(fh, 1, 'int16=>int16');% = 214; (* INT16 *) + +A.sMuxAdc = fread(fh, 1, 'int16=>int16');% = 216; (* INT16 *) +A.sTestDac = fread(fh, 1, 'int16=>int16');% = 218; (* INT16 *) +A.sStimDac = fread(fh, 1, 'int16=>int16');% = 220; (* INT16 *) +A.sStimDacOffset = fread(fh, 1, 'int16=>int16');% = 222; (* INT16 *) + +A.sMaxDigitalBit = fread(fh, 1, 'int16=>int16');% = 224; (* INT16 *) +A.sHasCFastHigh = fread(fh, 1, 'uint8=>uint8');% = 226; (* BYTE *) +A.sCFastHigh = fread(fh, 1, 'uint8=>uint8');% = 227; (* BYTE *) +A.sHasBathSense = fread(fh, 1, 'uint8=>uint8');% = 228; (* BYTE *) +A.sBathSense = fread(fh, 1, 'uint8=>uint8');% = 229; (* BYTE *) +A.sHasF2Bypass = fread(fh, 1, 'uint8=>uint8');% = 230; (* BYTE *) +A.sF2Mode = fread(fh, 1, 'uint8=>uint8');% = 231; (* BYTE *) + +A.sAmplKind = fread(fh, 1, 'uint8=>uint8');% = 232; (* BYTE *) +A.sIsEpc9N = fread(fh, 1, 'uint8=>uint8');% = 233; (* BYTE *) +A.sADBoard = fread(fh, 1, 'uint8=>uint8');% = 234; (* BYTE *) +A.sBoardVersion = fread(fh, 1, 'uint8=>uint8');% = 235; (* BYTE *) +A.sActiveE9Board = fread(fh, 1, 'uint8=>uint8');% = 236; (* BYTE *) +A.sMode = fread(fh, 1, 'uint8=>uint8');% = 237; (* BYTE *) +A.sRange = fread(fh, 1, 'uint8=>uint8');% = 238; (* BYTE *) +A.sF2Response = fread(fh, 1, 'uint8=>uint8');% = 239; (* BYTE *) + +A.sRsOn = fread(fh, 1, 'uint8=>uint8');% = 240; (* BYTE *) +A.sCSlowRange = fread(fh, 1, 'uint8=>uint8');% = 241; (* BYTE *) +A.sCCRange = fread(fh, 1, 'uint8=>uint8');% = 242; (* BYTE *) +A.sCCGain = fread(fh, 1, 'uint8=>uint8');% = 243; (* BYTE *) +A.sCSlowToTestDac = fread(fh, 1, 'uint8=>uint8');% = 244; (* BYTE *) +A.sStimPath = fread(fh, 1, 'uint8=>uint8');% = 245; (* BYTE *) +A.sCCTrackTau = fread(fh, 1, 'uint8=>uint8');% = 246; (* BYTE *) +A.sWasClipping = fread(fh, 1, 'uint8=>uint8');% = 247; (* BYTE *) + +A.sRepetitiveCSlow = fread(fh, 1, 'uint8=>uint8');% = 248; (* BYTE *) +A.sLastCSlowRange = fread(fh, 1, 'uint8=>uint8');% = 249; (* BYTE *) + A.sOld1 = fread(fh, 1, 'uint8=>uint8');% = 250; (* BYTE *) +A.sCanCCFast = fread(fh, 1, 'uint8=>uint8');% = 251; (* BYTE *) +A.sCanLowCCRange = fread(fh, 1, 'uint8=>uint8');% = 252; (* BYTE *) +A.sCanHighCCRange = fread(fh, 1, 'uint8=>uint8');% = 253; (* BYTE *) +A.sCanCCTrackingg = fread(fh, 1, 'uint8=>uint8');% = 254; (* BYTE *) +A.sCHasVmonPath = fread(fh, 1, 'uint8=>uint8');% = 255; (* BYTE *) + +A.sHasNewCCMode = fread(fh, 1, 'uint8=>uint8');% = 256; (* BYTE *) +A.sSelector = fread(fh, 1, 'uint8=>char');% = 257; (* CHAR *) +A.sHoldInverted = fread(fh, 1, 'uint8=>uint8');% = 258; (* BYTE *) +A.sAutoCFast = fread(fh, 1, 'uint8=>uint8');% = 259; (* BYTE *) +A.sAutoCSlow = fread(fh, 1, 'uint8=>uint8');% = 260; (* BYTE *) +A.sHasVmonX100 = fread(fh, 1, 'uint8=>uint8');% = 261; (* BYTE *) +A.sTestDacOn = fread(fh, 1, 'uint8=>uint8');% = 262; (* BYTE *) +A.sQMuxAdcOn = fread(fh, 1, 'uint8=>uint8');% = 263; (* BYTE *) + +A.sImon1Bandwidth = fread(fh, 1, 'double=>double');% = 264; (* LONGREAL *) +A.sStimScale = fread(fh, 1, 'double=>double');% = 272; (* LONGREAL *) + +A.sGain = fread(fh, 1, 'uint8=>uint8');% = 280; (* BYTE *) +A.sFilter1 = fread(fh, 1, 'uint8=>uint8');% = 281; (* BYTE *) +A.sStimFilterOn = fread(fh, 1, 'uint8=>uint8');% = 282; (* BYTE *) +A.sRsSlow = fread(fh, 1, 'uint8=>uint8');% = 283; (* BYTE *) + A.sOld2 = fread(fh, 1, 'uint8=>uint8');% = 284; (* BYTE *) +A.sCCCFastOn = fread(fh, 1, 'uint8=>uint8');% = 285; (* BYTE *) +A.sCCFastSpeed = fread(fh, 1, 'uint8=>uint8');% = 286; (* BYTE *) +A.sF2Source = fread(fh, 1, 'uint8=>uint8');% = 287; (* BYTE *) + +A.sTestRange = fread(fh, 1, 'uint8=>uint8');% = 288; (* BYTE *) +A.sTestDacPath = fread(fh, 1, 'uint8=>uint8');% = 289; (* BYTE *) +A.sMuxChannel = fread(fh, 1, 'uint8=>uint8');% = 290; (* BYTE *) +A.sMuxGain64 = fread(fh, 1, 'uint8=>uint8');% = 291; (* BYTE *) +A.sVmonX100 = fread(fh, 1, 'uint8=>uint8');% = 292; (* BYTE *) +A.sIsQuadro = fread(fh, 1, 'uint8=>uint8');% = 293; (* BYTE *) +A.sF1Mode = fread(fh, 1, 'uint8=>uint8');% = 294; (* BYTE *) + A.sOld3 = fread(fh, 1, 'uint8=>uint8');% = 295; (* BYTE *) + +A.sStimFilterHz = fread(fh, 1, 'double=>double');% = 296; (* LONGREAL *) +A.sRsTau = fread(fh, 1, 'double=>double');% = 304; (* LONGREAL *) +A.sDacToAdcDelay = fread(fh, 1, 'double=>double');% = 312; (* LONGREAL *) +A.sInputFilterTau = fread(fh, 1, 'double=>double');% = 320; (* LONGREAL *) +A.sOutputFilterTau = fread(fh, 1, 'double=>double');% = 328; (* LONGREAL *) +A.sVmonFactor = fread(fh, 1, 'double=>double');% = 336; (* LONGREAL *) +A.sCalibDate = fread(fh, 2, 'double=>double');% = 344; (* 16 = SizeCalibDate *) +A.sVmonOffset = fread(fh, 1, 'double=>double');% = 360; (* LONGREAL *) + +A.sEEPROMKind = fread(fh, 1, 'uint8=>uint8');% = 368; (* BYTE *) +A.sVrefX2 = fread(fh, 1, 'uint8=>uint8');% = 369; (* BYTE *) +A.sHasVrefX2AndF2Vmon = fread(fh, 1, 'uint8=>uint8');% = 370; (* BYTE *) +A.sSpare1 = fread(fh, 1, 'uint8=>uint8');% = 371; (* BYTE *) +A.sSpare2 = fread(fh, 1, 'uint8=>uint8');% = 372; (* BYTE *) +A.sSpare3 = fread(fh, 1, 'uint8=>uint8');% = 373; (* BYTE *) +A.sSpare4 = fread(fh, 1, 'uint8=>uint8');% = 374; (* BYTE *) +A.sSpare5 = fread(fh, 1, 'uint8=>uint8');% = 375; (* BYTE *) + +A.sCCStimDacScale = fread(fh, 1, 'double=>double');% = 376; (* LONGREAL *) +A.sVmonFiltBandwidth = fread(fh, 1, 'double=>double');% = 384; (* LONGREAL *) +A.sVmonFiltFrequency = fread(fh, 1, 'double=>double');% = 392; (* LONGREAL *) +A.AmplifierStateSize = 400;% (* = 50 * 8 *) + +fseek(fh, offset+A.AmplifierStateSize, 'bof'); + +end \ No newline at end of file diff --git a/@HEKA_Importer/readPulseFileHEKA.m b/@HEKA_Importer/readPulseFileHEKA.m index c261c67..798cb41 100644 --- a/@HEKA_Importer/readPulseFileHEKA.m +++ b/@HEKA_Importer/readPulseFileHEKA.m @@ -45,23 +45,24 @@ function readPulseFileHEKA(obj,Level) %-------------------------------------------------------------------------- fh = obj.fileData.fh; -p.RoVersion=fread(fh, 1, 'int32=>int32'); -p.RoMark=fread(fh, 1, 'int32=>int32');% = 4; (* INT32 *) -p.RoVersionName=deblank(fread(fh, 32, 'uint8=>char')');% = 8; (* String32Type *) -p.RoAuxFileName=deblank(fread(fh, 80, 'uint8=>char')');% = 40; (* String80Type *) -p.RoRootText=deblank(fread(fh, 400, 'uint8=>char')');% (* String400Type *) -p.RoStartTime=fread(fh, 1, 'double=>double') ;% = 520; (* LONGREAL *) -p.RoStartTimeMATLAB=obj.HI_time2date(p.RoStartTime); -p.RoMaxSamples=fread(fh, 1, 'int32=>int32'); % = 528; (* INT32 *) -p.RoCRC=fread(fh, 1, 'int32=>int32'); % = 532; (* CARD32 *) -p.RoFeatures=fread(fh, 1, 'int16=>int16'); % = 536; (* SET16 *) -p.RoFiller1=fread(fh, 1, 'int16=>int16');% = 538; (* INT16 *) -p.RoFiller2=fread(fh, 1, 'int32=>int32');% = 540; (* INT32 *) -p.RoTcEnumerator = fread(fh,32,'int16=>int16');% = 544; (* ARRAY[0..Max_TcKind_M1] OF INT16 *) -p.RoTcKind = fread(fh,32,'int8=>int8');% = 608; (* ARRAY[0..Max_TcKind_M1] OF INT8 *) -p.RootRecSize = 640; % (* = 80 * 8 *); +p.RoVersion = fread(fh, 1, 'int32=>int32');% = 4; (* INT32 *) +p.RoMark = fread(fh, 1, 'int32=>int32');% = 4; (* INT32 *) +p.RoVersionName = deblank(fread(fh, 32, 'uint8=>char')');% = 8; (* String32Type *) +p.RoAuxFileName = deblank(fread(fh, 80, 'uint8=>char')');% = 40; (* String80Type *) +p.RoRootText = deblank(fread(fh, 400, 'uint8=>char')');% (* String400Type *) +p.RoStartTime = fread(fh, 1, 'double=>double') ;% = 520; (* LONGREAL *) +p.RoStartTimeMATLAB = obj.HI_time2date(p.RoStartTime); +p.RoMaxSamples = fread(fh, 1, 'int32=>int32'); % = 528; (* INT32 *) +p.RoCRC = fread(fh, 1, 'int32=>int32'); % = 532; (* CARD32 *) +p.RoFeatures = fread(fh, 1, 'int16=>int16'); % = 536; (* SET16 *) +p.RoFiller1 = fread(fh, 1, 'int16=>int16');% = 538; (* INT16 *) +p.RoFiller2 = fread(fh, 1, 'int32=>int32');% = 540; (* INT32 *) +p.RoTcEnumerator = fread(fh,32,'int16=>int16');% = 544; (* ARRAY[0..Max_TcKind_M1] OF INT16 *) +p.RoTcKind = fread(fh,32,'int8=>int8');% = 608; (* ARRAY[0..Max_TcKind_M1] OF INT8 *) +p.RootRecSize = 640;% (* = 80 * 8 *); p=orderfields(p); +obj.fileData.fileVersion = p.RoVersion; end %-------------------------------------------------------------------------- @@ -70,18 +71,16 @@ function readPulseFileHEKA(obj,Level) % Group fh = obj.fileData.fh; +g.GrMark = fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) +g.GrLabel = deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Size *) +g.GrText = deblank(fread(fh, 80, 'uint8=>char')');% = 36; (* String80Size *) +g.GrExperimentNumber = fread(fh, 1, 'int32=>int32');% = 116; (* INT32 *) +g.GrGroupCount = fread(fh, 1, 'int32=>int32');% = 120; (* INT32 *) +g.GrCRC = fread(fh, 1, 'int32=>int32');% = 124; (* CARD32 *) +g.GrMatrixWidth = fread(fh,1,'double=>double');% = 128; (* LONGREAL *) +g.GrMatrixHeight = fread(fh,1,'double=>double');% = 136; (* LONGREAL *) +g.GroupRecSize = 144; % (* = 18 * 8 *) -g.GrMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) -g.GrLabel=deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Size *) -g.GrText=deblank(fread(fh, 80, 'uint8=>char')');% = 36; (* String80Size *) -g.GrExperimentNumber=fread(fh, 1, 'int32=>int32');% = 116; (* INT32 *) -g.GrGroupCount=fread(fh, 1, 'int32=>int32');% = 120; (* INT32 *) -g.GrCRC=fread(fh, 1, 'int32=>int32');% = 124; (* CARD32 *) -g.GrMatrixWidth = fread(fh,1,'double=>double');% = 128; (* LONGREAL *) -g.GrMatrixHeight = fread(fh,1,'double=>double');% = 136; (* LONGREAL *) -g.GroupRecSize = 144; % (* = 18 * 8 *) - -% g.GroupRecSize=128;% (* = 16 * 8 *) g=orderfields(g); end @@ -91,57 +90,77 @@ function readPulseFileHEKA(obj,Level) %-------------------------------------------------------------------------- fh = obj.fileData.fh; -s.SeMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) -s.SeLabel=deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Type *) -s.SeComment=deblank(fread(fh, 80, 'uint8=>char')');% = 36; (* String80Type *) -s.SeSeriesCount=fread(fh, 1, 'int32=>int32');% = 116; (* INT32 *) -s.SeNumbersw=fread(fh, 1, 'int32=>int32');% = 120; (* INT32 *) - +s.SeMark = fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) +s.SeLabel = deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Type *) +s.SeComment = deblank(fread(fh, 80, 'uint8=>char')');% = 36; (* String80Type *) +s.SeSeriesCount = fread(fh, 1, 'int32=>int32');% = 116; (* INT32 *) +s.SeNumbersw = fread(fh, 1, 'int32=>int32');% = 120; (* INT32 *) +s.SeAmplStateOffset = fread(fh, 1, 'int32=>int32');% = 124; (* INT32 * +s.SeAmplStateSeries = fread(fh, 1, 'int32=>int32');% = 128; (* INT32 * %% -s.SeAmplStateFlag = fread(fh,1,'int32=>int32');% = 124; (* INT32 *) // flag > 0 => load local oldAmpState, otherwise load from .amp File. -s.SeAmplStateRef = fread(fh,1,'int32=>int32'); % = 128; (* INT32 *) // ref = 0 => use local oldAmpState -s.SeMethodTag = fread(fh,1,'int32=>int32'); % = 132; (* INT32 *) -s.SeTime = fread(fh,1,'double=>double'); % = 136; (* LONGREAL *) -s.SeTimeMATLAB=obj.HI_time2date(s.SeTime); -s.SePageWidth=fread(fh, 1, 'double=>double') ;% = 144; (* LONGREAL *) -for k=1:2 % = 152; (* ARRAY[0..1] OF UserParamDescrType = 2*40 *) +% s.SeAmplStateFlag = fread(fh,1,'int32=>int32');% = 124; (* INT32 *) // flag > 0 => load local oldAmpState, otherwise load from .amp File. +% s.SeAmplStateRef = fread(fh,1,'int32=>int32'); % = 128; (* INT32 *) // ref = 0 => use local oldAmpState +s.SeMethodTag = fread(fh,1,'int32=>int32'); % = 132; (* INT32 *) +s.SeTime = fread(fh,1,'double=>double'); % = 136; (* LONGREAL *) +s.SeTimeMATLAB = obj.HI_time2date(s.SeTime); +s.SePageWidth = fread(fh, 1, 'double=>double') ;% = 144; (* LONGREAL *) +for k=1:4 % = 152; (* ARRAY[0..1] OF UserParamDescrType = 4*40 *) s.SeSwUserParamDescr(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% s.SeSwUserParamDescr(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% end -s.SeFiller1 = deblank(fread(fh,80,'uint8=>char')'); % = 232; (* ARRAY[0..1] OF UserParamDescrType = 2*40 *) -s.SeMethodName = deblank(fread(fh,32,'uint8=>char')');% = 312; (* String32Type *) -% - -s.SePhotoParams1 = fread(fh, 4, 'double=>double'); %= 344; (* ARRAY[0..3] OF LONGREAL = 4*8 *) -s.SeOldLockInParams=getSeLockInParams(fh);% = 376; (* SeLockInSize = 96, see "Pulsed.de" *) -s.SeOldAmplifierState=getAmplifierState(fh);% = 472; (* AmplifierStateSize = 400 *) -s.SeUsername=deblank(fread(fh, 80, 'uint8=>char')');% - -for k=1:4 - s.SeSeUserParamDescr(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% (* ARRAY[0..3] OF UserParamDescrType = 4*40 *) +% s.SeFiller1 = deblank(fread(fh,80,'uint8=>char')'); % = 232; (* ARRAY[0..1] OF UserParamDescrType = 2*40 *) +s.SeMethodName = deblank(fread(fh,32,'uint8=>char')');% = 312; (* String32Type *) +s.SeSeUserParams1 = fread(fh ,4 ,'double=>double');% = 344; (* ARRAY[0..3] OF LONGREAL *) + +s.SeLockInParams = getSeLockInParams(fh);% = 376; (* SeLockInSize = 96, see "Pulsed.de" *) +s.SeAmplifierState = getAmplifierState(fh);% = 472; (* AmplifierStateSize = 400 *) +s.SeUsername = deblank(fread(fh, 80, 'uint8=>char')');% = 872; (* String80Type *) +for k=1:4% = 952; (* ARRAY[0..3] OF UserParamDescrType = 4*40 *) + s.SeSeUserParamDescr(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% = 952; (* ARRAY[0..3] OF UserParamDescrType = 4*40 *) s.SeSeUserParamDescr(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% end -% s.SeOldLockInParams = fread(fh,96); % = 376; (* SeOldLockInSize = 96, see "Pulsed.de" *) -% s.SeOldAmpState = fread(fh,400); % = 472; (* SeOldAmpState = 400 -> the AmplStateRecord is now stored in the .amp file *) -% s.SeUsername = deblank(fread(fh,80,'uint8=>char')); % = 872; (* String80Type *) - -s.SePhotoParams2 = deblank(fread(fh,160,'uint8=>char')'); %= 952; (* ARRAY[0..3] OF UserParamDescrType = 4*40 *) -s.SeFiller1=fread(fh, 1, 'int32=>int32');% = 1112; (* INT32 *) -s.SeCRC=fread(fh, 1, 'int32=>int32');% = 1116; (* CARD32 *) - -s.SeSeUserParams2=fread(fh, 4, 'double=>double'); %= 1120; (* ARRAY[0..3] OF LONGREAL *) +s.SeFiller1 = fread(fh, 1, 'int32=>int32');% = 1112; (* INT32 *) +s.SeCRC = fread(fh, 1, 'int32=>int32');% = 1116; (* CARD32 *) +s.SeSeUserParams2 = fread(fh, 4, 'double=>double'); %= 1120; (* ARRAY[0..3] OF LONGREAL *) for k=1:4 %= 1152; (* ARRAY[0..3] OF UserParamDescrType = 4*40 *) s.SeSeUserParamDescr2(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% s.SeSeUserParamDescr2(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% end -s.SeScanParams=fread(fh, 96, 'uint8=>uint8'); %= 1312; (* ScanParamsSize = 96 (ElProScan Extension) *) -for k=1:8 %= 1408; (* ARRAY[0..7] OF UserParamDescrType = 8*40 *) - s.SeSeUserDescr2(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% - s.SeSeUserDescr2(k).Unit=deblank(fread(fh, 8, 'uint8=>char')'); -end -s.SeriesRecSize=1728;% = 1728; +s.SeScanParams = fread(fh, 96, 'uint8=>uint8'); %= 1312; (* ScanParamsSize = 96 (ElProScan Extension) *) +s.SeriesRecSize = 1408;% = 1408; (* = 176 * 8 *) + + + +% s.SePhotoParams1 = fread(fh, 4, 'double=>double'); % = 344; (* ARRAY[0..3] OF LONGREAL = 4*8 *) + +% s.SeUsername = deblank(fread(fh, 80, 'uint8=>char')');% + + + + + +% s.SeLockInParams = fread(fh,96); % = 376; (* SeOldLockInSize = 96, see "Pulsed.de" *) +% s.SeAmplifierState = fread(fh,400); % = 472; (* SeOldAmpState = 400 -> the AmplStateRecord is now stored in the .amp file *) +% % s.SeUsername = deblank(fread(fh,80,'uint8=>char')); % = 872; (* String80Type *) +% +% s.SePhotoParams2 = deblank(fread(fh,160,'uint8=>char')'); %= 952; (* ARRAY[0..3] OF UserParamDescrType = 4*40 *) +% s.SeFiller1 = fread(fh, 1, 'int32=>int32');% = 1112; (* INT32 *) +% s.SeCRC = fread(fh, 1, 'int32=>int32');% = 1116; (* CARD32 *) +% +% s.SeSeUserParams2 = fread(fh, 4, 'double=>double'); %= 1120; (* ARRAY[0..3] OF LONGREAL *) +% for k=1:4 %= 1152; (* ARRAY[0..3] OF UserParamDescrType = 4*40 *) +% s.SeSeUserParamDescr2(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% +% s.SeSeUserParamDescr2(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% +% end +% s.SeScanParams = fread(fh, 96, 'uint8=>uint8'); %= 1312; (* ScanParamsSize = 96 (ElProScan Extension) *) +% +% for k=1:8 %= 1408; (* ARRAY[0..7] OF UserParamDescrType = 8*40 *) +% s.SeSeUserDescr2(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% +% s.SeSeUserDescr2(k).Unit=deblank(fread(fh, 8, 'uint8=>char')'); +% end +% s.SeriesRecSize = 1728;% = 1728; s=orderfields(s); s.Sweeps = []; % used to store all the sweeps within the recording structure later on From cffaef89ddd152ebd972321ceadb63256b594ead Mon Sep 17 00:00:00 2001 From: ChristianKeine Date: Mon, 24 Jun 2019 09:08:19 -0500 Subject: [PATCH 18/39] v1000 support --- @HEKA_Importer/readPulseFileHEKA.asv | 33 ++++++---- @HEKA_Importer/readPulseFileHEKA.m | 90 ++++++++++++++++++++-------- 2 files changed, 89 insertions(+), 34 deletions(-) diff --git a/@HEKA_Importer/readPulseFileHEKA.asv b/@HEKA_Importer/readPulseFileHEKA.asv index 30c1480..636629e 100644 --- a/@HEKA_Importer/readPulseFileHEKA.asv +++ b/@HEKA_Importer/readPulseFileHEKA.asv @@ -141,15 +141,16 @@ s.SeUsername = deblank(fread(fh, 80, 'uint8=>char')');% = 872; (* String80Typ switch obj.fileData.fileVersion case 9 for k=1:4% = 952; (* ARRAY[0..3] OF UserParamDescrType = 4*40 *) - s.SeSeUserParamDescr(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% - s.SeSeUserParamDescr(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% + s.SeSeUserParamDescr1(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% + s.SeSeUserParamDescr1(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% end case 1000 - + for k=1:4% = 952; (* ARRAY[0..3] OF UserParamDescrType = 4*40 *) + s.SePhotoParams2(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% + s.SePhotoParams2(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% + end end - - s.SeFiller1 = fread(fh, 1, 'int32=>int32');% = 1112; (* INT32 *) s.SeCRC = fread(fh, 1, 'int32=>int32');% = 1116; (* CARD32 *) s.SeSeUserParams2 = fread(fh, 4, 'double=>double'); %= 1120; (* ARRAY[0..3] OF LONGREAL *) @@ -159,7 +160,23 @@ for k=1:4 %= 1152; (* ARRAY[0..3] OF UserParamDescrType = 4*40 *) end s.SeScanParams = fread(fh, 96, 'uint8=>uint8'); %= 1312; (* ScanParamsSize = 96 (ElProScan Extension) *) -s.SeriesRecSize = 1408;% = 1408; (* = 176 * 8 *) + +switch obj.fileData.fileVersion + case 9 + s.SeriesRecSize = 1408;% = 1408; (* = 176 * 8 *) + case 1000 + for k=1:8 % = 1408; (* ARRAY[0..7] OF UserParamDescrType = 8*40 *) + s.SeSeUserDescr2(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% + s.SeSeUserDescr2(k).Unit=deblank(fread(fh, 8, 'uint8=>char')'); + end + s.SeriesRecSize = 1728;% = 1728; +end + + +s=orderfields(s); +s.Sweeps = []; % used to store all the sweeps within the recording structure later on + + @@ -191,10 +208,6 @@ s.SeriesRecSize = 1408;% = 1408; (* = 176 * 8 *) % s.SeSeUserDescr2(k).Unit=deblank(fread(fh, 8, 'uint8=>char')'); % end % s.SeriesRecSize = 1728;% = 1728; - -s=orderfields(s); -s.Sweeps = []; % used to store all the sweeps within the recording structure later on - end %-------------------------------------------------------------------------- diff --git a/@HEKA_Importer/readPulseFileHEKA.m b/@HEKA_Importer/readPulseFileHEKA.m index 798cb41..daafcf8 100644 --- a/@HEKA_Importer/readPulseFileHEKA.m +++ b/@HEKA_Importer/readPulseFileHEKA.m @@ -95,41 +95,87 @@ function readPulseFileHEKA(obj,Level) s.SeComment = deblank(fread(fh, 80, 'uint8=>char')');% = 36; (* String80Type *) s.SeSeriesCount = fread(fh, 1, 'int32=>int32');% = 116; (* INT32 *) s.SeNumbersw = fread(fh, 1, 'int32=>int32');% = 120; (* INT32 *) -s.SeAmplStateOffset = fread(fh, 1, 'int32=>int32');% = 124; (* INT32 * -s.SeAmplStateSeries = fread(fh, 1, 'int32=>int32');% = 128; (* INT32 * +switch obj.fileData.fileVersion + case 9 + s.SeAmplStateOffset = fread(fh, 1, 'int32=>int32');% = 124; (* INT32 * + s.SeAmplStateSeries = fread(fh, 1, 'int32=>int32');% = 128; (* INT32 * + case 1000 + s.SeAmplStateFlag = fread(fh,1,'int32=>int32');% = 124; (* INT32 *) // flag > 0 => load local oldAmpState, otherwise load from .amp File. + s.SeAmplStateRef = fread(fh,1,'int32=>int32'); % = 128; (* INT32 *) // ref = 0 => use local oldAmpState +end + %% -% s.SeAmplStateFlag = fread(fh,1,'int32=>int32');% = 124; (* INT32 *) // flag > 0 => load local oldAmpState, otherwise load from .amp File. -% s.SeAmplStateRef = fread(fh,1,'int32=>int32'); % = 128; (* INT32 *) // ref = 0 => use local oldAmpState s.SeMethodTag = fread(fh,1,'int32=>int32'); % = 132; (* INT32 *) s.SeTime = fread(fh,1,'double=>double'); % = 136; (* LONGREAL *) s.SeTimeMATLAB = obj.HI_time2date(s.SeTime); s.SePageWidth = fread(fh, 1, 'double=>double') ;% = 144; (* LONGREAL *) -for k=1:4 % = 152; (* ARRAY[0..1] OF UserParamDescrType = 4*40 *) - s.SeSwUserParamDescr(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% - s.SeSwUserParamDescr(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% + +switch obj.fileData.fileVersion + case 9 + for k=1:4 % = 152; (* ARRAY[0..1] OF UserParamDescrType = 4*40 *) + s.SeSwUserParamDescr(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% + s.SeSwUserParamDescr(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% + end + case 1000 + for k=1:2 % = 152; (* ARRAY[0..1] OF UserParamDescrType = 4*40 *) + s.SeUserDescr1(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% + s.SeUserDescr1(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% + end + s.SeFiller1 = deblank(fread(fh,80,'uint8=>char')'); % = 232; (* ARRAY[0..1] OF UserParamDescrType = 2*40 *) end -% s.SeFiller1 = deblank(fread(fh,80,'uint8=>char')'); % = 232; (* ARRAY[0..1] OF UserParamDescrType = 2*40 *) + s.SeMethodName = deblank(fread(fh,32,'uint8=>char')');% = 312; (* String32Type *) -s.SeSeUserParams1 = fread(fh ,4 ,'double=>double');% = 344; (* ARRAY[0..3] OF LONGREAL *) -s.SeLockInParams = getSeLockInParams(fh);% = 376; (* SeLockInSize = 96, see "Pulsed.de" *) -s.SeAmplifierState = getAmplifierState(fh);% = 472; (* AmplifierStateSize = 400 *) +switch obj.fileData.fileVersion + case 9 + s.SeSeUserParams1 = fread(fh ,4 ,'double=>double');% = 344; (* ARRAY[0..3] OF LONGREAL *) + s.SeLockInParams = getSeLockInParams(fh);% = 376; (* SeLockInSize = 96, see "Pulsed.de" *) + s.SeAmplifierState = getAmplifierState(fh);% = 472; (* AmplifierStateSize = 400 *) + case 1000 + s.SePhotoParams1 = fread(fh, 4, 'double=>double'); % = 344; (* ARRAY[0..3] OF LONGREAL = 4*8 *) + s.SeOldLockInParams = getSeLockInParams(fh);% = 376; (* SeOldLockInSize = 96, see "Pulsed.de" *) + s.SeOldAmpState = getAmplifierState(fh);% = 472; (* SeOldAmpState = 400 -> the AmplStateRecord is now stored in the .amp file *) +end + s.SeUsername = deblank(fread(fh, 80, 'uint8=>char')');% = 872; (* String80Type *) -for k=1:4% = 952; (* ARRAY[0..3] OF UserParamDescrType = 4*40 *) - s.SeSeUserParamDescr(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% = 952; (* ARRAY[0..3] OF UserParamDescrType = 4*40 *) - s.SeSeUserParamDescr(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% +switch obj.fileData.fileVersion + case 9 + for k=1:4% = 952; (* ARRAY[0..3] OF UserParamDescrType = 4*40 *) + s.SeSeUserParamDescr1(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% + s.SeSeUserParamDescr1(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% + end + case 1000 + for k=1:4% = 952; (* ARRAY[0..3] OF UserParamDescrType = 4*40 *) + s.SePhotoParams2(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% + s.SePhotoParams2(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% + end end -s.SeFiller1 = fread(fh, 1, 'int32=>int32');% = 1112; (* INT32 *) -s.SeCRC = fread(fh, 1, 'int32=>int32');% = 1116; (* CARD32 *) -s.SeSeUserParams2 = fread(fh, 4, 'double=>double'); %= 1120; (* ARRAY[0..3] OF LONGREAL *) -for k=1:4 %= 1152; (* ARRAY[0..3] OF UserParamDescrType = 4*40 *) +s.SeFiller1 = fread(fh, 1, 'int32=>int32');% = 1112; (* INT32 *) +s.SeCRC = fread(fh, 1, 'int32=>int32');% = 1116; (* CARD32 *) +s.SeSeUserParams2 = fread(fh, 4, 'double=>double');% = 1120; (* ARRAY[0..3] OF LONGREAL *) +for k=1:4 % = 1152; (* ARRAY[0..3] OF UserParamDescrType = 4*40 *) s.SeSeUserParamDescr2(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% s.SeSeUserParamDescr2(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% end -s.SeScanParams = fread(fh, 96, 'uint8=>uint8'); %= 1312; (* ScanParamsSize = 96 (ElProScan Extension) *) -s.SeriesRecSize = 1408;% = 1408; (* = 176 * 8 *) +s.SeScanParams = fread(fh, 96, 'uint8=>uint8');% = 1312; (* ScanParamsSize = 96 (ElProScan Extension) *) + +switch obj.fileData.fileVersion + case 9 + s.SeriesRecSize = 1408;% = 1408; (* = 176 * 8 *) + case 1000 + for k=1:8 % = 1408; (* ARRAY[0..7] OF UserParamDescrType = 8*40 *) + s.SeSeUserDescr2(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% + s.SeSeUserDescr2(k).Unit=deblank(fread(fh, 8, 'uint8=>char')'); + end + s.SeriesRecSize = 1728;% = 1728; +end + +s=orderfields(s); +s.Sweeps = []; % used to store all the sweeps within the recording structure later on + + @@ -161,10 +207,6 @@ function readPulseFileHEKA(obj,Level) % s.SeSeUserDescr2(k).Unit=deblank(fread(fh, 8, 'uint8=>char')'); % end % s.SeriesRecSize = 1728;% = 1728; - -s=orderfields(s); -s.Sweeps = []; % used to store all the sweeps within the recording structure later on - end %-------------------------------------------------------------------------- From d7cd750788d6d571b9903a6660d7e6edcb497783 Mon Sep 17 00:00:00 2001 From: ChristianKeine Date: Mon, 24 Jun 2019 09:10:26 -0500 Subject: [PATCH 19/39] v1000 support for sweeps --- @HEKA_Importer/readPulseFileHEKA.asv | 65 ++++++++++++++-------------- @HEKA_Importer/readPulseFileHEKA.m | 50 +++++---------------- 2 files changed, 43 insertions(+), 72 deletions(-) diff --git a/@HEKA_Importer/readPulseFileHEKA.asv b/@HEKA_Importer/readPulseFileHEKA.asv index 636629e..b288fe6 100644 --- a/@HEKA_Importer/readPulseFileHEKA.asv +++ b/@HEKA_Importer/readPulseFileHEKA.asv @@ -97,11 +97,11 @@ s.SeSeriesCount = fread(fh, 1, 'int32=>int32');% = 116; (* INT32 *) s.SeNumbersw = fread(fh, 1, 'int32=>int32');% = 120; (* INT32 *) switch obj.fileData.fileVersion case 9 - s.SeAmplStateOffset = fread(fh, 1, 'int32=>int32');% = 124; (* INT32 * - s.SeAmplStateSeries = fread(fh, 1, 'int32=>int32');% = 128; (* INT32 * + s.SeAmplStateOffset = fread(fh, 1, 'int32=>int32');% = 124; (* INT32 * + s.SeAmplStateSeries = fread(fh, 1, 'int32=>int32');% = 128; (* INT32 * case 1000 - s.SeAmplStateFlag = fread(fh,1,'int32=>int32');% = 124; (* INT32 *) // flag > 0 => load local oldAmpState, otherwise load from .amp File. - s.SeAmplStateRef = fread(fh,1,'int32=>int32'); % = 128; (* INT32 *) // ref = 0 => use local oldAmpState + s.SeAmplStateFlag = fread(fh,1,'int32=>int32');% = 124; (* INT32 *) // flag > 0 => load local oldAmpState, otherwise load from .amp File. + s.SeAmplStateRef = fread(fh,1,'int32=>int32'); % = 128; (* INT32 *) // ref = 0 => use local oldAmpState end %% @@ -112,67 +112,66 @@ s.SePageWidth = fread(fh, 1, 'double=>double') ;% = 144; (* LONGREAL *) switch obj.fileData.fileVersion case 9 - for k=1:4 % = 152; (* ARRAY[0..1] OF UserParamDescrType = 4*40 *) + for k=1:4 % = 152; (* ARRAY[0..1] OF UserParamDescrType = 4*40 *) s.SeSwUserParamDescr(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% s.SeSwUserParamDescr(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% end case 1000 - for k=1:2 % = 152; (* ARRAY[0..1] OF UserParamDescrType = 4*40 *) + for k=1:2 % = 152; (* ARRAY[0..1] OF UserParamDescrType = 4*40 *) s.SeUserDescr1(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% s.SeUserDescr1(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% end - s.SeFiller1 = deblank(fread(fh,80,'uint8=>char')'); % = 232; (* ARRAY[0..1] OF UserParamDescrType = 2*40 *) + s.SeFiller1 = deblank(fread(fh,80,'uint8=>char')'); % = 232; (* ARRAY[0..1] OF UserParamDescrType = 2*40 *) end s.SeMethodName = deblank(fread(fh,32,'uint8=>char')');% = 312; (* String32Type *) switch obj.fileData.fileVersion case 9 - s.SeSeUserParams1 = fread(fh ,4 ,'double=>double'); % = 344; (* ARRAY[0..3] OF LONGREAL *) - s.SeLockInParams = getSeLockInParams(fh);% = 376; (* SeLockInSize = 96, see "Pulsed.de" *) - s.SeAmplifierState = getAmplifierState(fh);% = 472; (* AmplifierStateSize = 400 *) + s.SeSeUserParams1 = fread(fh ,4 ,'double=>double');% = 344; (* ARRAY[0..3] OF LONGREAL *) + s.SeLockInParams = getSeLockInParams(fh);% = 376; (* SeLockInSize = 96, see "Pulsed.de" *) + s.SeAmplifierState = getAmplifierState(fh);% = 472; (* AmplifierStateSize = 400 *) case 1000 - s.SePhotoParams1 = fread(fh, 4, 'double=>double'); % = 344; (* ARRAY[0..3] OF LONGREAL = 4*8 *) - s.SeOldLockInParams = getSeLockInParams(fh);% = 376; (* SeLockInSize = 96, see "Pulsed.de" *) - s.SeOldAmpState = getAmplifierState(fh);% = 472; (* AmplifierStateSize = 400 *) + s.SePhotoParams1 = fread(fh, 4, 'double=>double'); % = 344; (* ARRAY[0..3] OF LONGREAL = 4*8 *) + s.SeOldLockInParams = getSeLockInParams(fh);% = 376; (* SeOldLockInSize = 96, see "Pulsed.de" *) + s.SeOldAmpState = getAmplifierState(fh);% = 472; (* SeOldAmpState = 400 -> the AmplStateRecord is now stored in the .amp file *) end s.SeUsername = deblank(fread(fh, 80, 'uint8=>char')');% = 872; (* String80Type *) switch obj.fileData.fileVersion case 9 - for k=1:4% = 952; (* ARRAY[0..3] OF UserParamDescrType = 4*40 *) + for k=1:4% = 952; (* ARRAY[0..3] OF UserParamDescrType = 4*40 *) s.SeSeUserParamDescr1(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% s.SeSeUserParamDescr1(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% end case 1000 - for k=1:4% = 952; (* ARRAY[0..3] OF UserParamDescrType = 4*40 *) + for k=1:4% = 952; (* ARRAY[0..3] OF UserParamDescrType = 4*40 *) s.SePhotoParams2(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% s.SePhotoParams2(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% end end -s.SeFiller1 = fread(fh, 1, 'int32=>int32');% = 1112; (* INT32 *) -s.SeCRC = fread(fh, 1, 'int32=>int32');% = 1116; (* CARD32 *) -s.SeSeUserParams2 = fread(fh, 4, 'double=>double'); %= 1120; (* ARRAY[0..3] OF LONGREAL *) -for k=1:4 %= 1152; (* ARRAY[0..3] OF UserParamDescrType = 4*40 *) +s.SeFiller1 = fread(fh, 1, 'int32=>int32');% = 1112; (* INT32 *) +s.SeCRC = fread(fh, 1, 'int32=>int32');% = 1116; (* CARD32 *) +s.SeSeUserParams2 = fread(fh, 4, 'double=>double');% = 1120; (* ARRAY[0..3] OF LONGREAL *) +for k=1:4 % = 1152; (* ARRAY[0..3] OF UserParamDescrType = 4*40 *) s.SeSeUserParamDescr2(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% s.SeSeUserParamDescr2(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% end -s.SeScanParams = fread(fh, 96, 'uint8=>uint8'); %= 1312; (* ScanParamsSize = 96 (ElProScan Extension) *) +s.SeScanParams = fread(fh, 96, 'uint8=>uint8');% = 1312; (* ScanParamsSize = 96 (ElProScan Extension) *) switch obj.fileData.fileVersion case 9 - s.SeriesRecSize = 1408;% = 1408; (* = 176 * 8 *) + s.SeriesRecSize = 1408;% = 1408; (* = 176 * 8 *) case 1000 - for k=1:8 % = 1408; (* ARRAY[0..7] OF UserParamDescrType = 8*40 *) + for k=1:8 % = 1408; (* ARRAY[0..7] OF UserParamDescrType = 8*40 *) s.SeSeUserDescr2(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% s.SeSeUserDescr2(k).Unit=deblank(fread(fh, 8, 'uint8=>char')'); end - s.SeriesRecSize = 1728;% = 1728; + s.SeriesRecSize = 1728;% = 1728; end - s=orderfields(s); s.Sweeps = []; % used to store all the sweeps within the recording structure later on @@ -216,14 +215,16 @@ function sw=getSweep(obj) fh = obj.fileData.fh; -sw.SwMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) -sw.SwLabel=deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Type *) -sw.SwAuxDataFileOffset=fread(fh, 1, 'int32=>int32');% = 36; (* INT32 *) -sw.SwStimCount=fread(fh, 1, 'int32=>int32');% = 40; (* INT32 *) -sw.SwSweepCount=fread(fh, 1, 'int32=>int32');% = 44; (* INT32 *) -sw.SwTime=fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) -sw.SwTimeMATLAB=obj.HI_time2date(sw.SwTime);% Also add in MATLAB datenum format -sw.SwTimer=fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) +sw.SwMark = fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) +sw.SwLabel = deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Type *) +sw.SwAuxDataFileOffset = fread(fh, 1, 'int32=>int32');% = 36; (* INT32 *) +sw.SwStimCount = fread(fh, 1, 'int32=>int32');% = 40; (* INT32 *) +sw.SwSweepCount = fread(fh, 1, 'int32=>int32');% = 44; (* INT32 *) +sw.SwTime = fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) +sw.SwTimeMATLAB = obj.HI_time2date(sw.SwTime);% Also add in MATLAB datenum format +sw.SwTimer= fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) + + sw.SwSwUserParams=fread(fh, 2, 'double=>double');% = 64; (* ARRAY[0..1] OF LONGREAL *) sw.SwPipPressure=fread(fh, 2, 'double=>double'); % = 80; (* LONGREAL * sw.SwRMSNoise=fread(fh,2,'double=>double'); % = 88; (* LONGREAL *) diff --git a/@HEKA_Importer/readPulseFileHEKA.m b/@HEKA_Importer/readPulseFileHEKA.m index daafcf8..3f04a0b 100644 --- a/@HEKA_Importer/readPulseFileHEKA.m +++ b/@HEKA_Importer/readPulseFileHEKA.m @@ -175,38 +175,6 @@ function readPulseFileHEKA(obj,Level) s=orderfields(s); s.Sweeps = []; % used to store all the sweeps within the recording structure later on - - - - -% s.SePhotoParams1 = fread(fh, 4, 'double=>double'); % = 344; (* ARRAY[0..3] OF LONGREAL = 4*8 *) - -% s.SeUsername = deblank(fread(fh, 80, 'uint8=>char')');% - - - - - -% s.SeLockInParams = fread(fh,96); % = 376; (* SeOldLockInSize = 96, see "Pulsed.de" *) -% s.SeAmplifierState = fread(fh,400); % = 472; (* SeOldAmpState = 400 -> the AmplStateRecord is now stored in the .amp file *) -% % s.SeUsername = deblank(fread(fh,80,'uint8=>char')); % = 872; (* String80Type *) -% -% s.SePhotoParams2 = deblank(fread(fh,160,'uint8=>char')'); %= 952; (* ARRAY[0..3] OF UserParamDescrType = 4*40 *) -% s.SeFiller1 = fread(fh, 1, 'int32=>int32');% = 1112; (* INT32 *) -% s.SeCRC = fread(fh, 1, 'int32=>int32');% = 1116; (* CARD32 *) -% -% s.SeSeUserParams2 = fread(fh, 4, 'double=>double'); %= 1120; (* ARRAY[0..3] OF LONGREAL *) -% for k=1:4 %= 1152; (* ARRAY[0..3] OF UserParamDescrType = 4*40 *) -% s.SeSeUserParamDescr2(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% -% s.SeSeUserParamDescr2(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% -% end -% s.SeScanParams = fread(fh, 96, 'uint8=>uint8'); %= 1312; (* ScanParamsSize = 96 (ElProScan Extension) *) -% -% for k=1:8 %= 1408; (* ARRAY[0..7] OF UserParamDescrType = 8*40 *) -% s.SeSeUserDescr2(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% -% s.SeSeUserDescr2(k).Unit=deblank(fread(fh, 8, 'uint8=>char')'); -% end -% s.SeriesRecSize = 1728;% = 1728; end %-------------------------------------------------------------------------- @@ -215,14 +183,16 @@ function readPulseFileHEKA(obj,Level) fh = obj.fileData.fh; -sw.SwMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) -sw.SwLabel=deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Type *) -sw.SwAuxDataFileOffset=fread(fh, 1, 'int32=>int32');% = 36; (* INT32 *) -sw.SwStimCount=fread(fh, 1, 'int32=>int32');% = 40; (* INT32 *) -sw.SwSweepCount=fread(fh, 1, 'int32=>int32');% = 44; (* INT32 *) -sw.SwTime=fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) -sw.SwTimeMATLAB=obj.HI_time2date(sw.SwTime);% Also add in MATLAB datenum format -sw.SwTimer=fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) +sw.SwMark = fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) +sw.SwLabel = deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Type *) +sw.SwAuxDataFileOffset = fread(fh, 1, 'int32=>int32');% = 36; (* INT32 *) +sw.SwStimCount = fread(fh, 1, 'int32=>int32');% = 40; (* INT32 *) +sw.SwSweepCount = fread(fh, 1, 'int32=>int32');% = 44; (* INT32 *) +sw.SwTime = fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) +sw.SwTimeMATLAB = obj.HI_time2date(sw.SwTime);% Also add in MATLAB datenum format +sw.SwTimer = fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) + + sw.SwSwUserParams=fread(fh, 2, 'double=>double');% = 64; (* ARRAY[0..1] OF LONGREAL *) sw.SwPipPressure=fread(fh, 2, 'double=>double'); % = 80; (* LONGREAL * sw.SwRMSNoise=fread(fh,2,'double=>double'); % = 88; (* LONGREAL *) From 30c25b3f49b544c4aa099ab5523b127fd2d27985 Mon Sep 17 00:00:00 2001 From: ChristianKeine Date: Mon, 24 Jun 2019 09:26:50 -0500 Subject: [PATCH 20/39] update sweep export to v1000 --- @HEKA_Importer/readPulseFileHEKA.asv | 89 +++++++++++----------------- @HEKA_Importer/readPulseFileHEKA.m | 45 +++++++++----- 2 files changed, 62 insertions(+), 72 deletions(-) diff --git a/@HEKA_Importer/readPulseFileHEKA.asv b/@HEKA_Importer/readPulseFileHEKA.asv index b288fe6..10e42a4 100644 --- a/@HEKA_Importer/readPulseFileHEKA.asv +++ b/@HEKA_Importer/readPulseFileHEKA.asv @@ -175,38 +175,6 @@ end s=orderfields(s); s.Sweeps = []; % used to store all the sweeps within the recording structure later on - - - - -% s.SePhotoParams1 = fread(fh, 4, 'double=>double'); % = 344; (* ARRAY[0..3] OF LONGREAL = 4*8 *) - -% s.SeUsername = deblank(fread(fh, 80, 'uint8=>char')');% - - - - - -% s.SeLockInParams = fread(fh,96); % = 376; (* SeOldLockInSize = 96, see "Pulsed.de" *) -% s.SeAmplifierState = fread(fh,400); % = 472; (* SeOldAmpState = 400 -> the AmplStateRecord is now stored in the .amp file *) -% % s.SeUsername = deblank(fread(fh,80,'uint8=>char')); % = 872; (* String80Type *) -% -% s.SePhotoParams2 = deblank(fread(fh,160,'uint8=>char')'); %= 952; (* ARRAY[0..3] OF UserParamDescrType = 4*40 *) -% s.SeFiller1 = fread(fh, 1, 'int32=>int32');% = 1112; (* INT32 *) -% s.SeCRC = fread(fh, 1, 'int32=>int32');% = 1116; (* CARD32 *) -% -% s.SeSeUserParams2 = fread(fh, 4, 'double=>double'); %= 1120; (* ARRAY[0..3] OF LONGREAL *) -% for k=1:4 %= 1152; (* ARRAY[0..3] OF UserParamDescrType = 4*40 *) -% s.SeSeUserParamDescr2(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% -% s.SeSeUserParamDescr2(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% -% end -% s.SeScanParams = fread(fh, 96, 'uint8=>uint8'); %= 1312; (* ScanParamsSize = 96 (ElProScan Extension) *) -% -% for k=1:8 %= 1408; (* ARRAY[0..7] OF UserParamDescrType = 8*40 *) -% s.SeSeUserDescr2(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% -% s.SeSeUserDescr2(k).Unit=deblank(fread(fh, 8, 'uint8=>char')'); -% end -% s.SeriesRecSize = 1728;% = 1728; end %-------------------------------------------------------------------------- @@ -215,30 +183,39 @@ function sw=getSweep(obj) fh = obj.fileData.fh; -sw.SwMark = fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) -sw.SwLabel = deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Type *) -sw.SwAuxDataFileOffset = fread(fh, 1, 'int32=>int32');% = 36; (* INT32 *) -sw.SwStimCount = fread(fh, 1, 'int32=>int32');% = 40; (* INT32 *) -sw.SwSweepCount = fread(fh, 1, 'int32=>int32');% = 44; (* INT32 *) -sw.SwTime = fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) -sw.SwTimeMATLAB = obj.HI_time2date(sw.SwTime);% Also add in MATLAB datenum format -sw.SwTimer= fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) - - -sw.SwSwUserParams=fread(fh, 2, 'double=>double');% = 64; (* ARRAY[0..1] OF LONGREAL *) -sw.SwPipPressure=fread(fh, 2, 'double=>double'); % = 80; (* LONGREAL * -sw.SwRMSNoise=fread(fh,2,'double=>double'); % = 88; (* LONGREAL *) -sw.SwTemperature=fread(fh, 1, 'double=>double');% = 96; (* LONGREAL *) -sw.SwOldIntSol=fread(fh, 1, 'int32=>int32');% = 104; (* INT32 *) -sw.SwOldExtSol=fread(fh, 1, 'int32=>int32');% = 108; (* INT32 *) -sw.SwDigitalIn=fread(fh, 1, 'int16=>int16');% = 112; (* SET16 *) -sw.SwSweepKind=fread(fh, 1, 'int16=>int16');% = 114; (* SET16 *) -sw.SwDigitalOut=fread(fh,1, 'int16=>int16'); % = 116; (* SET16 *) -sw.SwFiller1=fread(fh, 1, 'int16=>int16');% = 118; (* INT32 *) -sw.SwMarkers=fread(fh, 4, 'double=>double');% = 120; (* ARRAY[0..3] OF LONGREAL, see SwMarkersNo *) -sw.SwFiller2=fread(fh, 1, 'int32=>int32');% = 152; (* INT32 *) -sw.SwCRC=fread(fh, 1, 'int32=>int32');% = 156; (* CARD32 *) -sw.SwSwHolding=fread(fh,16,'double=>double'); % = 160; (* ARRAY[0..15] OF LONGREAL, see SwHoldingNo *) +sw.SwMark = fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) +sw.SwLabel = deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Type *) +sw.SwAuxDataFileOffset = fread(fh, 1, 'int32=>int32');% = 36; (* INT32 *) +sw.SwStimCount = fread(fh, 1, 'int32=>int32');% = 40; (* INT32 *) +sw.SwSweepCount = fread(fh, 1, 'int32=>int32');% = 44; (* INT32 *) +sw.SwTime = fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) +sw.SwTimeMATLAB = obj.HI_time2date(sw.SwTime);% Also add in MATLAB datenum format +sw.SwTimer = fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) +switch obj.fileDate.fileVersion + case 9 + sw.SwSwUserParams = fread(fh, 4, 'double=>double');% = 64; (* ARRAY[0..3] OF LONGREAL *) + case 1000 + sw.SwSwUserParams = fread(fh, 2, 'double=>double');% = 64; (* ARRAY[0..1] OF LONGREAL *) + sw.SwPipPressure = fread(fh, 2, 'double=>double');% = 80; (* LONGREAL * + sw.SwRMSNoise = fread(fh,2,'double=>double'); % = 88; (* LONGREAL *) +end + +sw.SwSwUserParams = fread(fh, 2, 'double=>double');% = 64; (* ARRAY[0..1] OF LONGREAL *) +sw.SwTemperature = fread(fh, 1, 'double=>double');% = 96; (* LONGREAL *) +sw.SwOldIntSol = fread(fh, 1, 'int32=>int32');% = 104; (* INT32 *) +sw.SwOldExtSol = fread(fh, 1, 'int32=>int32');% = 108; (* INT32 *) +sw.SwDigitalIn = fread(fh, 1, 'int16=>int16');% = 112; (* SET16 *) +sw.SwSweepKind = fread(fh, 1, 'int16=>int16');% = 114; (* SET16 *) +sw.SwDigitalOut = fread(fh,1, 'int16=>int16');% = 116; (* SET16 *) +sw.SwFiller1 = fread(fh, 1, 'int16=>int16');% = 118; (* INT32 *) +sw.SwMarkers = fread(fh, 4, 'double=>double');% = 120; (* ARRAY[0..3] OF LONGREAL, see SwMarkersNo *) +sw.SwFiller2 = fread(fh, 1, 'int32=>int32');% = 152; (* INT32 *) +sw.SwCRC = fread(fh, 1, 'int32=>int32');% = 156; (* CARD32 *) +sw.SwSwHolding = fread(fh,16,'double=>double');% = 160; (* ARRAY[0..15] OF LONGREAL, see SwHoldingNo *) + +switch obj.fileData.fileVersion + case 9 + sw.SwSwUserParamEx=fread(fh,8,'double=>double'); % = 288; (* ARRAY[0..7] OF LONGREAL *) sw.SweepRecSize = 352;% sw=orderfields(sw); diff --git a/@HEKA_Importer/readPulseFileHEKA.m b/@HEKA_Importer/readPulseFileHEKA.m index 3f04a0b..08d8f5d 100644 --- a/@HEKA_Importer/readPulseFileHEKA.m +++ b/@HEKA_Importer/readPulseFileHEKA.m @@ -192,23 +192,36 @@ function readPulseFileHEKA(obj,Level) sw.SwTimeMATLAB = obj.HI_time2date(sw.SwTime);% Also add in MATLAB datenum format sw.SwTimer = fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) +switch obj.fileDate.fileVersion + case 9 + sw.SwSwUserParams = fread(fh, 4, 'double=>double');% = 64; (* ARRAY[0..3] OF LONGREAL *) + case 1000 + sw.SwSwUserParams = fread(fh, 2, 'double=>double');% = 64; (* ARRAY[0..1] OF LONGREAL *) + sw.SwPipPressure = fread(fh, 2, 'double=>double');% = 80; (* LONGREAL * + sw.SwRMSNoise = fread(fh,2,'double=>double'); % = 88; (* LONGREAL *) +end + +sw.SwSwUserParams = fread(fh, 2, 'double=>double');% = 64; (* ARRAY[0..1] OF LONGREAL *) +sw.SwTemperature = fread(fh, 1, 'double=>double');% = 96; (* LONGREAL *) +sw.SwOldIntSol = fread(fh, 1, 'int32=>int32');% = 104; (* INT32 *) +sw.SwOldExtSol = fread(fh, 1, 'int32=>int32');% = 108; (* INT32 *) +sw.SwDigitalIn = fread(fh, 1, 'int16=>int16');% = 112; (* SET16 *) +sw.SwSweepKind = fread(fh, 1, 'int16=>int16');% = 114; (* SET16 *) +sw.SwDigitalOut = fread(fh,1, 'int16=>int16');% = 116; (* SET16 *) +sw.SwFiller1 = fread(fh, 1, 'int16=>int16');% = 118; (* INT32 *) +sw.SwMarkers = fread(fh, 4, 'double=>double');% = 120; (* ARRAY[0..3] OF LONGREAL, see SwMarkersNo *) +sw.SwFiller2 = fread(fh, 1, 'int32=>int32');% = 152; (* INT32 *) +sw.SwCRC = fread(fh, 1, 'int32=>int32');% = 156; (* CARD32 *) +sw.SwSwHolding = fread(fh,16,'double=>double');% = 160; (* ARRAY[0..15] OF LONGREAL, see SwHoldingNo *) + +switch obj.fileData.fileVersion + case 9 + sw.SweepRecSize = 288;% = 288; (* = 36 * 8 *) + case 1000 + sw.SwSwUserParamEx = fread(fh,8,'double=>double'); % = 288; (* ARRAY[0..7] OF LONGREAL *) + sw.SweepRecSize = 352;% = 352; +end -sw.SwSwUserParams=fread(fh, 2, 'double=>double');% = 64; (* ARRAY[0..1] OF LONGREAL *) -sw.SwPipPressure=fread(fh, 2, 'double=>double'); % = 80; (* LONGREAL * -sw.SwRMSNoise=fread(fh,2,'double=>double'); % = 88; (* LONGREAL *) -sw.SwTemperature=fread(fh, 1, 'double=>double');% = 96; (* LONGREAL *) -sw.SwOldIntSol=fread(fh, 1, 'int32=>int32');% = 104; (* INT32 *) -sw.SwOldExtSol=fread(fh, 1, 'int32=>int32');% = 108; (* INT32 *) -sw.SwDigitalIn=fread(fh, 1, 'int16=>int16');% = 112; (* SET16 *) -sw.SwSweepKind=fread(fh, 1, 'int16=>int16');% = 114; (* SET16 *) -sw.SwDigitalOut=fread(fh,1, 'int16=>int16'); % = 116; (* SET16 *) -sw.SwFiller1=fread(fh, 1, 'int16=>int16');% = 118; (* INT32 *) -sw.SwMarkers=fread(fh, 4, 'double=>double');% = 120; (* ARRAY[0..3] OF LONGREAL, see SwMarkersNo *) -sw.SwFiller2=fread(fh, 1, 'int32=>int32');% = 152; (* INT32 *) -sw.SwCRC=fread(fh, 1, 'int32=>int32');% = 156; (* CARD32 *) -sw.SwSwHolding=fread(fh,16,'double=>double'); % = 160; (* ARRAY[0..15] OF LONGREAL, see SwHoldingNo *) -sw.SwSwUserParamEx=fread(fh,8,'double=>double'); % = 288; (* ARRAY[0..7] OF LONGREAL *) -sw.SweepRecSize = 352;% sw=orderfields(sw); sw.Traces = []; % used to store all the traces/channels within the sweep structure later on end From 73831caacf232a637906308b05ac17d12aa2bc85 Mon Sep 17 00:00:00 2001 From: ChristianKeine Date: Mon, 24 Jun 2019 09:35:32 -0500 Subject: [PATCH 21/39] update trace import --- @HEKA_Importer/readPulseFileHEKA.asv | 141 ++++++++++++++------------- @HEKA_Importer/readPulseFileHEKA.m | 133 +++++++++++++------------ 2 files changed, 138 insertions(+), 136 deletions(-) diff --git a/@HEKA_Importer/readPulseFileHEKA.asv b/@HEKA_Importer/readPulseFileHEKA.asv index 10e42a4..379e27e 100644 --- a/@HEKA_Importer/readPulseFileHEKA.asv +++ b/@HEKA_Importer/readPulseFileHEKA.asv @@ -191,6 +191,7 @@ sw.SwSweepCount = fread(fh, 1, 'int32=>int32');% = 44; (* INT32 *) sw.SwTime = fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) sw.SwTimeMATLAB = obj.HI_time2date(sw.SwTime);% Also add in MATLAB datenum format sw.SwTimer = fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) + switch obj.fileDate.fileVersion case 9 sw.SwSwUserParams = fread(fh, 4, 'double=>double');% = 64; (* ARRAY[0..3] OF LONGREAL *) @@ -215,9 +216,12 @@ sw.SwSwHolding = fread(fh,16,'double=>double');% = 160; (* ARRAY[0..15] OF switch obj.fileData.fileVersion case 9 + sw.SweepRecSize = 288;% = 288; (* = 36 * 8 *) + case 1000 + sw.SwSwUserParamEx = fread(fh,8,'double=>double'); % = 288; (* ARRAY[0..7] OF LONGREAL *) + sw.SweepRecSize = 352;% = 352; +end -sw.SwSwUserParamEx=fread(fh,8,'double=>double'); % = 288; (* ARRAY[0..7] OF LONGREAL *) -sw.SweepRecSize = 352;% sw=orderfields(sw); sw.Traces = []; % used to store all the traces/channels within the sweep structure later on end @@ -227,75 +231,74 @@ function tr=getTrace(obj) %-------------------------------------------------------------------------- fh = obj.fileData.fh; -tr.TrMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) -tr.TrLabel=deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Type *) -tr.TrTraceCount=fread(fh, 1, 'int32=>int32');% = 36; (* INT32 *) -tr.TrData=fread(fh, 1, 'int32=>int32');% = 40; (* INT32 *) -tr.TrDataPoints=fread(fh, 1, 'int32=>int32');% = 44; (* INT32 *) -tr.TrInternalSolution=fread(fh, 1, 'int32=>int32');% = 48; (* INT32 *) -tr.TrAverageCount=fread(fh, 1, 'int32=>int32');% = 52; (* INT32 *) -tr.TrLeakCount=fread(fh, 1, 'int32=>int32');% = 56; (* INT32 *) -tr.TrLeakTraces=fread(fh, 1, 'int32=>int32');% = 60; (* INT32 *) -tr.TrDataKind=fread(fh, 1, 'uint16=>uint16');% = 64; (* SET16 *) NB Stored unsigned -tr.TrFiller1=fread(fh, 1, 'int16=>int16');% = 66; (* SET16 *) -tr.TrRecordingMode=fread(fh, 1, 'uint8=>uint8');% = 68; (* BYTE *) -tr.TrAmplIndex=fread(fh, 1, 'uint8=>uint8');% = 69; (* CHAR *) -tr.TrDataFormat=fread(fh, 1, 'uint8=>uint8');% = 70; (* BYTE *) -tr.TrDataAbscissa=fread(fh, 1, 'uint8=>uint8');% = 71; (* BYTE *) -tr.TrDataScaler=fread(fh, 1, 'double=>double');% = 72; (* LONGREAL *) -tr.TrTimeOffset=fread(fh, 1, 'double=>double');% = 80; (* LONGREAL *) -tr.TrZeroData=fread(fh, 1, 'double=>double');% = 88; (* LONGREAL *) -tr.TrYUnit=deblank(fread(fh, 8, 'uint8=>char')');% = 96; (* String8Type *) -tr.TrXInterval=fread(fh, 1, 'double=>double');% = 104; (* LONGREAL *) -tr.TrXStart=fread(fh, 1, 'double=>double');% = 112; (* LONGREAL *) +tr.TrMark = fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) +tr.TrLabel = deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Type *) +tr.TrTraceCount = fread(fh, 1, 'int32=>int32');% = 36; (* INT32 *) +tr.TrData = fread(fh, 1, 'int32=>int32');% = 40; (* INT32 *) +tr.TrDataPoints = fread(fh, 1, 'int32=>int32');% = 44; (* INT32 *) +tr.TrInternalSolution = fread(fh, 1, 'int32=>int32');% = 48; (* INT32 *) +tr.TrAverageCount = fread(fh, 1, 'int32=>int32');% = 52; (* INT32 *) +tr.TrLeakCount = fread(fh, 1, 'int32=>int32');% = 56; (* INT32 *) +tr.TrLeakTraces = fread(fh, 1, 'int32=>int32');% = 60; (* INT32 *) +tr.TrDataKind = fread(fh, 1, 'uint16=>uint16');% = 64; (* SET16 *) NB Stored unsigned +tr.TrFiller1 = fread(fh, 1, 'int16=>int16');% = 66; (* SET16 *) +tr.TrRecordingMode = fread(fh, 1, 'uint8=>uint8');% = 68; (* BYTE *) +tr.TrAmplIndex = fread(fh, 1, 'uint8=>uint8');% = 69; (* CHAR *) +tr.TrDataFormat = fread(fh, 1, 'uint8=>uint8');% = 70; (* BYTE *) +tr.TrDataAbscissa = fread(fh, 1, 'uint8=>uint8');% = 71; (* BYTE *) +tr.TrDataScaler = fread(fh, 1, 'double=>double');% = 72; (* LONGREAL *) +tr.TrTimeOffset = fread(fh, 1, 'double=>double');% = 80; (* LONGREAL *) +tr.TrZeroData = fread(fh, 1, 'double=>double');% = 88; (* LONGREAL *) +tr.TrYUnit = deblank(fread(fh, 8, 'uint8=>char')');% = 96; (* String8Type *) +tr.TrXInterval = fread(fh, 1, 'double=>double');% = 104; (* LONGREAL *) +tr.TrXStart = fread(fh, 1, 'double=>double');% = 112; (* LONGREAL *) % 17.04.10 TrXUnit bytes may include some trailing characters after NULL % byte -tr.TrXUnit=deblank(fread(fh, 8, 'uint8=>char')');% = 120; (* String8Type *) -tr.TrYRange=fread(fh, 1, 'double=>double');% = 128; (* LONGREAL *) -tr.TrYOffset=fread(fh, 1, 'double=>double');% = 136; (* LONGREAL *) -tr.TrBandwidth=fread(fh, 1, 'double=>double');% = 144; (* LONGREAL *) -tr.TrPipetteResistance=fread(fh, 1, 'double=>double');% = 152; (* LONGREAL *) -tr.TrCellPotential=fread(fh, 1, 'double=>double');% = 160; (* LONGREAL *) -tr.TrSealResistance=fread(fh, 1, 'double=>double');% = 168; (* LONGREAL *) -tr.TrCSlow=fread(fh, 1, 'double=>double');% = 176; (* LONGREAL *) -tr.TrGSeries=fread(fh, 1, 'double=>double');% = 184; (* LONGREAL *) -tr.TrRsValue=fread(fh, 1, 'double=>double');% = 192; (* LONGREAL *) -tr.TrGLeak=fread(fh, 1, 'double=>double');% = 200; (* LONGREAL *) -tr.TrMConductance=fread(fh, 1, 'double=>double');% = 208; (* LONGREAL *) -tr.TrLinkDAChannel=fread(fh, 1, 'int32=>int32');% = 216; (* INT32 *) -tr.TrValidYrange=fread(fh, 1, 'uint8=>logical');% = 220; (* BOOLEAN *) -tr.TrAdcMode=fread(fh, 1, 'uint8=>uint8');% = 221; (* CHAR *) -tr.TrAdcChannel=fread(fh, 1, 'int16=>int16');% = 222; (* INT16 *) -tr.TrYmin=fread(fh, 1, 'double=>double');% = 224; (* LONGREAL *) -tr.TrYmax=fread(fh, 1, 'double=>double');% = 232; (* LONGREAL *) -tr.TrSourceChannel=fread(fh, 1, 'int32=>int32');% = 240; (* INT32 *) -tr.TrExternalSolution=fread(fh, 1, 'int32=>int32');% = 244; (* INT32 *) -tr.TrCM=fread(fh, 1, 'double=>double');% = 248; (* LONGREAL *) -tr.TrGM=fread(fh, 1, 'double=>double');% = 256; (* LONGREAL *) -tr.TrPhase=fread(fh, 1, 'double=>double');% = 264; (* LONGREAL *) -tr.TrDataCRC=fread(fh, 1, 'int32=>int32');% = 272; (* CARD32 *) -tr.TrCRC=fread(fh, 1, 'int32=>int32');% = 276; (* CARD32 *) -tr.TrGS=fread(fh, 1, 'double=>double');% = 280; (* LONGREAL *) -tr.TrSelfChannel=fread(fh, 1, 'int32=>int32');% = 288; (* INT32 *) - -% Added 15.08.2012 -tr.TrInterleaveSize=fread(fh, 1, 'int32=>int32');% = 292; (* INT32 *) -tr.TrInterleaveSkip=fread(fh, 1, 'int32=>int32');% = 296; (* INT32 *) -tr.TrImageIndex=fread(fh, 1, 'int32=>int32');% = 300; (* INT32 *) -tr.TrMarkers=fread(fh, 10, 'double=>double');% = 304; (* ARRAY[0..9] OF LONGREAL *) -tr.TrSECM_X=fread(fh, 1, 'double=>double');% = 384; (* LONGREAL *) -tr.TrSECM_Y=fread(fh, 1, 'double=>double');% = 392; (* LONGREAL *) -tr.TrSECM_Z=fread(fh, 1, 'double=>double');% = 400; (* LONGREAL *) -tr.TrTrHolding = fread(fh, 1, 'double=>double');% = 408; (* LONGREAL *) -tr.TrTcEnumerator = fread(fh, 1, 'int32=>int32');% = 416; (* INT32 *) -tr.TrXTrace = fread(fh, 1, 'int32=>int32');% = 420; (* INT32 *) -tr.TrIntSolValue = fread(fh, 1, 'double=>double');% = 424; (* LONGREAL *) -tr.TrExtSolValue = fread(fh, 1, 'double=>double');% = 432; (* LONGREAL *) -tr.TrIntSolName = deblank(fread(fh, 32, 'uint8=>char')');% = 440; (* String32Size *) -tr.TrExtSolName = deblank(fread(fh, 32, 'uint8=>char')');% = 472; (* String32Size *) -tr.TrDataPedestal = fread(fh, 1, 'double=>double');% = 504; (* LONGREAL *) - -tr.TraceRecSize=512; %(* = 64 * 8 *) +tr.TrXUnit = deblank(fread(fh, 8, 'uint8=>char')');% = 120; (* String8Type *) +tr.TrYRange = fread(fh, 1, 'double=>double');% = 128; (* LONGREAL *) +tr.TrYOffset = fread(fh, 1, 'double=>double');% = 136; (* LONGREAL *) +tr.TrBandwidth = fread(fh, 1, 'double=>double');% = 144; (* LONGREAL *) +tr.TrPipetteResistance = fread(fh, 1, 'double=>double');% = 152; (* LONGREAL *) +tr.TrCellPotential = fread(fh, 1, 'double=>double');% = 160; (* LONGREAL *) +tr.TrSealResistance = fread(fh, 1, 'double=>double');% = 168; (* LONGREAL *) +tr.TrCSlow = fread(fh, 1, 'double=>double');% = 176; (* LONGREAL *) +tr.TrGSeries = fread(fh, 1, 'double=>double');% = 184; (* LONGREAL *) +tr.TrRsValue = fread(fh, 1, 'double=>double');% = 192; (* LONGREAL *) +tr.TrGLeak = fread(fh, 1, 'double=>double');% = 200; (* LONGREAL *) +tr.TrMConductance = fread(fh, 1, 'double=>double');% = 208; (* LONGREAL *) +tr.TrLinkDAChannel = fread(fh, 1, 'int32=>int32');% = 216; (* INT32 *) +tr.TrValidYrange = fread(fh, 1, 'uint8=>logical');% = 220; (* BOOLEAN *) +tr.TrAdcMode = fread(fh, 1, 'uint8=>uint8');% = 221; (* CHAR *) +tr.TrAdcChannel = fread(fh, 1, 'int16=>int16');% = 222; (* INT16 *) +tr.TrYmin = fread(fh, 1, 'double=>double');% = 224; (* LONGREAL *) +tr.TrYmax = fread(fh, 1, 'double=>double');% = 232; (* LONGREAL *) +tr.TrSourceChannel = fread(fh, 1, 'int32=>int32');% = 240; (* INT32 *) +tr.TrExternalSolution = fread(fh, 1, 'int32=>int32');% = 244; (* INT32 *) +tr.TrCM = fread(fh, 1, 'double=>double');% = 248; (* LONGREAL *) +tr.TrGM = fread(fh, 1, 'double=>double');% = 256; (* LONGREAL *) +tr.TrPhase = fread(fh, 1, 'double=>double');% = 264; (* LONGREAL *) +tr.TrDataCRC = fread(fh, 1, 'int32=>int32');% = 272; (* CARD32 *) +tr.TrCRC = fread(fh, 1, 'int32=>int32');% = 276; (* CARD32 *) +tr.TrGS = fread(fh, 1, 'double=>double');% = 280; (* LONGREAL *) +tr.TrSelfChannel = fread(fh, 1, 'int32=>int32');% = 288; (* INT32 *) + +tr.TrInterleaveSize = fread(fh, 1, 'int32=>int32');% = 292; (* INT32 *) +tr.TrInterleaveSkip = fread(fh, 1, 'int32=>int32');% = 296; (* INT32 *) +tr.TrImageIndex = fread(fh, 1, 'int32=>int32');% = 300; (* INT32 *) +tr.TrMarkers = fread(fh, 10, 'double=>double');% = 304; (* ARRAY[0..9] OF LONGREAL *) +tr.TrSECM_X = fread(fh, 1, 'double=>double');% = 384; (* LONGREAL *) +tr.TrSECM_Y = fread(fh, 1, 'double=>double');% = 392; (* LONGREAL *) +tr.TrSECM_Z = fread(fh, 1, 'double=>double');% = 400; (* LONGREAL *) +tr.TrTrHolding = fread(fh, 1, 'double=>double');% = 408; (* LONGREAL *) +tr.TrTcEnumerator = fread(fh, 1, 'int32=>int32');% = 416; (* INT32 *) +tr.TrXTrace = fread(fh, 1, 'int32=>int32');% = 420; (* INT32 *) +tr.TrIntSolValue = fread(fh, 1, 'double=>double');% = 424; (* LONGREAL *) +tr.TrExtSolValue = fread(fh, 1, 'double=>double');% = 432; (* LONGREAL *) +tr.TrIntSolName = deblank(fread(fh, 32, 'uint8=>char')');% = 440; (* String32Size *) +tr.TrExtSolName = deblank(fread(fh, 32, 'uint8=>char')');% = 472; (* String32Size *) +tr.TrDataPedestal = fread(fh, 1, 'double=>double');% = 504; (* LONGREAL *) + +tr.TraceRecSize=512;% (* = 64 * 8 *) tr=orderfields(tr); diff --git a/@HEKA_Importer/readPulseFileHEKA.m b/@HEKA_Importer/readPulseFileHEKA.m index 08d8f5d..af384eb 100644 --- a/@HEKA_Importer/readPulseFileHEKA.m +++ b/@HEKA_Importer/readPulseFileHEKA.m @@ -231,75 +231,74 @@ function readPulseFileHEKA(obj,Level) %-------------------------------------------------------------------------- fh = obj.fileData.fh; -tr.TrMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) -tr.TrLabel=deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Type *) -tr.TrTraceCount=fread(fh, 1, 'int32=>int32');% = 36; (* INT32 *) -tr.TrData=fread(fh, 1, 'int32=>int32');% = 40; (* INT32 *) -tr.TrDataPoints=fread(fh, 1, 'int32=>int32');% = 44; (* INT32 *) -tr.TrInternalSolution=fread(fh, 1, 'int32=>int32');% = 48; (* INT32 *) -tr.TrAverageCount=fread(fh, 1, 'int32=>int32');% = 52; (* INT32 *) -tr.TrLeakCount=fread(fh, 1, 'int32=>int32');% = 56; (* INT32 *) -tr.TrLeakTraces=fread(fh, 1, 'int32=>int32');% = 60; (* INT32 *) -tr.TrDataKind=fread(fh, 1, 'uint16=>uint16');% = 64; (* SET16 *) NB Stored unsigned -tr.TrFiller1=fread(fh, 1, 'int16=>int16');% = 66; (* SET16 *) -tr.TrRecordingMode=fread(fh, 1, 'uint8=>uint8');% = 68; (* BYTE *) -tr.TrAmplIndex=fread(fh, 1, 'uint8=>uint8');% = 69; (* CHAR *) -tr.TrDataFormat=fread(fh, 1, 'uint8=>uint8');% = 70; (* BYTE *) -tr.TrDataAbscissa=fread(fh, 1, 'uint8=>uint8');% = 71; (* BYTE *) -tr.TrDataScaler=fread(fh, 1, 'double=>double');% = 72; (* LONGREAL *) -tr.TrTimeOffset=fread(fh, 1, 'double=>double');% = 80; (* LONGREAL *) -tr.TrZeroData=fread(fh, 1, 'double=>double');% = 88; (* LONGREAL *) -tr.TrYUnit=deblank(fread(fh, 8, 'uint8=>char')');% = 96; (* String8Type *) -tr.TrXInterval=fread(fh, 1, 'double=>double');% = 104; (* LONGREAL *) -tr.TrXStart=fread(fh, 1, 'double=>double');% = 112; (* LONGREAL *) +tr.TrMark = fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) +tr.TrLabel = deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Type *) +tr.TrTraceCount = fread(fh, 1, 'int32=>int32');% = 36; (* INT32 *) +tr.TrData = fread(fh, 1, 'int32=>int32');% = 40; (* INT32 *) +tr.TrDataPoints = fread(fh, 1, 'int32=>int32');% = 44; (* INT32 *) +tr.TrInternalSolution = fread(fh, 1, 'int32=>int32');% = 48; (* INT32 *) +tr.TrAverageCount = fread(fh, 1, 'int32=>int32');% = 52; (* INT32 *) +tr.TrLeakCount = fread(fh, 1, 'int32=>int32');% = 56; (* INT32 *) +tr.TrLeakTraces = fread(fh, 1, 'int32=>int32');% = 60; (* INT32 *) +tr.TrDataKind = fread(fh, 1, 'uint16=>uint16');% = 64; (* SET16 *) NB Stored unsigned +tr.TrFiller1 = fread(fh, 1, 'int16=>int16');% = 66; (* SET16 *) +tr.TrRecordingMode = fread(fh, 1, 'uint8=>uint8');% = 68; (* BYTE *) +tr.TrAmplIndex = fread(fh, 1, 'uint8=>uint8');% = 69; (* CHAR *) +tr.TrDataFormat = fread(fh, 1, 'uint8=>uint8');% = 70; (* BYTE *) +tr.TrDataAbscissa = fread(fh, 1, 'uint8=>uint8');% = 71; (* BYTE *) +tr.TrDataScaler = fread(fh, 1, 'double=>double');% = 72; (* LONGREAL *) +tr.TrTimeOffset = fread(fh, 1, 'double=>double');% = 80; (* LONGREAL *) +tr.TrZeroData = fread(fh, 1, 'double=>double');% = 88; (* LONGREAL *) +tr.TrYUnit = deblank(fread(fh, 8, 'uint8=>char')');% = 96; (* String8Type *) +tr.TrXInterval = fread(fh, 1, 'double=>double');% = 104; (* LONGREAL *) +tr.TrXStart = fread(fh, 1, 'double=>double');% = 112; (* LONGREAL *) % 17.04.10 TrXUnit bytes may include some trailing characters after NULL % byte -tr.TrXUnit=deblank(fread(fh, 8, 'uint8=>char')');% = 120; (* String8Type *) -tr.TrYRange=fread(fh, 1, 'double=>double');% = 128; (* LONGREAL *) -tr.TrYOffset=fread(fh, 1, 'double=>double');% = 136; (* LONGREAL *) -tr.TrBandwidth=fread(fh, 1, 'double=>double');% = 144; (* LONGREAL *) -tr.TrPipetteResistance=fread(fh, 1, 'double=>double');% = 152; (* LONGREAL *) -tr.TrCellPotential=fread(fh, 1, 'double=>double');% = 160; (* LONGREAL *) -tr.TrSealResistance=fread(fh, 1, 'double=>double');% = 168; (* LONGREAL *) -tr.TrCSlow=fread(fh, 1, 'double=>double');% = 176; (* LONGREAL *) -tr.TrGSeries=fread(fh, 1, 'double=>double');% = 184; (* LONGREAL *) -tr.TrRsValue=fread(fh, 1, 'double=>double');% = 192; (* LONGREAL *) -tr.TrGLeak=fread(fh, 1, 'double=>double');% = 200; (* LONGREAL *) -tr.TrMConductance=fread(fh, 1, 'double=>double');% = 208; (* LONGREAL *) -tr.TrLinkDAChannel=fread(fh, 1, 'int32=>int32');% = 216; (* INT32 *) -tr.TrValidYrange=fread(fh, 1, 'uint8=>logical');% = 220; (* BOOLEAN *) -tr.TrAdcMode=fread(fh, 1, 'uint8=>uint8');% = 221; (* CHAR *) -tr.TrAdcChannel=fread(fh, 1, 'int16=>int16');% = 222; (* INT16 *) -tr.TrYmin=fread(fh, 1, 'double=>double');% = 224; (* LONGREAL *) -tr.TrYmax=fread(fh, 1, 'double=>double');% = 232; (* LONGREAL *) -tr.TrSourceChannel=fread(fh, 1, 'int32=>int32');% = 240; (* INT32 *) -tr.TrExternalSolution=fread(fh, 1, 'int32=>int32');% = 244; (* INT32 *) -tr.TrCM=fread(fh, 1, 'double=>double');% = 248; (* LONGREAL *) -tr.TrGM=fread(fh, 1, 'double=>double');% = 256; (* LONGREAL *) -tr.TrPhase=fread(fh, 1, 'double=>double');% = 264; (* LONGREAL *) -tr.TrDataCRC=fread(fh, 1, 'int32=>int32');% = 272; (* CARD32 *) -tr.TrCRC=fread(fh, 1, 'int32=>int32');% = 276; (* CARD32 *) -tr.TrGS=fread(fh, 1, 'double=>double');% = 280; (* LONGREAL *) -tr.TrSelfChannel=fread(fh, 1, 'int32=>int32');% = 288; (* INT32 *) - -% Added 15.08.2012 -tr.TrInterleaveSize=fread(fh, 1, 'int32=>int32');% = 292; (* INT32 *) -tr.TrInterleaveSkip=fread(fh, 1, 'int32=>int32');% = 296; (* INT32 *) -tr.TrImageIndex=fread(fh, 1, 'int32=>int32');% = 300; (* INT32 *) -tr.TrMarkers=fread(fh, 10, 'double=>double');% = 304; (* ARRAY[0..9] OF LONGREAL *) -tr.TrSECM_X=fread(fh, 1, 'double=>double');% = 384; (* LONGREAL *) -tr.TrSECM_Y=fread(fh, 1, 'double=>double');% = 392; (* LONGREAL *) -tr.TrSECM_Z=fread(fh, 1, 'double=>double');% = 400; (* LONGREAL *) -tr.TrTrHolding = fread(fh, 1, 'double=>double');% = 408; (* LONGREAL *) -tr.TrTcEnumerator = fread(fh, 1, 'int32=>int32');% = 416; (* INT32 *) -tr.TrXTrace = fread(fh, 1, 'int32=>int32');% = 420; (* INT32 *) -tr.TrIntSolValue = fread(fh, 1, 'double=>double');% = 424; (* LONGREAL *) -tr.TrExtSolValue = fread(fh, 1, 'double=>double');% = 432; (* LONGREAL *) -tr.TrIntSolName = deblank(fread(fh, 32, 'uint8=>char')');% = 440; (* String32Size *) -tr.TrExtSolName = deblank(fread(fh, 32, 'uint8=>char')');% = 472; (* String32Size *) -tr.TrDataPedestal = fread(fh, 1, 'double=>double');% = 504; (* LONGREAL *) - -tr.TraceRecSize=512; %(* = 64 * 8 *) +tr.TrXUnit = deblank(fread(fh, 8, 'uint8=>char')');% = 120; (* String8Type *) +tr.TrYRange = fread(fh, 1, 'double=>double');% = 128; (* LONGREAL *) +tr.TrYOffset = fread(fh, 1, 'double=>double');% = 136; (* LONGREAL *) +tr.TrBandwidth = fread(fh, 1, 'double=>double');% = 144; (* LONGREAL *) +tr.TrPipetteResistance = fread(fh, 1, 'double=>double');% = 152; (* LONGREAL *) +tr.TrCellPotential = fread(fh, 1, 'double=>double');% = 160; (* LONGREAL *) +tr.TrSealResistance = fread(fh, 1, 'double=>double');% = 168; (* LONGREAL *) +tr.TrCSlow = fread(fh, 1, 'double=>double');% = 176; (* LONGREAL *) +tr.TrGSeries = fread(fh, 1, 'double=>double');% = 184; (* LONGREAL *) +tr.TrRsValue = fread(fh, 1, 'double=>double');% = 192; (* LONGREAL *) +tr.TrGLeak = fread(fh, 1, 'double=>double');% = 200; (* LONGREAL *) +tr.TrMConductance = fread(fh, 1, 'double=>double');% = 208; (* LONGREAL *) +tr.TrLinkDAChannel = fread(fh, 1, 'int32=>int32');% = 216; (* INT32 *) +tr.TrValidYrange = fread(fh, 1, 'uint8=>logical');% = 220; (* BOOLEAN *) +tr.TrAdcMode = fread(fh, 1, 'uint8=>uint8');% = 221; (* CHAR *) +tr.TrAdcChannel = fread(fh, 1, 'int16=>int16');% = 222; (* INT16 *) +tr.TrYmin = fread(fh, 1, 'double=>double');% = 224; (* LONGREAL *) +tr.TrYmax = fread(fh, 1, 'double=>double');% = 232; (* LONGREAL *) +tr.TrSourceChannel = fread(fh, 1, 'int32=>int32');% = 240; (* INT32 *) +tr.TrExternalSolution = fread(fh, 1, 'int32=>int32');% = 244; (* INT32 *) +tr.TrCM = fread(fh, 1, 'double=>double');% = 248; (* LONGREAL *) +tr.TrGM = fread(fh, 1, 'double=>double');% = 256; (* LONGREAL *) +tr.TrPhase = fread(fh, 1, 'double=>double');% = 264; (* LONGREAL *) +tr.TrDataCRC = fread(fh, 1, 'int32=>int32');% = 272; (* CARD32 *) +tr.TrCRC = fread(fh, 1, 'int32=>int32');% = 276; (* CARD32 *) +tr.TrGS = fread(fh, 1, 'double=>double');% = 280; (* LONGREAL *) +tr.TrSelfChannel = fread(fh, 1, 'int32=>int32');% = 288; (* INT32 *) + +tr.TrInterleaveSize = fread(fh, 1, 'int32=>int32');% = 292; (* INT32 *) +tr.TrInterleaveSkip = fread(fh, 1, 'int32=>int32');% = 296; (* INT32 *) +tr.TrImageIndex = fread(fh, 1, 'int32=>int32');% = 300; (* INT32 *) +tr.TrMarkers = fread(fh, 10, 'double=>double');% = 304; (* ARRAY[0..9] OF LONGREAL *) +tr.TrSECM_X = fread(fh, 1, 'double=>double');% = 384; (* LONGREAL *) +tr.TrSECM_Y = fread(fh, 1, 'double=>double');% = 392; (* LONGREAL *) +tr.TrSECM_Z = fread(fh, 1, 'double=>double');% = 400; (* LONGREAL *) +tr.TrTrHolding = fread(fh, 1, 'double=>double');% = 408; (* LONGREAL *) +tr.TrTcEnumerator = fread(fh, 1, 'int32=>int32');% = 416; (* INT32 *) +tr.TrXTrace = fread(fh, 1, 'int32=>int32');% = 420; (* INT32 *) +tr.TrIntSolValue = fread(fh, 1, 'double=>double');% = 424; (* LONGREAL *) +tr.TrExtSolValue = fread(fh, 1, 'double=>double');% = 432; (* LONGREAL *) +tr.TrIntSolName = deblank(fread(fh, 32, 'uint8=>char')');% = 440; (* String32Size *) +tr.TrExtSolName = deblank(fread(fh, 32, 'uint8=>char')');% = 472; (* String32Size *) +tr.TrDataPedestal = fread(fh, 1, 'double=>double');% = 504; (* LONGREAL *) + +tr.TraceRecSize=512;% (* = 64 * 8 *) tr=orderfields(tr); From 5990066ed45e45518066c7f8b32d34a0905c94d5 Mon Sep 17 00:00:00 2001 From: ChristianKeine Date: Mon, 24 Jun 2019 09:44:29 -0500 Subject: [PATCH 22/39] added file format specs --- .../FileFormat_2x90/AmplTreeFile_v9.txt | 258 +++++++ .../FileFormat_2x90/AnalysisFile_v9.txt | 280 ++++++++ .../FileFormat_2x90/DataFile_v9.txt | 125 ++++ .../FileFormat_2x90/DataFormat_v9.doc | Bin 0 -> 72704 bytes .../FileFormat_2x90/FileFormat.txt | 632 ++++++++++++++++++ .../FileFormat_2x90/MarkerFile_v9.txt | 37 + .../FileFormat_2x90/MethodFile_v9.txt | 258 +++++++ .../FileFormat_2x90/PulsedFile_v9.txt | 235 +++++++ .../FileFormat_2x90/SolutionsFile_v9.txt | 41 ++ .../FileFormat_2x90/StimFile_v9.txt | 258 +++++++ .../FileFormat_2x90/TimeFormat.txt | 80 +++ .../FileFormat_v1000/AmplTreeFile_v1000.txt | 220 ++++++ .../FileFormat_v1000/AnalysisFile_v11.txt | 318 +++++++++ .../FileFormat_v1000/DataFile_v1000.txt | 127 ++++ .../FileFormat_v1000/DataFormat_v1000.doc | Bin 0 -> 70144 bytes .../FileFormat_v1000/FileFormat.txt | 631 +++++++++++++++++ .../FileFormat_v1000/MarkerFile_v9.txt | 37 + .../FileFormat_v1000/MethodFile_v9.txt | 259 +++++++ .../FileFormat_v1000/PulsedFile_v1000.txt | 240 +++++++ .../FileFormat_v1000/SolutionsFile_v1000.txt | 41 ++ .../FileFormat_v1000/StimFile_v1000.txt | 260 +++++++ .../FileFormat_v1000/TimeFormat.txt | 79 +++ @HEKA_Importer/readPulseFileHEKA.m | 19 +- 23 files changed, 4417 insertions(+), 18 deletions(-) create mode 100644 @HEKA_Importer/HEKA_FileFormat/FileFormat_2x90/AmplTreeFile_v9.txt create mode 100644 @HEKA_Importer/HEKA_FileFormat/FileFormat_2x90/AnalysisFile_v9.txt create mode 100644 @HEKA_Importer/HEKA_FileFormat/FileFormat_2x90/DataFile_v9.txt create mode 100644 @HEKA_Importer/HEKA_FileFormat/FileFormat_2x90/DataFormat_v9.doc create mode 100644 @HEKA_Importer/HEKA_FileFormat/FileFormat_2x90/FileFormat.txt create mode 100644 @HEKA_Importer/HEKA_FileFormat/FileFormat_2x90/MarkerFile_v9.txt create mode 100644 @HEKA_Importer/HEKA_FileFormat/FileFormat_2x90/MethodFile_v9.txt create mode 100644 @HEKA_Importer/HEKA_FileFormat/FileFormat_2x90/PulsedFile_v9.txt create mode 100644 @HEKA_Importer/HEKA_FileFormat/FileFormat_2x90/SolutionsFile_v9.txt create mode 100644 @HEKA_Importer/HEKA_FileFormat/FileFormat_2x90/StimFile_v9.txt create mode 100644 @HEKA_Importer/HEKA_FileFormat/FileFormat_2x90/TimeFormat.txt create mode 100644 @HEKA_Importer/HEKA_FileFormat/FileFormat_v1000/AmplTreeFile_v1000.txt create mode 100644 @HEKA_Importer/HEKA_FileFormat/FileFormat_v1000/AnalysisFile_v11.txt create mode 100644 @HEKA_Importer/HEKA_FileFormat/FileFormat_v1000/DataFile_v1000.txt create mode 100644 @HEKA_Importer/HEKA_FileFormat/FileFormat_v1000/DataFormat_v1000.doc create mode 100644 @HEKA_Importer/HEKA_FileFormat/FileFormat_v1000/FileFormat.txt create mode 100644 @HEKA_Importer/HEKA_FileFormat/FileFormat_v1000/MarkerFile_v9.txt create mode 100644 @HEKA_Importer/HEKA_FileFormat/FileFormat_v1000/MethodFile_v9.txt create mode 100644 @HEKA_Importer/HEKA_FileFormat/FileFormat_v1000/PulsedFile_v1000.txt create mode 100644 @HEKA_Importer/HEKA_FileFormat/FileFormat_v1000/SolutionsFile_v1000.txt create mode 100644 @HEKA_Importer/HEKA_FileFormat/FileFormat_v1000/StimFile_v1000.txt create mode 100644 @HEKA_Importer/HEKA_FileFormat/FileFormat_v1000/TimeFormat.txt diff --git a/@HEKA_Importer/HEKA_FileFormat/FileFormat_2x90/AmplTreeFile_v9.txt b/@HEKA_Importer/HEKA_FileFormat/FileFormat_2x90/AmplTreeFile_v9.txt new file mode 100644 index 0000000..778f417 --- /dev/null +++ b/@HEKA_Importer/HEKA_FileFormat/FileFormat_2x90/AmplTreeFile_v9.txt @@ -0,0 +1,258 @@ + + PatchMaster v2.74, 28-Nov-2014 + + SizeByte = 1; + SizeChar = 1; + SizeEnum = 1; + SizeBoolean = 1; + SizeInt16 = 2; + SizeCard16 = 2; + SizeSet16 = 2; + SizeInt32 = 4; + SizeCard32 = 4; + SizeReal = 4; + SizeLongReal = 8; + + String8Size = 8; + String32Size = 32; + + StimParams = 10; + StimParamChars = 320; + + RootLevel = 0; + StimulationLevel = 1; + ChannelLevel = 2; + StimSegmentLevel = 3; + + + (* + CompressionMode : Specifies how to the data + -> meaning of bits: + bit 0 (CompReal) -> high = store as real + low = store as int16 + bit 1 (CompMean) -> high = use mean + low = use single sample + bit 2 (CompFilter) -> high = use digital filter + *) + + (* + StimToDacID : Specifies how to convert the Segment "Voltage" to + the actual voltage sent to the DAC + -> meaning of bits: + bit 0 (UseStimScale) -> use StimScale + bit 1 (UseRelative) -> relative to Vmemb + bit 2 (UseFileTemplate) -> use file template + bit 3 (UseForLockIn) -> use for LockIn computation + bit 4 (UseForWavelength) + bit 5 (UseScaling) + bit 6 (UseForChirp) + bit 7 (UseForImaging) + bit 14 (UseReserved) + bit 15 (UseReserved) + *) + + SegmentClass = ( SegmentConstant, + SegmentRamp, + SegmentContinuous, + SegmentConstSine, + SegmentSquarewave, + SegmentChirpwave ); + + IncrementModeType = ( ModeInc, + ModeDec, + ModeIncInterleaved, + ModeDecInterleaved, + ModeAlternate, + ModeLogInc, + ModeLogDec, + ModeLogIncInterleaved, + ModeLogDecInterleaved, + ModeLogAlternate ); + + ExtTriggerType = ( TrigNone, + TrigSeries, + TrigSweep, + TrigSweepNoLeak ); + + AmplModeType = ( AnyAmplMode, + VCAmplMode, + CCAmplMode, + IDensityMode ); + + AutoRangingType = ( AutoRangingOff, + AutoRangingPeak, + AutoRangingMean, + AutoRangingRelSeg ); + + AdcType = ( AdcOff, + Analog, + Digitals, + Digital, + AdcVirtual ); + + LeakStoreType = ( LNone, + LStoreAvg, + LStoreEach, + LNoStore ); + + LeakHoldType = ( Labs, + Lrel, + LabsLH, + LrelLH ); + + BreakType = ( NoBreak, + BreakPos, + BreakNeg ); + + LeakCompType = ( LeakCompSoft, + LeakCompHard ); + + SegStoreType = ( SegNoStore, + SegStore, + SegStoreStart, + SegStoreEnd ); + + + (* StimSegmentRecord = RECORD *) + seMark = 0; (* INT32 *) + seClass = 4; (* BYTE *) + seStoreKind = 5; (* BYTE *) + seVoltageIncMode = 6; (* BYTE *) + seDurationIncMode = 7; (* BYTE *) + seVoltage = 8; (* LONGREAL *) + seVoltageSource = 16; (* INT32 *) + seDeltaVFactor = 20; (* LONGREAL *) + seDeltaVIncrement = 28; (* LONGREAL *) + seDuration = 36; (* LONGREAL *) + seDurationSource = 44; (* INT32 *) + seDeltaTFactor = 48; (* LONGREAL *) + seDeltaTIncrement = 56; (* LONGREAL *) + seFiller1 = 64; (* INT32 *) + seCRC = 68; (* CARD32 *) + seScanRate = 72; (* LONGREAL *) + StimSegmentRecSize = 80; (* = 10 * 8 *) + + (* ChannelRecord = RECORD *) + chMark = 0; (* INT32 *) + chLinkedChannel = 4; (* INT32 *) + chCompressionFactor = 8; (* INT32 *) + chYUnit = 12; (* String8Type *) + chAdcChannel = 20; (* INT16 *) + chAdcMode = 22; (* BYTE *) + chDoWrite = 23; (* BOOLEAN *) + stLeakStore = 24; (* BYTE *) + chAmplMode = 25; (* BYTE *) + chOwnSegTime = 26; (* BOOLEAN *) + chSetLastSegVmemb = 27; (* BOOLEAN *) + chDacChannel = 28; (* INT16 *) + chDacMode = 30; (* BYTE *) + chHasLockInSquare = 31; (* BYTE *) + chRelevantXSegment = 32; (* INT32 *) + chRelevantYSegment = 36; (* INT32 *) + chDacUnit = 40; (* String8Type *) + chHolding = 48; (* LONGREAL *) + chLeakHolding = 56; (* LONGREAL *) + chLeakSize = 64; (* LONGREAL *) + chLeakHoldMode = 72; (* BYTE *) + chLeakAlternate = 73; (* BOOLEAN *) + chAltLeakAveraging = 74; (* BOOLEAN *) + chLeakPulseOn = 75; (* BOOLEAN *) + chStimToDacID = 76; (* SET16 *) + chCompressionMode = 78; (* SET16 *) + chCompressionSkip = 80; (* INT32 *) + chDacBit = 84; (* INT16 *) + chHasLockInSine = 86; (* BOOLEAN *) + chBreakMode = 87; (* BYTE *) + chZeroSeg = 88; (* INT32 *) + chStimSweep = 92; (* INT32 *) + chSine_Cycle = 96; (* LONGREAL *) + chSine_Amplitude = 104; (* LONGREAL *) + chLockIn_VReversal = 112; (* LONGREAL *) + chChirp_StartFreq = 120; (* LONGREAL *) + chChirp_EndFreq = 128; (* LONGREAL *) + chChirp_MinPoints = 136; (* LONGREAL *) + chSquare_NegAmpl = 144; (* LONGREAL *) + chSquare_DurFactor = 152; (* LONGREAL *) + chLockIn_Skip = 160; (* INT32 *) + chPhoto_MaxCycles = 164; (* INT32 *) + chPhoto_SegmentNo = 168; (* INT32 *) + chLockIn_AvgCycles = 172; (* INT32 *) + chImaging_RoiNo = 176; (* INT32 *) + chChirp_Skip = 180; (* INT32 *) + chChirp_Amplitude = 184; (* LONGREAL *) + chPhoto_Adapt = 192; (* BYTE *) + chSine_Kind = 193; (* BYTE *) + chChirp_PreChirp = 194; (* BYTE *) + chSine_Source = 195; (* BYTE *) + chSquare_NegSource = 196; (* BYTE *) + chSquare_PosSource = 197; (* BYTE *) + chChirp_Kind = 198; (* BYTE *) + chChirp_Source = 199; (* BYTE *) + chDacOffset = 200; (* LONGREAL *) + chAdcOffset = 208; (* LONGREAL *) + chTraceMathFormat = 216; (* BYTE *) + chHasChirp = 217; (* BOOLEAN *) + chSquare_Kind = 218; (* BYTE *) + chFiller1 = 219; (* ARRAY[0..5] OF CHAR *) + chSquare_BaseIncr = 224; (* LONGREAL *) + chSquare_Cycle = 232; (* LONGREAL *) + chSquare_PosAmpl = 240; (* LONGREAL *) + chCompressionOffset = 248; (* INT32 *) + chPhotoMode = 252; (* INT32 *) + chBreakLevel = 256; (* LONGREAL *) + chTraceMath = 264; (* String128Type *) + chFiller2 = 392; (* INT32 *) + chCRC = 396; (* CARD32 *) + ChannelRecSize = 400; (* = 50 * 8 *) + + (* StimulationRecord = RECORD *) + stMark = 0; (* INT32 *) + stEntryName = 4; (* String32Type *) + stFileName = 36; (* String32Type *) + stAnalName = 68; (* String32Type *) + stDataStartSegment = 100; (* INT32 *) + stDataStartTime = 104; (* LONGREAL *) + stSampleInterval = 112; (* LONGREAL *) + stSweepInterval = 120; (* LONGREAL *) + stLeakDelay = 128; (* LONGREAL *) + stFilterFactor = 136; (* LONGREAL *) + stNumberSweeps = 144; (* INT32 *) + stNumberLeaks = 148; (* INT32 *) + stNumberAverages = 152; (* INT32 *) + stActualAdcChannels = 156; (* INT32 *) + stActualDacChannels = 160; (* INT32 *) + stExtTrigger = 164; (* BYTE *) + stNoStartWait = 165; (* BOOLEAN *) + stUseScanRates = 166; (* BOOLEAN *) + stNoContAq = 167; (* BOOLEAN *) + stHasLockIn = 168; (* BOOLEAN *) + stOldStartMacKind = 169; (* CHAR *) + stOldEndMacKind = 170; (* BOOLEAN *) + stAutoRange = 171; (* BYTE *) + stBreakNext = 172; (* BOOLEAN *) + stIsExpanded = 173; (* BOOLEAN *) + stLeakCompMode = 174; (* BOOLEAN *) + stHasChirp = 175; (* BOOLEAN *) + stOldStartMacro = 176; (* String32Type *) + stOldEndMacro = 208; (* String32Type *) + sIsGapFree = 240; (* BOOLEAN *) + sHandledExternally = 241; (* BOOLEAN *) + stFiller1 = 242; (* BOOLEAN *) + stFiller2 = 243; (* BOOLEAN *) + stCRC = 244; (* CARD32 *) + StimulationRecSize = 248; (* = 31 * 8 *) + + (* RootRecord = RECORD *) + roVersion = 0; (* INT32 *) + roMark = 4; (* INT32 *) + roVersionName = 8; (* String32Type *) + roMaxSamples = 40; (* INT32 *) + roFiller1 = 44; (* INT32 *) + (* StimParams = 10 *) + (* StimParamChars = 320 *) + roParams = 48; (* ARRAY[0..9] OF LONGREAL *) + roParamText = 128; (* ARRAY[0..9],[0..31]OF CHAR *) + roReserved = 448; (* String128Type *) + roFiller2 = 576; (* INT32 *) + roCRC = 580; (* CARD32 *) + RootRecSize = 584; (* = 73 * 8 *) diff --git a/@HEKA_Importer/HEKA_FileFormat/FileFormat_2x90/AnalysisFile_v9.txt b/@HEKA_Importer/HEKA_FileFormat/FileFormat_2x90/AnalysisFile_v9.txt new file mode 100644 index 0000000..1f68b0a --- /dev/null +++ b/@HEKA_Importer/HEKA_FileFormat/FileFormat_2x90/AnalysisFile_v9.txt @@ -0,0 +1,280 @@ + + PatchMaster v2.74, 27-Dec-2014 + + SizeByte = 1; + SizeChar = 1; + SizeEnum = 1; + SizeBoolean = 1; + SizeInt16 = 2; + SizeCard16 = 2; + SizeSet16 = 2; + SizeInt32 = 4; + SizeCard32 = 4; + SizeReal = 4; + SizeLongReal = 8; + + String8Size = 8; + String32Size = 32; + String64Size = 64; + MaxGraphs = 12; + + RootLevel = 0; + MethodLevel = 1; + FunctionLevel = 2; + + FunctionType = ( SweepCountAbsc, (* general *) + TimeAbsc, + TimerAbsc, + RealtimeAbsc, + SegAmplitude, (* X segment property *) + SegDuration, + ScanRateAbsc, + ExtremumMode, (* Y analysis *) + MaximumMode, + MinimumMode, + MeanMode, + IntegralMode, + VarianceMode, + SlopeMode, + TimeToExtrMode, + AnodicChargeMode, (* potentiostat *) + CathodChargeMode, + CSlowMode, (* potmaster: spare *) + RSeriesMode, (* potmaster: spare *) + UserParam1Mode, + UserParam2Mode, + LockInCMMode, (* lock-in *) + LockInGMMode, + LockInGSMode, + SeriesTime, (* misk *) + StimulusMode, + SegmentTimeAbs, + OpEquationMode, (* math *) + ConstantMode, + OperatorPlusMode, + OperatorMinusMode, + OperatorMultMode, + OperatorDivMode, + OperatorAbsMode, + OperatorLogMode, + OperatorSqrMode, + OperatorInvMode, + OperatorInvLogMode, + OperatorInvSqrMode, + TraceMode, (* trace *) + QMode, + InvTraceMode, + InvQMode, + LnTraceMode, + LnQMode, + LogTraceMode, + LogQMode, + TraceXaxisMode, + FreqMode, (* spectra *) + DensityMode, + HistoAmplMode, (* histogram *) + HistoBinsMode, + OnlineIndex, + ExtrAmplMode, + SegmentTimeRel, + CellPotential, (* potmaster: OCP *) + SealResistance, (* potmaster: ElectrodeArea *) + RsValue, (* potmaster: spare *) + GLeak, (* potmaster: spare *) + MConductance, (* potmaster: spare *) + Temperature, + PipettePressure, (* potmaster: spare *) + InternalSolution, + ExternalSolution, + DigitalIn, + OperatorBitInMode, + ReversalMode, + LockInPhase, + LockInFreq, + TotMeanMode, (* obsolete: replaced by MeanMode + CursorKind *) + DiffMode, + IntSolValue, + ExtSolValue, + OperatorAtanMode, + OperatorInvAtanMode, + TimeToMinMode, + TimeToMaxMode, + TimeToThreshold, + TraceEquationMode, + ThresholdAmpl, + XposMode, + YposMode, + ZposMode, + TraceCountMode, + AP_Baseline, + AP_MaximumAmpl, + AP_MaximumTime, + AP_MinimumAmpl, + AP_MinimumTime, + AP_RiseTime1Dur, + AP_RiseTime1Slope, + AP_RiseTime1Time, + AP_RiseTime2Dur, + AP_RiseTime2Slope, + AP_RiseTime2Time, + AP_Tau, + MatrixXindexMode, + MatrixYindexMode, + YatX_Mode, + ThresholdCount, + SECM_3Dx, + SECM_3Dy, + InterceptMode, + MinAmplMode, + MaxAmplMode, + TauMode ); + + TicDirectionType = ( TicLeft, TicRight, TicBoth ); + + ScaleType = ( ScaleFixed, ScaleSeries, ScaleSweeps ); + + AxisLevelType = ( Min, Zero, Max ); + + AxisTypeType = ( ScaleLinear, + ScaleLog, + ScaleInverse, + ScaleSqrt, + ScaleSquare ); + + MarkerKindType = ( MarkerPoint, + MarkerPlus, + MarkerStar, + MarkerDiamond, + MarkerX, + MarkerSquare ); + + GraphWindowType = ( Win0, Win1, Win2 ); + + NormalizeType = ( NormalizeNone, NormalizeMax, NormalizeMinMax ); + + CursorType = ( Cursor_Segment, (* cursor relative to segment *) + Cursor_Trace ); (* cursor relative to trace *) + + BaselineType = ( Baseline_Zero, (* baseline relative to zero *) + Baseline_Cursors, (* baseline = intersection with cursors *) + Baseline_Auto ); (* baseline = intersection with cursors *) + + SearchDirectionType = ( Search_All, + Search_Positive, + Search_Negative ); + + + (* FunctionRecord = RECORD *) + fnMark = 0; (* INT32 *) + fnName = 4; (* String32Size *) + fnUnit = 36; (* String8Size *) + fnLeftOperand = 44; (* INT16 *) + fnRightOperand = 46; (* INT16 *) + fnLeftBound = 48; (* LONGREAL *) + fnRightBound = 56; (* LONGREAL *) + fnConstant = 64; (* LONGREAL *) + fnXSegmentOffset = 72; (* INT32 *) + fnYSegmentOffset = 76; (* INT32 *) + fnTcEnumarator = 80; (* INT16 *) + fnFunction = 82; (* BYTE *) + fnDoNotebook = 83; (* BOOLEAN *) + fnNoFit = 84; (* BOOLEAN *) + fnNewName = 85; (* BOOLEAN *) + fnTargetValue = 86; (* INT16 *) + fnCursorKind = 88; (* BYTE *) + fnTcKind1 = 89; (* 3 BYTE *) + fnTcKind2 = 90; (* 3 BYTE *) + fnCursorSource = 91; (* BYTE *) + fnCRC = 92; (* CARD32 *) + fnEquation = 96; (* String64Size *) + fnBaselineMode = 160; (* BYTE *) + fnSearchDirection = 161; (* BYTE *) + fnSourceValue = 162; (* INT16 *) + fnCursorAnker = 164; (* INT16 *) + fnSpare1 = 165; (* INT16 *) + FunctionRecSize = 168; (* = 21 * 8 *) + + + (* ScalingRecord = RECORD *) + scMinValue = 0; (* LONGREAL *) + scMaxValue = 8; (* LONGREAL *) + scGridFactor = 16; (* LONGREAL *) + scTicLength = 24; (* INT16 *) + scTicNumber = 26; (* INT16 *) + scTicDirection = 28; (* BYTE *) + scAxisLevel = 29; (* BYTE *) + scAxisType = 30; (* BYTE *) + scScaleMode = 31; (* BYTE *) + scNoUnit = 32; (* BOOLEAN *) + scObsolete = 33; (* BOOLEAN *) + scZeroLine = 34; (* BOOLEAN *) + scGrid = 35; (* BOOLEAN *) + scNice = 36; (* BOOLEAN *) + scLabel = 37; (* BOOLEAN *) + scCentered = 38; (* BOOLEAN *) + scIncludeZero = 39; (* BOOLEAN *) + ScalingRecSize = 40; (* = 5 * 8 *) + + + (* EntryRecord = RECORD *) + enXWave = 0; (* INT16 *) + enYWave = 2; (* INT16 *) + enMarkerSize = 4; (* INT16 *) + enMarkerColorRed = 6; (* CARD16 *) + enMarkerColorGreen = 8; (* CARD16 *) + enMarkerColorBlue = 10; (* CARD16 *) + enMarkerKind = 12; (* BYTE *) + enEActive = 13; (* BOOLEAN *) + enLine = 14; (* BOOLEAN *) + enTraceColor = 15; (* BOOLEAN *) + EntryRecSize = 16; (* = 2 * 8 *) + + + (* GraphRecord = RECORD *) + grGActive = 0; (* BOOLEAN *) + grOverlay = 1; (* BOOLEAN *) + grWrap = 2; (* CHAR *) + grOvrlSwp = 3; (* BOOLEAN *) + grNormalize = 4; (* BYTE *) + grSpare1 = 5; (* BYTE *) + grSpare2 = 6; (* BYTE *) + grSpare3 = 7; (* BYTE *) + grXScaling = 8; (* ScalingRecord; *) + grYScaling = 48; (* ScalingRecord *) + grEntry0 = 88; (* EntryRecSize *) + grEntry1 = 104; (* EntryRecSize *) + grEntry2 = 120; (* EntryRecSize *) + grEntry3 = 136; (* EntryRecSize *) + GraphRecSize = 152; (* = 19 * 8 *) + + + (* MethodRecord = RECORD *) + oaMark = 0; (* INT32 *) + oaEntryName = 4; (* String32Size *) + oaSharedXWin1 = 36; (* BOOLEAN *) + oaSharedXWin2 = 37; (* BOOLEAN *) + oa1 = 38; (* BOOLEAN *) + oa2 = 39; (* BOOLEAN *) + oaGraph0 = 40; (* MaxGraphs * GraphRecSize = 1824 *) + oa3 = 1864; (* INT32 *) + oaCRC = 1868; (* CARD32 *) + oaHeaders = 1872; (* MaxGraphs * String32Size = 384 *) + oaLastXmin = 2256; (* MaxGraphs * LONGREAL = 96 *) + oaLastXmax = 2352; (* MaxGraphs * LONGREAL = 96 *) + oaLastYmin = 2448; (* MaxGraphs * LONGREAL = 96 *) + oaLastYmax = 2544; (* MaxGraphs * LONGREAL = 96 *) + MethodRecSize = 2640; (* = 330 * 8 *) + + + (* RootRecord = RECORD *) + roVersion = 0; (* INT32 *) + roMark = 4; (* INT32 *) + roVersionName = 8; (* String32Size *) + roObsolete = 40; (* BYTE *) (* was StimControl *) + roMaxTraces = 41; (* CHAR *) + roWinDefined = 42; (* BOOLEAN *) + rt1 = 43; (* BYTE *) + roCRC = 44; (* CARD32 *) + roWinNr = 48; (* MaxFileGraphs *) + rt2 = 60; (* INT32 *) + RootRecSize = 64; (* = 6 * 8 *) diff --git a/@HEKA_Importer/HEKA_FileFormat/FileFormat_2x90/DataFile_v9.txt b/@HEKA_Importer/HEKA_FileFormat/FileFormat_2x90/DataFile_v9.txt new file mode 100644 index 0000000..1c0ebaa --- /dev/null +++ b/@HEKA_Importer/HEKA_FileFormat/FileFormat_2x90/DataFile_v9.txt @@ -0,0 +1,125 @@ + + PatchMaster v2.74, 21-Jan-2014 + +1. Data File Types + +There are 4 types of data files: + + - the oldest files where the raw data start at the very beginning + (e.g. converted "PULSE" datafiles) + - the older files where the first 4 byte were "DATA", followed by raw data + - the new files with the empty "bundle" header => signature is "DAT1" + - the new files with the filled "bundle" header => signature is "DAT2" + - note that in "bundle" header the 4 bytes following the signature + are zero! + + +2. Structure of "bundle" Header + +The "bundle" header has the following structure: + + (* BundleHeader = RECORD *) + oSignature = 0; (* ARRAY[0..7] OF CHAR *) + oVersion = 8; (* ARRAY[0..31] OF CHAR *) + oTime = 40; (* LONGREAL *) + oItems = 48; (* INT32 *) + oIsLittleEndian = 52; (* BOOLEAN *) + oReserved = 53; (* ARRAY[0..10] OF CHAR *) + oBundleItems = 64; (* ARRAY[0..11] OF BundleItem *) + BundleHeaderSize = 256; (* = 32 * 8 *) + + (* BundleItem = RECORD *) + oStart = 0; (* INT32 *) + oLength = 4; (* INT32 *) + oExtension = 8; (* ARRAY[0..7] OF CHAR *) + BundleItemSize = 16; (* = 2 * 8 *) + + + Signature is "DAT1" or "DAT2", see above. + "DAT1" signals an empty or invalid BundleHeader + "DAT2" signals a valid BundleHeader + + Version contains the text version of the PatchMaster writing the file + + Time is the date and time of last modification + + Items is the number of valid BundleItem elements + + IsLittleEndian is the endian flag: Windows=TRUE, MacOS=FALSE + + BundleItems is an array of BundleItem, each containing: + "oStart" tells at which offset the respective sub-file starts + "oLength" tells the number of bytes of that file + "oExtension" tells the filename extension of the file. One can + recognize the described file by its filename extension. + + Typically, the following indices are used: + raw data file: ".dat" = 0; + Pulsed Tree file: ".pul" = 1; + PGF Tree file: ".pgf" = 2; + Amplifier file: ".amp" = 3; (* EPC/N only *) + Solution file: ".sol" = 4; (* when storing solutions only *) + Notebook file: ".txt" = 5; (* auto store only *) + reserved: = 6; + Marker file: ".mrk" = 7; + Method file: ".mth" = 8; + Analysis file: ".onl" = 9; + + +3. Structure of Trace Data + +3.1. General + + Trace data are described by the parameters of the "TraceRecord", see Document + "PulsedFileFormat_v9.txt". + + Specifically: + TrData offset [in bytes] into the data file + TrDataPoints number of data points + TrDataKind defines the format: int16, int32, real32, real64 + TrDataScaler scaling factor from raw format to IUPAC units: + ampere, volt, meter, second, etc. + TrInterleaveSize interleave block size [in bytes] + TrInterleaveSkip distance [in bytes] to the next interleave block + TrInterleaveSkip distance [in bytes] from beginning of an interleave block + to the beginning of the following interleaved block + +3.2. Interleaving + + TrInterleaveSize is typically zero, denoting that the data are stored as one + contiguous block. For long continuous acquisitions interleaving is required. + In that case, TrInterleaveSize defines the size [in bytes] of one data block + and TrInterleaveSkip defines how many bytes are to be skipped from beginning + of one block to beginning of the next data block. + + Example: + - TrInterleaveSize = 1000 + - TrInterleaveSkip = 3000 + + | Start of trace data at TrData into data file + V + <- 1000 bytes -------><- 2000 bytes ----------------------><- 1000 bytes -------> + 1. block of trace (data blocks of other traces) 2. block of trace + <- 3000 bytes --------------------------------------------><- ... + + +3.3. "start segment" and "non-stored" Segments + + - "start segment" + If stDataStartSegment > 0 : + Any data originating from a segment before the stDataStartSegment segment, + is not stored, nor any data between the start of stDataStartSegment segment and + stDataStartTime. + + - "non-stored" data + Additionally, any data originating from a segment with seDoStore = false is not stored. + + +4. How to get V-membrane/I-membrane of a Trace + +4.1. Get the stimulus channel which defined the appropriate stimulus pattern. That channel is the one having the index chLinkedChannel. An exception is a LockIn trace. +The chLinkedChannel channel is the parent LockIn current trace, and its chLinkedChannel +is the actual channel defining the appropriate stimulus pattern. + +4.2. The field "Holding" of the chLinkedChannel channel contains now V-membrane/ +I-membrane of the trace. diff --git a/@HEKA_Importer/HEKA_FileFormat/FileFormat_2x90/DataFormat_v9.doc b/@HEKA_Importer/HEKA_FileFormat/FileFormat_2x90/DataFormat_v9.doc new file mode 100644 index 0000000000000000000000000000000000000000..243b0c2ae967ca87df1852142154fb31ed9f1f65 GIT binary patch literal 72704 zcmeHQ349bq)~}f)lSx9j5^lr>A`THEM35T^0tV#1q9VtTOvpfzi8B)*9;>dnipP3@ zAfg=NszFw9R|OOg&{alJaaT}85my1Tq9V%Wk$nGGS9+3}BoO&F>@S_)KUMvz>w5Lx zt5?va8vTyaXt-oLuj)5$Km6pXYn~82ke2_YC%-CSWEkJ2mSs9Tp0ek>X>yNX9 z1Bd>yg*`hcCX%reO<$!!WR@lvR0|FK@Fd0>ve`3d&wMcU!C0Oc^e-l|IqQ(i*pVCy z$MAMR$(2sZ${J}}xVX9i#o}0ucB#-DSG0;@BEMSvb3|1iqJwNCuDc$gx_*j-vC$Cq zpFnR8daP7|s=@=f?l7(!g0M$4V^nTSltUWR8X+Au3A^CB;$+4QWDMYh+BFRMn^6H3 z4#kfvP+zE{VtdtfDx`Ah*k>1^Do=$fzep|T1M!6pm9Jt*<-d*eise*1C;pfZRnC(b z^Fc`XT81iLxKQ;+l}F|L1pcY=K8%ADqpZy>K|{P^Ip#K;O1%Gh!B=ksUugV3C~fiq zr6_q)VF$G970@4saEzr3u<)`;z| zd4~Ec{|7k`!;i5}e`d}or_b;58goU^?&6EPi;t;m>jVjLaNo0TnRMWn{U0nO^ry7ZO~?ELXnE>&!KLes5u>ztHP4 zJlQ-U+nww3$z;DP%a~bYh=!z5LsDe5bWyyCZupA|+?meY+#;RTXA~9~evi?|;6-*Z z=Habcjf!so_r%Y1z9`uzVc{? zW+^<^1iw44Ft^ZWOmyWHB$#POmf1g`S2l zq%c<(Qkbh6k%p?>+3qUxIr9oa!V!$98Z?d2*)Q+eyBRfdOdzmrYBct4>L-6{+tk%kM{UoGd-R;VJr2|*MnOi_{vAu z3z-NK8K*JRo$vG(iN?=!`*R>vyeT;@XBI@%7{*07m4vUCk>i}}!UYq(E?2p*cQJf8 zo$1Q;%u6vy@}!<}#Bx$->TBCaG*2_G*~cir!GX3FcGx$~SwJ|owIu4Wn8 zUQeEp<@U{y+LiBeft+))hA>vXc`jE0 zRpaw}ysoS+W?Lv|VyNaiy>4o)94Uu8+i=cxx^tZ~b6uSwY}XXJ&?9aiPoWVL#kg}B z&viNH7*GtK6a>*AgUDSWQdBXG0heZetx0I|X_g?{EHgQ?X-c5}%Zm`r^SN^8x_rW< zR+<$mSmtu0ya?m7xHEA`aTXH>mCV&((GVDWl7#7V`=mg@7pKHec0qM>JtS?W-YqI0 z@x@@*tUR#GXXH7HprpFhK0df!^lmN*O0Fk!j!$&h=f0LtV7@}g2Mh!yQJZFAVDm}6 zs6~s0Lo`J03AlbSn&`^SG8{;rS%g`mvzh`YQo|q`nI11joU%g2{LXw3p*nP)Pbw{I zsa*IRcR}UCQ{q!o3^7$Xxi*#0R$Nskkbntc^6?2xTvZ^AuIy*U**biIhQl;SnC+?< zBq}6mkc{De*i9%Z#>i|o`^LwQ=Ug$2=po#j;D#YOdc4QuUlom^7DVJ`e!0E>@<@@>>u9R6RU5w#fCmWfC-np(-(b1RYIP>#e zxzU#jn=IJH1y9W0sF#~IPock{&~G?~q+Qw>wPbOkJD=0ihJeOp4~-L&wkmpfewKT# zJFAd9B0=Nr3vLn`VCs!Dt(oWqWK8e;cd7y^%bUynN6a<`j4O1hz~l3|X{3-CRw(7%qRN&=@{X zkg*fJl(Pxha%C3uEX$jRjyiLF9zFx1Sali5lpID2t7vzy8W!eOp@y6-S=3o=Eq_l% zyv*wl*kTsXDIt}L2r4Lurv|0IL zgQs^f+$rEBxghW+bIThdCWPo{Zhu4A3U|4Z@^R$Xqit!%EU&WwG7arjGdOij>tPo6 zRtyI@fqbs=<#^`ld11T@tA-+D9*QS-5VnsdBMd&xH`d$jB5lbRvm~#k zTp7^@BxP}X1X+?Miq<^yT=4glnx(||fV>AU8sIKTIU{|86JEZU!aT&6Pgv;q-Q-ka zHKEoU1v@5orC*E+|i}L=D>xMtwY_}hKpRS z@^rFIuDLXK3rPs43FXZqK@O6B6jp`wry(be&l!_{CBc^l$sF7wQ!guVfrM0KgqW$m zVHyXsq9=xBV03g(%=JMlyBdrw4T$ozRc2$b(+5w5tde%KgCvwPVTs7skb3xPI9RF@ zpHvT%!+;{I7%QFe%ng?8Qbj93P8T+rB_8R6MPNj?PEK@%sRzx$d9AKW6o&LYgaoQJe#%!MB2k~ybb+#{nzoQnjxn5eLnhG=jH7A!(N*+s&^_vgU#);|0! z2n_9grC~`W+HB0DZqV9Sqmxw7J9!<70 z&z%eZkGLf~7;t-nSZwpOBFyxBwI)*qTd{2OqRC6#^i@>Q)b$6de&gm#P} z_GXvDa%r8)MFmas z%;W6F1|KRB6+i|lV|F2Jy`z#euv{#a_^PYCKtA)6uJq6=+_ONR3m}wP?)k=WSPQY;;PVuEvCER_ z$-;^ndoENKsiBiBBb@v^bQK*S_uXgUABi?vgWC$wOIm{CN>K;wln`oO7TN<*paI9A z(6y8Y+pKQ%lN7}3%=cl8#fW*(Qm=s#oK*;+g@DDIl!{vvZqRxNokhtg3x$Ah)Iu*hCGQZ6=(L`yR=e2@vWjywA_W@21usDwqpO&?;M z7bZ-miEcS(da!57TSKhN2IFLVOc@-qjLuzDTf6h#r;1Uhg0Y#F4Vi{PH00G6VKli# z7UM)s(fdGr-3*?W-@pm#>L}+dcczhFm^ahq?Q3-F*`rtL#XT?XX*hCR^E(>@j72my zi{nT03v?fS@guoaq)j|*P7oJJ|9IQu`DjW*fS!2@3@p;H+Rt@m`@8x*UA^vEIglm3 zF)VpU{GhIh_G1Lbi#;ncYLEb*ss79ycWxF;6yGqH$~@PZTgat-ekSeBbM6NhfGs7A z+VIg6FG@AU)nZB8MeR5{dZ-;mk(?4wcL$8_F){F1u`_8ZlXqHeMex~G?1;lot+Kl@Qr`2%tf9;-W<|@cqjR@U1`T*T8}f+SrW* zuUBf%9_7O4a(O2%#z>Xl=j4`fp4ScI4nB|-p^4IqISO{iR|FpZP!5-=cT0>$Co8riUq`Sbet^;A|<{>6m^``qYeA<9D;g!4dQ{w*z?~T`Ysh$J% z9H{3&JqPMJP|tyS4%Bm?o&)t9sOLaE2kJRc&w+Xl)N`Po1N9uJ=RiFN>N#-MasY3w zb_2QtX~1CM9^fJ13E*$Q34r0P&K5u$pe=9?a6aGwQh-6gWMB$#H82&J1>^u8;8tKc zunJfWJPND>{tEmZcp3N?@G-C(_yqV0*bjUI`~<|}4a!D9W1tDp251Y=o0Xk`OMoH3 zP+%A^78nO)06D-PfLnkCz^%YNz`ei{;BjCxum#u(ybinzya#*;dmuYoucs01I9*rXOpt zkeEO!lB~`oD{J-tHU5vG3G0DpfepYrz;<9azV;D<8oBrq(9RwjB|BBNk&J zo5UEW#iAHNgT6@Ga7}|wN!lMY4R4G~+Vh%*v5~ZIH4R!UY2DFCQ3r-o(!82RSZpATj&CG1$qO0flGivzyx3ta5XR$SPU!y{sKG>yaupe zVeWorKYaDWS6_T$`s37(LZ{JnJmqKh5&N)m?hy9f3i}Qzh$L&zTK2TxJUH1dEWb!8 z$f4n8jmuLc#WW*Kq%jVso8OT*spAV3q42I;(^=4E*O?Mn&mLSN1!)+5P9w?EBFQp5 zn^PxRn03im7SY3E-_?y-*O%>!u^G(PEw%xYZ6+{Vr{)!DiN|n3>s_RL^wTqCZOWr< z%cJL%M|i2zzAnic1ZDyXz)K1BQ5?f9mG2+PO7-<4O6BnE;C)l9x$IQGM@yc z1f2vG{U>uC9S_e*hFO(n&l=0Hk^mK&r9#naIqucVa1F-4QEkSa>@(Tsi2&JVvdi}a zWS7Y%zXp&^CVN~8lmTRuQvkBd`+*Zc$7aIjlD+K%kiGr+*bj%k{&MdpAARuNJ8y1z zdE=qyo>}|&>W3d(^yfQnz3KWQUqN0@=5$8Bz&cEm!WY=6V_Oi5vTf!6zvc5EpY=B! z;q%{{n7k?HTL?wY!#Z|MrXAOmuDaA7h*7?tnsSwn&6H`GnzBsCR>`#0n(~sQY}S-* zI`#o#QMP~b|6i21{RzzDn7jLfPHh;Vug}u4JeiiSDdbj&9=1Z zwPq{7OsfeZx0_D}o89^FmzlE!$7`%r%El@U`mf9k)oazHvu5sKwwmherj4dCd(sqV zOU)Q%_l)AK_`!yFAI_tbHZ5?5APvVZx!mI55c0#=H z?SG%MXzjpk0OtVRfmEOm@bl3h4jue*@9v%NZ{N0c^M+^FJ@M!x%NE~r=dFMI z!+dYvEa%l3!k3|)9>i?4(-Uur<2yrrP4PiIPFJLvsH05r$vhry%iv*@?Jz>QGc*+Y zK-{m))t=IQI`$A^IM&M##3@`zB8F&Ra2pj@dv_%=fVc;0h=^X3>0+WC# zKq7wMwi)mgunyP_dQTziQ zg6Y`#i^!CBcEm2Ax|?%)JAd--kk}&}UzIICg4*@*h`PPliXLN)l%+%4?UiA)~xcvd#%h?lQ}zR>+H$RrU71RiU)56p3Y=oE)4OyY5%L) zQLV9*E9q9@8L;lvOF6Sw<&y=C`xoZXspqOIrz*pq``YX513OHg*^!>?N8>*{@d{?>}1`vMYZ-tnVo#E zs>YuDF7mnN0OWI#zqJG)e~Wyre*olbeGXg?KkIH_A8;7>JA9&h&&6{zKnZZOfqSmN zM&NVcFc8-s{uuD{vBTe%eEHeO|J?r8)|WRu_smm&`F7>Q^eDjXxBl_Q`T1E_vGRl8 zZQpqkcetC<9r*IQq61wAid90EnIA9qol)?*LomDYr=5-jNx%w)zVWC>Wb#3__;hDZ8LZnWjlyawrVg|le|@>y1sTuW$j77!;NuG z_kY%v4-H#piU;2&Fee1Z&#sxFdaHW&%pJ^D6J6e9cKL!<>_PtDIP<86U;l?sG3Q78 zf7IsISlX3msKPVgAu{{v*y`!9*IwYCfYDKWC+0Wv;QbQzR>5qyaQrb|czzIG3WqOvZ8TnqJ^!dbh-+aBlp2=qs2cm4-@Q6s1t@&~KKNtU-TAMQ4 zLPYFV@{=vpnRuctQ#2N3u;%w#ZaR1Ujth*vBs|=+L)E$KV8}QFkOn{rok-wa96Y?BJ$t2jk;pvr{0BEH8^^~Gd-?Y zTgGBQrxJ$nOaFAWF|qAo3uqOuydCq9I{twS9{~*l87y+x6!tznYh613;hjsz2O{_8!@4OwHm^U<$|K9Lr4clzR)w>a{Ei|r5Wx@17QdqCopJ8u2=>SoEwGk2Ht`u?|zcPIV*%C60_ zXBGXjeD@=sy~p?ddSLmoHyaIU@%@YQ#?4NCGK zKEM9T4tL*w-%|e#BRlPPfA-eD%Kq({e#zZ?U9FyK{LVG=Td%nJ;1`LT?a#b6=WyT6 z7SGlxhcDh7cW&QnKkM_>X9dxpHr%lF-GTwRw_Grz`NdmoS47X5ao*KmIqo}u`{W5* zyS&`>=(NB0KRmi<;Hb?9HU=UdZT;=FKWuA%w>K~UtHHk=owH!hJqbIXZu0a4cdXrU z&#=IGt^W0Lr=0T(`{ieze0KNIH%gOsWH!2X;HaeA_iSJH@zJja-d)=I?Z|H*%U}82 ztNS~SN?SRmWY)94{kda{ITtQ{?9N@Q_goYAc*ie~K6>AgNBkcg7}n`s_nH;oe6()O z6Pr`6xxVAUjh8p~K0faK=kILW!F&6*)%V}`+mK@kyT@eR7}z$q!=8n?=l|{HtjDez z|3&{lw|#l&`lh>H>-#ZVKBM`I?Uuhhb$vqqEmQV&+Su^vo4anh^`dvXz1bjh`;N@V zKWw>wNt-pPUVrAq$y-}r5#44+!uG*?)_7YSTCitd^Nlf2-!f<4*37%6?!3Bi$R9?2 zHr+q<(A-z{zVXfQ%*|iT-sEk&;!m^o74?p~aO(w!TW@aYd2RXO=9}Zc-+J4hpI&mo zyw}eu==W)Cuh);RkAM26D?g5GGvl0fH$PBt-4Fmp z{~mMuCGD$>{N?E;CBBbt|L3%hBRczo-I zeU=j`*Eec+^JQP$b~vGTgG+8*xux+REbni<@QbJuU4Ly?I^(VVU#`68#(||LPaLcw za(U#ruk|}T=0x6^{jTEsKN-2>r5jfrA3Od1Y0F1F|K09K-`dsK{oaW^*G6A^{KDx)SH9JK-M5+j zR;>N>;0yC^xaaM=|FeAO!0Vpd^yMcR*I)g^w#VPv`Qy279sOwCHF?RsM@(MZ@4D+6 zzVhP%@4t!;?_0fY`+Iw@8~F2Q*=2KjeD}zY4U@8`|FrJvo%{xdB-W%V4`?{gy_da#tz-M=NoiO{Ig4n#`HYKto95he zVegC{$9X#9Z8qIcFlx?<&yLyey3|I5jzr@wYI|F3t=d1rm<+;7%B zGwO?V?@xTQ=*_RE{`B~}H>}w^bm@{0rvB9G!1Zh1JNeJV_ljP5^!-Cb&A*^i8Gjx>Vc606CCh(YHsX~XH+;P@`;vQ) z97@=G$K&6;^W?6j{#mcS`1PmXe{g8e_!YlB^yqHSjze=MJa|KCpO*{vuDQ{Y-DoS# z3H3)k2kJRc&w+Xl)N`Po1N9uJ=fJ6PfP5%g_0uAs*5b5G#?qS6E6lV)$LsyHlxOtw z1q}e)BgZ%4v4;)dl|XuvlHnC1hS#_lz1`RhkdF$|BfogT9PeoYc)X6a1@IUh!m2)S;y8!A>A;P)9JYYUh1Y8ST2V4)_0Q>>C5x5B$kCHshkFgkva{bK9b0DFH zM{~Saj%xWqa$<`iX~MgI{6A-!hXhp{^>mm)rhgbl|KaKO*GAkI(qe=M`= z`l%5$$={1EBH_i6f!=$;`5_21St0oA;(QRP)&Fme`bkFw2WnP7mD+&@6UP{g{%q8l z2`-G~V<8hna<%`P;|CoY;3}$Lvb0hj#dj5&FPIJu=>^T{1x@M!E$YoR$$UlCajIYS z-G)moA;w?Tt3q>$5$N@B>=d5vaXRBqb&Zr2MnI#7LUYLuoX*hz<4-n|>?QG`CS?r4 zMNg8k!lC+4w&QdTs-Nm5TV2!or{h|+S873=YzTqmhx$U}Nd2KQNwz614k5{zvj0RQ z6{4{IID0uT60<+a0FCw`Osw0wVcx)Gyf29pgZ_OTf&0I}?|E3c=W+TamO|qq#I3EM zLa0ysZe4lg>_l4PIhRuK=rD21ieD6>D}>>v zn1yn2j<(}hL|UR{7|;3lvlYL^f$Qk#z*D;7lyW9o-?psgu>{1{XxbB+R;+1%)wE|c z?eCiQyryl^w3jsPRZZKXY5&l)w>0e?O?y|8ygPJxcj)p|jILAV-J#37LzkywiPqV= zyxF?E*}6Oxqw7?8vvqm1b$Ke5XdR);8==b^q03V-x=xihLYFr}m#1QhR+1bcp~)7Z z|3p(#n{2U2UL{+UbSGP)HBD(jvL#;Al(r;W5;RR|RkEd(rYY@9ww$YJN=uV1=V_YK z=48tSnx^`etoxR%`<85(tgjo-V+rWdSWO$LX(Kdkn5GTUv_YCSP}BNqT5nD3p=qg_ zmZE80BrQgdTZ|sJ7(H$(mS~O9;})a)7Nh&7Vu{ug=%pC95~jwj1iuEQXlmRrAIP?p zFg0!^OpRL!Q{z^`)VP%}HEtzLjavy*<5t4dxRo$9ZY4~OTM1L+R>IV{mB8KzT`gg1 z+)9|z!4mi}s?BQLN|+kA5_mf*uNt=!rpB#=sc|b|YTQbg8n+Ur#;t^@aVueJ+)9`l zw-Tntt%Rv@D`8!Vh?w#$0_<`<9?G)_u%Vi!Jc|HRo<)Eu&mzE-XAxk^ zvk0(@bYA6I1TgEUHY=G9Fy&bUwCo3%@+<;cM*>WF76GkG0j4~QfY!MHQ=UaY>t=x7 zDB*KlKeO z%Zs&DDb_tK)>frhbD~&Vm151YVr^B5HD`;pRe^WGTaaKSFGjURS(RdKRf@G$DQ3#5 z6l<$etgT8hQ&y!|Ta{vMRf@G$Db`k{SX-51ZB>f3RVmh1rC3{)Vr^B5VO2z%-BOkl ztZpgaiHHfACz_Iex3-vW-8Z-Hn~Eh`7wYmB>hc!q@>GnjQ@mQJ%Uh_+Q?W#=Lt8h8 zwr&n>-5lDwIka_iXzS+C*3F@-5g9=H;1-v4sG2WOj$RFwr&n>-5g9=H;1-v4yh>#;F_{-4yLS| zLt8h8wr&nRz7B2O9NM}$v~_c6>*ip}x;eCUb1-Gy9NM}$v~_c6>*mnb&7rNEgDLCg z(ALeNb<3fxn?viMLt8h8)>VhLZVs)}4sG2WTK65=x;eCsaA@o1(ALeNt(!yJ90#nM z&>32ZP%Ocku5DAgz77wq>+6(lO4qh2UDungZBx2#U%IwU>AD~3+BT)@{-$f&l&<-b zu5DAg=3lzDP3c5+%?pY|>I8B?RX&IU}MboBgnp4v$8y)3icOE7G*RMVDe+9R5_QqzQ2nP9cEzi3*qzV0ba6J8}<_pGKpudmyn zX~L_d>t5D0;Z+jtbxjjqCDGt_aR0+D?Jm*Y*EHc(5>5G+c5U_S+UnW0)w64>XV+HG zuC1P3TRq5z)MUH1dUkE~?Aq$twbiq0t7q3%&#tYWU0Xf7wt9AL_3T<}?b_nQtiO~UDWg7#on_jAr=9p;tjA=F z?^PSiM!G9^uFLPvbg~z2R_&(U`u0(FCcXmSZ58z+xZf&!Fcp{agUTsyOIg{f((<-Y z4^%(R+$!fuIIdZEKH^q(Ft^HH2KeQyAJ_nZ7ngcJDr3JOHA_r1y&4HTe!l`hedR+)F1DPST z^`)|kxLgVN5yC^)RqS;%Z>-xoZnj)%C=Xw zis2<;L&`d_>bf3WS4j`(&b?`7gf&P>t-UVPbv`Vw z2_I^07pK?x`Ekk_o*$>z$XEPt&W}?nNkXOhvDW%9u+Dpmeb2C`IIzykLElPpP{Bi} zwG_0g^VXpC8MX$crFGp$`nmMX`bh2SydJc!qz4u3VQTHy3#FxX-9PxbwBo9%f}aE~ z)SeG}OY8dj`IFK!yMBJ9&Rc{R&#*;UQRg}E&>7~y4RxLaMQ4};Q|mkjt~|pW*jwjk zgik8X2$kl=T6>5CO6&TLa-Y&OyQBO{otJ|bE6G76&)|3PkXF=rK0H(tKGa$xZm9Eo zD5?n`E~@R0+SEGFhbwEshaR=%!+<)^hd!0~P+=dTN?A~MTGjn)zKvi1?|0`whui6H zzvUy#KUfoMnYi~)cmD~XG0R7?%652Vi+*@qTuV1<>E*Fl-1?8dTR!!#N8lVML8UMR!PGVCbBb7a^;hD~G`C&MTa@}D{s-0BF9 zRpe3uYi&tpC-G_#y<#L@GfJk{gYXcE$klYI&R0;iH|1ab*f zm&=M*n$R~qkhB`@UoY__&Izkk-*`M^-xxhSxX@yk5HC{_O>%{&2j^6E(xb4&c!^Ws zNj%y@D6f;^DyMijh5l1(qw&gS01rJ0jKMhp4<(YYL((Z8HYZ*e&5)>=Gt@|Qz<7`2 zGP>51L8aq-8kd>17W(0c@G{c@<1KRDA#>u@CZ6+-YIEY{CSK=knG-KD@tm`(&575T zcuu^q#9NEkm3Yn()#ijO^PI`7OoWyw8OF)5i40rF@EjR-lwoHXiW-wGSMZvXE#qZ4 zQij81I7o(lW!OW8DG00LD_;5GHR0tR-bcLJ!*k*#o~lO#4M_Vm;F@{21 zPcO;v7iE-`^E4&pNCKVycOYFQ?jYp093i*m2)Qjs$Za`7Zp#sJTaJ+1a)ckq{M?q~ zoZE7Q+?FHcwj3e14A3r&!8Qv6P=;DL=(heu}016ifLjmhw|9<)^qB`RTyi zLPrpC9YH80)?KZRER;DH%A5;j&V|+HgvI7u!3zyC6q1J*7v#B+JiMSF&xPdSMFe>+ zBo8kf$a5iic(Fj93(3O^1oB)+9$pj>=Th<QOZiEc@{?YT{E+>jS=<>>1 zwm(X{Xy#6bc2P*PdOF8?os-gna|-U@F?P-sJi0E!Niv)wL#GU9$uLibJ{cCt@J1Ql zD#JTvc%KZH%J2~xu90D}44;wV^D=x%hFfI#mJHvO;lF4e!Xy3Mi$y3bpIyqIUCN(b z%AZ}zpIyqIUCN(b%AZ}zpIyqIUCN(b%AZ}zpIyqIUCJLGbEbI^9{ouf{wTw5Wq44A zU&wHe40mD~QPE;n^11M1Um3WH{H!sE6EfH;{G^r0*#SJDqcxtYr3Y)f^M_>V(c(~k zRd3e1tZdmbtY7G-!RYbe5tUj%Qh{H(;D?yqdPAa?uvkcv@D zW-6r%9+GYrQ~rQ)1b+4`9#^K&L%Jv~SYeMKB8!vnvT4VJu+ ztq(gY+i{%HQR&Pi*SlBXdfD@`-FQsbveeS-)Y`pl+3(WsBSBohFo^52-KiDZJzYx6 ztB{tZbx>O3q_p4;@Y^g{R-kuDLRQfB4Rx^XF{2b?Eym~`crlO99 zmGZK(?b}T{db+l!2GVj-1!-XorIg=@c4wSD?JnCOrTj)nN=6-&6lD|n6QPx)MalU} zw0>S4Z+&Gg-6CZj4`^C?orRWhI=J4e4syNRGQy|_TSm;HUvm3`haoM^&!Sn>CiQe6 zc;37Y@?2T;N*rffq-Df|hwRu{B;_xNc9-IDLAL9xvgl&&Z&$jC9jk+qqO=qDrz>hF zYpQv^3Ouj79y)*Su2Sozq?hi6q`z<$N;)2c!#eD&^SMg#@EU%0`D|)8pMy&A$QgdJ z`fO@9UxAk5K{3|z>}fZA+*@hRFWn1^_(C1DD&-cj((DO;C6l*(K-m*`Y5we4_1h%R zUjfgT)IpxBbwz4QRrAmaw0>?KZ+#`1!7Qrm%PQEHx;%@freGl*?4fHP01q3%%GB-F z_Xyj1JR*dB$-38i<)@qZPA~Y^AO8goL}0s}zCbV>Up>gi_Xke(Xo~%EdMZdAHOY^A z8(2z;qdR_k--#CF@-JW1BzN#N4N*Vs+D8D?hTzoDXMT`}b`@z+_;Lq*^&t!-FpNR7r3Rq4wUr`Dd{^7sEwh5xarmwvOH zj#2JRugB-f_8S=LYz$ zhC;fI!s2!!^v1;UIzS2=wnODq7Uebn-g^VksXi3N+dt9m&vo(AC4f2;2e?-);r|1l$JP4lD%j0O&gp3QE@M z!?T|QP2nQMLVn!PB>E*L`s)F;{{d2k5b`)07EoBjT%41fCbCOMv}9vOM6$8KI3O=Q zCNi5@23e4vjVoesGuH)+nuT)n@hu~R-?Y2{^+Y5^#J?HEEIX{M(SjY;CJVa#mhjkN zmIw^$#HN8X10-is1T+($v>%*oyL3c1)D?xg@UeRPb#P>XoW4w(ljd_ zccBv=+hdAv7}N=ynX0CwpqfUq2wv03kTqQdYEx(_YD#!4 z$I>aQ0eU~ElU0^xy>vv|pwe);KKiq?K}X6~^Dk00#|+>C*PNJ#a`~5-#`3wy3BGv| zD?pE7eE2-%*CkM7G%IcNL)j7jJ*qfxd?qE|s!wk$-BUsK= z8o|-H$&Ef(M&o}RzL4W)KHi?eyk#^)Q~j-ALs4FACl)u%!h(v0WiyY|DpoqCy``yT z6>>FV=28rN$BWuYGw)24>%|oXu-UPl;^KytMK@ZI6xn1!;J1NqPK3p@%cqf9FA_c+ z_)JNyj%g@<28ySdpma=kO9u!qCqRE2g zrD!Cc&Osw->ap+-j8N+~9H#%Le@sL1Gf+HA_#0Yj!7o7m4RKpgE6GMDh|%DTWEHh9MWGZ;<`|>sqw)90!Hb}1<(p-pfcHz7+ zEJy@t4e9-S$RmEa+blQKxZ#)#BgH4r#M}m2WP3b)&Q@KE-~TbnV4o-!iCBcDMQU1< zrrAUc`FG)Yk|l5$_9fz*FRd`|;aLf)N6fqyiokM^hY-QP+ZM@a49T;=fzcfZC*rkc zj2%Iq;YlJ_dn8=|^pMvq$A@3G1AUq@c0Z5;N23q&JOF$GXCn>{2|k>{Qh~8(!xCU0 zwFBjyi!wR@9f9+JPQdwq14stC0OYok{9g#r11_lmSt4rRZq(Zs_4Gm6W6&@v(?Aje z{L-iRUS3ax@1oBAz(IiepU`)4*#mcpZ%DF~(uTWCG-otTSY5$LO6-SF278WJw8 zcNJ-U!lrdc$>GZEjvB+KrB;#Fqlz@@z3>A!Mlwb?3TJpfoWHG7E-vTtK#DBx$Oejl$#C4S0;nC) z`0C>6AyVc;N7=Keov;CT2iPvr7p^Q}5HJy#B+(b#Bn$#30+S@HXmu?Rpz_M+`0;3W0dJolGgM!0VQGdo zx4EkRoO&yIYX1DUT9JlXWH9>d!PhYRYJX=s_n+pX@3}}R2ui6Lmr~h$eD|0g-C;e;zy`7S_wayRQl&oX=FX=2$d%1 z){tprZRrS=4@Qw6q0(TQ!luzLu+kAKA0`5Rgi3?a4Vy;xg^p19Xjg%bP-&Q~`4K8@ zYuj$t_3hJlg-Y9R{V8g}%0YRd(*EUp$ad_d2BSlzrFHT(`P+x>o(Prp$KjrYkFOm& zCsf+NHZ9w1o4fJpP-#OO=bd-eBQu^4m9}Yo6UX>@|6U&|ZP$R&oj*zX?$c0d4!jY! z!ZG54ijqs$W~TlvIb6P%3%d3TCxfepM_v*xUwcRDh;aG3`Ys$<@cM_VL$z~9uRf#0 z<$EaW?s4JL-pV>~RqExR90^tCkv5;?h0Awa^JShR*4K`Q%D1NZZ#R%Ig-Roxrd_a# zM;yGwMsVM0ozRSyXnRzyQWoDVUN~T*rQQ}J(^YwWB76& zA2OyY$g9OMNZB88s{Rv|r&LJCLWghYHCnI$8wn4VPD4mVlch?jCWq*^>hJ$w4ziRL z`&r(PP_5!NGHlO7<=~d{lyX$f-B5L$dX7`?`Kj0O`{dyJ3|I!LZ3wkr5MD}7JqN7| zXsOv~!8h1N*bmwL2Fv~ZRmkqC*YUrSqiX#iM$*os`M~a?Y@}sioV_v9f9p&0M0U95GgiV0P2Owe9&sH_9qnuYY z%~9SevE^F5tt+o%68b^2?j-a>&AL@v`B1H*`7PvaTkfBTR&oC%DH6_u*txZ`i=ks_ z$f;I3N@r+wL-7V|T>{Awc~mNmLUq1Qrjz$)PFMMRSVVsEh^_kDfD>I*y7ivCN z<$Wm2BhS~IuFm~dQ6G8K=5%%bt4vp(p1Ov-a}}phoiB(G<&igSPA88x)OmwQaXqaB z%<1ZUu}r7chdEuHw~Z3{Y2{*0SLct(bn<@9>FT_TP2{IliaA}KKPS^^Rbft7=l!Ea zep&&U)7AMKGM!ce=5$(7n9qZ4kGS7uPUrG%BB=2lX&3dY^FtNR?}`!Ws{Ago;#`&Y zoIF>nWmQEGvq4nn{o_Rbpw1#)oxdT|)k;~Fr_M(<5c$<=S*5ELa>erx<@K>DL5Ax5 z>UdF}S}Ci`)cIF3U9FZ?x;oEoDDtZnvr1RzKgo2pYF6p${Q5>BzuMeLf_@vgi1^)N z5dN7CvS4xC_X@UPbVrl!X3ABMD(Vd?YQ5zqK6HcB0E+UeHioK%kx+gE8A3IN96`~T zHdu<0BiIIaRQ6+i6tXd@ND2>CQEZL+*a0_B#BmqQi)vx`=`_?rK$VaPgA=ZVswWv$ z0)-F%E~O;FSXJMaP}8t#%eoqs5NgU)CG>#7tG*3Ym9V+iB@BVltX&(n*Sds>Fub*E z!>3i0Q1voOjYY*U3&vTsspiHZ8pa{oY#btC(@(t^d_ir5-CWFLH7ced-$j|WprPD7 zi9s@ z%^7dihMNsAuNpViW<(dGgc*%&r^SaLSC~stZT^*&{l4Ws)AKv$p-Q1OoH)u7!EECQATuK`a@hHctx=vjy>fvbSNSY7l3h5%!MaXF<% zu}@`#EH^QhhkNh@e_NVYEIbb8vss|6FS8j$yVJVOYK4^WgB~XtM5}N7qou)RHvU0I ztJM|}6&Yov)s9;6AS#BG!il)Gn}=JtK1Pp)x!62}<8eEe9?Q;0dQX&tb){9We?U`p zQhppa(Z30Jgqt2Iqg(rUFhaj6x>U5i-B3n;wjc zWY^elZ^;hRrYLtNSlhPVPVa0@y^KnU!RJrKqv-S)x(y;o5AH-X?n#OA5R(uzk00$L z*x?E?Bva~x>N)Ti+iTI!;nDeO_a6c3bHm zJy@3nLZH!*es@J)l$V x*Xg|f16KoI9RB?d?rzI}zh9{}FX?Qqp9~rfN literal 0 HcmV?d00001 diff --git a/@HEKA_Importer/HEKA_FileFormat/FileFormat_2x90/FileFormat.txt b/@HEKA_Importer/HEKA_FileFormat/FileFormat_2x90/FileFormat.txt new file mode 100644 index 0000000..aba604c --- /dev/null +++ b/@HEKA_Importer/HEKA_FileFormat/FileFormat_2x90/FileFormat.txt @@ -0,0 +1,632 @@ + + PatchMaster v2.74, 30-Sep-2014 + +(************************************************************************ + +PatchMaster generates multiple files when you create a data file. They +can be combined into a "bundle" file, if requested. The bundle file format +is described in the document "DataFile_v9.txt". +The files are: + + 1. The data file itself (file with file extension ".dat"). + This raw data file is a continuous data stream. + + 2. The "pul" file, containing acquisition parameters, such as gain, + capacitance, etc. The pointer to the data stored in the raw data + file is also stored in this file. + The information is stored in the "Tree" format described below. + + 3. The "pgf" file, containing the stimulus templates. + The information is stored in the "Tree" format described below. + + 5. The "sol" file containing the solution data base. + The information is stored in the "Tree" format described below. + + 6. The "onl" file containing the stored online analysis methods. + The information is stored in the "Tree" format described below. + + 7. The "mth" file containing the applied acquisition methods. + The format is described in the file "MethodFile_v9.txt". + + 8. The "mrk" file containing the markers. + The information is stored in the "Tree" format described below. + + 9. The optional "amp" file, when a multiple amplifier is used. + It contains the multiple amplifier settings and solutions. + The information is stored in the "Tree" format described below. + + 10. The optional "ana" file with the analysis results created by + FitMaster. + The information is stored in the "Tree" format described below. + +The descriptions of the variables, their names and meanings, and their +respective record offsets are described in the following files: + AmplTreeFile_v9.txt + DataFile_v9.txt + DataFormat_v9.doc + FileFormat.txt + MarkerFile_v9.txt + MethodFile_v9.txt + Online_v9.txt + PulsedFile_v9.txt + SolutionsFile_v9.txt + StimFile_v9.txt + TimeFormat.txt + + +The following is a description of the "Tree" format. Following the +description of the "Tree" format a source code listing is enclosed. +That program shows how to scan and load a "Tree" file. It can be +compiled and executed by the PowerMod environment. The source code +is commented and can easily be translated to other languages. + +The idea behind the "Tree" format is that it allows extending the +information stored in a file without braking the older file format. +Thus, newer program versions can load files created by older program +versions and vice versa without requiring any file conversions. This +approach is presently (in 1995) working since more than 10 years +across many program versions. + +An example tree can be diagrammed as follows: + + Level 0 Record (Root) + Level 1 Record 1 + Level 2 Record 1.1 + Level 3 Record 1.1.1 + Level 3 Record 1.1.2 + Level 2 Record 1.2 + Level 1 Record 2 + Level 2 Record 2.1 + Level 3 Record 2.1.1 + Level 2 Record 2.2 + Level 3 Record 2.2.1 + Level 3 Record 2.2.2 + Level 3 Record 2.2.3 + Level 3 Record 2.2.4 + Level 1 Record 3 + +There is only ever one record of level 0, the root record. The above +tree has four levels, the root (level 0), levels 1 and 2, and the leaf +nodes (level 3). + +The format of a tree stored to a file is as follows: + + 1) Magic number : 054726565H + 2) Number of levels + 3) Level sizes, one per level + 4) Tree records, top down, left-to-right. Each record has the format: + A) Record contents + B) Number of children + +All of the values (except the record contents) are INT32 values, i.e., +32-bit (4 bytes) values. + +The "Tree" format is based on proposals from Stefan Heinemann, +Erwin Neher, and Walter Stuehmer. + +WARNING: Never assume you know the record sizes. The record sizes may + have changed, e.g., because the file has been created by an + older program version which used fewer fields than it is + currently using. You MUST use the record sizes stored in the + files themselves, otherwise you are asking for BIG troubles! + + +The trace data are stored in the data file as follows: + + first trace + -> at offset "Data" + -> having "DataPoints" samples + -> to be scaled with "DataFactor1" + + leak trace, if "Leak" = TRUE + -> at offset (Data + 2*DataPoints) + -> having "DataPoints" samples + -> to be scaled with "DataFactor1" + + second trace, if "SecondTrace" = TRUE + -> at offset: + (Data + 2*DataPoints), if no leak + (Data + 4*DataPoints), if leak present + -> having "DataPoints" samples + -> to be scaled with "DataFactor2" + +notes about stored trace data: +- it is stored "Leak Subtracted" +- but not "Zero Subtracted" +- add the leak to get the "non subtracted" trace +- subtract "ZeroCurrent" from the scaled trace to get the "Zero Subtracted" trace + +notes about the second trace: +- stored without "Leak Subtraction" +- stored without "Zero Subtraction" + +************************************************************************) + + +MODULE FileFormat; + +FROM SYSTEM IMPORT ADR, ADDRESS, BYTE, LONG, SHORT; +FROM SYSTEMp1 IMPORT INT32, ADDADR; + +IMPORT Alert, FileSelect, IOBytes, IOFiles, Strings, TermIO, Buffer; + + +(* + * MagicNumber - This is a special value used as a prefix for a tree + * stored to a file. The value contains the four byte values of the + * characters 'Tree' in order. + * + * SwappedMagicNumber - This is the MagicNumber written by a CPU + * which used the opposite byte ordering. + *) + +CONST + MagicNumber = 054726565H; (* i.e. "Tree" in ASCII *) + SwappedMagicNumber = 065657254H; (* i.e. "eerT" in ASCII *) + + +(* + * SwappedInt32 - Swaps the byte of a 32 bit long variable. + *) + +PROCEDURE SwappedInt32( Value : INT32 ): INT32; +VAR + Source, + Target : POINTER TO ARRAY[0..3] OF BYTE; + Result : INT32; +BEGIN + Source := ADR( Value ); + Target := ADR( Result ); + Target^[0] := Source^[3]; + Target^[1] := Source^[2]; + Target^[2] := Source^[1]; + Target^[3] := Source^[0]; + RETURN Result; +END SwappedInt32; + + +(* + * LoadOneRecord + * + * Loads one data block. + * All "TermIO" statements are for demonstration purpose only. + * + * The variables are + * Stream : the file handle to the open file + * FileSize : the number of bytes the data block has in the + * file. + * MemorySize : the byte length of the memory block where the + * data is going to be stored. + * WhereToStore : the address of where the data block is going + * to be stored. + * + * The procedure returns TRUE, if it encountered no errors. + *) + +PROCEDURE LoadOneRecord( + Stream : IOFiles.FileHandleType; + FileSize : LONGINT; + MemorySize : LONGINT; + WhereToStore : ADDRESS ) + : BOOLEAN; + +VAR + Excess : LONGINT; + FileBytes : LONGINT; + +BEGIN + + (* Here we load the next block of data into memory. + * + * First, we have to compare the number of bytes we can load from the file + * with the bytes of allocated memory for that record. + * + * There are 3 possibilities: + * 1. The size of the allocated memory ("MemorySize") equals the number + * of bytes of the data block in the file ("FileSize"). Thus, we can + * load the complete block. + * 2. There are fewer bytes in the file than we expect. This can occur, + * e.g., when the file has been written by an earlier version which + * used fewer parameters than the present one. In this case, we would + * have to zero out those fields which are not filled with data from + * the file. + * 3. There are more bytes in the file than we expect. This can happen, + * when the program which created that tree file was using more + * parameters than we presently know of. In that case, we would load + * only as much byte as we had reserved RAM for. + *) + + Excess := MemorySize - FileSize; + + IF Excess = 0D THEN + (* The file record has as many bytes as there is space in RAM *) + + FileBytes := MemorySize; + + ELSIF Excess < 0D THEN + (* The file record has more many bytes than there is space in RAM. + * Load only as many bytes as there is space in RAM. + *) + + FileBytes := MemorySize; + + ELSE (* i.e., Excess > 0D *) + (* The file record has fewer bytes than there is space in RAM. + * Load only as many bytes as there are in the file. + *) + + FileBytes := FileSize; + + (* Do not forget to clear the remaining fields which are not going + * to be filled from the file. + *) + + Buffer.Set( ADDADR( WhereToStore, FileSize ), Excess, 0 ); + + END (* IF *); + + RETURN IOBytes.Read( Stream, FileBytes, WhereToStore ); + +END LoadOneRecord; + + +(* + * LoadOneLevel + * + * Processes the loading of one data block from a "Tree", and all + * its "children". + * All "TermIO" statements are for demonstration purpose only. + * + * The variables are + * Stream : the file handle to the open file + * Sizes : the array containing the level sizes + * Levels : the number of levels in the tree + * NeedsByteSwap : the flag telling, whether byte-swapping is needed + * Level : the actual tree level to load + * IsFirst : a flag telling, whether it is the first child + * loaded. This is only required for text output! + * Position : the variable containing the position in the file. + * + * The procedure returns TRUE, if it encountered no errors. + *) + +PROCEDURE LoadOneLevel( + VAR Stream : IOFiles.FileHandleType; + VAR Sizes : ARRAY OF INT32; + VAR Levels : LONGINT; + NeedsByteSwap : BOOLEAN; + Level : LONGINT; + IsFirst : BOOLEAN; + VAR Position : LONGINT ) + : BOOLEAN; + +VAR + Count : INT32; + Size : LONGINT; + Children : LONGINT; + i : INTEGER; + WriteInfo : BOOLEAN; + +BEGIN + + WriteInfo := IsFirst OR ( Level < Levels ); + + IF WriteInfo THEN + FOR i := 1 TO SHORT( Level ) DO + TermIO.WriteString( ' ' ); + END; (* FOR *) + TermIO.WriteString( 'level: ' ); + TermIO.WriteInt( Level, 0 ); + TermIO.WriteString( '; file offset: ' ); + TermIO.WriteInt( Position, 0 ); + END; (* IF *) + + + (* Here would normally be the code which loads the next block of data + * somewhere into memory. In the present example, we just skip the bytes + * containing these data. + * + * In case we would load the data block from the file, we would call the + * following procedure: + + IF NOT + LoadOneRecord( Stream, Sizes[SHORT(Level)], MemorySize, WhereToStore ) + THEN + Alert.IOError( '7-Error' ); + RETURN FALSE; + END; + + (* If byte-swapping is required, we would now have to swap the bytes of all + fields in the loaded record! + *) + + IF NeedsByteSwap THEN ( go and swap the record fields ... ) END; + + * End of code we would call. + *) + + + (* Increase the file pointer by "Sizes[Level]" bytes and set the file position + * just beyond the next data block: + *) + + INC( Position, Sizes[SHORT(Level)] ); + + IF NOT + IOBytes.SetPosition( Stream, IOFiles.FromStart, Position ) + THEN + Alert.IOError( '8-Error' ); + RETURN FALSE; + END; + + + (* The next 4 bytes contain the number of children of the present level. *) + + Size := SIZE( INT32 ); + + IF NOT IOBytes.Read( Stream, Size, ADR(Count) ) THEN + Alert.IOError( '9-Error' ); + RETURN FALSE; + END; + + (* The file pointer increased by 4 bytes: *) + INC( Position, 4 ); + + (* And we swap the bytes, if needed: *) + + IF NeedsByteSwap THEN Count := SwappedInt32( Count ); END; + + IF WriteInfo THEN + TermIO.WriteString( '; children: ' ); + TermIO.WriteInt( Count, 0 ); + TermIO.WriteLn; + END; (* IF *) + + + (* Now, we can proceed to load all the children of the present level, + * if there are any: + *) + + INC( Level ); + + Children := 0D; + + IF Level < Levels THEN + + WHILE Children < Count DO + + IF NOT + LoadOneLevel( + Stream, + Sizes, + Levels, + NeedsByteSwap, + Level, + Children = 0D, + Position ) + THEN + RETURN FALSE; + END; (* IF *) + + INC( Children ); + + END (* WHILE *); + + END (* IF *); + + RETURN TRUE; + +END LoadOneLevel; + + +(* + * LoadTree + * + * Scans a complete Tree. + * All "TermIO" statements are for demonstration purpose only. + * + * The variables are + * Stream : the file handle to the open file + * Sizes : the array is returns the level sizes in the Tree + * on disk. + * Levels : the number of levels in the tree + * NeedsByteSwap : the flag telling, whether byte-swapping is needed + * + * The procedure returns TRUE, if it encountered no errors. + *) + +PROCEDURE LoadTree( + VAR Stream : IOFiles.FileHandleType; + VAR Sizes : ARRAY OF INT32; + VAR Levels : LONGINT; + VAR NeedsByteSwap : BOOLEAN ) + : BOOLEAN; +VAR + Value : INT32; + Position : LONGINT; + Size : LONGINT; + i : INTEGER; + Success : BOOLEAN; + +BEGIN + + (* We start at the beginning of the file. We keep the variable + * "Position" containing the actual position in the file. + *) + + Position := 0D; + + + (* The first 4 bytes should contain the "MagicNumber", see above. + * a variable of type INT32 is a 32-bit long, signed word. + *) + + Size := SIZE( INT32 ); + + IF NOT IOBytes.Read( Stream, Size, ADR(Value) ) THEN + Alert.IOError( '2-Error' ); + RETURN FALSE; + END; + + IF Value = MagicNumber THEN + NeedsByteSwap := FALSE; + ELSIF Value = SwappedMagicNumber THEN + NeedsByteSwap := TRUE; + ELSE + Alert.OK( '3-Error: File does not start with "Tree" !' ); + RETURN FALSE; + END; (* IF *) + + (* The file pointer increased by 4 bytes: *) + INC( Position, 4 ); + + + (* Next we load the number of levels in the Tree, which is stored in the + * next 4 bytes (at offset 4): + *) + + Size := SIZE( INT32 ); + + IF NOT IOBytes.Read( Stream, Size, ADR(Levels) ) THEN + Alert.IOError( '4-Error' ); + RETURN FALSE; + END; + + (* The file pointer increased by 4 bytes: *) + INC( Position, 4 ); + + + (* If the file originates from a platform with opposite byte ordering, + * then we have to swap the bytes: + *) + + IF NeedsByteSwap THEN Levels := SwappedInt32( Levels ); END; + + TermIO.WriteString( ' -> levels: ' ); + TermIO.WriteInt( Levels, 0 ); + + + (* The next bytes contain the sizes of all levels. Thus, there is + * one 4-byte variable for each level, totaling in "Levels" times 4 + * bytes. + * + * First, we check, if the array "Sizes" passed to this procedure is + * large enough to contain all level sizes: + *) + + IF ( Levels <= 0D ) OR ( Levels > LONG(HIGH(Sizes)+1) ) THEN + Alert.OK( '5-Error: number of level either <= 0 or too large!' ); + RETURN FALSE; + END (* IF *); + + + (* Next, we load the "Level Size": *) + + Size := Levels * LONG( SIZE( INT32 ) ); + + IF NOT IOBytes.Read( Stream, Size, ADR(Sizes) ) THEN + Alert.IOError( '6-Error' ); + RETURN FALSE; + END; + + (* The file pointer increased by "Size" bytes: *) + INC( Position, Size ); + + (* And we swap the bytes, if needed: *) + + IF NeedsByteSwap THEN + FOR i := 0 TO SHORT( Levels - 1D ) DO + Sizes[i] := SwappedInt32( Sizes[i] ); + END; (* FOR *) + END; (* IF *) + + TermIO.WriteString( '; sizes: ' ); + FOR i := 0 TO SHORT( Levels - 1D ) DO + TermIO.WriteInt( Sizes[i], 0 ); + IF i < SHORT( Levels - 1D ) THEN + TermIO.WriteString( ', ' ); + END; (* IF *) + END; (* FOR *) + + TermIO.WriteString( '; swap: ' ); + TermIO.WriteBoolean( NeedsByteSwap ); + TermIO.WriteLn; + + + (* Now, the tree data follow. + * We can load them by a recursive procedure: + *) + + Success := + LoadOneLevel( + Stream, + Sizes, + Levels, + NeedsByteSwap, + 0D, + TRUE, + Position ); + + IF Success THEN + TermIO.WriteString( 'total file length: ' ); + TermIO.WriteInt( Position, 0 ); + END; (* IF *) + + TermIO.WriteLn; + TermIO.WriteLn; + + RETURN Success; + +END LoadTree; + + +VAR + FileName : IOFiles.FileNameType; + Stream : IOFiles.FileHandleType; + Sizes : ARRAY[0..9] OF INT32; + Levels : LONGINT; + NeedsByteSwap : BOOLEAN; + Success : BOOLEAN; + Dummy : BOOLEAN; + +BEGIN + + (* Get a filename of a tree file to load: *) + + FileName[0] := 0C; + + IF NOT + FileSelect.Select( + FileName, + '*.*', + FileSelect.ExistingFile, + 'Select the TREE file to scan:' ) + THEN + RETURN; + END; (* IF *) + + TermIO.DoBuffer := TRUE; + TermIO.WriteLn; + TermIO.WriteLine( FileName ); + + + (* Open the file : *) + + IF NOT + IOBytes.Open( FileName, IOFiles.NILEncryption, IOFiles.Read, Stream ) + THEN + Alert.IOError( '1-Error' ); + RETURN; + END; + + + (* Now, load the "Tree" : *) + + Success := LoadTree( Stream, Sizes, Levels, NeedsByteSwap ); + + + (* And, finally, we are done and can close the file. *) + + Dummy := IOBytes.Close( Stream ); + +END FileFormat. \ No newline at end of file diff --git a/@HEKA_Importer/HEKA_FileFormat/FileFormat_2x90/MarkerFile_v9.txt b/@HEKA_Importer/HEKA_FileFormat/FileFormat_2x90/MarkerFile_v9.txt new file mode 100644 index 0000000..0ba8d5e --- /dev/null +++ b/@HEKA_Importer/HEKA_FileFormat/FileFormat_2x90/MarkerFile_v9.txt @@ -0,0 +1,37 @@ + + PatchMaster v2.74, 21-Jan-2014 + + SizeByte = 1; + SizeChar = 1; + SizeEnum = 1; + SizeBoolean = 1; + SizeInt16 = 2; + SizeCard16 = 2; + SizeSet16 = 2; + SizeInt32 = 4; + SizeCard32 = 4; + SizeReal = 4; + SizeLongReal = 8; + + String80Size = 80; + + RootLevel = 0; + MarkerLevel = 1; + + MarkerType = ( MarkerGeneral, + MarkerSolutionIndex, + MarkerSolutionValue ); + + (* MarkerRecord = RECORD *) + MaMarkerTime = 0; (* LONGREAL *) + MaMarkerText = 8; (* String80Type *) + MaMarkerTrace = 88; (* INT32 *) + MaMarkerKind = 92; (* BYTE *) + MaFiller = 93; (* 7 *) + MaCRC = 100; (* CARD32 *) + MarkerRecSize = 104; (* = 13 * 8 *) + + (* RootRecord = RECORD *) + RoVersion = 0; (* INT32 *) + RoCRC = 4; (* CARD32 *) + RootRecSize = 8; (* = 1 * 8 *) \ No newline at end of file diff --git a/@HEKA_Importer/HEKA_FileFormat/FileFormat_2x90/MethodFile_v9.txt b/@HEKA_Importer/HEKA_FileFormat/FileFormat_2x90/MethodFile_v9.txt new file mode 100644 index 0000000..778f417 --- /dev/null +++ b/@HEKA_Importer/HEKA_FileFormat/FileFormat_2x90/MethodFile_v9.txt @@ -0,0 +1,258 @@ + + PatchMaster v2.74, 28-Nov-2014 + + SizeByte = 1; + SizeChar = 1; + SizeEnum = 1; + SizeBoolean = 1; + SizeInt16 = 2; + SizeCard16 = 2; + SizeSet16 = 2; + SizeInt32 = 4; + SizeCard32 = 4; + SizeReal = 4; + SizeLongReal = 8; + + String8Size = 8; + String32Size = 32; + + StimParams = 10; + StimParamChars = 320; + + RootLevel = 0; + StimulationLevel = 1; + ChannelLevel = 2; + StimSegmentLevel = 3; + + + (* + CompressionMode : Specifies how to the data + -> meaning of bits: + bit 0 (CompReal) -> high = store as real + low = store as int16 + bit 1 (CompMean) -> high = use mean + low = use single sample + bit 2 (CompFilter) -> high = use digital filter + *) + + (* + StimToDacID : Specifies how to convert the Segment "Voltage" to + the actual voltage sent to the DAC + -> meaning of bits: + bit 0 (UseStimScale) -> use StimScale + bit 1 (UseRelative) -> relative to Vmemb + bit 2 (UseFileTemplate) -> use file template + bit 3 (UseForLockIn) -> use for LockIn computation + bit 4 (UseForWavelength) + bit 5 (UseScaling) + bit 6 (UseForChirp) + bit 7 (UseForImaging) + bit 14 (UseReserved) + bit 15 (UseReserved) + *) + + SegmentClass = ( SegmentConstant, + SegmentRamp, + SegmentContinuous, + SegmentConstSine, + SegmentSquarewave, + SegmentChirpwave ); + + IncrementModeType = ( ModeInc, + ModeDec, + ModeIncInterleaved, + ModeDecInterleaved, + ModeAlternate, + ModeLogInc, + ModeLogDec, + ModeLogIncInterleaved, + ModeLogDecInterleaved, + ModeLogAlternate ); + + ExtTriggerType = ( TrigNone, + TrigSeries, + TrigSweep, + TrigSweepNoLeak ); + + AmplModeType = ( AnyAmplMode, + VCAmplMode, + CCAmplMode, + IDensityMode ); + + AutoRangingType = ( AutoRangingOff, + AutoRangingPeak, + AutoRangingMean, + AutoRangingRelSeg ); + + AdcType = ( AdcOff, + Analog, + Digitals, + Digital, + AdcVirtual ); + + LeakStoreType = ( LNone, + LStoreAvg, + LStoreEach, + LNoStore ); + + LeakHoldType = ( Labs, + Lrel, + LabsLH, + LrelLH ); + + BreakType = ( NoBreak, + BreakPos, + BreakNeg ); + + LeakCompType = ( LeakCompSoft, + LeakCompHard ); + + SegStoreType = ( SegNoStore, + SegStore, + SegStoreStart, + SegStoreEnd ); + + + (* StimSegmentRecord = RECORD *) + seMark = 0; (* INT32 *) + seClass = 4; (* BYTE *) + seStoreKind = 5; (* BYTE *) + seVoltageIncMode = 6; (* BYTE *) + seDurationIncMode = 7; (* BYTE *) + seVoltage = 8; (* LONGREAL *) + seVoltageSource = 16; (* INT32 *) + seDeltaVFactor = 20; (* LONGREAL *) + seDeltaVIncrement = 28; (* LONGREAL *) + seDuration = 36; (* LONGREAL *) + seDurationSource = 44; (* INT32 *) + seDeltaTFactor = 48; (* LONGREAL *) + seDeltaTIncrement = 56; (* LONGREAL *) + seFiller1 = 64; (* INT32 *) + seCRC = 68; (* CARD32 *) + seScanRate = 72; (* LONGREAL *) + StimSegmentRecSize = 80; (* = 10 * 8 *) + + (* ChannelRecord = RECORD *) + chMark = 0; (* INT32 *) + chLinkedChannel = 4; (* INT32 *) + chCompressionFactor = 8; (* INT32 *) + chYUnit = 12; (* String8Type *) + chAdcChannel = 20; (* INT16 *) + chAdcMode = 22; (* BYTE *) + chDoWrite = 23; (* BOOLEAN *) + stLeakStore = 24; (* BYTE *) + chAmplMode = 25; (* BYTE *) + chOwnSegTime = 26; (* BOOLEAN *) + chSetLastSegVmemb = 27; (* BOOLEAN *) + chDacChannel = 28; (* INT16 *) + chDacMode = 30; (* BYTE *) + chHasLockInSquare = 31; (* BYTE *) + chRelevantXSegment = 32; (* INT32 *) + chRelevantYSegment = 36; (* INT32 *) + chDacUnit = 40; (* String8Type *) + chHolding = 48; (* LONGREAL *) + chLeakHolding = 56; (* LONGREAL *) + chLeakSize = 64; (* LONGREAL *) + chLeakHoldMode = 72; (* BYTE *) + chLeakAlternate = 73; (* BOOLEAN *) + chAltLeakAveraging = 74; (* BOOLEAN *) + chLeakPulseOn = 75; (* BOOLEAN *) + chStimToDacID = 76; (* SET16 *) + chCompressionMode = 78; (* SET16 *) + chCompressionSkip = 80; (* INT32 *) + chDacBit = 84; (* INT16 *) + chHasLockInSine = 86; (* BOOLEAN *) + chBreakMode = 87; (* BYTE *) + chZeroSeg = 88; (* INT32 *) + chStimSweep = 92; (* INT32 *) + chSine_Cycle = 96; (* LONGREAL *) + chSine_Amplitude = 104; (* LONGREAL *) + chLockIn_VReversal = 112; (* LONGREAL *) + chChirp_StartFreq = 120; (* LONGREAL *) + chChirp_EndFreq = 128; (* LONGREAL *) + chChirp_MinPoints = 136; (* LONGREAL *) + chSquare_NegAmpl = 144; (* LONGREAL *) + chSquare_DurFactor = 152; (* LONGREAL *) + chLockIn_Skip = 160; (* INT32 *) + chPhoto_MaxCycles = 164; (* INT32 *) + chPhoto_SegmentNo = 168; (* INT32 *) + chLockIn_AvgCycles = 172; (* INT32 *) + chImaging_RoiNo = 176; (* INT32 *) + chChirp_Skip = 180; (* INT32 *) + chChirp_Amplitude = 184; (* LONGREAL *) + chPhoto_Adapt = 192; (* BYTE *) + chSine_Kind = 193; (* BYTE *) + chChirp_PreChirp = 194; (* BYTE *) + chSine_Source = 195; (* BYTE *) + chSquare_NegSource = 196; (* BYTE *) + chSquare_PosSource = 197; (* BYTE *) + chChirp_Kind = 198; (* BYTE *) + chChirp_Source = 199; (* BYTE *) + chDacOffset = 200; (* LONGREAL *) + chAdcOffset = 208; (* LONGREAL *) + chTraceMathFormat = 216; (* BYTE *) + chHasChirp = 217; (* BOOLEAN *) + chSquare_Kind = 218; (* BYTE *) + chFiller1 = 219; (* ARRAY[0..5] OF CHAR *) + chSquare_BaseIncr = 224; (* LONGREAL *) + chSquare_Cycle = 232; (* LONGREAL *) + chSquare_PosAmpl = 240; (* LONGREAL *) + chCompressionOffset = 248; (* INT32 *) + chPhotoMode = 252; (* INT32 *) + chBreakLevel = 256; (* LONGREAL *) + chTraceMath = 264; (* String128Type *) + chFiller2 = 392; (* INT32 *) + chCRC = 396; (* CARD32 *) + ChannelRecSize = 400; (* = 50 * 8 *) + + (* StimulationRecord = RECORD *) + stMark = 0; (* INT32 *) + stEntryName = 4; (* String32Type *) + stFileName = 36; (* String32Type *) + stAnalName = 68; (* String32Type *) + stDataStartSegment = 100; (* INT32 *) + stDataStartTime = 104; (* LONGREAL *) + stSampleInterval = 112; (* LONGREAL *) + stSweepInterval = 120; (* LONGREAL *) + stLeakDelay = 128; (* LONGREAL *) + stFilterFactor = 136; (* LONGREAL *) + stNumberSweeps = 144; (* INT32 *) + stNumberLeaks = 148; (* INT32 *) + stNumberAverages = 152; (* INT32 *) + stActualAdcChannels = 156; (* INT32 *) + stActualDacChannels = 160; (* INT32 *) + stExtTrigger = 164; (* BYTE *) + stNoStartWait = 165; (* BOOLEAN *) + stUseScanRates = 166; (* BOOLEAN *) + stNoContAq = 167; (* BOOLEAN *) + stHasLockIn = 168; (* BOOLEAN *) + stOldStartMacKind = 169; (* CHAR *) + stOldEndMacKind = 170; (* BOOLEAN *) + stAutoRange = 171; (* BYTE *) + stBreakNext = 172; (* BOOLEAN *) + stIsExpanded = 173; (* BOOLEAN *) + stLeakCompMode = 174; (* BOOLEAN *) + stHasChirp = 175; (* BOOLEAN *) + stOldStartMacro = 176; (* String32Type *) + stOldEndMacro = 208; (* String32Type *) + sIsGapFree = 240; (* BOOLEAN *) + sHandledExternally = 241; (* BOOLEAN *) + stFiller1 = 242; (* BOOLEAN *) + stFiller2 = 243; (* BOOLEAN *) + stCRC = 244; (* CARD32 *) + StimulationRecSize = 248; (* = 31 * 8 *) + + (* RootRecord = RECORD *) + roVersion = 0; (* INT32 *) + roMark = 4; (* INT32 *) + roVersionName = 8; (* String32Type *) + roMaxSamples = 40; (* INT32 *) + roFiller1 = 44; (* INT32 *) + (* StimParams = 10 *) + (* StimParamChars = 320 *) + roParams = 48; (* ARRAY[0..9] OF LONGREAL *) + roParamText = 128; (* ARRAY[0..9],[0..31]OF CHAR *) + roReserved = 448; (* String128Type *) + roFiller2 = 576; (* INT32 *) + roCRC = 580; (* CARD32 *) + RootRecSize = 584; (* = 73 * 8 *) diff --git a/@HEKA_Importer/HEKA_FileFormat/FileFormat_2x90/PulsedFile_v9.txt b/@HEKA_Importer/HEKA_FileFormat/FileFormat_2x90/PulsedFile_v9.txt new file mode 100644 index 0000000..3d02ef9 --- /dev/null +++ b/@HEKA_Importer/HEKA_FileFormat/FileFormat_2x90/PulsedFile_v9.txt @@ -0,0 +1,235 @@ + + PatchMaster v2.74, 22-Sep-2014 + + SizeByte = 1; + SizeChar = 1; + SizeEnum = 1; + SizeBoolean = 1; + SizeInt16 = 2; + SizeCard16 = 2; + SizeSet16 = 2; + SizeInt32 = 4; + SizeCard32 = 4; + SizeReal = 4; + SizeLongReal = 8; + + String8Size = 8; + String32Size = 32; + String80Size = 80; + String400Size = 400; + + ParamDescrSize = 24; + TrMarkerNo = 10; + SwMarkerNo = 4; + SwHoldingNo = 16; + SwUserParamNo = 4; + SeUserParamNo1 = 4; + SeUserParamNo2 = 4; + GrStimParams = 10; + AmplifierStateSize = 400; + ScanParamsSize = 96; + Max_TcKind_M1 = 31; + + SizeStateVersion = 8; + SizeSerialNumber = 8; + SizeCalibDate = 16; + + + RootLevel = 0; + GroupLevel = 1; + SeriesLevel = 2; + SweepLevel = 3; + TraceLevel = 4; + + + LittleEndianBit = 0; + IsLeak = 1; + IsVirtual = 2; + IsImon = 3; + IsVmon = 4; + Clip = 5; + (* + DataKind -> meaning of bits: + - LittleEndianBit => byte sequence + "PowerPC Mac" = cleared + "Windows and Intel Mac" = set + - IsLeak + set if trace is a leak trace + - IsVirtual + set if trace is a virtual trace + - IsImon + -> set if trace was from Imon ADC + -> it flags a trace to be used to + compute LockIn traces from + -> limited to "main" traces, not "leaks"! + - IsVmon + -> set if trace was from Vmon ADC + - Clip + -> set if amplifier of trace was clipping + *) + + RecordingModeType = ( InOut, + OnCell, + OutOut, + WholeCell, + CClamp, + VClamp, + NoMode ); + + DataFormatType = ( int16, + int32, + real32, + real64 ); + + UserParamDescrType = RECORD + Name : String32Type; + Unit : String8Type; + END; (* RECORD *) + + (* AmplifierState = RECORD *) + see definition in AmplTreeFile_v9.txt + + (* LockInParams = RECORD *) + see definition in AmplTreeFile_v9.txt + + (* TraceRecord = RECORD *) + TrMark = 0; (* INT32 *) + TrLabel = 4; (* String32Type *) + TrTraceID = 36; (* INT32 *) + TrData = 40; (* INT32 *) + TrDataPoints = 44; (* INT32 *) + TrInternalSolution = 48; (* INT32 *) + TrAverageCount = 52; (* INT32 *) + TrLeakID = 56; (* INT32 *) + TrLeakTraces = 60; (* INT32 *) + TrDataKind = 64; (* SET16 *) + TrUseXStart = 66; (* BOOLEAN *) + TrTcKind = 67; (* BYTE *) + TrRecordingMode = 68; (* BYTE *) + TrAmplIndex = 69; (* CHAR *) + TrDataFormat = 70; (* BYTE *) + TrDataAbscissa = 71; (* BYTE *) + TrDataScaler = 72; (* LONGREAL *) + TrTimeOffset = 80; (* LONGREAL *) + TrZeroData = 88; (* LONGREAL *) + TrYUnit = 96; (* String8Type *) + TrXInterval = 104; (* LONGREAL *) + TrXStart = 112; (* LONGREAL *) + TrXUnit = 120; (* String8Type *) + TrYRange = 128; (* LONGREAL *) + TrYOffset = 136; (* LONGREAL *) + TrBandwidth = 144; (* LONGREAL *) + TrPipetteResistance = 152; (* LONGREAL *) + TrCellPotential = 160; (* LONGREAL *) + TrSealResistance = 168; (* LONGREAL *) + TrCSlow = 176; (* LONGREAL *) + TrGSeries = 184; (* LONGREAL *) + TrRsValue = 192; (* LONGREAL *) + TrGLeak = 200; (* LONGREAL *) + TrMConductance = 208; (* LONGREAL *) + TrLinkDAChannel = 216; (* INT32 *) + TrValidYrange = 220; (* BOOLEAN *) + TrAdcMode = 221; (* CHAR *) + TrAdcChannel = 222; (* INT16 *) + TrYmin = 224; (* LONGREAL *) + TrYmax = 232; (* LONGREAL *) + TrSourceChannel = 240; (* INT32 *) + TrExternalSolution = 244; (* INT32 *) + TrCM = 248; (* LONGREAL *) + TrGM = 256; (* LONGREAL *) + TrPhase = 264; (* LONGREAL *) + TrDataCRC = 272; (* CARD32 *) + TrCRC = 276; (* CARD32 *) + TrGS = 280; (* LONGREAL *) + TrSelfChannel = 288; (* INT32 *) + TrInterleaveSize = 292; (* INT32 *) + TrInterleaveSkip = 296; (* INT32 *) + TrImageIndex = 300; (* INT32 *) + TrTrMarkers = 304; (* ARRAY[0..9] OF LONGREAL *) + TrSECM_X = 384; (* LONGREAL *) + TrSECM_Y = 392; (* LONGREAL *) + TrSECM_Z = 400; (* LONGREAL *) + TrTrHolding = 408; (* LONGREAL *) + TrTcEnumerator = 416; (* INT32 *) + TrXTrace = 420; (* INT32 *) + TrIntSolValue = 424; (* LONGREAL *) + TrExtSolValue = 432; (* LONGREAL *) + TrIntSolName = 440; (* String32Size *) + TrExtSolName = 472; (* String32Size *) + TrDataPedestal = 504; (* LONGREAL *) + TraceRecSize = 512; (* = 64 * 8 *) + + (* SweepRecord = RECORD *) + SwMark = 0; (* INT32 *) + SwLabel = 4; (* String32Type *) + SwAuxDataFileOffset = 36; (* INT32 *) + SwStimCount = 40; (* INT32 *) + SwSweepCount = 44; (* INT32 *) + SwTime = 48; (* LONGREAL *) + SwTimer = 56; (* LONGREAL *) + SwSwUserParams = 64; (* ARRAY[0..3] OF LONGREAL *) + SwTemperature = 96; (* LONGREAL *) + SwOldIntSol = 104; (* INT32 *) + SwOldExtSol = 108; (* INT32 *) + SwDigitalIn = 112; (* SET16 *) + SwSweepKind = 114; (* SET16 *) + SwDigitalOut = 116; (* SET16 *) + SwFiller1 = 118; (* INT16 *) + SwSwMarkers = 120; (* ARRAY[0..3] OF LONGREAL, see SwMarkersNo *) + SwFiller2 = 152; (* INT32 *) + SwCRC = 156; (* CARD32 *) + SwSwHolding = 160; (* ARRAY[0..15] OF LONGREAL, see SwHoldingNo *) + SweepRecSize = 288; (* = 36 * 8 *) + + (* SeriesRecord = RECORD *) + SeMark = 0; (* INT32 *) + SeLabel = 4; (* String32Type *) + SeComment = 36; (* String80Type *) + SeSeriesCount = 116; (* INT32 *) + SeNumberSweeps = 120; (* INT32 *) + SeAmplStateOffset = 124; (* INT32 *) + SeAmplStateSeries = 128; (* INT32 *) + SeMethodTag = 132; (* INT32 *) + SeTime = 136; (* LONGREAL *) + SePageWidth = 144; (* LONGREAL *) + SeSwUserParamDescr = 152; (* ARRAY[0..3] OF UserParamDescrType = 4*40 *) + SeMethodName = 312; (* String32Type *) + SeSeUserParams1 = 344; (* ARRAY[0..3] OF LONGREAL *) + SeLockInParams = 376; (* SeLockInSize = 96, see "Pulsed.de" *) + SeAmplifierState = 472; (* AmplifierStateSize = 400 *) + SeUsername = 872; (* String80Type *) + SeSeUserParamDescr1 = 952; (* ARRAY[0..3] OF UserParamDescrType = 4*40 *) + SeFiller1 = 1112; (* INT32 *) + SeCRC = 1116; (* CARD32 *) + SeSeUserParams2 = 1120; (* ARRAY[0..3] OF LONGREAL *) + SeSeUserParamDescr2 = 1152; (* ARRAY[0..3] OF UserParamDescrType = 4*40 *) + SeScanParams = 1312; (* ScanParamsSize = 96 *) + SeriesRecSize = 1408; (* = 176 * 8 *) + + (* GroupRecord = RECORD *) + GrMark = 0; (* INT32 *) + GrLabel = 4; (* String32Size *) + GrText = 36; (* String80Size *) + GrExperimentNumber = 116; (* INT32 *) + GrGroupCount = 120; (* INT32 *) + GrCRC = 124; (* CARD32 *) + GrMatrixWidth = 128; (* LONGREAL *) + GrMatrixHeight = 136; (* LONGREAL *) + GroupRecSize = 144; (* = 18 * 8 *) + + (* RootRecord = RECORD *) + RoVersion = 0; (* INT32 *) + RoMark = 4; (* INT32 *) + RoVersionName = 8; (* String32Type *) + RoAuxFileName = 40; (* String80Type *) + RoRootText = 120; (* String400Type *) + RoStartTime = 520; (* LONGREAL *) + RoMaxSamples = 528; (* INT32 *) + RoCRC = 532; (* CARD32 *) + RoFeatures = 536; (* SET16 *) + RoFiller1 = 538; (* INT16 *) + RoFiller2 = 540; (* INT32 *) + RoTcEnumerator = 544; (* ARRAY[0..Max_TcKind_M1] OF INT16 *) + RoTcKind = 608; (* ARRAY[0..Max_TcKind_M1] OF INT8 *) + RootRecSize = 640; (* = 80 * 8 *) + diff --git a/@HEKA_Importer/HEKA_FileFormat/FileFormat_2x90/SolutionsFile_v9.txt b/@HEKA_Importer/HEKA_FileFormat/FileFormat_2x90/SolutionsFile_v9.txt new file mode 100644 index 0000000..ee855a0 --- /dev/null +++ b/@HEKA_Importer/HEKA_FileFormat/FileFormat_2x90/SolutionsFile_v9.txt @@ -0,0 +1,41 @@ + + PatchMaster v2.60, 24-Jan-2011 + + To find the solution belonging to a Trace locate that Solution record with a + SoNumber value equal to the solution value stored in Trace.InternalSolution + and Trace.ExternalSolution. + + SizeInt16 = 2; + SizeInt32 = 4; + SizeReal = 4; + ChemicalNameSize = 30; + SolutionNameSize = 80; + + RootLevel = 0; + SolutionLevel = 1; + ChemicalLevel = 2; + + (* ChemicalRecord = RECORD *) + ChConcentration = 0; (* REAL *) + ChName = 4; (* ChemicalNameSize *) + ChSpare1 = 34; (* INT16 *) + ChCRC = 36; (* CARD32 *) + ChemicalSize = 40; + + (* SolutionRecord = RECORD *) + SoNumber = 0; (* INT32 *) + SoName = 4; (* SolutionNameSize *) + SoNumeric = 84; (* REAL *) + SoNumericName = 88; (* ChemicalNameSize *) + SopH = 118; (* REAL *) + SopHCompound = 122; (* ChemicalNameSize *) + SoOsmol = 152; (* REAL *) + SoCRC = 156; (* CARD32 *) + SolutionSize = 160; + + (* RootRecord = RECORD *) + RoVersion = 0; (* INT16 *) + RoDataBaseName = 2; (* SolutionNameSize *) + RoSpare1 = 82; (* INT16 *) + RoCRC = 84; (* CARD32 *) + RootSize = 88; diff --git a/@HEKA_Importer/HEKA_FileFormat/FileFormat_2x90/StimFile_v9.txt b/@HEKA_Importer/HEKA_FileFormat/FileFormat_2x90/StimFile_v9.txt new file mode 100644 index 0000000..778f417 --- /dev/null +++ b/@HEKA_Importer/HEKA_FileFormat/FileFormat_2x90/StimFile_v9.txt @@ -0,0 +1,258 @@ + + PatchMaster v2.74, 28-Nov-2014 + + SizeByte = 1; + SizeChar = 1; + SizeEnum = 1; + SizeBoolean = 1; + SizeInt16 = 2; + SizeCard16 = 2; + SizeSet16 = 2; + SizeInt32 = 4; + SizeCard32 = 4; + SizeReal = 4; + SizeLongReal = 8; + + String8Size = 8; + String32Size = 32; + + StimParams = 10; + StimParamChars = 320; + + RootLevel = 0; + StimulationLevel = 1; + ChannelLevel = 2; + StimSegmentLevel = 3; + + + (* + CompressionMode : Specifies how to the data + -> meaning of bits: + bit 0 (CompReal) -> high = store as real + low = store as int16 + bit 1 (CompMean) -> high = use mean + low = use single sample + bit 2 (CompFilter) -> high = use digital filter + *) + + (* + StimToDacID : Specifies how to convert the Segment "Voltage" to + the actual voltage sent to the DAC + -> meaning of bits: + bit 0 (UseStimScale) -> use StimScale + bit 1 (UseRelative) -> relative to Vmemb + bit 2 (UseFileTemplate) -> use file template + bit 3 (UseForLockIn) -> use for LockIn computation + bit 4 (UseForWavelength) + bit 5 (UseScaling) + bit 6 (UseForChirp) + bit 7 (UseForImaging) + bit 14 (UseReserved) + bit 15 (UseReserved) + *) + + SegmentClass = ( SegmentConstant, + SegmentRamp, + SegmentContinuous, + SegmentConstSine, + SegmentSquarewave, + SegmentChirpwave ); + + IncrementModeType = ( ModeInc, + ModeDec, + ModeIncInterleaved, + ModeDecInterleaved, + ModeAlternate, + ModeLogInc, + ModeLogDec, + ModeLogIncInterleaved, + ModeLogDecInterleaved, + ModeLogAlternate ); + + ExtTriggerType = ( TrigNone, + TrigSeries, + TrigSweep, + TrigSweepNoLeak ); + + AmplModeType = ( AnyAmplMode, + VCAmplMode, + CCAmplMode, + IDensityMode ); + + AutoRangingType = ( AutoRangingOff, + AutoRangingPeak, + AutoRangingMean, + AutoRangingRelSeg ); + + AdcType = ( AdcOff, + Analog, + Digitals, + Digital, + AdcVirtual ); + + LeakStoreType = ( LNone, + LStoreAvg, + LStoreEach, + LNoStore ); + + LeakHoldType = ( Labs, + Lrel, + LabsLH, + LrelLH ); + + BreakType = ( NoBreak, + BreakPos, + BreakNeg ); + + LeakCompType = ( LeakCompSoft, + LeakCompHard ); + + SegStoreType = ( SegNoStore, + SegStore, + SegStoreStart, + SegStoreEnd ); + + + (* StimSegmentRecord = RECORD *) + seMark = 0; (* INT32 *) + seClass = 4; (* BYTE *) + seStoreKind = 5; (* BYTE *) + seVoltageIncMode = 6; (* BYTE *) + seDurationIncMode = 7; (* BYTE *) + seVoltage = 8; (* LONGREAL *) + seVoltageSource = 16; (* INT32 *) + seDeltaVFactor = 20; (* LONGREAL *) + seDeltaVIncrement = 28; (* LONGREAL *) + seDuration = 36; (* LONGREAL *) + seDurationSource = 44; (* INT32 *) + seDeltaTFactor = 48; (* LONGREAL *) + seDeltaTIncrement = 56; (* LONGREAL *) + seFiller1 = 64; (* INT32 *) + seCRC = 68; (* CARD32 *) + seScanRate = 72; (* LONGREAL *) + StimSegmentRecSize = 80; (* = 10 * 8 *) + + (* ChannelRecord = RECORD *) + chMark = 0; (* INT32 *) + chLinkedChannel = 4; (* INT32 *) + chCompressionFactor = 8; (* INT32 *) + chYUnit = 12; (* String8Type *) + chAdcChannel = 20; (* INT16 *) + chAdcMode = 22; (* BYTE *) + chDoWrite = 23; (* BOOLEAN *) + stLeakStore = 24; (* BYTE *) + chAmplMode = 25; (* BYTE *) + chOwnSegTime = 26; (* BOOLEAN *) + chSetLastSegVmemb = 27; (* BOOLEAN *) + chDacChannel = 28; (* INT16 *) + chDacMode = 30; (* BYTE *) + chHasLockInSquare = 31; (* BYTE *) + chRelevantXSegment = 32; (* INT32 *) + chRelevantYSegment = 36; (* INT32 *) + chDacUnit = 40; (* String8Type *) + chHolding = 48; (* LONGREAL *) + chLeakHolding = 56; (* LONGREAL *) + chLeakSize = 64; (* LONGREAL *) + chLeakHoldMode = 72; (* BYTE *) + chLeakAlternate = 73; (* BOOLEAN *) + chAltLeakAveraging = 74; (* BOOLEAN *) + chLeakPulseOn = 75; (* BOOLEAN *) + chStimToDacID = 76; (* SET16 *) + chCompressionMode = 78; (* SET16 *) + chCompressionSkip = 80; (* INT32 *) + chDacBit = 84; (* INT16 *) + chHasLockInSine = 86; (* BOOLEAN *) + chBreakMode = 87; (* BYTE *) + chZeroSeg = 88; (* INT32 *) + chStimSweep = 92; (* INT32 *) + chSine_Cycle = 96; (* LONGREAL *) + chSine_Amplitude = 104; (* LONGREAL *) + chLockIn_VReversal = 112; (* LONGREAL *) + chChirp_StartFreq = 120; (* LONGREAL *) + chChirp_EndFreq = 128; (* LONGREAL *) + chChirp_MinPoints = 136; (* LONGREAL *) + chSquare_NegAmpl = 144; (* LONGREAL *) + chSquare_DurFactor = 152; (* LONGREAL *) + chLockIn_Skip = 160; (* INT32 *) + chPhoto_MaxCycles = 164; (* INT32 *) + chPhoto_SegmentNo = 168; (* INT32 *) + chLockIn_AvgCycles = 172; (* INT32 *) + chImaging_RoiNo = 176; (* INT32 *) + chChirp_Skip = 180; (* INT32 *) + chChirp_Amplitude = 184; (* LONGREAL *) + chPhoto_Adapt = 192; (* BYTE *) + chSine_Kind = 193; (* BYTE *) + chChirp_PreChirp = 194; (* BYTE *) + chSine_Source = 195; (* BYTE *) + chSquare_NegSource = 196; (* BYTE *) + chSquare_PosSource = 197; (* BYTE *) + chChirp_Kind = 198; (* BYTE *) + chChirp_Source = 199; (* BYTE *) + chDacOffset = 200; (* LONGREAL *) + chAdcOffset = 208; (* LONGREAL *) + chTraceMathFormat = 216; (* BYTE *) + chHasChirp = 217; (* BOOLEAN *) + chSquare_Kind = 218; (* BYTE *) + chFiller1 = 219; (* ARRAY[0..5] OF CHAR *) + chSquare_BaseIncr = 224; (* LONGREAL *) + chSquare_Cycle = 232; (* LONGREAL *) + chSquare_PosAmpl = 240; (* LONGREAL *) + chCompressionOffset = 248; (* INT32 *) + chPhotoMode = 252; (* INT32 *) + chBreakLevel = 256; (* LONGREAL *) + chTraceMath = 264; (* String128Type *) + chFiller2 = 392; (* INT32 *) + chCRC = 396; (* CARD32 *) + ChannelRecSize = 400; (* = 50 * 8 *) + + (* StimulationRecord = RECORD *) + stMark = 0; (* INT32 *) + stEntryName = 4; (* String32Type *) + stFileName = 36; (* String32Type *) + stAnalName = 68; (* String32Type *) + stDataStartSegment = 100; (* INT32 *) + stDataStartTime = 104; (* LONGREAL *) + stSampleInterval = 112; (* LONGREAL *) + stSweepInterval = 120; (* LONGREAL *) + stLeakDelay = 128; (* LONGREAL *) + stFilterFactor = 136; (* LONGREAL *) + stNumberSweeps = 144; (* INT32 *) + stNumberLeaks = 148; (* INT32 *) + stNumberAverages = 152; (* INT32 *) + stActualAdcChannels = 156; (* INT32 *) + stActualDacChannels = 160; (* INT32 *) + stExtTrigger = 164; (* BYTE *) + stNoStartWait = 165; (* BOOLEAN *) + stUseScanRates = 166; (* BOOLEAN *) + stNoContAq = 167; (* BOOLEAN *) + stHasLockIn = 168; (* BOOLEAN *) + stOldStartMacKind = 169; (* CHAR *) + stOldEndMacKind = 170; (* BOOLEAN *) + stAutoRange = 171; (* BYTE *) + stBreakNext = 172; (* BOOLEAN *) + stIsExpanded = 173; (* BOOLEAN *) + stLeakCompMode = 174; (* BOOLEAN *) + stHasChirp = 175; (* BOOLEAN *) + stOldStartMacro = 176; (* String32Type *) + stOldEndMacro = 208; (* String32Type *) + sIsGapFree = 240; (* BOOLEAN *) + sHandledExternally = 241; (* BOOLEAN *) + stFiller1 = 242; (* BOOLEAN *) + stFiller2 = 243; (* BOOLEAN *) + stCRC = 244; (* CARD32 *) + StimulationRecSize = 248; (* = 31 * 8 *) + + (* RootRecord = RECORD *) + roVersion = 0; (* INT32 *) + roMark = 4; (* INT32 *) + roVersionName = 8; (* String32Type *) + roMaxSamples = 40; (* INT32 *) + roFiller1 = 44; (* INT32 *) + (* StimParams = 10 *) + (* StimParamChars = 320 *) + roParams = 48; (* ARRAY[0..9] OF LONGREAL *) + roParamText = 128; (* ARRAY[0..9],[0..31]OF CHAR *) + roReserved = 448; (* String128Type *) + roFiller2 = 576; (* INT32 *) + roCRC = 580; (* CARD32 *) + RootRecSize = 584; (* = 73 * 8 *) diff --git a/@HEKA_Importer/HEKA_FileFormat/FileFormat_2x90/TimeFormat.txt b/@HEKA_Importer/HEKA_FileFormat/FileFormat_2x90/TimeFormat.txt new file mode 100644 index 0000000..2082bdb --- /dev/null +++ b/@HEKA_Importer/HEKA_FileFormat/FileFormat_2x90/TimeFormat.txt @@ -0,0 +1,80 @@ + + PatchMaster v2.90 + +Time is stored as seconds from 01-Jan-1990. +To convert the stored time into a string, proceed as follows: + +MacOS + JanFirst1990 - The number of seconds between 1/1/1904 (Apple's + beginning of time) and 1/1/1990, the beginning of + time for PowerMod's environment. + + JanFirst1990 = 1580970496.0; + MacTime = (int)( StoredTime - JanFirst1990 ); + + Pass MacTime to the API function DateTimeUtils.SecondsToDate + to convert it to a string + +Windows + Windows uses 01-Jan-1601 as its starting point in calculating dates. + + Pass StoredTime to the function PatchMasterSecondsToFileTime or + PatchMasterSecondsToDate below to convert it to a standard Windows + format. + +#define MAC_BASE 9561652096.0 +#define HIGH_DWORD 4294967296.0 +#define JanFirst1990 1580970496.0 + +// Function PatchMasterSecondsToFileTime +// Convert seconds to FILETIME. +// In converting double to DWORD we must be carefull because the +// double will first be converted to a signed int. +// Do the operations modulo 2^31. +// Get the next bit from the high DWORD and then shift high DWORD +// throwing away the highest bit. + +void PatchMasterSecondsToFileTime( double time, FILETIME* file_time ) +{ + time -= JanFirst1990; + + if (time < 0.0) + time += HIGH_DWORD; + + time += MAC_BASE; + + time *= 10000000.0; + + file_time->dwHighDateTime = (DWORD) (time / (HIGH_DWORD / 2.0)); + + file_time->dwLowDateTime = (DWORD) + (time - (double) file_time->dwHighDateTime * (HIGH_DWORD / 2.0)); + + file_time->dwLowDateTime |= ((file_time->dwHighDateTime & 1) << 31); + + file_time->dwHighDateTime >>= 1; +} + +void PatchMasterSecondsToDate( double storedTime, SYSTEMTIME* system_time ) +{ + FILETIME file_time; + PatchMasterSecondsToFileTime( storedTime, &file_time ); + FileTimeToSystemTime( &file_time, system_time ); +} + + +Example 1: applied to the root date of "DemoV9Bundle.dat": +1. RootTime = 221667551 +2. subtract JanFirst1990 time = 221667551 - 1580970496 = -1359302944 +3. is it < 0 ? + yes => add HIGH_DWORD time = -1359302944 + 4294967296 = 2935664351 +4. add correction for Windows time = 2935664351 + 9561652096 = 12497316447 +5. convert to date date = 09-Jan-1997 + +Example 2: applied to the root date of "Malcom.dat": +1. RootTime = 4922414972 +2. subtract JanFirst1990 time = 4922414972 - 1580970496 = 3341444476 +3. is it < 0 ? + no +4. add correction for Windows time = 3341444476 + 9561652096 = 12903096572 +5. convert to date date = 19-Nov-2009 \ No newline at end of file diff --git a/@HEKA_Importer/HEKA_FileFormat/FileFormat_v1000/AmplTreeFile_v1000.txt b/@HEKA_Importer/HEKA_FileFormat/FileFormat_v1000/AmplTreeFile_v1000.txt new file mode 100644 index 0000000..5fe3544 --- /dev/null +++ b/@HEKA_Importer/HEKA_FileFormat/FileFormat_v1000/AmplTreeFile_v1000.txt @@ -0,0 +1,220 @@ + + PatchMaster v2.90.4, Patchmaster Next + + SizeByte = 1; + SizeChar = 1; + SizeEnum = 1; + SizeBoolean = 1; + SizeInt16 = 2; + SizeCard16 = 2; + SizeSet16 = 2; + SizeInt32 = 4; + SizeCard32 = 4; + SizeReal = 4; + SizeLongReal = 8; + + String8Size = 8; + String32Size = 32; + + + RootLevel = 0; + SeriesLevel = 1; + StateLevel = 2; + + + AmplifierType = ( Epc7Ampl, + Epc8Ampl, + Epc9Ampl, + Epc10Ampl, + Epc10PlusAmpl ); + + ADBoardType = ( ITC16Board, + ITC18Board, + LIH1600Board ); + + Modes = ( TestMode, + VCMode, + CCMode, + NoMode => (* AmplifierState is invalid *) ); + + + (* AmplifierState = RECORD *) + sStateVersion = 0; (* 8 = SizeStateVersion *) + sCurrentGain = 8; (* LONGREAL *) + sF2Bandwidth = 16; (* LONGREAL *) + sF2Frequency = 24; (* LONGREAL *) + sRsValue = 32; (* LONGREAL *) + sRsFraction = 40; (* LONGREAL *) + sGLeak = 48; (* LONGREAL *) + sCFastAmp1 = 56; (* LONGREAL *) + sCFastAmp2 = 64; (* LONGREAL *) + sCFastTau = 72; (* LONGREAL *) + sCSlow = 80; (* LONGREAL *) + sGSeries = 88; (* LONGREAL *) + sVCStimDacScale = 96; (* LONGREAL *) + sCCStimScale = 104; (* LONGREAL *) + sVHold = 112; (* LONGREAL *) + sLastVHold = 120; (* LONGREAL *) + sVpOffset = 128; (* LONGREAL *) + sVLiquidJunction = 136; (* LONGREAL *) + sCCIHold = 144; (* LONGREAL *) + sCSlowStimVolts = 152; (* LONGREAL *) + sCCTrackVHold = 160; (* LONGREAL *) + sTimeoutCSlow = 168; (* LONGREAL *) + sSearchDelay = 176; (* LONGREAL *) + sMConductance = 184; (* LONGREAL *) + sMCapacitance = 192; (* LONGREAL *) + sSerialNumber = 200; (* 8 = SizeSerialNumber *) + + sE9Boards = 208; (* INT16 *) + sCSlowCycles = 210; (* INT16 *) + sIMonAdc = 212; (* INT16 *) + sVMonAdc = 214; (* INT16 *) + + sMuxAdc = 216; (* INT16 *) + sTestDac = 218; (* INT16 *) + sStimDac = 220; (* INT16 *) + sStimDacOffset = 222; (* INT16 *) + + sMaxDigitalBit = 224; (* INT16 *) + sHasCFastHigh = 226; (* BYTE *) + sCFastHigh = 227; (* BYTE *) + sHasBathSense = 228; (* BYTE *) + sBathSense = 229; (* BYTE *) + sHasF2Bypass = 230; (* BYTE *) + sF2Mode = 231; (* BYTE *) + + sAmplKind = 232; (* BYTE *) + sIsEpc9N = 233; (* BYTE *) + sADBoard = 234; (* BYTE *) + sBoardVersion = 235; (* BYTE *) + sActiveE9Board = 236; (* BYTE *) + sMode = 237; (* BYTE *) + sRange = 238; (* BYTE *) + sF2Response = 239; (* BYTE *) + + sRsOn = 240; (* BYTE *) + sCSlowRange = 241; (* BYTE *) + sCCRange = 242; (* BYTE *) + sCCGain = 243; (* BYTE *) + sCSlowToTestDac = 244; (* BYTE *) + sStimPath = 245; (* BYTE *) + sCCTrackTau = 246; (* BYTE *) + sWasClipping = 247; (* BYTE *) + + sRepetitiveCSlow = 248; (* BYTE *) + sLastCSlowRange = 249; (* BYTE *) + sOld1 = 250; (* BYTE *) + sCanCCFast = 251; (* BYTE *) + sCanLowCCRange = 252; (* BYTE *) + sCanHighCCRange = 253; (* BYTE *) + sCanCCTracking = 254; (* BYTE *) + sHasVmonPath = 255; (* BYTE *) + + sHasNewCCMode = 256; (* BYTE *) + sSelector = 257; (* CHAR *) + sHoldInverted = 258; (* BYTE *) + sAutoCFast = 259; (* BYTE *) + sAutoCSlow = 260; (* BYTE *) + sHasVmonX100 = 261; (* BYTE *) + sTestDacOn = 262; (* BYTE *) + sQMuxAdcOn = 263; (* BYTE *) + + sImon1Bandwidth = 264; (* LONGREAL *) + sStimScale = 272; (* LONGREAL *) + + sGain = 280; (* BYTE *) + sFilter1 = 281; (* BYTE *) + sStimFilterOn = 282; (* BYTE *) + sRsSlow = 283; (* BYTE *) + sOld2 = 284; (* BYTE *) + sCCCFastOn = 285; (* BYTE *) + sCCFastSpeed = 286; (* BYTE *) + sF2Source = 287; (* BYTE *) + + sTestRange = 288; (* BYTE *) + sTestDacPath = 289; (* BYTE *) + sMuxChannel = 290; (* BYTE *) + sMuxGain64 = 291; (* BYTE *) + sVmonX100 = 292; (* BYTE *) + sIsQuadro = 293; (* BYTE *) + sF1Mode = 294; (* BYTE *) + sOld3 = 295; (* BYTE *) + + sStimFilterHz = 296; (* LONGREAL *) + sRsTau = 304; (* LONGREAL *) + sDacToAdcDelay = 312; (* LONGREAL *) + sInputFilterTau = 320; (* LONGREAL *) + sOutputFilterTau = 328; (* LONGREAL *) + sVmonFactor = 336; (* LONGREAL *) + sCalibDate = 344; (* 16 = SizeCalibDate *) + sVmonOffset = 360; (* LONGREAL *) + + sEEPROMKind = 368; (* BYTE *) + sVrefX2 = 369; (* BYTE *) + sHasVrefX2AndF2Vmon = 370; (* BYTE *) + sSpare1 = 371; (* BYTE *) + sSpare2 = 372; (* BYTE *) + sSpare3 = 373; (* BYTE *) + sSpare4 = 374; (* BYTE *) + sSpare5 = 375; (* BYTE *) + + sCCStimDacScale = 376; (* LONGREAL *) + sVmonFiltBandwidth = 384; (* LONGREAL *) + sVmonFiltFrequency = 392; (* LONGREAL *) + AmplifierStateSize = 400; (* = 50 * 8 *) + + + (* LockInParams = RECORD *) + loExtCalPhase = 0; (* LONGREAL *) + loExtCalAtten = 8; (* LONGREAL *) + loPLPhase = 16; (* LONGREAL *) + loPLPhaseY1 = 24; (* LONGREAL *) + loPLPhaseY2 = 32; (* LONGREAL *) + loUsedPhaseShift = 40; (* LONGREAL *) + loUsedAttenuation = 48; (* LONGREAL *) + loSpare = 56; (* LONGREAL *) + loExtCalValid = 64; (* BOOLEAN *) + loPLPhaseValid = 65; (* BOOLEAN *) + loLockInMode = 66; (* BYTE *) + loCalMode = 67; (* BYTE *) + loSpares = 68; (* remaining *) + LockInParamsSize = 96; + + + (* AmplStateRecord = RECORD *) + AmMark = 0; (* INT32 *) + AmStateCount = 4; (* INT32 *) + AmStateVersion = 8; (* CHAR *) + AmFiller1 = 9; (* BYTE *) + AmFiller2 = 10; (* BYTE *) + AmFiller3 = 11; (* BYTE *) + AmFiller4 = 12; (* INT32 *) + AmLockInParams = 16; (* LockInParamsSize = 96 *) + AmAmplifierState = 112; (* AmplifierStateSize = 400 *) + AmIntSol = 512; (* INT32 *) + AmExtSol = 516; (* INT32 *) + AmFiller5 = 520; (* spares: 36 bytes *) + AmCRC = 556; (* CARD32 *) + StateRecSize = 560; (* = 70 * 8 *) + + (* SeriesRecord = RECORD *) + SeMark = 0; (* INT32 *) + SeSeriesCount = 4; (* INT32 *) + SeFiller1 = 8; (* INT32 *) + SeCRC = 12; (* CARD32 *) + SeriesRecSize = 16; (* = 2 * 8 *) + + (* RootRecord = RECORD *) + RoVersion = 0; (* INT32 *) + RoMark = 4; (* INT32 *) + RoVersionName = 8; (* String32Type *) + RoAmplifierName = 40; (* String32Type *) + RoAmplifier = 72; (* CHAR *) + RoADBoard = 73; (* CHAR *) + RoCreator = 74; (* CHAR *) + RoFiller1 = 75; (* BYTE *) + RoCRC = 76; (* CARD32 *) + RootRecSize = 80; (* = 10 * 8 *) + (* END RootRecord *) + diff --git a/@HEKA_Importer/HEKA_FileFormat/FileFormat_v1000/AnalysisFile_v11.txt b/@HEKA_Importer/HEKA_FileFormat/FileFormat_v1000/AnalysisFile_v11.txt new file mode 100644 index 0000000..ec317c8 --- /dev/null +++ b/@HEKA_Importer/HEKA_FileFormat/FileFormat_v1000/AnalysisFile_v11.txt @@ -0,0 +1,318 @@ + + PatchMaster v2.90.4 / Patchmaster Next + + SizeByte = 1; + SizeChar = 1; + SizeEnum = 1; + SizeBoolean = 1; + SizeInt16 = 2; + SizeCard16 = 2; + SizeSet16 = 2; + SizeInt32 = 4; + SizeCard32 = 4; + SizeReal = 4; + SizeLongReal = 8; + + String8Size = 8; + String32Size = 32; + String64Size = 64; + MaxGraphs = 12; + + RootLevel = 0; + MethodLevel = 1; + FunctionLevel = 2; + + FunctionType = ( SweepCountAbsc, (* general *) + TimeAbsc, + TimerAbsc, + RealtimeAbsc, + + SegAmplitude, (* X segment property *) + SegDuration, + ScanRateAbsc, + + ExtremumMode, (* Y analysis *) + MaximumMode, + MinimumMode, + MeanMode, + IntegralMode, + VarianceMode, + SlopeMode, + TimeToExtrMode, + AnodicChargeMode, (* potentiostat *) + CathodChargeMode, + + (* patch clamp *) + CSlowMode, (* potmaster: spare *) + RSeriesMode, (* potmaster: spare *) + UserParam1Mode, + UserParam2Mode, + + LockInCMMode, (* lock-in *) + LockInGMMode, + LockInGSMode, + + SeriesTime, (* misk *) + StimulusMode, + SegmentTimeAbs, + + OpEquationMode, (* math *) + ConstantMode, + OperatorPlusMode, + OperatorMinusMode, + OperatorMultMode, + OperatorDivMode, + OperatorAbsMode, + OperatorLogMode, + OperatorSqrMode, + OperatorInvMode, + OperatorInvLogMode, + OperatorInvSqrMode, + + TraceMode, (* trace *) + QMode, + InvTraceMode, + InvQMode, + LnTraceMode, + LnQMode, + LogTraceMode, + LogQMode, + TraceXaxisMode, + + FreqMode, (* spectra *) + DensityMode, + + HistoAmplMode, (* histogram *) + HistoBinsMode, + + OnlineIndex, + ExtrAmplMode, + SegmentTimeRel, + + (* remaning trace parameters *) + CellPotential, (* potmaster: OCP *) + SealResistance, (* potmaster: ElectrodeArea *) + RsValue, (* potmaster: spare *) + GLeak, (* potmaster: spare *) + MConductance, (* potmaster: spare *) + + Temperature, (* sweep parameters *) + PipettePressure, (* potmaster: spare *) + InternalSolution, + ExternalSolution, + DigitalIn, + + OperatorBitInMode, + ReversalMode, + LockInPhase, + LockInFreq, + TotMeanMode, (* obsolete: replaced by MeanMode + CursorKind *) + DiffMode, + IntSolValue, + ExtSolValue, + OperatorAtanMode, + OperatorInvAtanMode, + + TimeToMinMode, + TimeToMaxMode, + TimeToThreshold, + + TraceEquationMode, + ThresholdAmpl, + + XposMode, + YposMode, + ZposMode, + + TraceCountMode, + + AP_Baseline, + AP_MaximumAmpl, + AP_MaximumTime, + AP_MinimumAmpl, + AP_MinimumTime, + AP_RiseTime1Dur, + AP_RiseTime1Slope, + AP_RiseTime1Time, + AP_RiseTime2Dur, + AP_RiseTime2Slope, + AP_RiseTime2Time, + AP_Tau, + + MatrixXindexMode, + MatrixYindexMode, + YatX_Mode, + ThresholdCount, + SECM_3Dx, + SECM_3Dy, + InterceptMode, + MinAmplMode, + MaxAmplMode, + TauMode, + ZeroOffset, + LockInAmpl, + + UserParam3Mode, + UserParam4Mode, + UserParam5Mode, + UserParam6Mode, + UserParam7Mode, + UserParam8Mode, + UserParam9Mode, + UserParam10Mode + ); + + TicDirectionType = ( TicLeft, TicRight, TicBoth ); + + ScaleType = ( ScaleFixed, ScaleSeries, ScaleSweeps ); + + AxisLevelType = ( Min, Zero, Max ); + + AxisTypeType = ( ScaleLinear, + ScaleLog, + ScaleInverse, + ScaleSqrt, + ScaleSquare ); + + MarkerKindType = ( MarkerPoint, + MarkerPlus, + MarkerStar, + MarkerDiamond, + MarkerX, + MarkerSquare ); + + GraphWindowType = ( Win0, Win1, Win2 ); + + NormalizeType = ( NormalizeNone, NormalizeMax, NormalizeMinMax ); + + CursorType = ( Cursor_Segment, (* cursor relative to segment *) + Cursor_Trace ); (* cursor relative to trace *) + + BaselineType = ( Baseline_Zero, (* baseline relative to zero *) + Baseline_Cursors, (* baseline = intersection with cursors *) + Baseline_Auto ); (* baseline = intersection with cursors *) + + SearchDirectionType = ( Search_All, + Search_Positive, + Search_Negative ); + + + (* FunctionRecord = RECORD *) + fnMark = 0; (* INT32 *) + fnName = 4; (* String32Size *) + fnUnit = 36; (* String8Size *) + fnLeftOperand = 44; (* INT16 *) + fnRightOperand = 46; (* INT16 *) + fnLeftBound = 48; (* LONGREAL *) + fnRightBound = 56; (* LONGREAL *) + fnConstant = 64; (* LONGREAL *) + fnXSegmentOffset = 72; (* INT32 *) + fnYSegmentOffset = 76; (* INT32 *) + fnTcEnumarator = 80; (* INT16 *) + fnFunction = 82; (* BYTE *) + fnDoNotebook = 83; (* BOOLEAN *) + fnNoFit = 84; (* BOOLEAN *) + fnNewName = 85; (* BOOLEAN *) + fnTargetValue = 86; (* INT16 *) + fnCursorKind = 88; (* BYTE *) + fnTcKind1 = 89; (* 3 BYTE *) + fnTcKind2 = 90; (* 3 BYTE *) + fnCursorSource = 91; (* BYTE *) + fnCRC = 92; (* CARD32 *) + fnEquation = 96; (* String64Size *) + fnBaselineMode = 160; (* BYTE *) + fnSearchDirection = 161; (* BYTE *) + fnSourceValue = 162; (* INT16 *) + fnCursorAnker = 164; (* INT16 *) + fnSpare1 = 165; (* INT16 *) + FunctionRecSize = 168; (* = 21 * 8 *) + + + (* ScalingRecord = RECORD *) + scMinValue = 0; (* LONGREAL *) + scMaxValue = 8; (* LONGREAL *) + scGridFactor = 16; (* LONGREAL *) + scTicLength = 24; (* INT16 *) + scTicNumber = 26; (* INT16 *) + scTicDirection = 28; (* BYTE *) + scAxisLevel = 29; (* BYTE *) + scAxisType = 30; (* BYTE *) + scScaleMode = 31; (* BYTE *) + scNoUnit = 32; (* BOOLEAN *) + scObsolete = 33; (* BOOLEAN *) + scZeroLine = 34; (* BOOLEAN *) + scGrid = 35; (* BOOLEAN *) + scNice = 36; (* BOOLEAN *) + scLabel = 37; (* BOOLEAN *) + scCentered = 38; (* BOOLEAN *) + scIncludeZero = 39; (* BOOLEAN *) + ScalingRecSize = 40; (* = 5 * 8 *) + + + (* EntryRecord = RECORD *) + enXWave = 0; (* INT16 *) + enYWave = 2; (* INT16 *) + enMarkerSize = 4; (* INT16 *) + enMarkerColorRed = 6; (* CARD16 *) + enMarkerColorGreen = 8; (* CARD16 *) + enMarkerColorBlue = 10; (* CARD16 *) + enMarkerKind = 12; (* BYTE *) + enEActive = 13; (* BOOLEAN *) + enLine = 14; (* BOOLEAN *) + enTraceColor = 15; (* BOOLEAN *) + EntryRecSize = 16; (* = 2 * 8 *) + + + (* GraphRecord = RECORD *) + grGActive = 0; (* BOOLEAN *) + grOverlay = 1; (* BOOLEAN *) + grWrap = 2; (* CHAR *) + grOvrlSwp = 3; (* BOOLEAN *) + grNormalize = 4; (* BYTE *) + grSort = 5; (* BOOLEAN *) + grSpare1 = 6; (* BYTE *) + grSpare2 = 7; (* BYTE *) + grXScaling = 8; (* ScalingRecord; *) + grYScaling = 48; (* ScalingRecord *) + grEntry0 = 88; (* EntryRecSize *) + grEntry1 = 104; (* EntryRecSize *) + grEntry2 = 120; (* EntryRecSize *) + grEntry3 = 136; (* EntryRecSize *) + GraphRecSize = 152; (* = 19 * 8 *) + + + (* MethodRecord = RECORD *) + oaMark = 0; (* INT32 *) + oaEntryName = 4; (* String32Size *) + oaSharedXWin1 = 36; (* BOOLEAN *) + oaSharedXWin2 = 37; (* BOOLEAN *) + oa1 = 38; (* BOOLEAN *) + oa2 = 39; (* BOOLEAN *) + oaGraph0 = 40; (* MaxFileGraphs * GraphRecSize = 1824 *) + oa3 = 1864; (* INT32 *) + oaCRC = 1868; (* CARD32 *) + oaHeaders = 1872; (* MaxFileGraphs * String32Size = 384 *) + oaLastXmin = 2256; (* MaxFileGraphs * LONGREAL = 96 *) + oaLastXmax = 2352; (* MaxFileGraphs * LONGREAL = 96 *) + oaLastYmin = 2448; (* MaxFileGraphs * LONGREAL = 96 *) + oaLastYmax = 2544; (* MaxFileGraphs * LONGREAL = 96 *) + MethodRecSize = 2640; (* = 330 * 8 *) + + + (* RootRecord = RECORD *) + (* + NOTE: The "Version" field must be at offset zero in the file + while the "Mark" field must be at offset zero in RAM! + *) + roVersion = 0; (* INT32 *) + roMark = 4; (* INT32 *) + roVersionName = 8; (* String32Size *) + roObsolete = 40; (* BYTE *) (* was StimControl *) + roMaxTraces = 41; (* CHAR *) + roWinDefined = 42; (* BOOLEAN *) + rt1 = 43; (* BYTE *) + roCRC = 44; (* CARD32 *) + roWinNr = 48; (* MaxFileGraphs *) + rt2 = 60; (* INT32 *) + RootRecSize = 64; (* = 6 * 8 *) + diff --git a/@HEKA_Importer/HEKA_FileFormat/FileFormat_v1000/DataFile_v1000.txt b/@HEKA_Importer/HEKA_FileFormat/FileFormat_v1000/DataFile_v1000.txt new file mode 100644 index 0000000..05f8ca9 --- /dev/null +++ b/@HEKA_Importer/HEKA_FileFormat/FileFormat_v1000/DataFile_v1000.txt @@ -0,0 +1,127 @@ + + Patchmaster Next / PatchMaster v2.90.4 30-Oct-2018 + +1. Data File Types + +There are 4 types of .dat files: + + - the oldest files where the raw data start at the very beginning + (e.g. converted "PULSE" datafiles) + - the older files where the first 4 byte were "DATA", followed by raw data + - the new files with the empty "bundle" header => signature is "DAT1" + - the new files with the filled "bundle" header => signature is "DAT2" + - note that in "bundle" header the 4 bytes following the signature + are zero! + + +2. Structure of "bundle" Header + +The "bundle" header has the following structure: + + (* BundleHeader = RECORD *) + oSignature = 0; (* ARRAY[0..7] OF CHAR *) + oVersion = 8; (* ARRAY[0..31] OF CHAR *) + oTime = 40; (* LONGREAL *) + oItems = 48; (* INT32 *) + oIsLittleEndian = 52; (* BOOLEAN *) + oReserved = 53; (* ARRAY[0..10] OF CHAR *) + oBundleItems = 64; (* ARRAY[0..11] OF BundleItem *) + BundleHeaderSize = 256; (* = 32 * 8 *) + + (* BundleItem = RECORD *) + oStart = 0; (* INT32 *) + oLength = 4; (* INT32 *) + oExtension = 8; (* ARRAY[0..7] OF CHAR *) + BundleItemSize = 16; (* = 2 * 8 *) + + + Signature is "DAT1" or "DAT2", see above. + "DAT1" signals an empty or invalid BundleHeader + "DAT2" signals a valid BundleHeader + + Version contains the text version of the PatchMaster writing the file + + Time is the date and time of last modification + + Items is the number of valid BundleItem elements + + IsLittleEndian is the endian flag: Windows=TRUE, MacOS=FALSE + + BundleItems is an array of BundleItem, each containing: + "oStart" tells at which offset the respective sub-file starts + "oLength" tells the number of bytes of that file + "oExtension" tells the filename extension of the file. One can + recognize the described file by its filename extension. + + Typically, the following indices are used: + raw data file: ".dat" = 0; + Pulsed Tree file: ".pul" = 1; + PGF Tree file: ".pgf" = 2; + Amplifier file: ".amp" = 3; + Solution file: ".sol" = 4; (* when storing solutions only *) + Notebook file: ".txt" = 5; (* auto store only *) + reserved: = 6; + Marker file: ".mrk" = 7; + Method file: ".mth" = 8; + Analysis file: ".onl" = 9; + + +3. Structure of Trace Data + +3.1. General + + Trace data are described by the parameters of the "TraceRecord", see Document + "PulsedFileFormat_v1000.txt". + + Specifically: + TrData offset [in bytes] into the data file + TrDataPoints number of data points + TrDataKind defines the format: int16, int32, real32, real64 + TrDataScaler scaling factor from raw format to IUPAC units: + ampere, volt, meter, second, etc. + TrInterleaveSize interleave block size [in bytes] + TrInterleaveSkip distance [in bytes] to the next interleave block + TrInterleaveSkip distance [in bytes] from beginning of an interleave block + to the beginning of the following interleaved block + +3.2. Interleaving + + TrInterleaveSize is typically zero, denoting that the data are stored as one + contiguous block. For long continuous acquisitions interleaving is required. + In that case, TrInterleaveSize defines the size [in bytes] of one data block + and TrInterleaveSkip defines how many bytes are to be skipped from beginning + of one block to beginning of the next data block. + + Example: + - TrInterleaveSize = 1000 + - TrInterleaveSkip = 3000 + + | Start of trace data at TrData into data file + V + <- 1000 bytes -------><- 2000 bytes ----------------------><- 1000 bytes -------> + 1. block of trace (data blocks of other traces) 2. block of trace + <- 3000 bytes --------------------------------------------><- ... + + +3.3. "start segment" and "non-stored" Segments + + - "start segment" + If stDataStartSegment > 0 : + Any data originating from a segment before the stDataStartSegment segment, + is not stored, nor any data between the start of stDataStartSegment segment and + stDataStartTime. + + - "non-stored" data + Additionally, any data originating from a segment with seDoStore = false is not + stored. + + +4. How to get V-membrane/I-membrane of a Trace + +4.1. Get the stimulus channel which defined the appropriate stimulus pattern. That channel is the one having the index chLinkedChannel. An exception is a LockIn trace. +The chLinkedChannel channel is the parent LockIn current trace, and its chLinkedChannel +is the actual channel defining the appropriate stimulus pattern. + +4.2. The field "Holding" of the chLinkedChannel channel contains now V-membrane/ +I-membrane of the trace. + diff --git a/@HEKA_Importer/HEKA_FileFormat/FileFormat_v1000/DataFormat_v1000.doc b/@HEKA_Importer/HEKA_FileFormat/FileFormat_v1000/DataFormat_v1000.doc new file mode 100644 index 0000000000000000000000000000000000000000..eeff94cb7898e8e178c3bec0a7114ffb843300eb GIT binary patch literal 70144 zcmeEP2S60Z*WaTaDx#v;^+ePY0RemOioLfG%L#{^0*BlIV#7p@CDzz`jf%a*5-Vyf z*fokBy9UK*EMVon-<#bXj%M&5^Zm{DW%bAGzMcB!y*F=WXK&A*$$x9<=3=*n3`c#z zQb;w~2{vYQ3!K-Guk#5)Eu1TWRFla>O?_6 z&*D%DLc{WckXPt8px=Obhvyw;)O3Grt(*jpuaI)1djO$fsdTq9U6@P`oR;0W9AO7L ziOnruQ)pF8JpWi&P)?4JI)E;VNa?Z)>*9VF+@E0FCTg;$CT z!UM$HUqTR?BD5?i2rdX0BOlV3r3mTBX=p^^?MUcaK@h^EbcI+B>Ho-lsDSdaI;dWB z$e|oh4(0lYu`=^lZm)cwuCL)@JK95hIV1IU#*p&=9rxw>$@yfwCjOWoaz5s?oSe(; z$u2+2m-whu2|^V`PIAmyobFQn<@U+)7AlnUn)&zwFG;2sLOnVm>pDo6*Q|)|aZPf2 z5}_wTl0Q0HO7Rvz4(RBQ^i>hkHAGF2%cpyvmiV>aPvahG~LS24h&bpD{d4tI`Ls8v(i?twFkN)cULXMXAK9G@`0_NX1el zdo#Mq7!|7X(*y-Y@uUV-c&N&#SJhInEZtO*f!Yw2M&(cSCX$M(7pB#ql-er$E~r!| zO{9u7gWXoMzuLh@ZHPgq4^g>#AZbO`R(9%K$b+ToY}5sZ2Zb9{U9`cWLCDS^W}i8I zX#W5?Jx-BcEVhx~pm3c*XQVqXTC_C#Ou~bBCgDMHB^se5Y0neUPfH z))=Vw&$gz)#=tC6Hww`NMH$f5a_a1AtPjc9&@5yE`Dj%AbRn9sC^4T%oiPw3CMtni zjXy+GWzP~4$)IBQN#MC086Zeti5ms|11Lbr6oAuiDouz#PSIDYKuv@eId=)uYSXmD zO=ZAkKW&gcQZ6TJ_OOcj>4Q;MQX;X&l(`WVVb!JdjfjBC@$O{pU}+6HNECFHM@Q@+ z=xcaCcd=y}=ot+sr|J9n(!cFMN)c=pHUY>-7Qh4euxl#QCRJ_MVojbU0tsFoU_Rds05+}$YI91m4@ z(YzTVwc1cB#$eQkY5m>It*1y6yC*^urlZ;#!!&-7Q?)KYrHRn!f;9btv=t#`gTl3F z5wobDP>C*LZcOTfw3>k`NV);pQ^$%GQW4o5VnhW~AE>&ZRV=Pl6^a`|;|f`GDUl|C z1`%q%6bYxn25nG;)*u?;OyfufTh7%_H68skgUNx+Sqw3hGwbc?O))%>B=m{!^7Qod zfE}CRVc$&)eGk%;=$SQedRnK?0LS_VgJT9&uqFx$$}4VQ{Tqe`Mv$xo>HP*8#5Nmr zL)fTi2#1Kks?aU!xc=zd5Yj5D)by5+4l#9S#Gip$YJ>dIT_G45G1OF)$IUKOF-V7> zJ`9~sNugp!O$dn4Bf1VDRhCN0ocTaqXy(j4?7cly;`pXvs+BgxF>UEgGA7ECfsKM< ztWe2fOYO`!#AlzON^RCpu#O+;C(0yaKdD+8VKyOc=q7WkS=-*e6Jv}@W!sc_A4)F(!WEsE=})sndrWL&J?Kb<;*oDzc$~ z?4K@#(Hb=cjfo#BCkopV+m<2zx(JAB2I(BBET8c4LD@qL!(62lGUZs$u?)zdJp?5 z7}&CQ=}2JhC8Y`Fo*o8uW&)u48eNE+%1;xj@zXKgbyI1Lexe$&@q>(@*h*=XAsa8- ziuB_a4Rk>UJsX*jtsD(xs(m)9`H_03*Uj*tkLV_2i$68i+=_lq?Q9XI4-Z{p+eQ;c zBd37|MED1iYVr=0RnboiKLa8O74-`wZGgCG4S%NAY$P=xHjSv6BdgebHn>UOF81xO~#X_7&VM4?KlogYvkEjD~LGjrP zK~g_f-AFA)X<5@e?5jfL)6YQQNkP=-(*}##XT=ApQPAKJqpfWX z*oKUgaFWYRywG4+W-}s<933kmnDNWpVQxiE%z~U;p7Lkn8`R+=e3NS{a?Z=^Z(tp3 zS5~ac&~#hd=HVf1aQkTF06CIvO%GM31p#VDI%Z1_5P3In3uJE{vv_lEXCsSQ=AK?C zje#FwuGl9cYh|IdujP@p1i@-crY=NYV+zP9_B1IIXYw?Xg!pU1{8f!QH)+{2ZMi~R zcnN~vqw0s5^gsif*^|ka)-2hz&R?sc;YVCa)Ud@)m_Ce&m_z|?IRa17Nb1SwDeyN{6JP3xFS<=BY5^CWH>ceQd zj}e$viF^#nlc7v$evUynZM0@1DOoFjO%(ie#zUI(1wm(m$fQ#$<~h+#T#GlPnLviw zFhqm-nqU#i35XJ_YYc>w%-!w&5ExqUYJ~ZaSZ7rvHG?J=#KTaw;2NThgiiy1O>7*E z^vn?xYbf5KNwefDz?;L!56>e&6RZn@pGMpgJq>WXvp891_o5(nY^o*Q71@e8R~V{1 zD?%S+)buAWBZ$pP4S~8))*-Y^46!%&EXIV{O_0(u zWTQVhi1I9nl8FKlh>q+Zhq?P)9}%tqPXxQF2m7Ol4{MBOqvc*#hKEJ zt}ogg3ZeAZ4OX>;wGh_|4EpdetdjWY{V^TJnhE7aYN#R02xmMPO+^F9%{Hj;heR8- z!LtPDCC#4^Q!E2^N)&3A7wQ91pbkf;P+Urb)lnVVNeU9C2{E9L#U9h6reP}dVE=Fk zEd&f}vs|f|MPX}dRYjde&d3XyfNxYoFp#FBA}gav0tdGM2p}l&h5is!lZj*vo!tmSaxK!A=U+eaZ-KE5~!s- zD!R#a^eZ@OQ>g>BgDa})sisrk%&>3ABJegE?AtJ_NQ-a=Hzv8Hf2{8I ztT!b?fR^b)RhUd+VjiRoFuEJ{?qRzAfktU~jmG2j* z3-X7FV(aOWGDm2F!kM%W_M;_r%1O#t&H(E{=(U#Zx>WI2iLu40Cmza)i^l4z@`|8% z+ryq#^;KSWc5qp-vS^kkYqY#-z(yc(QCk|#q>{y0WYqk10Rdo6K$t#QROTpsII9ln zKfIHW{;-4068F>kX<#TsR?x6beCemfI3PV~qcs(Xu0Du{S6RPcE7$^@xSGS9k^n7c znBrn5F&0TgBPUsRs1RG3LC=w*Vu(R(o(+2@<1bEIX&|8`Q?#uoY8@PIFp??D%noU# zSvHcWJnK=u%FMXwZD-d7eS;?q5V{$X)WO%lqz>BXNrG3yyIR#W;nQlvy39aNr9Iqa zmQa2Yf<+7B21E~I6zq;63O)#!OfArd!cWto3u&QObVw))8}s<16ihPE^0pek_MP1z zGB8FWr8`>yFo?@_%zpV{Vh0rr1=B;r$lQwg8X`fWe3=C6sTrsZi7{-7IuMes1;^a$ z!_r0KOk9wHZu1!=8#Z7~SmC-54?Oq(_xMM10Q>w30Y!kKKyjcXPzopmxB%sW3V=6I z1!w{^1)2fVfCa!JAO`peNCw^lf*p3i0Y!n5Kq;U!P!Vti+yGCYG0+3(1@s2`06Jg* z5DW|g#sUk0Wx#S^1+W3w2y6zn0sDcAz*XQHa2mI6+J zrSp^*nzSk?v~Oi8bOZ!Dkyc&#jg5FFAeO_?yDAj|a!d?uBv9CEfHey#mzK28llqqWQtm_QKk6IeJ@J-!M||lHOazVtcC_mU zXbdy~)&OgPN5EsCNFMY%kOX`H-b(Fe!E5u2Wb=!c<`?PiB$?m2_a9tb&o)i=chc41 zzjATayw>u$!ctJ?7jl&sayPdU`ume0nO{@K%GZ{-PuGG1TS~DnOHkks_GVeSSZG`< zgrX$dt$;2-SAhE17w88J28IJ8fM{SmFaaPLmXqW`GBqb9E^sZB@Hn$ou)98wtigyKd#Fkw+bkkbvQy249PCgskvRC zYuJSb#DjsrufPpJ)>i=|`ye0;I0IY-Xxr*$;0W+5ZDGZBZY7WhaHOr>*g0+wR01@> zP+%JH6L0~z2;2Y?fJERC@ECXo`~e90A)0_SU;`8Y9D$BNC!jO%72pdj1C|48fpx&I zzy;s~AQV8IfKq@vP#3rlJOBho)DNf)Gy?hp?*ZC^TNr2uz{tPG@%;5;{C)8H^&Psx z3Bvdz@kfrtZjX)Kz8!zrADqX=zJBmvGh#ev@o`~h;b7Gz2}sv(7O?qHNl9jC91u#0 zJy%WnO=DN3I5LQ_LIbgB6#9|zzC@R8I!dCR&m?OZH9Czhice%Gn>W78EaSgaZEgz%IuX zb%la}lZ&Ed0GYo25Ose_0ZL(+D0EQ>7PC4CmQ@wXcu&D%lj)Y7jY_cb%w>Z#ggjCx z*pzq5NVAK#f;F`&5RdK?=yd}V6(pY(OvY8Qcnqf^rFhzDiL}#_X{S}=Z3IOw%MOAj z8U8>(RYhpl8Bai^p^(|M6P(C9x>j~~d*POV5rmBfxn*4=J(G1z)~_wp6!};xpHMi} z{Gy5ZMfTCmV`VyTLtWzqZhczU$lYPyH8Sn5GoQHp=TemeZnM^HMWb`pI$7Z4mQd?5 z(mqe?1RL3on%hv>E`~v<{}UN#WZu0E%rDa2p&POsG7ja3J0iA&^z;Iv$Fc0_Bv z22?;LzzuK*yn!k}bD#y_1GEP^0Aqo1z<6K|Fc;Vg`~++R;0+{QPr80R{$%_~{1^X7 ze{mWA`Y8K%;Pr0u6OO*#fxnp(oIHu)M4El^5g9VU&tZ_$M)1GUSCGg5LQR$nK61ZP zpUeGCeNFwGZrn}+kNI(vpW$S%`9->D7;yi0k3YB8%m?`9lMRh*e$5SyO#8?B0O%VV zS)WOlWj!VxCf)r{Z2wa84o~MMnBT~B&g}mdI3@pg?SIuAw@wx;^U*CM?Q@O)vW+&k z&$4a)-|qhvoboLtN-OOSRPm9F_gwn8ava;z$SCO-C%x^?oPUk zh33(6ZV=2<{Ws4)%Pfmow|rQ2{nDgcu$BEI@{MG_XpT9<$C_V6m|s*hzc4#zt*v5{ z)7HvT{`XtEKlcv)d@jfQhmoJ$m2xAqQsw`m{~%bAA51>5?EjMQEBn1iasInm#|r6I zXwvC&_R-R<4rH4DQSLMcWHM96Hm5Qp%gV>t`k5>wtJ&rpOS4=vIW+HZnf7^V_Bo_k zu%-D8^|Md}YpXyYunbrU90863XMnT7HQ+jM1God+1(Jaj;58r=MP~vffRaEdpgd3k zXbrRh+5)|RAAm)`MIatX22ubMAmEoKaszn)d!PW|2$TmZ0BXPks0_3N+5;T`9dH1M z2LwFwZ~*cHUVt}H8>j;`2U-9=KwF?4paJ>;et-@b089iX0h57Qz-(YQum{)+ynp{b z<^7BI?;l=zc?d~VEPVFS zWKqd7WLEYp7RtXg59!Y(>d$=!adhjHAv(;Q2)EXA@^|9!gqIiy)o%6>5Uz_S1QIrLwZ=l`(& z2V;X#&Wu}5#NofH|1{sBxsE)~p*fB`zlq0rI&J-%=l^-3j-QXMpJ{|-p6Q|-OS9bJ za%isqGVSx!?6c^~`0B!(@fC&)FARb^3 zR0V1RV}W0Q!@zam29N;U1a1L>GagU^QNTtZ9(V`{WwAFIXbyA(bU++%4iH?h9~tNg zTmpo0X>)zd`IBfCpYr|z&E;>=AG*TjRq^bWc<224qx;VzcG|IvBJDzU(oq`UJb+dJu^y)=*Z z-25V4v~(9w%%j~jzqpXIi(ky6rMrkVzmslKlC>mYIscyglQow~%@ z1tKsvM6jXj{ICoFH}u^CXyPn#4A}TH}iEe*O5y*I}Pl zW#(;VUn#PJtQxFRdF3i*St;5O8uD37r(N@mCI4^B`&R(JZ~^?h>h>u%;QxcV{VV?e zihnjkAc_CK;_J;+O?bXhVD&iPew^lGZ!A*Ge9tH< zj*;Gi?X#VjnOItNNL>+JwdUSsd#^5=KQKPIw@H`*I^}Q{%a-^?Qo+7uia(nOTE>`f ztI&P%IE)0BfIM;C1*_)1LU%kq6;cN)PR$J-SF(H2kvFUCzP9LE@ahQt*)11cd``u+ zoj$LvW%+MbO#5Zxe4FV7PmOJPwb=5cPIg^_H_ckpplQV6%J0jRxwyjVT+eCwR`|3m z=TuR9zTh<1aw`gyD>&DtW$Qo6mcQ}Gf;uni&)*&CH>-E$lLt3FtY63Q`+}6=XR7o+ zT`Xq&%RR&A`z*fhaeLL7(jTU651HKC>&*PvA*U8R-`M)p&=cMK+gw>QXw3NMb!V44 zbMt1>+Dq4aEb9ES?}t^UrZs$adcS}9)^EHi-@fIg7J9d@?rXX4Rl%hGo2-&sU-r7Z zv2XiBi@sSna^dKDwnIxLTO>8R+h~f9Q98K&4;w?Y9={x65&R$%xWHm4d1SIR=#tvJ5I2w|zk(<5KLoKVfN`Mef~zW(7z z*J0ORgtmFOe9;)c+NG1-N?2d|`RszaC#}oA-Fs9^eM!qYBv{n{G!M4{utSP|8iIbp zgGnO!?RW@6Z=JHQ7tzEO;!5vF((BgrS~dHMk@T7ty^cj&3TaCqZ6~4acAH9!Y^K%ANg z0|AO3ijef89#9`>05k*|0gZtsKvSR@&>Uz1_y8?|RzPb2kAj4@Ks%s4&;jTObOJg9 zU4X6tmDe3%51=RT72pee4fFzf1ATzLfClIX_yPWa76<^a&w%Cg9l`;?Kp+SR20{Qm zK;?`@NNqJBGy>rO?b3(@1_M#R5MU@U3>XfK0HT4BKqus+M@ki19)d88rNE6G9!`R_ z0>!ffW=62FvtTJ>#q`8Ve)MfsfqfaPHYg*lL~>Jbz{t43qkYmzF2RDAPnF0?Vh=>R zK!S*)J6azG&NoHq2kr%<2Z#?jJ&K`x(h-pZIV+#?rtjv_(H^}&0A>22%nqzCsF!no zIN=99@*p~uFR?UJV)=_?GXKpZ^ubpgYd~{qK$EIMi)u1WGLP}`b1GkMyA7f$vgm)g zd^t4F(Gsn0$+XX$n)CDjr2i>*(q%d*%1QC54DB*k=jFfl5Eqxtn5G0$^KLL@A1#% zKpTwyBm>mjNidAZFsKeLi)ZI9jF|4vZ7e^8Z8(1E z(x_?_fS>!s55#7QLwU4g-_P;z*BgU*zK!v95`R@2tr3GisL%!a@s$f^kbU{1jI~ zsTfB~u^3hgTPd_>{CjJGUpb*7a5%F&?zp6s1uc#%ma;QPoGs_HRh$;XY3n&{Bd2ZU zv~8UBGpFt5wEdiRfYT0h+EGqB!D**B?Hs55%4wH4?Fy&e;Ix~Zc9+xcb6O&&J?6Bh zoc0H&z2dYKPJ72`A2_WK8;^*8z1SJ?v?r%^=d{k8){)cNa$0LnYr$#FIIR(1m!yP5aQs?5kxxGku+PZtA!+?YZRiqIa;hyh%#6ZXQEsZO_tC#ir!N1 ztWkU|_0Aea4^9)$3R+Cy`Ay*YP2l;-XB1D)ZvxM60?$uAD`+u*=Qn`oH-P6SpHVzH zzX3eI0X#qXte{0Jo?k1TUn`!Ud`9u){95t+TJikkvw{{RIb!|K zdD~oh+gughc)U*RjM~nwA!3jlhdklnm4C;aGIM$v*Z0{ z$NSBW_nUlH(87-Qn;mbP9dDa_R?s35dMWl>q9FHMB7PT4rpf(=@j$9eq9FHMq9FHM zq9FHMq9FHMq9FHMq9FHMq9FHMq9FHMq9FHMq9FHMq9FHMq9FHMBJ7Pg8Yc>Jza>DI6?L-;sn{Vh!bSbA`W&?jwgE-af0kw#0j!z z5huu=MVuge7IA{?S;PtZrT&Z)WX~c_kUfhyLG~=-1lhBQ6J*aKPLMr|I6?L-;sn{V zh!bSbA`Y)%i@b>wZt^dlqrvf*eowEaC*&vxpO9&mvBcJ&QO&_AKHg33arH z!=6ofoFID^ae{2O;{?&FQ(Do|7sQ$DS;Psgd4I^BMV!!#(`3&gPLMr| zI6?L-;sn{Vh!bSbA`ahlm+L2c7I7GLWST6~af0kw#Bte=6J*aKj_XLAAbS>ZT$kbm z*|Uh_Iu|F%o<$tj%{U=V)?^)y6J*aKj_Z0HNhU1#pN;&FAd`fwM}Dz|G2E)eaH|r- zONznjj2us{Q4F^#F}&t6+^WRz7RGR^62mzW!>vjT=U5E4Dlwe1G2E)ayI?hNv>-1= zu8V9{Vz^a_;Z`L^kgZA#w<BGgRf*wNC5Bs-7;aT!xK)V}WUCUxtx62$XmVX- zs}jSlN({FuF|aCPJe?%Vjutvez6;_^lzF1b(y!wdQ^(t;<871A3R;Zk`HkoKjpzBv zXB1E7)p(xYc%GkpR?tGtt(%%#H#N6zYHr=sf^6N?+`6f`byIWersmd7&8?f7TQ@bg zZfb7b)ZDtMxph->>!#+`P0g*Fnp-zDw{B`~-PGK=sRh}(skwDibL*xSWb3Bp)=kZ= zo0?lUHMeeRZr#+}x~T=(x~aK!Q*-O4=KZVY)=kZ=o0?lUHMeeRLAGvcZr#*^Y~9q{ zx~aK!Q*-O4=GINkt(#hqt(%%#H#OHSHMeeRu7hfB-PBxH)!e$NxlXIObyIWQS99y8 z<~Bmjt(%&AC~9uq)ZFH%VckTXp_vGsIa>H|+vLOJVIwk+C)*|;Zkv2~xjx)B`SAMr zaNFd=+u_4)lMipN54TM|oG(7yHu-S=`Ec9h!}ZOF>zfbPHy>`Be7J4$;kL<#+a@1w zn|!!!^5M40hubC}Zkv3#ZSvu^$%lJ9KHN6>aNFdQ&g1a`*9khzRdswWm;JnwW_&dB zi@^+TGmw6+rjW*bn#YMfsKgU6u~(INW+Br$a#~kT>&|JuoYsreG@RzgY5h4($7#Ww zrsp&Rr-gG`6sHa4v}jKIhSSDy+E`Bep3^3A+B8m^&S|qbZ7!!Ro$*rD}TRkPWdP;8f zl-%kmxz$s0tyOZXr{vnLnSJtemmN^bR(+^Q(K)l+ioqvTdk$*rD}TRkPW zW=cMiD7n>B@)1WVykNaRyqEoMrSOE)w}IZgKWmBKYnljj9W;UcG9 z;1(d`YEIgU5qFekPOG?d zM_wzkON_41v=!5Y_e7#fH{*7F3dO}^sS}BO1gYsNLUU>R; z%gNJIDMLCapR~G|OiNPJ>Ow7$+iA|NG@i&lKb2w5H3dsY+zLp~Ez?}7On0ojQ`yh( zM!MJ*u`aYKCvv&~+d+`AhVM+1)78*|J*OyRZ7)b)tP;Om$oeyVi$8@AH%+U|`XoC( z$o*~g5$VZVYEGU^lNy;1Vs1H=nro(c>1t@f_Ozr)g4bV^g#D)W>GIE768>`z%>Bz8 z*llW*u7(*o;Qg05kP}__6b}5kE@UqQe$bVSy0ANwF3@^W8SC7#E_iu(E&0ou@TGI% zS|%=#-j}hq<6QWwJXmZ>NoR9Dw=S4YX10piO9JiP$|wo*O^NAhm{Aw1{6$@e{^B_> z^l#_Dm#zmxGwA_6!8aQjVGTUI|GF-G>3o=<6F&T9yV&Q8A0K`H=JBylj(o-c=J@EF zNfI)RkAGPo>VNT`V(q`#Q>_2R%R%i-a*)A8_{&mI>WjAq#r|e%ked3X`$%t7|6U)d z)EBP@#WLwZ27BoJ*XIkVsb9K(@HX{NRuI62zs`q*)GvMhd^Pp&oj>pU;w{3izu6)z z`rqA#8g^K!z6zpN3%zj!`G<%ADa{_2WauP>etJ#)f`s(+Oa z^}cvM)XKz%4C@FVl?C}ptNi?$E#v?D=d*Lbc^p0MS6osY7V=w|#ApBX^q&BlptvLz zSqiUg<>GPaK`p%$mkW>n?byrtONH%tG>tb~@IadWD)G-*aa>r6%>xv!lEU>;xK#>& zmcso~cvuQgNZ~mtyd;G;r0}j3CQ9K`DSRb`@5E5iCzX}2=qZJrrLe6OwvfU`Qdma{ zt4U#HDXb`kWu>sB6c(1k{8E@(3a!PE{k(?At+L=)MlOX4#T2f>8@yUXuNaB18M)Hy zLD)nhrgCQI*{7Uco;!fI@7A*7W_=WX+S=k( z%{Xj&644&l1Z+wqVTYvCdA2EqWB4%v5gAiv)f3L>?~Y7H*C@JE?zryFWM++memEj~ znQ=ycizz2aDe-C(OF7|BQ{v?&R^|XHC0=4;DF^&%O1#FzQsRXrR$IKT#8S5U)0B{9 zmeN%)iJ`(;3Ufwvoc-QrJ)mYfE8ODfB@2 zF}~uJA661x?qO}jt350wUgG(9k6<%0Ya>F|Mj=sbBSO|jgshDSSsM|uHX>wgM9A8R zkd=s#wGkm}BSO|jgshDSSsM|uHX>wgMELPGl9Z#a3cMIYA>z|ZGVDbeS<2ZxS;}z> zbo%Q|x=P$Z$ZR=6X3G&WTaJ*~a)iv5BV@K5A+zNO&q?W-Eyp#pWLHwB-nyEl0>~IYMU35i(njklAvC%$6f$wj3d|Z%;mLp`g9Q80sTfEq>$HR)Gjd-%{A={P++an^U_Rbl$N|YbGy1{r9Bgs#UBtJ2d z{KQD|6C=q_j3hrXlKjL-@)IM;PmCl#F_QemNb(aS$xnC}?|T2NBWo9p+&<7Q3TagLVc5h|(!KO4Mebl5JL3wru1jH8DfE>>jTH8m!eA*hNMV!| zMoZxsDg0gvr%B;#DO@Op%cU?z3O7pOHYwaKg$JbYs1%-(!e40|!j^vK#Ud0fpHh-P zr6hk!N&b|Q{3#{*Q%drul;lq-$)8e^KcyspN=g2dlKd$p`BO^rhi%R@4#J~$k;BCYCgJ9eObGxWxQQ}W;IHS{paoaJzcvRn&nbauus1)IDPFEMNRjJBPMM4 zRqRj%XIcAfd*vjKzqMB?3KG}7GH~6rO{zDx=_+O`3Vm9==g$2s^?sg?>y^`SU8=Wt z#(MXWq-8&(W%d^+Ex9FW!4u%)LV8(&-nodfg1Ybc0_$!k*F96sb*5if%@?PpC?fId z4Oy9tI-0GNn@lH9n(63&YI|}ZEmbl|i;!26@@Uk%`#-1NrX7-$M?+G&e}R%B+eEe_ zG?TQ*a=sX~kNm=GpIJ)}NV1L%nu;3#K+D(%T(9v3ay`v5!l1loN-02JCxopuhaa=ecSw?I;6q5fzQodcRcPh3E3i1Cai!P4+rBas&$zPzP z$l8hL(;2l>D8PBX1U&z8J#@D3E>rC#Nl#6Hq;LNRN;YS<&$J3J z&Hr;|{WcQM_kriLzCfPK^9r_4Dw8Fb$Du{2eZ&`D`%E%}QB<}sOJHBV+I*uxh!#dNKCqAt{ zHKpJG{}le`Lb>$djgHMN=N+y1X8eMF8%Ec9@!jH~Ll#x@b3RpeR_g*MUcFm5wdujl z$5M8WdvR!;eS^abCeGWxF?CVNu;W3xQr+r5*m(Zw%`!1Kx4u-X*Y*Bg;vbBz=o+k= z=h^Jl#o=pLAB&yPt?$qid)myoq3vD%WZoX<*0i|$vPQe;yDwL*4_%ZjoeinlDth_L z8m*$Q=6a};&epUz^s+{q=tELO@oY%J0p)vy#qO9exAdI&frsXJce7s}e#5iI!Jkr# z2jp$@u;rmVvBvt=<>xRrZ>{-%x)aGhMd=Cx#;l=i9zM3H4 zz9|R4)07^we(ViPUrS%>cb-Whm-7WxOgjC;#bdsc_FOzRfBU132#fem+N@h!N;{&R zQ`Cv3FJ_H@;O=;8esqBuDL=4N-}3Wzw5h6}8<^mIZjW|ZS{(UCWZOSVoTh}Q5417n z4ag!!wn?v#pHjKygL*|K&)b};KJvqa4HY|`tJchQ*Giwg*01XJ>bxQ>&&q)lx)|F| zJ6=UwzjLhvQ57_}+3ZrmnBV3(&n#T4y?9m#QI{d&>1QQz`+kWwBKcKE^&|J0xfev{ zmvTV?=eIPrUB+_!pzXDC%h)-;j}9Jt!}eOPYk96&T~l5Yd~JPm``Y{3`6_(#?#{j4 zYGt*B#~aUyAK{w2Z|xSHijGeFx|PwBO4b%|%%g&(^fa zyQ9|i2ch#11-H8pjPs6Wmm-DkI))>H6qB8&yJdctMZ3~7enZ*)8&1ZLoHDp${xZpr zs#lnQe8`|J(+1XvjX!W9xLvnH-NF)b&DnKo{H{}PcHCQ5zNF#A?dnHM7RvL$ za8ft+S_#9=+ttUGEfHea`3s`mF7a^juEQV3L{2?hY+S$V1r5C?&hPj3`$3&grX1N> z@j)s`RVEjyad={lBW=9~jUUvx&HH}wb-Z4<2kbk1atChgtcV*S69#ogy6Xk+u1rt5 zGwW5mq~)b1=QmA$-9JkWdOkDF%q-9L73o=RW6 zI(Db-_b=Q|Z>@PoJbAILBt?Kd^>Hu`0za_}GC_w!>RTetW@9bE*3KA8*x5$~R`M z&CrL(1NOhT)}-{CrDt`6HdH+09x?OaWc@AuoI6Pe5`49nqdk6WJpJK;h9Az&e7}Cr z<<@!o`$k`UlA3b=x5f8wjHrCQ!|S>Gf4@D=w)79BPt z&nYezS1$%AZ@*uM6)4`7tnl4(fVAl@M zWpn%0D71X8U*Np%V=fQhUM=EH8Pku4d!-auduQvBb{qG0O|GW*d>{TOb;G@z!9VZ! zIhZ%~+kLgR1e^9*Iz$KTyB2XPws7GwCSlJZ<@<7`H(js%+|8=$ixH(SMo<6!L!VyF zs&qe-_-p5j%k!(>&I^9EXI|-$pZ6zT=@Z{5IeNZcmpJr6(*9pJmwq%j>CA)DI^6Or z{U|VLYs~vAQ$D<%8U19>nJ#b6Z0|baa!l{Dmp0DaAC$Od`O4|LHYUIB6I?tx+VH;G zk?5aB^^C4+iu}HN>i(IF7l))IY}?x4*D80%zkfCB-TdBfPSjcbeq+~RNmIhZlP+#} zd-Up>5m#TFKJ)g+CJVcc*jD!0FG0?m)=gK|?eNE{gx@{tzbbWX?ZOW?g0JX@J__&h zVPK_wSAB0BzL;=z!ov~azQ3=k_eY)M@AphN^Y(zp>9@nSTwS~H#Pl1!Pfo5Ke9>Wh z*AG?i+P?`OVO!}2ZXMZQH)>&xVGUAGJBNmBxvKxUe}&yCvxaWDQ^nM@aR1b46Q+C! zEqpX}@ZqDWfrXFm+i}P5=EcLC7q8v<7PYmiy~cF3QmJoR^mqK`{=#*UDc$N?><)1JW_O+OvGXRh z=-buTYUSRCrYY|qN827Uxiw48-9Bk>Y!mA{W83!Fc|C0WS9xAl+E}&6nsLtJP)~mk zW7s$U6yF(Z5K{*)xH!9gV8QN1V)wTkxUgEwGGmGq8|TyMw`)H&U2gOJvfrAmYGgOb zXGXtKD>l2RXLWO~SFnBK>D$Nl&Qq(4FWdYwZbo(G%=iZNe022+`c4>gXK5i< z*M3(LYdrl>{ff)hp6-PL`bWK+e`TRQAtmAcgZXohI5aK%bXR1@0j|qj$0s=#sPUn# zDgO>P$M&;+Fb?Ck72Jw&U(mRu07;Nt)n+WZLjCuaqv`Vy`WK*`Z`rVVAI2PVBd0I z-&0SkaI#zHgKm4>U-jNv_gTBB`fc|-*coTJtk{zwe;g|_DJ(eTUgHn1296#$#qr{X z{2OLYSaWtt^SE+Ff8AR?utIp95WhE@ue|yt)#a?8!;t!IUB+EIx$g3-d-W%!7CUbB zWJSp0pZ4D`+qTi-_KE#Bf0$gh@W9HmS9~A8^xB}@E6d(}wQSn+g~oFanwLMNTfXS= zrFF|!?eQ2itn9;`t)0SFc09A~`x4G!U6vASO0WbJ}D7^x)XZ8)j9CJXA8Y z&h=b14!zoBzhPw0%T~qvmR$GE%+P6fEw=4hl90Hk-Puyx5~>YY7?wKvwd0-k;~JFt z=*f>8@+TTDjXU4FY^zItec}fCPd(Pi*>-#hx1u`FGkq5ws5>gk=0%UuBqAlLrJ*&V^ZY{8S?RcyG$Oej3>EuA!3yWW$zOkxW`G8^FpKcA_ zm3sNroyg>d8`sVGqgTC6!OL#V?dv=!Vp!D0$){)M-RZb5Z_2?Pw-m2EhB-h>Z;yTE zSTj$9F^do68=*LJu<~u|*Y592rS?5~|L)=`(e+c`yngtRlh#(HW9vL?|JwGweQKWQ zi4U%Mn&J|h4IdEJzIDl637Q=(?k`V#@o3iDLlM)u75A-l&Cz~nvq#GV{hQwG^HuN# z!}&$O`PFN2s>P%@ub#`wuNe>#GvW89reB`cjab{Mn^TGV+L#}%wmG{ydPz!$K4*H* zZ@caHE6a|?=hK~jeQk*Ckd(@OqIw?nTKB}S&Z0HfA8wBvKIQnNNAoY%ANteJcdvFI z_VpjfRvx|hqV&;Mm(~pmcCFc}+nPEbIR{ee9 zi@YuYeO|8n`r`fZi)OC#e7xQeP_K6Dgw7qu)=0Wozjs2}vZmGv(PxeiZPqDa?Slt5 zCb@SWa3VBUaLg~W;++;gzw-0IDV1w>ubN`0c(UH~GsAm77=Ers^%ssmze~`(dGtrn z_+@Lm=k|{NcKf>99*UOcshA&TOHhb2&UN4J27`FWMoAU)v zN9|j7W`Fa_9g5CwRx)hkM7PDpsE1)czkA-fXIEo)$JzIr-|wBPZCsy)YkyeeyYk_% zE)VMt|GE2_dy9IU>6N^Hb>ehw;M+?B-fn*GRnK&CW}OXD4l}wYB$t{ow9ku#p53B$ zze!jgwPR-cgs<{X+4Z>7+T;GY)*f%utj&<#iJO1ck2~@s8r6Mrr_Rk^4Njc@Vs5K_ zXNUi`GoZoL=ShwU6IMPxu{wUXvH$*Ezg>TNF6mmQMIYuZyP`jvG_doW;i0iUT7ilBA$zA-g25TNgDg#t8= z(f2K>j-vtkF5N_+Ffaq4`8j>xD<7}|pzm?51Dt@L0D5LqXua?6*vB) z;~S*<78nJL2F3vNJwF-py28KV|4j~*vMGeEdJ18%!U0DN_B^6LYD-_x=w0YP3_%mu!Q4o?W;z2XQi{4TKug`ddc&|Htc4seip8 zM@7KPBQUD*zylx|uz@%_0p)?}Ky#oQ5CB8~-vP6L?9x%bYLsyq{QeF2PxJZzo{qk0 z*#meDD8bJnKsR6nFcnw=Yyx6|v%pB;7Vr$9K`I}h0z83+z`ytY_xO^PT~VR<_N}ah z4nRkskB`DC*vHl?1TX+b08xa7g3$L5yi?Rr$V09ZJMc9C_Ra1Pd^ek(n)riC-CR&; z(yEA*lO1xgW4S~KiiQf@k1)%@Ubv2DK3b$T;CIUd5$f>tiM~QkFKtx9cx35fX@A68 zP(YR(MxV9FKiczy~973*S)Ebr(t<)f|N^kNmugM zf+Z{Y>l~F_1tk{{EU9G26@iNK{&~QyhUG1!+%1~4Dv>UCMCV5u>17GR8>O%zgOnsG}yhg)ZZI*j(d{ab= zo)2L;x51eKb=zn@8l-qQ=$rO`<>-y<`yzXq6{WWKQaCHtnbp)j zi<<gc;ZzEE1g0RX!Kh(*B5*0`85&=uVdTN6$}1W%1@BDofKcg+PuE9XpHE%(VlOd9GPAnwd zNAJ;rioPfa(wJT*8ne1LRy0mm_vX-p{*a3>rV06ARV~RfknI}`iN;qB&E={?YfGzw zU@!UWWrV~8hyC;jyac3zX1Kmh^dUxVh_O$Xs8Fq;m&f4Xpmozuv^(UPuUU%E`%(AZ zTP@hqP+2bV+oO|@E*lnmY_5w_+~qB+y1q+kbG}RC)heeTw<}dr7S*{MwzstHwnK9k ztZKFKdE-hhkBhhH_2bPN?XRrwHvXGpMe1sPbeQvU*SPc96ztqk3%1X_HVPL z-sGuarKheq|F)*ZiE0t$M}8QY_f&Yt>qQ=qpH}m3T$4-pEw^tf*`wa?_utHMxij^r zT@9+YTi2?Ia@5w?A1)-Ve$zb8sjy-uq;`1Ezv~Up4s6@z;~lzVzaz z312`+ jS3QgcpQ=MJX@#Iqm^R2z*@OO$o^ocuAfG>-=MNPr7g71g zsZA;`A1>ThM+Z6=zgGP5wf0ACa_v@*Uhy;~re5lX@88^>@lfS7Z;j2NJ53s#2)rFp zZ-4Z+abs4jDyQ@v9Qxhzq1U$c+0)_N^17$IivQ@d-E(FEhjCZh@9DImvH!WaeCJy= zyH>TIOZ2K~gZf-5J!etTTh-hA`pT)(r5b%VOj#Xg+Iqq-L~^h{0B58b3+G4&2k!r22KD<0LDOVu(q<<-?o|%O@D0| zNl2cPZF3z`e!He@- z+xK)^U~4}?d&*FslQ^)LmQf9PU(m{`(?@jT#>@vTB^Tsv4H@bF;TU4}!r>425arTI(7dIvh zeU;Gp;*B%C%U{?X`*prq$?xATocHv$@wAi6q#>zWudF!#N4+u~cQu^x)N9>Xt)-Tjz^~0l`HcVdA)oZNA<@Zg6+TGq=?ylVr&yFvD^zHK2XXl?C zu)N#Au8vJR-E7^_VnFH2v;8N380x#tFW0Wl6)(gtcplSfLdxdvU+ii;Zc>p>zxPsI zeWCfzdiR3cv(Klf3l!M*+nZ`19(I3vWBsz_UynO(x#hd-O-=X1evZAfXX(Rx=X!eS z@{Mk^w$E>u1lN>7cawKk3n}!rs&MMzrt=fOU%&N65t~}^f_6&Y8_Sbd_uTR9yVM7z z9*$UD->LT~?+*t`jqon|Z6WtPHrm&r4yE(%8Z~WwpHbe!20Gl_@Tx_lYv(sM@+z13 zrqnK{?eh*j8Ib$f59j?v+DJ)&&)-pf?QCj8c^vs+JBhr?fe+uO6gVx&bUmzIy> zPUWh6uEd?laq3!kf2mWZW1eqzG_L6A`SrjH<+qi8-+ghz2D&NB%1+FqJDhvYxV>c# zA9Xae>$c@#17ZC>Mbx_&XY{>IuOGZ>uiy9f(W%G#9~uUBops%-RoTwJ&wiTvY_WdC z;}7q~>Z9MhopR;E?!lTnH$Oaye46^lnUt8Zg=ViD{BG6Ln;%|(xYodw+9&$M)unsS zoSSR6c$!u2r}_82T(rf?>9<=`&b)r*65!>$vT1`!R;{MZJG?a7%`f+dz)|Y3TQ--s z-!XkE`w(@QDH1{3* ze1qosH$S~D&~?n@mKGzf>{Ncc-~HNx`YAROcXg|GuyFMP$u`UKKCjZoy-Grhf#VCz zK3=rdYTYwO7r(-BiQk=Rd%cIxGvnxrFOKAP8{PVW*VtFZ+C?jMN1h~i-qkY5W%j-6 zKfbW?3UF?bG_1&S|N95qwJbLO@|nZ6MysDM@=W}8vG>rit0SLTwsP3@uGWEByBjR9 zU)1QkY87WHmhJ0l7+d+NU%=s~#wN3syF0aAT%p^9Cx$x{Cm*Q2rSUr}zX=}aEc~8c zd6?J6a{HE`-am}U*Q8smBO79ej7;j$^=UAsW|zvqW-G+3xC<# zNcZjQGN-1*K3;k1Xop7yx(jtzzA!kx9@j9%_K!PNkNYWVPrOxs^{bW>*IBGg7*nTr zjqA^Ec1ziLfj_Y}>x^d54IGb@sM@z5ns>C5HyTo2@S~|H<8#bwUnz+p;TQl|enX z#M75G#)j_hb!zG#)^A?UpO^ouRqZ`5O#3h~{MxVAldGnhhPO8aHnDynI?%Ft`sdM*|cKX9sC5k0#R)vgN z_4wWl_brD`59w7hC}3t+RnN(n4)!aNca8sdA=^$^?rFR?pm^e_cy~p)p(P6(@vlC9 z<*24Z>#Ux*VoLadz`O;9XiJZ2cIm*f`Kyb@9G6TRqh3v@4Vvjlh!z@ zLciBV7qnPaY;UefkKgX{-F0Evsy0g>jymhA`>D=Tzd@b*jJh5YvLt41#lT0slHYf$ zGJ5LV zKdgAT_I_bxaJtMq-@OXE+tbTk8uQchm}!=)!0Hp_7PbEM$&qnejLEr*)<03`w0_&` zQwLi8u>Qb}Uk49LTzIZp^aRx}2P1kF4Q*s~z2t=|13i>qe^+Syx{3Q29-OhN*Nf_{ zj&`U%`8U_*QO&%jN7-D8*|TK%&0NKc=-w_=;etG@s{HGK9 zK5IU+^u37XPT$SCwy%@#S2t(RFMKU2$=YQ~e&f#rUB^U}``XuFWq+FjXNBC_#niBG4`je8U7S?LLrp?Xc-Kz~6KCq9zX2_Ghb9XIBsb|sh;fZd3 z=Yu0`*SFenWpS5p&n@YknAdmI@zvFWrj%cg6M>wn#qZ(8{quWqI)PGuQ zb=&eTozxy)bHeggXf=Jo*$G|VjNDLj`IK(=oR_a`bZqxopOo<7Oa7Rz7f}du7YsQ2bJ-@VsMd1>gcS1(?XUr+186?==34=oV`3e zomJWpKfS*$q<=lMuRu(p~|6*34h z)YjB<4m27=Ygevp@PnJIF?i@hwIR3{pbrby7;zcazp{UrCK4G32UYg=^sHVvSfdMZ zR`u)eRnIxd=;f?34#t`PK%DjK?@cssqT$ScAkH*?ewdUYhIArRa9^bGI8|gy6**2- znNn4zRFf&yWJ-0JQr%e<7^Djsh!#=ctP0Qv`G^Gh%(-%X;$Fj2Y+>drI;SUHG@)#X zF41A(rCmWm*oFtGdyC^{Im9hbYki_GPS00~>bgqIf2XXUS@y1v2vk;sGiL(b;nWL}5SKLX(%00IDmL22?;9pe*15 zpn3w5F$<$cSP`fM{DKUw0|@}N)v@*r)69u@iuQ`}!}5=M?3iEn#i@y9{1c=iKsh`J;PELLaS#~4TWI$j55f0 z;L~F)9X)k})nxG-BgBG=m>=juUIB}Ext~#!_oIM(!U-yd{U(%Bu(G7jN;a^h--y9u z?`M>N&P*n%kG;?bOLlrJvQ`yp301JvRh9kq#DnbY@74Usy;|Ac^Fq$q<>`fzv%ly4 zk$Y7?a<3X%C_a`-zK7^-_<}0 zZn%JHzR06F@)(8m56tqQ__VE{7&0pfdg1syaC3c4&MVVP@xLIS`@kgxLW}A0UDxCO@Ox0gN^{T(H67% z&j&P8a6!$zflI(WAQUW%1iC#@0g=xsM`D9~O`-WU-6s~B-#5Re`;7JY zGjh$Nf+}1St#Cv9F*|69I5%roSF9kr5YtVkOKdg`J@c`Bh3%BA^bltgKo z*dUEku*j{nQQBBpk-)>4rX9o?I+}o6It+XotfuR6ZJtM!Pi{48PUYHxkuZYNk!86Z zSUu_K8$H>gk{jc%9{r?39YPp=5Z3oKxKpDVYrn0PorQ(9g_Tvh3~@iLEqeAuKnKo; zf!@T!4Yw>DEQx8B;G3&(Yp6@+UTebYq65E)e=32VvGoUEj8wMBdk5=J$^(29d1qw} ziLs%wZG>AU7c^2FUD7h`G5@F?E zxEfbc%DniJIR+r;5A86tfm1}vWSOr0XI<|NZ-M4*X~nYx@&+L5>u> zJ=4de-Hn95a*%=^q(6eP^{7GAPd9JMmMN=zeL4`;?imJKg$vH_K@MQ7qq75DE!g2B`={{H7 zzfwLq#g=dcC=VMurlvxySh40Rgl%mrIa=`L>77Sl3Hx)t*93=-|2mk<;Q74N4 literal 0 HcmV?d00001 diff --git a/@HEKA_Importer/HEKA_FileFormat/FileFormat_v1000/FileFormat.txt b/@HEKA_Importer/HEKA_FileFormat/FileFormat_v1000/FileFormat.txt new file mode 100644 index 0000000..bb8b903 --- /dev/null +++ b/@HEKA_Importer/HEKA_FileFormat/FileFormat_v1000/FileFormat.txt @@ -0,0 +1,631 @@ + + PatchMaster v2.90.4, Patchmaster Next + +(************************************************************************ + +PatchMaster generates multiple files when you create a data file. They +can be combined into a "bundle" file, if requested. The bundle file format +is described in the document "DataFile_v9.txt". +The files are: + + 1. The data file itself (file with file extension ".dat"). + This raw data file is a continuous data stream. + + 2. The "pul" file, containing acquisition parameters, such as gain, + capacitance, etc. The pointer to the data stored in the raw data + file is also stored in this file. + The information is stored in the "Tree" format described below. + + 3. The "pgf" file, containing the stimulus templates. + The information is stored in the "Tree" format described below. + + 5. The "sol" file containing the solution data base. + The information is stored in the "Tree" format described below. + + 6. The "onl" file containing the stored online analysis methods. + The information is stored in the "Tree" format described below. + + 7. The "mth" file containing the applied acquisition methods. + The format is described in the file "MethodFile_v9.txt". + + 8. The "mrk" file containing the markers. + The information is stored in the "Tree" format described below. + + 9. The "amp" file contains the amplifier settings and solutions. + The information is stored in the "Tree" format described below. + + 10. The optional "ana" file with the analysis results created by + FitMaster. + The information is stored in the "Tree" format described below. + +The descriptions of the variables, their names and meanings, and their +respective record offsets are described in the following files: + AmplTreeFile_v1000.txt + DataFile_v1000.txt + DataFormat_v1000.doc + FileFormat.txt + MarkerFile_v9.txt + MethodFile_v9.txt + Analysis_v11.txt + PulsedFile_v1000.txt + SolutionsFile_v1000.txt + StimFile_v1000.txt + TimeFormat.txt + + +The following is a description of the "Tree" format. Following the +description of the "Tree" format a source code listing is enclosed. +That program shows how to scan and load a "Tree" file. It can be +compiled and executed by the PowerMod environment. The source code +is commented and can easily be translated to other languages. + +The idea behind the "Tree" format is that it allows extending the +information stored in a file without braking the older file format. +Thus, newer program versions can load files created by older program +versions and vice versa without requiring any file conversions. This +approach is presently (in 1995) working since more than 10 years +across many program versions. + +An example tree can be diagrammed as follows: + + Level 0 Record (Root) + Level 1 Record 1 + Level 2 Record 1.1 + Level 3 Record 1.1.1 + Level 3 Record 1.1.2 + Level 2 Record 1.2 + Level 1 Record 2 + Level 2 Record 2.1 + Level 3 Record 2.1.1 + Level 2 Record 2.2 + Level 3 Record 2.2.1 + Level 3 Record 2.2.2 + Level 3 Record 2.2.3 + Level 3 Record 2.2.4 + Level 1 Record 3 + +There is only ever one record of level 0, the root record. The above +tree has four levels, the root (level 0), levels 1 and 2, and the leaf +nodes (level 3). + +The format of a tree stored to a file is as follows: + + 1) Magic number : 054726565H + 2) Number of levels + 3) Level sizes, one per level + 4) Tree records, top down, left-to-right. Each record has the format: + A) Record contents + B) Number of children + +All of the values (except the record contents) are INT32 values, i.e., +32-bit (4 bytes) values. + +The "Tree" format is based on proposals from Stefan Heinemann, +Erwin Neher, and Walter Stuehmer. + +WARNING: Never assume you know the record sizes. The record sizes may + have changed, e.g., because the file has been created by an + older program version which used fewer fields than it is + currently using. You MUST use the record sizes stored in the + files themselves, otherwise you are asking for BIG troubles! + + +The trace data are stored in the data file as follows: + + first trace + -> at offset "Data" + -> having "DataPoints" samples + -> to be scaled with "DataFactor1" + + leak trace, if "Leak" = TRUE + -> at offset (Data + 2*DataPoints) + -> having "DataPoints" samples + -> to be scaled with "DataFactor1" + + second trace, if "SecondTrace" = TRUE + -> at offset: + (Data + 2*DataPoints), if no leak + (Data + 4*DataPoints), if leak present + -> having "DataPoints" samples + -> to be scaled with "DataFactor2" + +notes about stored trace data: +- it is stored "Leak Subtracted" +- but not "Zero Subtracted" +- add the leak to get the "non subtracted" trace +- subtract "ZeroCurrent" from the scaled trace to get the "Zero Subtracted" trace + +notes about the second trace: +- stored without "Leak Subtraction" +- stored without "Zero Subtraction" + +************************************************************************) + + +MODULE FileFormat; + +FROM SYSTEM IMPORT ADR, ADDRESS, BYTE, LONG, SHORT; +FROM SYSTEMp1 IMPORT INT32, ADDADR; + +IMPORT Alert, FileSelect, IOBytes, IOFiles, Strings, TermIO, Buffer; + + +(* + * MagicNumber - This is a special value used as a prefix for a tree + * stored to a file. The value contains the four byte values of the + * characters 'Tree' in order. + * + * SwappedMagicNumber - This is the MagicNumber written by a CPU + * which used the opposite byte ordering. + *) + +CONST + MagicNumber = 054726565H; (* i.e. "Tree" in ASCII *) + SwappedMagicNumber = 065657254H; (* i.e. "eerT" in ASCII *) + + +(* + * SwappedInt32 - Swaps the byte of a 32 bit long variable. + *) + +PROCEDURE SwappedInt32( Value : INT32 ): INT32; +VAR + Source, + Target : POINTER TO ARRAY[0..3] OF BYTE; + Result : INT32; +BEGIN + Source := ADR( Value ); + Target := ADR( Result ); + Target^[0] := Source^[3]; + Target^[1] := Source^[2]; + Target^[2] := Source^[1]; + Target^[3] := Source^[0]; + RETURN Result; +END SwappedInt32; + + +(* + * LoadOneRecord + * + * Loads one data block. + * All "TermIO" statements are for demonstration purpose only. + * + * The variables are + * Stream : the file handle to the open file + * FileSize : the number of bytes the data block has in the + * file. + * MemorySize : the byte length of the memory block where the + * data is going to be stored. + * WhereToStore : the address of where the data block is going + * to be stored. + * + * The procedure returns TRUE, if it encountered no errors. + *) + +PROCEDURE LoadOneRecord( + Stream : IOFiles.FileHandleType; + FileSize : LONGINT; + MemorySize : LONGINT; + WhereToStore : ADDRESS ) + : BOOLEAN; + +VAR + Excess : LONGINT; + FileBytes : LONGINT; + +BEGIN + + (* Here we load the next block of data into memory. + * + * First, we have to compare the number of bytes we can load from the file + * with the bytes of allocated memory for that record. + * + * There are 3 possibilities: + * 1. The size of the allocated memory ("MemorySize") equals the number + * of bytes of the data block in the file ("FileSize"). Thus, we can + * load the complete block. + * 2. There are fewer bytes in the file than we expect. This can occur, + * e.g., when the file has been written by an earlier version which + * used fewer parameters than the present one. In this case, we would + * have to zero out those fields which are not filled with data from + * the file. + * 3. There are more bytes in the file than we expect. This can happen, + * when the program which created that tree file was using more + * parameters than we presently know of. In that case, we would load + * only as much byte as we had reserved RAM for. + *) + + Excess := MemorySize - FileSize; + + IF Excess = 0D THEN + (* The file record has as many bytes as there is space in RAM *) + + FileBytes := MemorySize; + + ELSIF Excess < 0D THEN + (* The file record has more many bytes than there is space in RAM. + * Load only as many bytes as there is space in RAM. + *) + + FileBytes := MemorySize; + + ELSE (* i.e., Excess > 0D *) + (* The file record has fewer bytes than there is space in RAM. + * Load only as many bytes as there are in the file. + *) + + FileBytes := FileSize; + + (* Do not forget to clear the remaining fields which are not going + * to be filled from the file. + *) + + Buffer.Set( ADDADR( WhereToStore, FileSize ), Excess, 0 ); + + END (* IF *); + + RETURN IOBytes.Read( Stream, FileBytes, WhereToStore ); + +END LoadOneRecord; + + +(* + * LoadOneLevel + * + * Processes the loading of one data block from a "Tree", and all + * its "children". + * All "TermIO" statements are for demonstration purpose only. + * + * The variables are + * Stream : the file handle to the open file + * Sizes : the array containing the level sizes + * Levels : the number of levels in the tree + * NeedsByteSwap : the flag telling, whether byte-swapping is needed + * Level : the actual tree level to load + * IsFirst : a flag telling, whether it is the first child + * loaded. This is only required for text output! + * Position : the variable containing the position in the file. + * + * The procedure returns TRUE, if it encountered no errors. + *) + +PROCEDURE LoadOneLevel( + VAR Stream : IOFiles.FileHandleType; + VAR Sizes : ARRAY OF INT32; + VAR Levels : LONGINT; + NeedsByteSwap : BOOLEAN; + Level : LONGINT; + IsFirst : BOOLEAN; + VAR Position : LONGINT ) + : BOOLEAN; + +VAR + Count : INT32; + Size : LONGINT; + Children : LONGINT; + i : INTEGER; + WriteInfo : BOOLEAN; + +BEGIN + + WriteInfo := IsFirst OR ( Level < Levels ); + + IF WriteInfo THEN + FOR i := 1 TO SHORT( Level ) DO + TermIO.WriteString( ' ' ); + END; (* FOR *) + TermIO.WriteString( 'level: ' ); + TermIO.WriteInt( Level, 0 ); + TermIO.WriteString( '; file offset: ' ); + TermIO.WriteInt( Position, 0 ); + END; (* IF *) + + + (* Here would normally be the code which loads the next block of data + * somewhere into memory. In the present example, we just skip the bytes + * containing these data. + * + * In case we would load the data block from the file, we would call the + * following procedure: + + IF NOT + LoadOneRecord( Stream, Sizes[SHORT(Level)], MemorySize, WhereToStore ) + THEN + Alert.IOError( '7-Error' ); + RETURN FALSE; + END; + + (* If byte-swapping is required, we would now have to swap the bytes of all + fields in the loaded record! + *) + + IF NeedsByteSwap THEN ( go and swap the record fields ... ) END; + + * End of code we would call. + *) + + + (* Increase the file pointer by "Sizes[Level]" bytes and set the file position + * just beyond the next data block: + *) + + INC( Position, Sizes[SHORT(Level)] ); + + IF NOT + IOBytes.SetPosition( Stream, IOFiles.FromStart, Position ) + THEN + Alert.IOError( '8-Error' ); + RETURN FALSE; + END; + + + (* The next 4 bytes contain the number of children of the present level. *) + + Size := SIZE( INT32 ); + + IF NOT IOBytes.Read( Stream, Size, ADR(Count) ) THEN + Alert.IOError( '9-Error' ); + RETURN FALSE; + END; + + (* The file pointer increased by 4 bytes: *) + INC( Position, 4 ); + + (* And we swap the bytes, if needed: *) + + IF NeedsByteSwap THEN Count := SwappedInt32( Count ); END; + + IF WriteInfo THEN + TermIO.WriteString( '; children: ' ); + TermIO.WriteInt( Count, 0 ); + TermIO.WriteLn; + END; (* IF *) + + + (* Now, we can proceed to load all the children of the present level, + * if there are any: + *) + + INC( Level ); + + Children := 0D; + + IF Level < Levels THEN + + WHILE Children < Count DO + + IF NOT + LoadOneLevel( + Stream, + Sizes, + Levels, + NeedsByteSwap, + Level, + Children = 0D, + Position ) + THEN + RETURN FALSE; + END; (* IF *) + + INC( Children ); + + END (* WHILE *); + + END (* IF *); + + RETURN TRUE; + +END LoadOneLevel; + + +(* + * LoadTree + * + * Scans a complete Tree. + * All "TermIO" statements are for demonstration purpose only. + * + * The variables are + * Stream : the file handle to the open file + * Sizes : the array is returns the level sizes in the Tree + * on disk. + * Levels : the number of levels in the tree + * NeedsByteSwap : the flag telling, whether byte-swapping is needed + * + * The procedure returns TRUE, if it encountered no errors. + *) + +PROCEDURE LoadTree( + VAR Stream : IOFiles.FileHandleType; + VAR Sizes : ARRAY OF INT32; + VAR Levels : LONGINT; + VAR NeedsByteSwap : BOOLEAN ) + : BOOLEAN; +VAR + Value : INT32; + Position : LONGINT; + Size : LONGINT; + i : INTEGER; + Success : BOOLEAN; + +BEGIN + + (* We start at the beginning of the file. We keep the variable + * "Position" containing the actual position in the file. + *) + + Position := 0D; + + + (* The first 4 bytes should contain the "MagicNumber", see above. + * a variable of type INT32 is a 32-bit long, signed word. + *) + + Size := SIZE( INT32 ); + + IF NOT IOBytes.Read( Stream, Size, ADR(Value) ) THEN + Alert.IOError( '2-Error' ); + RETURN FALSE; + END; + + IF Value = MagicNumber THEN + NeedsByteSwap := FALSE; + ELSIF Value = SwappedMagicNumber THEN + NeedsByteSwap := TRUE; + ELSE + Alert.OK( '3-Error: File does not start with "Tree" !' ); + RETURN FALSE; + END; (* IF *) + + (* The file pointer increased by 4 bytes: *) + INC( Position, 4 ); + + + (* Next we load the number of levels in the Tree, which is stored in the + * next 4 bytes (at offset 4): + *) + + Size := SIZE( INT32 ); + + IF NOT IOBytes.Read( Stream, Size, ADR(Levels) ) THEN + Alert.IOError( '4-Error' ); + RETURN FALSE; + END; + + (* The file pointer increased by 4 bytes: *) + INC( Position, 4 ); + + + (* If the file originates from a platform with opposite byte ordering, + * then we have to swap the bytes: + *) + + IF NeedsByteSwap THEN Levels := SwappedInt32( Levels ); END; + + TermIO.WriteString( ' -> levels: ' ); + TermIO.WriteInt( Levels, 0 ); + + + (* The next bytes contain the sizes of all levels. Thus, there is + * one 4-byte variable for each level, totaling in "Levels" times 4 + * bytes. + * + * First, we check, if the array "Sizes" passed to this procedure is + * large enough to contain all level sizes: + *) + + IF ( Levels <= 0D ) OR ( Levels > LONG(HIGH(Sizes)+1) ) THEN + Alert.OK( '5-Error: number of level either <= 0 or too large!' ); + RETURN FALSE; + END (* IF *); + + + (* Next, we load the "Level Size": *) + + Size := Levels * LONG( SIZE( INT32 ) ); + + IF NOT IOBytes.Read( Stream, Size, ADR(Sizes) ) THEN + Alert.IOError( '6-Error' ); + RETURN FALSE; + END; + + (* The file pointer increased by "Size" bytes: *) + INC( Position, Size ); + + (* And we swap the bytes, if needed: *) + + IF NeedsByteSwap THEN + FOR i := 0 TO SHORT( Levels - 1D ) DO + Sizes[i] := SwappedInt32( Sizes[i] ); + END; (* FOR *) + END; (* IF *) + + TermIO.WriteString( '; sizes: ' ); + FOR i := 0 TO SHORT( Levels - 1D ) DO + TermIO.WriteInt( Sizes[i], 0 ); + IF i < SHORT( Levels - 1D ) THEN + TermIO.WriteString( ', ' ); + END; (* IF *) + END; (* FOR *) + + TermIO.WriteString( '; swap: ' ); + TermIO.WriteBoolean( NeedsByteSwap ); + TermIO.WriteLn; + + + (* Now, the tree data follow. + * We can load them by a recursive procedure: + *) + + Success := + LoadOneLevel( + Stream, + Sizes, + Levels, + NeedsByteSwap, + 0D, + TRUE, + Position ); + + IF Success THEN + TermIO.WriteString( 'total file length: ' ); + TermIO.WriteInt( Position, 0 ); + END; (* IF *) + + TermIO.WriteLn; + TermIO.WriteLn; + + RETURN Success; + +END LoadTree; + + +VAR + FileName : IOFiles.FileNameType; + Stream : IOFiles.FileHandleType; + Sizes : ARRAY[0..9] OF INT32; + Levels : LONGINT; + NeedsByteSwap : BOOLEAN; + Success : BOOLEAN; + Dummy : BOOLEAN; + +BEGIN + + (* Get a filename of a tree file to load: *) + + FileName[0] := 0C; + + IF NOT + FileSelect.Select( + FileName, + '*.*', + FileSelect.ExistingFile, + 'Select the TREE file to scan:' ) + THEN + RETURN; + END; (* IF *) + + TermIO.DoBuffer := TRUE; + TermIO.WriteLn; + TermIO.WriteLine( FileName ); + + + (* Open the file : *) + + IF NOT + IOBytes.Open( FileName, IOFiles.NILEncryption, IOFiles.Read, Stream ) + THEN + Alert.IOError( '1-Error' ); + RETURN; + END; + + + (* Now, load the "Tree" : *) + + Success := LoadTree( Stream, Sizes, Levels, NeedsByteSwap ); + + + (* And, finally, we are done and can close the file. *) + + Dummy := IOBytes.Close( Stream ); + +END FileFormat. diff --git a/@HEKA_Importer/HEKA_FileFormat/FileFormat_v1000/MarkerFile_v9.txt b/@HEKA_Importer/HEKA_FileFormat/FileFormat_v1000/MarkerFile_v9.txt new file mode 100644 index 0000000..4474fc5 --- /dev/null +++ b/@HEKA_Importer/HEKA_FileFormat/FileFormat_v1000/MarkerFile_v9.txt @@ -0,0 +1,37 @@ + + PatchMaster v2.90.4, 30-Oct-2018 + + SizeByte = 1; + SizeChar = 1; + SizeEnum = 1; + SizeBoolean = 1; + SizeInt16 = 2; + SizeCard16 = 2; + SizeSet16 = 2; + SizeInt32 = 4; + SizeCard32 = 4; + SizeReal = 4; + SizeLongReal = 8; + + String80Size = 80; + + RootLevel = 0; + MarkerLevel = 1; + + MarkerType = ( MarkerGeneral, + MarkerSolutionIndex, + MarkerSolutionValue ); + + (* MarkerRecord = RECORD *) + MaMarkerTime = 0; (* LONGREAL *) + MaMarkerText = 8; (* String80Type *) + MaMarkerTrace = 88; (* INT32 *) + MaMarkerKind = 92; (* BYTE *) + MaFiller = 93; (* 7 *) + MaCRC = 100; (* CARD32 *) + MarkerRecSize = 104; (* = 13 * 8 *) + + (* RootRecord = RECORD *) + RoVersion = 0; (* INT32 *) + RoCRC = 4; (* CARD32 *) + RootRecSize = 8; (* = 1 * 8 *) diff --git a/@HEKA_Importer/HEKA_FileFormat/FileFormat_v1000/MethodFile_v9.txt b/@HEKA_Importer/HEKA_FileFormat/FileFormat_v1000/MethodFile_v9.txt new file mode 100644 index 0000000..6ee0d26 --- /dev/null +++ b/@HEKA_Importer/HEKA_FileFormat/FileFormat_v1000/MethodFile_v9.txt @@ -0,0 +1,259 @@ + + PatchMaster v2.90.4, Patchmaster Next + + SizeByte = 1; + SizeChar = 1; + SizeEnum = 1; + SizeBoolean = 1; + SizeInt16 = 2; + SizeCard16 = 2; + SizeSet16 = 2; + SizeInt32 = 4; + SizeCard32 = 4; + SizeReal = 4; + SizeLongReal = 8; + + String8Size = 8; + String32Size = 32; + + StimParams = 10; + StimParamChars = 320; + + RootLevel = 0; + StimulationLevel = 1; + ChannelLevel = 2; + StimSegmentLevel = 3; + + + (* + CompressionMode : Specifies how to the data + -> meaning of bits: + bit 0 (CompReal) -> high = store as real + low = store as int16 + bit 1 (CompMean) -> high = use mean + low = use single sample + bit 2 (CompFilter) -> high = use digital filter + *) + + (* + StimToDacID : Specifies how to convert the Segment "Voltage" to + the actual voltage sent to the DAC + -> meaning of bits: + bit 0 (UseStimScale) -> use StimScale + bit 1 (UseRelative) -> relative to Vmemb + bit 2 (UseFileTemplate) -> use file template + bit 3 (UseForLockIn) -> use for LockIn computation + bit 4 (UseForWavelength) + bit 5 (UseScaling) + bit 6 (UseForChirp) + bit 7 (UseForImaging) + bit 14 (UseReserved) + bit 15 (UseReserved) + *) + + SegmentClass = ( SegmentConstant, + SegmentRamp, + SegmentContinuous, + SegmentConstSine, + SegmentSquarewave, + SegmentChirpwave ); + + IncrementModeType = ( ModeInc, + ModeDec, + ModeIncInterleaved, + ModeDecInterleaved, + ModeAlternate, + ModeLogInc, + ModeLogDec, + ModeLogIncInterleaved, + ModeLogDecInterleaved, + ModeLogAlternate ); + + ExtTriggerType = ( TrigNone, + TrigSeries, + TrigSweep, + TrigSweepNoLeak ); + + AmplModeType = ( AnyAmplMode, + VCAmplMode, + CCAmplMode, + IDensityMode ); + + AutoRangingType = ( AutoRangingOff, + AutoRangingPeak, + AutoRangingMean, + AutoRangingRelSeg ); + + AdcType = ( AdcOff, + Analog, + Digitals, + Digital, + AdcVirtual ); + + LeakStoreType = ( LNone, + LStoreAvg, + LStoreEach, + LNoStore ); + + LeakHoldType = ( Labs, + Lrel, + LabsLH, + LrelLH ); + + BreakType = ( NoBreak, + BreakPos, + BreakNeg ); + + LeakCompType = ( LeakCompSoft, + LeakCompHard ); + + SegStoreType = ( SegNoStore, + SegStore, + SegStoreStart, + SegStoreEnd ); + + + (* StimSegmentRecord = RECORD *) + seMark = 0; (* INT32 *) + seClass = 4; (* BYTE *) + seStoreKind = 5; (* BYTE *) + seVoltageIncMode = 6; (* BYTE *) + seDurationIncMode = 7; (* BYTE *) + seVoltage = 8; (* LONGREAL *) + seVoltageSource = 16; (* INT32 *) + seDeltaVFactor = 20; (* LONGREAL *) + seDeltaVIncrement = 28; (* LONGREAL *) + seDuration = 36; (* LONGREAL *) + seDurationSource = 44; (* INT32 *) + seDeltaTFactor = 48; (* LONGREAL *) + seDeltaTIncrement = 56; (* LONGREAL *) + seFiller1 = 64; (* INT32 *) + seCRC = 68; (* CARD32 *) + seScanRate = 72; (* LONGREAL *) + StimSegmentRecSize = 80; (* = 10 * 8 *) + + (* ChannelRecord = RECORD *) + chMark = 0; (* INT32 *) + chLinkedChannel = 4; (* INT32 *) + chCompressionFactor = 8; (* INT32 *) + chYUnit = 12; (* String8Type *) + chAdcChannel = 20; (* INT16 *) + chAdcMode = 22; (* BYTE *) + chDoWrite = 23; (* BOOLEAN *) + stLeakStore = 24; (* BYTE *) + chAmplMode = 25; (* BYTE *) + chOwnSegTime = 26; (* BOOLEAN *) + chSetLastSegVmemb = 27; (* BOOLEAN *) + chDacChannel = 28; (* INT16 *) + chDacMode = 30; (* BYTE *) + chHasLockInSquare = 31; (* BYTE *) + chRelevantXSegment = 32; (* INT32 *) + chRelevantYSegment = 36; (* INT32 *) + chDacUnit = 40; (* String8Type *) + chHolding = 48; (* LONGREAL *) + chLeakHolding = 56; (* LONGREAL *) + chLeakSize = 64; (* LONGREAL *) + chLeakHoldMode = 72; (* BYTE *) + chLeakAlternate = 73; (* BOOLEAN *) + chAltLeakAveraging = 74; (* BOOLEAN *) + chLeakPulseOn = 75; (* BOOLEAN *) + chStimToDacID = 76; (* SET16 *) + chCompressionMode = 78; (* SET16 *) + chCompressionSkip = 80; (* INT32 *) + chDacBit = 84; (* INT16 *) + chHasLockInSine = 86; (* BOOLEAN *) + chBreakMode = 87; (* BYTE *) + chZeroSeg = 88; (* INT32 *) + chStimSweep = 92; (* INT32 *) + chSine_Cycle = 96; (* LONGREAL *) + chSine_Amplitude = 104; (* LONGREAL *) + chLockIn_VReversal = 112; (* LONGREAL *) + chChirp_StartFreq = 120; (* LONGREAL *) + chChirp_EndFreq = 128; (* LONGREAL *) + chChirp_MinPoints = 136; (* LONGREAL *) + chSquare_NegAmpl = 144; (* LONGREAL *) + chSquare_DurFactor = 152; (* LONGREAL *) + chLockIn_Skip = 160; (* INT32 *) + chPhoto_MaxCycles = 164; (* INT32 *) + chPhoto_SegmentNo = 168; (* INT32 *) + chLockIn_AvgCycles = 172; (* INT32 *) + chImaging_RoiNo = 176; (* INT32 *) + chChirp_Skip = 180; (* INT32 *) + chChirp_Amplitude = 184; (* LONGREAL *) + chPhoto_Adapt = 192; (* BYTE *) + chSine_Kind = 193; (* BYTE *) + chChirp_PreChirp = 194; (* BYTE *) + chSine_Source = 195; (* BYTE *) + chSquare_NegSource = 196; (* BYTE *) + chSquare_PosSource = 197; (* BYTE *) + chChirp_Kind = 198; (* BYTE *) + chChirp_Source = 199; (* BYTE *) + chDacOffset = 200; (* LONGREAL *) + chAdcOffset = 208; (* LONGREAL *) + chTraceMathFormat = 216; (* BYTE *) + chHasChirp = 217; (* BOOLEAN *) + chSquare_Kind = 218; (* BYTE *) + chFiller1 = 219; (* ARRAY[0..5] OF CHAR *) + chSquare_BaseIncr = 224; (* LONGREAL *) + chSquare_Cycle = 232; (* LONGREAL *) + chSquare_PosAmpl = 240; (* LONGREAL *) + chCompressionOffset = 248; (* INT32 *) + chPhotoMode = 252; (* INT32 *) + chBreakLevel = 256; (* LONGREAL *) + chTraceMath = 264; (* String128Type *) + chFiller2 = 392; (* INT32 *) + chCRC = 396; (* CARD32 *) + ChannelRecSize = 400; (* = 50 * 8 *) + + (* StimulationRecord = RECORD *) + stMark = 0; (* INT32 *) + stEntryName = 4; (* String32Type *) + stFileName = 36; (* String32Type *) + stAnalName = 68; (* String32Type *) + stDataStartSegment = 100; (* INT32 *) + stDataStartTime = 104; (* LONGREAL *) + stSampleInterval = 112; (* LONGREAL *) + stSweepInterval = 120; (* LONGREAL *) + stLeakDelay = 128; (* LONGREAL *) + stFilterFactor = 136; (* LONGREAL *) + stNumberSweeps = 144; (* INT32 *) + stNumberLeaks = 148; (* INT32 *) + stNumberAverages = 152; (* INT32 *) + stActualAdcChannels = 156; (* INT32 *) + stActualDacChannels = 160; (* INT32 *) + stExtTrigger = 164; (* BYTE *) + stNoStartWait = 165; (* BOOLEAN *) + stUseScanRates = 166; (* BOOLEAN *) + stNoContAq = 167; (* BOOLEAN *) + stHasLockIn = 168; (* BOOLEAN *) + stOldStartMacKind = 169; (* CHAR *) + stOldEndMacKind = 170; (* BOOLEAN *) + stAutoRange = 171; (* BYTE *) + stBreakNext = 172; (* BOOLEAN *) + stIsExpanded = 173; (* BOOLEAN *) + stLeakCompMode = 174; (* BOOLEAN *) + stHasChirp = 175; (* BOOLEAN *) + stOldStartMacro = 176; (* String32Type *) + stOldEndMacro = 208; (* String32Type *) + sIsGapFree = 240; (* BOOLEAN *) + sHandledExternally = 241; (* BOOLEAN *) + stFiller1 = 242; (* BOOLEAN *) + stFiller2 = 243; (* BOOLEAN *) + stCRC = 244; (* CARD32 *) + StimulationRecSize = 248; (* = 31 * 8 *) + + (* RootRecord = RECORD *) + roVersion = 0; (* INT32 *) + roMark = 4; (* INT32 *) + roVersionName = 8; (* String32Type *) + roMaxSamples = 40; (* INT32 *) + roFiller1 = 44; (* INT32 *) + (* StimParams = 10 *) + (* StimParamChars = 320 *) + roParams = 48; (* ARRAY[0..9] OF LONGREAL *) + roParamText = 128; (* ARRAY[0..9],[0..31]OF CHAR *) + roReserved = 448; (* String128Type *) + roFiller2 = 576; (* INT32 *) + roCRC = 580; (* CARD32 *) + RootRecSize = 584; (* = 73 * 8 *) + diff --git a/@HEKA_Importer/HEKA_FileFormat/FileFormat_v1000/PulsedFile_v1000.txt b/@HEKA_Importer/HEKA_FileFormat/FileFormat_v1000/PulsedFile_v1000.txt new file mode 100644 index 0000000..ed8e9ac --- /dev/null +++ b/@HEKA_Importer/HEKA_FileFormat/FileFormat_v1000/PulsedFile_v1000.txt @@ -0,0 +1,240 @@ + + PatchMaster v2.90.4, 30-Oct-2018 + + SizeByte = 1; + SizeChar = 1; + SizeEnum = 1; + SizeBoolean = 1; + SizeInt16 = 2; + SizeCard16 = 2; + SizeSet16 = 2; + SizeInt32 = 4; + SizeCard32 = 4; + SizeReal = 4; + SizeLongReal = 8; + + String8Size = 8; + String32Size = 32; + String80Size = 80; + String400Size = 400; + + ParamDescrSize = 24; + TrMarkerNo = 10; + SwMarkerNo = 4; + SwHoldingNo = 16; + SwUserParamNo = 4; + SeUserParamNo1 = 4; + SeUserParamNo2 = 4; + GrStimParams = 10; + AmplifierStateSize = 400; + ScanParamsSize = 96; + Max_TcKind_M1 = 31; + + SizeStateVersion = 8; + SizeSerialNumber = 8; + SizeCalibDate = 16; + + + RootLevel = 0; + GroupLevel = 1; + SeriesLevel = 2; + SweepLevel = 3; + TraceLevel = 4; + + + LittleEndianBit = 0; + IsLeak = 1; + IsVirtual = 2; + IsImon = 3; + IsVmon = 4; + Clip = 5; + (* + DataKind -> meaning of bits: + - LittleEndianBit => byte sequence + "PowerPC Mac" = cleared + "Windows and Intel Mac" = set + - IsLeak + set if trace is a leak trace + - IsVirtual + set if trace is a virtual trace + - IsImon + -> set if trace was from Imon ADC + -> it flags a trace to be used to + compute LockIn traces from + -> limited to "main" traces, not "leaks"! + - IsVmon + -> set if trace was from Vmon ADC + - Clip + -> set if amplifier of trace was clipping + *) + + RecordingModeType = ( InOut, + OnCell, + OutOut, + WholeCell, + CClamp, + VClamp, + NoMode ); + + DataFormatType = ( int16, + int32, + real32, + real64 ); + + UserParamDescrType = RECORD + Name : String32Type; + Unit : String8Type; + END; (* RECORD *) + + (* AmplifierState = RECORD *) + see definition in AmplTreeFile_v9.txt + + (* LockInParams = RECORD *) + see definition in AmplTreeFile_v9.txt + + (* TraceRecord = RECORD *) + TrMark = 0; (* INT32 *) + TrLabel = 4; (* String32Type *) + TrTraceID = 36; (* INT32 *) + TrData = 40; (* INT32 *) + TrDataPoints = 44; (* INT32 *) + TrInternalSolution = 48; (* INT32 *) + TrAverageCount = 52; (* INT32 *) + TrLeakID = 56; (* INT32 *) + TrLeakTraces = 60; (* INT32 *) + TrDataKind = 64; (* SET16 *) + TrUseXStart = 66; (* BOOLEAN *) + TrTcKind = 67; (* BYTE *) + TrRecordingMode = 68; (* BYTE *) + TrAmplIndex = 69; (* CHAR *) + TrDataFormat = 70; (* BYTE *) + TrDataAbscissa = 71; (* BYTE *) + TrDataScaler = 72; (* LONGREAL *) + TrTimeOffset = 80; (* LONGREAL *) + TrZeroData = 88; (* LONGREAL *) + TrYUnit = 96; (* String8Type *) + TrXInterval = 104; (* LONGREAL *) + TrXStart = 112; (* LONGREAL *) + TrXUnit = 120; (* String8Type *) + TrYRange = 128; (* LONGREAL *) + TrYOffset = 136; (* LONGREAL *) + TrBandwidth = 144; (* LONGREAL *) + TrPipetteResistance = 152; (* LONGREAL *) + TrCellPotential = 160; (* LONGREAL *) + TrSealResistance = 168; (* LONGREAL *) + TrCSlow = 176; (* LONGREAL *) + TrGSeries = 184; (* LONGREAL *) + TrRsValue = 192; (* LONGREAL *) + TrGLeak = 200; (* LONGREAL *) + TrMConductance = 208; (* LONGREAL *) + TrLinkDAChannel = 216; (* INT32 *) + TrValidYrange = 220; (* BOOLEAN *) + TrAdcMode = 221; (* CHAR *) + TrAdcChannel = 222; (* INT16 *) + TrYmin = 224; (* LONGREAL *) + TrYmax = 232; (* LONGREAL *) + TrSourceChannel = 240; (* INT32 *) + TrExternalSolution = 244; (* INT32 *) + TrCM = 248; (* LONGREAL *) + TrGM = 256; (* LONGREAL *) + TrPhase = 264; (* LONGREAL *) + TrDataCRC = 272; (* CARD32 *) + TrCRC = 276; (* CARD32 *) + TrGS = 280; (* LONGREAL *) + TrSelfChannel = 288; (* INT32 *) + TrInterleaveSize = 292; (* INT32 *) + TrInterleaveSkip = 296; (* INT32 *) + TrImageIndex = 300; (* INT32 *) + TrTrMarkers = 304; (* ARRAY[0..9] OF LONGREAL *) + TrSECM_X = 384; (* LONGREAL *) + TrSECM_Y = 392; (* LONGREAL *) + TrSECM_Z = 400; (* LONGREAL *) + TrTrHolding = 408; (* LONGREAL *) + TrTcEnumerator = 416; (* INT32 *) + TrXTrace = 420; (* INT32 *) + TrIntSolValue = 424; (* LONGREAL *) + TrExtSolValue = 432; (* LONGREAL *) + TrIntSolName = 440; (* String32Size *) + TrExtSolName = 472; (* String32Size *) + TrDataPedestal = 504; (* LONGREAL *) + TraceRecSize = 512; (* = 64 * 8 *) + + (* SweepRecord = RECORD *) + SwMark = 0; (* INT32 *) + SwLabel = 4; (* String32Type *) + SwAuxDataFileOffset = 36; (* INT32 *) + SwStimCount = 40; (* INT32 *) + SwSweepCount = 44; (* INT32 *) + SwTime = 48; (* LONGREAL *) + SwTimer = 56; (* LONGREAL *) + SwSwUserParams = 64; (* ARRAY[0..1] OF LONGREAL *) + SwPipPressure = 80; (* LONGREAL *) + SwRMSNoise = 88; (* LONGREAL *) + SwTemperature = 96; (* LONGREAL *) + SwOldIntSol = 104; (* INT32 *) + SwOldExtSol = 108; (* INT32 *) + SwDigitalIn = 112; (* SET16 *) + SwSweepKind = 114; (* SET16 *) + SwDigitalOut = 116; (* SET16 *) + SwFiller1 = 118; (* INT16 *) + SwSwMarkers = 120; (* ARRAY[0..3] OF LONGREAL, see SwMarkersNo *) + SwFiller2 = 152; (* INT32 *) + SwCRC = 156; (* CARD32 *) + SwSwHolding = 160; (* ARRAY[0..15] OF LONGREAL, see SwHoldingNo *) + SwSwUserParamEx = 288; (* ARRAY[0..7] OF LONGREAL *) + SweepRecSize = 352; + + (* SeriesRecord = RECORD *) + SeMark = 0; (* INT32 *) + SeLabel = 4; (* String32Type *) + SeComment = 36; (* String80Type *) + SeSeriesCount = 116; (* INT32 *) + SeNumberSweeps = 120; (* INT32 *) + SeAmplStateFlag = 124; (* INT32 *) // flag > 0 => load local oldAmpState, otherwise load from .amp File. + SeAmplStateRef = 128; (* INT32 *) // ref = 0 => use local oldAmpState + SeMethodTag = 132; (* INT32 *) + SeTime = 136; (* LONGREAL *) + SePageWidth = 144; (* LONGREAL *) + SeUserDescr1 = 152; (* ARRAY[0..1] OF UserParamDescrType = 2*40 *) + SeFiller1 = 232; (* ARRAY[0..1] OF UserParamDescrType = 2*40 *) + SeMethodName = 312; (* String32Type *) + SePhotoParams1 = 344; (* ARRAY[0..3] OF LONGREAL = 4*8 *) + SeOldLockInParams = 376; (* SeOldLockInSize = 96, see "Pulsed.de" *) + SeOldAmpState = 472; (* SeOldAmpState = 400 -> the AmplStateRecord is now stored in the .amp file *) + SeUsername = 872; (* String80Type *) + SePhotoParams2 = 952; (* ARRAY[0..3] OF UserParamDescrType = 4*40 *) + SeFiller1 = 1112; (* INT32 *) + SeCRC = 1116; (* CARD32 *) + SeSeUserParams2 = 1120; (* ARRAY[0..3] OF LONGREAL *) + SeSeUserParamDescr2 = 1152; (* ARRAY[0..3] OF UserParamDescrType = 4*40 *) + SeScanParams = 1312; (* ScanParamsSize = 96 (ElProScan Extension) *) + SeUserDescr2 = 1408; (* ARRAY[0..7] OF UserParamDescrType = 8*40 *) + SeriesRecSize = 1728; + + (* GroupRecord = RECORD *) + GrMark = 0; (* INT32 *) + GrLabel = 4; (* String32Size *) + GrText = 36; (* String80Size *) + GrExperimentNumber = 116; (* INT32 *) + GrGroupCount = 120; (* INT32 *) + GrCRC = 124; (* CARD32 *) + GrMatrixWidth = 128; (* LONGREAL *) + GrMatrixHeight = 136; (* LONGREAL *) + GroupRecSize = 144; (* = 18 * 8 *) + + (* RootRecord = RECORD *) + RoVersion = 0; (* INT32 *) + RoMark = 4; (* INT32 *) + RoVersionName = 8; (* String32Type *) + RoAuxFileName = 40; (* String80Type *) + RoRootText = 120; (* String400Type *) + RoStartTime = 520; (* LONGREAL *) + RoMaxSamples = 528; (* INT32 *) + RoCRC = 532; (* CARD32 *) + RoFeatures = 536; (* SET16 *) + RoFiller1 = 538; (* INT16 *) + RoFiller2 = 540; (* INT32 *) + RoTcEnumerator = 544; (* ARRAY[0..Max_TcKind_M1] OF INT16 *) + RoTcKind = 608; (* ARRAY[0..Max_TcKind_M1] OF INT8 *) + RootRecSize = 640; (* = 80 * 8 *) + diff --git a/@HEKA_Importer/HEKA_FileFormat/FileFormat_v1000/SolutionsFile_v1000.txt b/@HEKA_Importer/HEKA_FileFormat/FileFormat_v1000/SolutionsFile_v1000.txt new file mode 100644 index 0000000..4d3b34a --- /dev/null +++ b/@HEKA_Importer/HEKA_FileFormat/FileFormat_v1000/SolutionsFile_v1000.txt @@ -0,0 +1,41 @@ + + PatchMaster v2.90.4, Patchmaster Next + + To find the solution belonging to a Trace locate that Solution record with a + SoNumber value equal to the solution value stored in Trace.InternalSolution + and Trace.ExternalSolution. + + SizeInt16 = 2; + SizeInt32 = 4; + SizeReal = 4; + ChemicalNameSize = 30; + SolutionNameSize = 80; + + RootLevel = 0; + SolutionLevel = 1; + ChemicalLevel = 2; + + (* ChemicalRecord = RECORD *) + ChConcentration = 0; (* REAL *) + ChName = 4; (* ChemicalNameSize *) + ChSpare1 = 34; (* INT16 *) + ChCRC = 36; (* CARD32 *) + ChemicalSize = 40; + + (* SolutionRecord = RECORD *) + SoNumber = 0; (* INT32 *) + SoName = 4; (* SolutionNameSize *) + SoNumeric = 84; (* REAL *) + SoNumericName = 88; (* ChemicalNameSize *) + SopH = 118; (* REAL *) + SopHCompound = 122; (* ChemicalNameSize *) + SoOsmol = 152; (* REAL *) + SoCRC = 156; (* CARD32 *) + SolutionSize = 160; + + (* RootRecord = RECORD *) + RoVersion = 0; (* INT32 *) + RoDataBaseName = 4; (* SolutionNameSize *) + RoCRC = 84; (* CARD32 *) + RootSize = 88; + diff --git a/@HEKA_Importer/HEKA_FileFormat/FileFormat_v1000/StimFile_v1000.txt b/@HEKA_Importer/HEKA_FileFormat/FileFormat_v1000/StimFile_v1000.txt new file mode 100644 index 0000000..1cd64ef --- /dev/null +++ b/@HEKA_Importer/HEKA_FileFormat/FileFormat_v1000/StimFile_v1000.txt @@ -0,0 +1,260 @@ + + PatchMaster v2.90.4, Patchmaster Next + + SizeByte = 1; + SizeChar = 1; + SizeEnum = 1; + SizeBoolean = 1; + SizeInt16 = 2; + SizeCard16 = 2; + SizeSet16 = 2; + SizeInt32 = 4; + SizeCard32 = 4; + SizeReal = 4; + SizeLongReal = 8; + + String8Size = 8; + String32Size = 32; + + StimParams = 10; + StimParamChars = 320; + + RootLevel = 0; + StimulationLevel = 1; + ChannelLevel = 2; + StimSegmentLevel = 3; + + + (* + CompressionMode : Specifies how to the data + -> meaning of bits: + bit 0 (CompReal) -> high = store as real + low = store as int16 + bit 1 (CompMean) -> high = use mean + low = use single sample + bit 2 (CompFilter) -> high = use digital filter + *) + + (* + StimToDacID : Specifies how to convert the Segment "Voltage" to + the actual voltage sent to the DAC + -> meaning of bits: + bit 0 (UseStimScale) -> use StimScale + bit 1 (UseRelative) -> relative to Vmemb + bit 2 (UseFileTemplate) -> use file template + bit 3 (UseForLockIn) -> use for LockIn computation + bit 4 (UseForWavelength) + bit 5 (UseScaling) + bit 6 (UseForChirp) + bit 7 (UseForImaging) + bit 14 (UseReserved) + bit 15 (UseReserved) + *) + + SegmentClass = ( SegmentConstant, + SegmentRamp, + SegmentContinuous, + SegmentConstSine, + SegmentSquarewave, + SegmentChirpwave ); + + IncrementModeType = ( ModeInc, + ModeDec, + ModeIncInterleaved, + ModeDecInterleaved, + ModeAlternate, + ModeLogInc, + ModeLogDec, + ModeLogIncInterleaved, + ModeLogDecInterleaved, + ModeLogAlternate ); + + ExtTriggerType = ( TrigNone, + TrigSeries, + TrigSweep, + TrigSweepNoLeak ); + + AmplModeType = ( AnyAmplMode, + VCAmplMode, + CCAmplMode, + IDensityMode ); + + AutoRangingType = ( AutoRangingOff, + AutoRangingPeak, + AutoRangingMean, + AutoRangingRelSeg ); + + AdcType = ( AdcOff, + Analog, + Digitals, + Digital, + AdcVirtual ); + + LeakStoreType = ( LNone, + LStoreAvg, + LStoreEach, + LNoStore ); + + LeakHoldType = ( Labs, + Lrel, + LabsLH, + LrelLH ); + + BreakType = ( NoBreak, + BreakPos, + BreakNeg ); + + LeakCompType = ( LeakCompSoft, + LeakCompHard ); + + SegStoreType = ( SegNoStore, + SegStore, + SegStoreStart, + SegStoreEnd ); + + + (* StimSegmentRecord = RECORD *) + seMark = 0; (* INT32 *) + seClass = 4; (* BYTE *) + seStoreKind = 5; (* BYTE *) + seVoltageIncMode = 6; (* BYTE *) + seDurationIncMode = 7; (* BYTE *) + seVoltage = 8; (* LONGREAL *) + seVoltageSource = 16; (* INT32 *) + seDeltaVFactor = 20; (* LONGREAL *) + seDeltaVIncrement = 28; (* LONGREAL *) + seDuration = 36; (* LONGREAL *) + seDurationSource = 44; (* INT32 *) + seDeltaTFactor = 48; (* LONGREAL *) + seDeltaTIncrement = 56; (* LONGREAL *) + seFiller1 = 64; (* INT32 *) + seCRC = 68; (* CARD32 *) + seScanRate = 72; (* LONGREAL *) + StimSegmentRecSize = 80; (* = 10 * 8 *) + + (* ChannelRecord = RECORD *) + chMark = 0; (* INT32 *) + chLinkedChannel = 4; (* INT32 *) + chCompressionFactor = 8; (* INT32 *) + chYUnit = 12; (* String8Type *) + chAdcChannel = 20; (* INT16 *) + chAdcMode = 22; (* BYTE *) + chDoWrite = 23; (* BOOLEAN *) + stLeakStore = 24; (* BYTE *) + chAmplMode = 25; (* BYTE *) + chOwnSegTime = 26; (* BOOLEAN *) + chSetLastSegVmemb = 27; (* BOOLEAN *) + chDacChannel = 28; (* INT16 *) + chDacMode = 30; (* BYTE *) + chHasLockInSquare = 31; (* BYTE *) + chRelevantXSegment = 32; (* INT32 *) + chRelevantYSegment = 36; (* INT32 *) + chDacUnit = 40; (* String8Type *) + chHolding = 48; (* LONGREAL *) + chLeakHolding = 56; (* LONGREAL *) + chLeakSize = 64; (* LONGREAL *) + chLeakHoldMode = 72; (* BYTE *) + chLeakAlternate = 73; (* BOOLEAN *) + chAltLeakAveraging = 74; (* BOOLEAN *) + chLeakPulseOn = 75; (* BOOLEAN *) + chStimToDacID = 76; (* SET16 *) + chCompressionMode = 78; (* SET16 *) + chCompressionSkip = 80; (* INT32 *) + chDacBit = 84; (* INT16 *) + chHasLockInSine = 86; (* BOOLEAN *) + chBreakMode = 87; (* BYTE *) + chZeroSeg = 88; (* INT32 *) + chStimSweep = 92; (* INT32 *) + chSine_Cycle = 96; (* LONGREAL *) + chSine_Amplitude = 104; (* LONGREAL *) + chLockIn_VReversal = 112; (* LONGREAL *) + chChirp_StartFreq = 120; (* LONGREAL *) + chChirp_EndFreq = 128; (* LONGREAL *) + chChirp_MinPoints = 136; (* LONGREAL *) + chSquare_NegAmpl = 144; (* LONGREAL *) + chSquare_DurFactor = 152; (* LONGREAL *) + chLockIn_Skip = 160; (* INT32 *) + chPhoto_MaxCycles = 164; (* INT32 *) + chPhoto_SegmentNo = 168; (* INT32 *) + chLockIn_AvgCycles = 172; (* INT32 *) + chImaging_RoiNo = 176; (* INT32 *) + chChirp_Skip = 180; (* INT32 *) + chChirp_Amplitude = 184; (* LONGREAL *) + chPhoto_Adapt = 192; (* BYTE *) + chSine_Kind = 193; (* BYTE *) + chChirp_PreChirp = 194; (* BYTE *) + chSine_Source = 195; (* BYTE *) + chSquare_NegSource = 196; (* BYTE *) + chSquare_PosSource = 197; (* BYTE *) + chChirp_Kind = 198; (* BYTE *) + chChirp_Source = 199; (* BYTE *) + chDacOffset = 200; (* LONGREAL *) + chAdcOffset = 208; (* LONGREAL *) + chTraceMathFormat = 216; (* BYTE *) + chHasChirp = 217; (* BOOLEAN *) + chSquare_Kind = 218; (* BYTE *) + chFiller1 = 219; (* ARRAY[0..5] OF CHAR *) + chSquare_BaseIncr = 224; (* LONGREAL *) + chSquare_Cycle = 232; (* LONGREAL *) + chSquare_PosAmpl = 240; (* LONGREAL *) + chCompressionOffset = 248; (* INT32 *) + chPhotoMode = 252; (* INT32 *) + chBreakLevel = 256; (* LONGREAL *) + chTraceMath = 264; (* String128Type *) + chFiller2 = 392; (* INT32 *) + chCRC = 396; (* CARD32 *) + ChannelRecSize = 400; (* = 50 * 8 *) + + (* StimulationRecord = RECORD *) + stMark = 0; (* INT32 *) + stEntryName = 4; (* String32Type *) + stFileName = 36; (* String32Type *) + stAnalName = 68; (* String32Type *) + stDataStartSegment = 100; (* INT32 *) + stDataStartTime = 104; (* LONGREAL *) + stSampleInterval = 112; (* LONGREAL *) + stSweepInterval = 120; (* LONGREAL *) + stLeakDelay = 128; (* LONGREAL *) + stFilterFactor = 136; (* LONGREAL *) + stNumberSweeps = 144; (* INT32 *) + stNumberLeaks = 148; (* INT32 *) + stNumberAverages = 152; (* INT32 *) + stActualAdcChannels = 156; (* INT32 *) + stActualDacChannels = 160; (* INT32 *) + stExtTrigger = 164; (* BYTE *) + stNoStartWait = 165; (* BOOLEAN *) + stUseScanRates = 166; (* BOOLEAN *) + stNoContAq = 167; (* BOOLEAN *) + stHasLockIn = 168; (* BOOLEAN *) + stOldStartMacKind = 169; (* CHAR *) + stOldEndMacKind = 170; (* BOOLEAN *) + stAutoRange = 171; (* BYTE *) + stBreakNext = 172; (* BOOLEAN *) + stIsExpanded = 173; (* BOOLEAN *) + stLeakCompMode = 174; (* BOOLEAN *) + stHasChirp = 175; (* BOOLEAN *) + stOldStartMacro = 176; (* String32Type *) + stOldEndMacro = 208; (* String32Type *) + sIsGapFree = 240; (* BOOLEAN *) + sHandledExternally = 241; (* BOOLEAN *) + stFiller1 = 242; (* BOOLEAN *) + stFiller2 = 243; (* BOOLEAN *) + stCRC = 244; (* CARD32 *) + StimulationRecSize = 248; (* = 31 * 8 *) + + (* RootRecord = RECORD *) + roVersion = 0; (* INT32 *) + roMark = 4; (* INT32 *) + roVersionName = 8; (* String32Type *) + roMaxSamples = 40; (* INT32 *) + roFiller1 = 44; (* INT32 *) + (* StimParams = 10 *) + (* StimParamChars = 320 *) + roParams = 48; (* ARRAY[0..9] OF LONGREAL *) + roParamText = 128; (* ARRAY[0..9],[0..31]OF CHAR *) + roReserved = 448; (* String128Type *) + roFiller2 = 576; (* INT32 *) + roReserved2 = 580; (* 560 Bytes *) + roCRC = 1140; (* CARD32 *) + RootRecSize = 1144; + diff --git a/@HEKA_Importer/HEKA_FileFormat/FileFormat_v1000/TimeFormat.txt b/@HEKA_Importer/HEKA_FileFormat/FileFormat_v1000/TimeFormat.txt new file mode 100644 index 0000000..f1f614c --- /dev/null +++ b/@HEKA_Importer/HEKA_FileFormat/FileFormat_v1000/TimeFormat.txt @@ -0,0 +1,79 @@ +PatchMaster v2.90 / PM Next + +Time is stored as seconds from 01-Jan-1990. +To convert the stored time into a string, proceed as follows: + +MacOS + JanFirst1990 - The number of seconds between 1/1/1904 (Apple's + beginning of time) and 1/1/1990, the beginning of + time for PowerMod's environment. + + JanFirst1990 = 1580970496.0; + MacTime = (int)( StoredTime - JanFirst1990 ); + + Pass MacTime to the API function DateTimeUtils.SecondsToDate + to convert it to a string + +Windows + Windows uses 01-Jan-1601 as its starting point in calculating dates. + + Pass StoredTime to the function PatchMasterSecondsToFileTime or + PatchMasterSecondsToDate below to convert it to a standard Windows + format. + +#define MAC_BASE 9561652096.0 +#define HIGH_DWORD 4294967296.0 +#define JanFirst1990 1580970496.0 + +// Function PatchMasterSecondsToFileTime +// Convert seconds to FILETIME. +// In converting double to DWORD we must be carefull because the +// double will first be converted to a signed int. +// Do the operations modulo 2^31. +// Get the next bit from the high DWORD and then shift high DWORD +// throwing away the highest bit. + +void PatchMasterSecondsToFileTime( double time, FILETIME* file_time ) +{ + time -= JanFirst1990; + + if (time < 0.0) + time += HIGH_DWORD; + + time += MAC_BASE; + + time *= 10000000.0; + + file_time->dwHighDateTime = (DWORD) (time / (HIGH_DWORD / 2.0)); + + file_time->dwLowDateTime = (DWORD) + (time - (double) file_time->dwHighDateTime * (HIGH_DWORD / 2.0)); + + file_time->dwLowDateTime |= ((file_time->dwHighDateTime & 1) << 31); + + file_time->dwHighDateTime >>= 1; +} + +void PatchMasterSecondsToDate( double storedTime, SYSTEMTIME* system_time ) +{ + FILETIME file_time; + PatchMasterSecondsToFileTime( storedTime, &file_time ); + FileTimeToSystemTime( &file_time, system_time ); +} + + +Example 1: applied to the root date of "DemoV9Bundle.dat": +1. RootTime = 221667551 +2. subtract JanFirst1990 time = 221667551 - 1580970496 = -1359302944 +3. is it < 0 ? + yes => add HIGH_DWORD time = -1359302944 + 4294967296 = 2935664351 +4. add correction for Windows time = 2935664351 + 9561652096 = 12497316447 +5. convert to date date = 09-Jan-1997 + +Example 2: applied to the root date of "Malcom.dat": +1. RootTime = 4922414972 +2. subtract JanFirst1990 time = 4922414972 - 1580970496 = 3341444476 +3. is it < 0 ? + no +4. add correction for Windows time = 3341444476 + 9561652096 = 12903096572 +5. convert to date date = 19-Nov-2009 diff --git a/@HEKA_Importer/readPulseFileHEKA.m b/@HEKA_Importer/readPulseFileHEKA.m index af384eb..2b7d344 100644 --- a/@HEKA_Importer/readPulseFileHEKA.m +++ b/@HEKA_Importer/readPulseFileHEKA.m @@ -1,9 +1,6 @@ function readPulseFileHEKA(obj,Level) %-------------------------------------------------------------------------- % Gets one record of the tree and the number of children - - - s = getOneRecord(obj,Level); obj.fileData.Tree{obj.fileData.Counter, Level+1} = s; @@ -18,7 +15,6 @@ function readPulseFileHEKA(obj,Level) function rec=getOneRecord(obj,Level) %-------------------------------------------------------------------------- % Gets one record -% Counter=Counter+1; obj.fileData.Counter = obj.fileData.Counter+1; switch Level @@ -38,7 +34,7 @@ function readPulseFileHEKA(obj,Level) end % The functions below return data as defined by the HEKA PatchMaster -% specification +% specification found at ftp://server.hekahome.de/pub/FileFormat/ %-------------------------------------------------------------------------- function p=getRoot(obj) @@ -103,13 +99,10 @@ function readPulseFileHEKA(obj,Level) s.SeAmplStateFlag = fread(fh,1,'int32=>int32');% = 124; (* INT32 *) // flag > 0 => load local oldAmpState, otherwise load from .amp File. s.SeAmplStateRef = fread(fh,1,'int32=>int32'); % = 128; (* INT32 *) // ref = 0 => use local oldAmpState end - -%% s.SeMethodTag = fread(fh,1,'int32=>int32'); % = 132; (* INT32 *) s.SeTime = fread(fh,1,'double=>double'); % = 136; (* LONGREAL *) s.SeTimeMATLAB = obj.HI_time2date(s.SeTime); s.SePageWidth = fread(fh, 1, 'double=>double') ;% = 144; (* LONGREAL *) - switch obj.fileData.fileVersion case 9 for k=1:4 % = 152; (* ARRAY[0..1] OF UserParamDescrType = 4*40 *) @@ -123,9 +116,7 @@ function readPulseFileHEKA(obj,Level) end s.SeFiller1 = deblank(fread(fh,80,'uint8=>char')'); % = 232; (* ARRAY[0..1] OF UserParamDescrType = 2*40 *) end - s.SeMethodName = deblank(fread(fh,32,'uint8=>char')');% = 312; (* String32Type *) - switch obj.fileData.fileVersion case 9 s.SeSeUserParams1 = fread(fh ,4 ,'double=>double');% = 344; (* ARRAY[0..3] OF LONGREAL *) @@ -136,7 +127,6 @@ function readPulseFileHEKA(obj,Level) s.SeOldLockInParams = getSeLockInParams(fh);% = 376; (* SeOldLockInSize = 96, see "Pulsed.de" *) s.SeOldAmpState = getAmplifierState(fh);% = 472; (* SeOldAmpState = 400 -> the AmplStateRecord is now stored in the .amp file *) end - s.SeUsername = deblank(fread(fh, 80, 'uint8=>char')');% = 872; (* String80Type *) switch obj.fileData.fileVersion case 9 @@ -150,7 +140,6 @@ function readPulseFileHEKA(obj,Level) s.SePhotoParams2(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% end end - s.SeFiller1 = fread(fh, 1, 'int32=>int32');% = 1112; (* INT32 *) s.SeCRC = fread(fh, 1, 'int32=>int32');% = 1116; (* CARD32 *) s.SeSeUserParams2 = fread(fh, 4, 'double=>double');% = 1120; (* ARRAY[0..3] OF LONGREAL *) @@ -158,9 +147,7 @@ function readPulseFileHEKA(obj,Level) s.SeSeUserParamDescr2(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% s.SeSeUserParamDescr2(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% end - s.SeScanParams = fread(fh, 96, 'uint8=>uint8');% = 1312; (* ScanParamsSize = 96 (ElProScan Extension) *) - switch obj.fileData.fileVersion case 9 s.SeriesRecSize = 1408;% = 1408; (* = 176 * 8 *) @@ -191,7 +178,6 @@ function readPulseFileHEKA(obj,Level) sw.SwTime = fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) sw.SwTimeMATLAB = obj.HI_time2date(sw.SwTime);% Also add in MATLAB datenum format sw.SwTimer = fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) - switch obj.fileDate.fileVersion case 9 sw.SwSwUserParams = fread(fh, 4, 'double=>double');% = 64; (* ARRAY[0..3] OF LONGREAL *) @@ -200,7 +186,6 @@ function readPulseFileHEKA(obj,Level) sw.SwPipPressure = fread(fh, 2, 'double=>double');% = 80; (* LONGREAL * sw.SwRMSNoise = fread(fh,2,'double=>double'); % = 88; (* LONGREAL *) end - sw.SwSwUserParams = fread(fh, 2, 'double=>double');% = 64; (* ARRAY[0..1] OF LONGREAL *) sw.SwTemperature = fread(fh, 1, 'double=>double');% = 96; (* LONGREAL *) sw.SwOldIntSol = fread(fh, 1, 'int32=>int32');% = 104; (* INT32 *) @@ -213,7 +198,6 @@ function readPulseFileHEKA(obj,Level) sw.SwFiller2 = fread(fh, 1, 'int32=>int32');% = 152; (* INT32 *) sw.SwCRC = fread(fh, 1, 'int32=>int32');% = 156; (* CARD32 *) sw.SwSwHolding = fread(fh,16,'double=>double');% = 160; (* ARRAY[0..15] OF LONGREAL, see SwHoldingNo *) - switch obj.fileData.fileVersion case 9 sw.SweepRecSize = 288;% = 288; (* = 36 * 8 *) @@ -221,7 +205,6 @@ function readPulseFileHEKA(obj,Level) sw.SwSwUserParamEx = fread(fh,8,'double=>double'); % = 288; (* ARRAY[0..7] OF LONGREAL *) sw.SweepRecSize = 352;% = 352; end - sw=orderfields(sw); sw.Traces = []; % used to store all the traces/channels within the sweep structure later on end From dc456445e072738aa1e061ffc8b2ae5a5dfe32a1 Mon Sep 17 00:00:00 2001 From: ChristianKeine Date: Mon, 24 Jun 2019 09:48:02 -0500 Subject: [PATCH 23/39] update stimulus segment import --- @HEKA_Importer/readStimulusFileHEKA.m | 32 +++++++++++++-------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/@HEKA_Importer/readStimulusFileHEKA.m b/@HEKA_Importer/readStimulusFileHEKA.m index e6fee26..31b8a72 100644 --- a/@HEKA_Importer/readStimulusFileHEKA.m +++ b/@HEKA_Importer/readStimulusFileHEKA.m @@ -188,22 +188,22 @@ function readStimulusFileHEKA(obj,Level) %-------------------------------------------------------------------------- fh = obj.fileData.fh; -ss.seMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) -ss.seClass=fread(fh, 1, 'uint8=>uint8');% = 4; (* BYTE *) -ss.seDoStore=fread(fh, 1, 'uint8=>logical');% = 5; (* BOOLEAN *) -ss.seVoltageIncMode=fread(fh, 1, 'uint8=>uint8');% = 6; (* BYTE *) -ss.seDurationIncMode=fread(fh, 1, 'uint8=>uint8');% = 7; (* BYTE *) -ss.seVoltage=fread(fh, 1, 'double=>double');% = 8; (* LONGREAL *) -ss.seVoltageSource=fread(fh, 1, 'int32=>int32');% = 16; (* INT32 *) -ss.seDeltaVFactor=fread(fh, 1, 'double=>double');% = 20; (* LONGREAL *) -ss.seDeltaVIncrement=fread(fh, 1, 'double=>double');% = 28; (* LONGREAL *) -ss.seDuration=fread(fh, 1, 'double=>double');% = 36; (* LONGREAL *) -ss.seDurationSource=fread(fh, 1, 'int32=>int32');% = 44; (* INT32 *) -ss.seDeltaTFactor=fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) -ss.seDeltaTIncrement=fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) -ss.seFiller1=fread(fh, 1, 'int32=>int32');% = 64; (* INT32 *) -ss.seCRC=fread(fh, 1, 'int32=>int32');% = 68; (* CARD32 *) -ss.seScanRate=fread(fh, 1, 'double=>double');% = 72; (* LONGREAL *) +ss.seMark = fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) +ss.seClass = fread(fh, 1, 'uint8=>uint8');% = 4; (* BYTE *) +ss.seDoStore = fread(fh, 1, 'uint8=>logical');% = 5; (* BOOLEAN *) +ss.seVoltageIncMode = fread(fh, 1, 'uint8=>uint8');% = 6; (* BYTE *) +ss.seDurationIncMode = fread(fh, 1, 'uint8=>uint8');% = 7; (* BYTE *) +ss.seVoltage = fread(fh, 1, 'double=>double');% = 8; (* LONGREAL *) +ss.seVoltageSource = fread(fh, 1, 'int32=>int32');% = 16; (* INT32 *) +ss.seDeltaVFactor = fread(fh, 1, 'double=>double');% = 20; (* LONGREAL *) +ss.seDeltaVIncrement = fread(fh, 1, 'double=>double');% = 28; (* LONGREAL *) +ss.seDuration = fread(fh, 1, 'double=>double');% = 36; (* LONGREAL *) +ss.seDurationSource = fread(fh, 1, 'int32=>int32');% = 44; (* INT32 *) +ss.seDeltaTFactor = fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) +ss.seDeltaTIncrement = fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) +ss.seFiller1 = fread(fh, 1, 'int32=>int32');% = 64; (* INT32 *) +ss.seCRC = fread(fh, 1, 'int32=>int32');% = 68; (* CARD32 *) +ss.seScanRate = fread(fh, 1, 'double=>double');% = 72; (* LONGREAL *) ss.StimSegmentRecSize = 80;% (* = 10 * 8 *) ss=orderfields(ss); From 44b906a50de172084d7673d7d092b3e5789d8c2c Mon Sep 17 00:00:00 2001 From: ChristianKeine Date: Mon, 24 Jun 2019 10:10:34 -0500 Subject: [PATCH 24/39] update stim channel import --- @HEKA_Importer/readStimulusFileHEKA.asv | 211 ++++++++++++++++++++++++ @HEKA_Importer/readStimulusFileHEKA.m | 144 ++++++++-------- 2 files changed, 283 insertions(+), 72 deletions(-) create mode 100644 @HEKA_Importer/readStimulusFileHEKA.asv diff --git a/@HEKA_Importer/readStimulusFileHEKA.asv b/@HEKA_Importer/readStimulusFileHEKA.asv new file mode 100644 index 0000000..20a0053 --- /dev/null +++ b/@HEKA_Importer/readStimulusFileHEKA.asv @@ -0,0 +1,211 @@ +function readStimulusFileHEKA(obj,Level) +%-------------------------------------------------------------------------- +% Gets one record of the tree and the number of children +s = getOneStimRecord(obj,Level); +obj.fileData.Tree{obj.fileData.Counter, Level+1} = s; +obj.fileData.Position = obj.fileData.Position+obj.fileData.Sizes(Level+1); +fseek(obj.fileData.fh, obj.fileData.Position, 'bof'); +obj.fileData.nchild=fread(obj.fileData.fh, 1, 'int32=>int32'); +obj.fileData.Position=ftell(obj.fileData.fh); +end + + +%-------------------------------------------------------------------------- +function rec=getOneStimRecord(obj,Level) +%-------------------------------------------------------------------------- +% Gets one record +obj.fileData.Counter = obj.fileData.Counter+1; +switch Level + case 0 + rec=getStimRoot(obj); + case 1 + rec=getStimulation(obj); + case 2 + rec=getChannel(obj); + case 3 + rec=getStimSegment(obj); + otherwise + error('Unexpected Level'); +end + +end + +% The functions below return data as defined by the HEKA PatchMaster +% specification + +%-------------------------------------------------------------------------- +function p=getStimRoot(obj) +%-------------------------------------------------------------------------- +fh = obj.fileData.fh; + +p.RoVersion=fread(fh, 1, 'int32=>int32'); +p.RoMark=fread(fh, 1, 'int32=>int32');% = 4; (* INT32 *) +p.RoVersionName=deblank(fread(fh, 32, 'uint8=>char')');% = 8; (* String32Type *) +p.RoMaxSamples=fread(fh, 1, 'int32=>int32'); % = 40; (* INT32 *) +p.RoFiller1 = fread(fh, 1, 'int32=>int32');% = 44; (* INT32 *) +p.RoParams = fread(fh, 10, 'double=>double');% = 48; (* ARRAY[0..9] OF LONGREAL *) +for k=1:10 + p.RoParamText{k}=deblank(fread(fh, 32, 'uint8=>char')');% = 128; (* ARRAY[0..9],[0..31]OF CHAR *) +end +p.RoReserved = fread(fh, 32, 'int32=>int32');% = 448; (* INT32 *) +p.RoFiller2= fread(fh, 1, 'int32=>int32');% = 576; (* INT32 *) +p.RoCRC= fread(fh, 1, 'int32=>int32');% = 580; (* CARD32 *) +p.RootRecSize= 584; % (* = 73 * 8 *) +p=orderfields(p); + +end + +%-------------------------------------------------------------------------- +function s=getStimulation(obj) +%-------------------------------------------------------------------------- +fh = obj.fileData.fh; + +% Stimulus level +s.stMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) +s.stEntryName=deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Type *) +s.stFileName=deblank(fread(fh, 32, 'uint8=>char')');% = 36; (* String32Type *) +s.stAnalName=deblank(fread(fh, 32, 'uint8=>char')');% = 68; (* String32Type *) +s.stDataStartSegment=fread(fh, 1, 'int32=>int32');% = 100; (* INT32 *) +s.stDataStartTime=fread(fh, 1, 'double=>double') ;% = 104; (* LONGREAL *) +s.stDataStartTimeMATLAB=obj.HI_time2date(s.stDataStartTime); +s.stSampleInterval=fread(fh, 1, 'double=>double') ;% = 112; (* LONGREAL *) +s.stSweepInterval=fread(fh, 1, 'double=>double') ;% = 120; (* LONGREAL *) +s.stLeakDelay=fread(fh, 1, 'double=>double') ;% = 128; (* LONGREAL *) +s.stFilterFactor=fread(fh, 1, 'double=>double') ;% = 136; (* LONGREAL *) +s.stNumberSweeps=fread(fh, 1, 'int32=>int32');% = 144; (* INT32 *) +s.stNumberLeaks=fread(fh, 1, 'int32=>int32');% = 148; (* INT32 *) +s.stNumberAverages=fread(fh, 1, 'int32=>int32');% = 152; (* INT32 *) +s.stActualAdcChannels=fread(fh, 1, 'int32=>int32');% = 156; (* INT32 *) +s.stActualDacChannels=fread(fh, 1, 'int32=>int32');% = 160; (* INT32 *) +s.stExtTrigger=fread(fh, 1, 'uint8=>uint8');% = 164; (* BYTE *) +s.stNoStartWait=fread(fh, 1, 'uint8=>logical');% = 165; (* BOOLEAN *) +s.stUseScanRates=fread(fh, 1, 'uint8=>logical');% = 166; (* BOOLEAN *) +s.stNoContAq=fread(fh, 1, 'uint8=>logical');% = 167; (* BOOLEAN *) +s.stHasLockIn=fread(fh, 1, 'uint8=>logical');% = 168; (* BOOLEAN *) +s.stOldStartMacKind=fread(fh, 1, 'uint8=>char');% = 169; (* CHAR *) +s.stOldEndMacKind=fread(fh, 1, 'uint8=>logical');% = 170; (* BOOLEAN *) +s.stAutoRange=fread(fh, 1, 'uint8=>uint8');% = 171; (* BYTE *) +s.stBreakNext=fread(fh, 1, 'uint8=>logical');% = 172; (* BOOLEAN *) +s.stIsExpanded=fread(fh, 1, 'uint8=>logical');% = 173; (* BOOLEAN *) +s.stLeakCompMode=fread(fh, 1, 'uint8=>logical');% = 174; (* BOOLEAN *) +s.stHasChirp=fread(fh, 1, 'uint8=>logical');% = 175; (* BOOLEAN *) +s.stOldStartMacro=deblank(fread(fh, 32, 'uint8=>char')');% = 176; (* String32Type *) +s.stOldEndMacro=deblank(fread(fh, 32, 'uint8=>char')');% = 208; (* String32Type *) +s.sIsGapFree=fread(fh, 1, 'uint8=>logical');% = 240; (* BOOLEAN *) +s.sHandledExternally=fread(fh, 1, 'uint8=>logical');% = 241; (* BOOLEAN *) +s.stFiller1=fread(fh, 1, 'uint8=>logical');% = 242; (* BOOLEAN *) +s.stFiller2=fread(fh, 1, 'uint8=>logical');% = 243; (* BOOLEAN *) +s.stCRC=fread(fh, 1, 'int32=>int32'); % = 244; (* CARD32 *) +s.stTag=deblank(fread(fh, 32, 'uint8=>char')');% = 248; (* String32Type *) +s.StimulationRecSize = 280;% (* = 35 * 8 *) + +s=orderfields(s); + +end + +%-------------------------------------------------------------------------- +function c=getChannel(obj) +%-------------------------------------------------------------------------- +fh = obj.fileData.fh; + +c.chMark = fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) +c.chLinkedChannel = fread(fh, 1, 'int32=>int32');% = 4; (* INT32 *) +c.chCompressionFactor = fread(fh, 1, 'int32=>int32');% = 8; (* INT32 *) +c.chYUnit = deblank(fread(fh, 8, 'uint8=>char')');% = 12; (* String8Type *) +c.chAdcChannel = fread(fh, 1, 'int16=>int16');% = 20; (* INT16 *) +c.chAdcMode = fread(fh, 1, 'uint8=>uint8');% = 22; (* BYTE *) +c.chDoWrite = fread(fh, 1, 'uint8=>logical');% = 23; (* BOOLEAN *) +c.stLeakStore = fread(fh, 1, 'uint8=>uint8');% = 24; (* BYTE *) +c.chAmplMode = fread(fh, 1, 'uint8=>uint8');% = 25; (* BYTE *) +c.chOwnSegTime = fread(fh, 1, 'uint8=>logical');% = 26; (* BOOLEAN *) +c.chSetLastSegVmemb = fread(fh, 1, 'uint8=>logical');% = 27; (* BOOLEAN *) +c.chDacChannel = fread(fh, 1, 'int16=>int16');% = 28; (* INT16 *) +c.chDacMode = fread(fh, 1, 'uint8=>uint8');% = 30; (* BYTE *) +c.chHasLockInSquare = fread(fh, 1, 'uint8=>uint8');% = 31; (* BYTE *) +c.chRelevantXSegment = fread(fh, 1, 'int32=>int32');% = 32; (* INT32 *) +c.chRelevantYSegment = fread(fh, 1, 'int32=>int32');% = 36; (* INT32 *) +c.chDacUnit = deblank(fread(fh, 8, 'uint8=>char')');% = 40; (* String8Type *) +c.chHolding = fread(fh, 1, 'double=>double') ;% = 48; (* LONGREAL *) +c.chLeakHolding = fread(fh, 1, 'double=>double') ;% = 56; (* LONGREAL *) +c.chLeakSize = fread(fh, 1, 'double=>double') ;% = 64; (* LONGREAL *) +c.chLeakHoldMode = fread(fh, 1, 'uint8=>uint8');% = 72; (* BYTE *) +c.chLeakAlternate = fread(fh, 1, 'uint8=>logical');% = 73; (* BOOLEAN *) +c.chAltLeakAveraging = fread(fh, 1, 'uint8=>logical');% = 74; (* BOOLEAN *) +c.chLeakPulseOn = fread(fh, 1, 'uint8=>logical');% = 75; (* BOOLEAN *) +c.chStimToDacID = fread(fh, 1, 'int16=>int16');% = 76; (* SET16 *) +c.chCompressionMode = fread(fh, 1, 'int16=>int16');% = 78; (* SET16 *) +c.chCompressionSkip = fread(fh, 1, 'int32=>int32');% = 80; (* INT32 *) +c.chDacBit = fread(fh, 1, 'int16=>int16');% = 84; (* INT16 *) +c.chHasLockInSine = fread(fh, 1, 'uint8=>logical');% = 86; (* BOOLEAN *) +c.chBreakMode = fread(fh, 1, 'uint8=>uint8');% = 87; (* BYTE *) +c.chZeroSeg = fread(fh, 1, 'int32=>int32');% = 88; (* INT32 *) +c.chStimSweep = fread(fh, 1, 'int32=>int32');% = 92; (* INT32 *) +c.chSine_Cycle = fread(fh, 1, 'double=>double') ;% = 96; (* LONGREAL *) +c.chSine_Amplitude = fread(fh, 1, 'double=>double') ;% = 104; (* LONGREAL *) +c.chLockIn_VReversal = fread(fh, 1, 'double=>double') ;% = 112; (* LONGREAL *) +c.chChirp_StartFreq = fread(fh, 1, 'double=>double') ;% = 120; (* LONGREAL *) +c.chChirp_EndFreq = fread(fh, 1, 'double=>double') ;% = 128; (* LONGREAL *) +c.chChirp_MinPoints = fread(fh, 1, 'double=>double') ;% = 136; (* LONGREAL *) +c.chSquare_NegAmpl = fread(fh, 1, 'double=>double') ;% = 144; (* LONGREAL *) +c.chSquare_DurFactor = fread(fh, 1, 'double=>double') ;% = 152; (* LONGREAL *) +c.chLockIn_Skip = fread(fh, 1, 'int32=>int32');% = 160; (* INT32 *) +c.chPhoto_MaxCycles = fread(fh, 1, 'int32=>int32');% = 164; (* INT32 *) +c.chPhoto_SegmentNo = fread(fh, 1, 'int32=>int32');% = 168; (* INT32 *) +c.chLockIn_AvgCycles = fread(fh, 1, 'int32=>int32');% = 172; (* INT32 *) +c.chImaging_RoiNo = fread(fh, 1, 'int32=>int32');% = 176; (* INT32 *) +c.chChirp_Skip = fread(fh, 1, 'int32=>int32');% = 180; (* INT32 *) +c.chChirp_Amplitude = fread(fh, 1, 'double=>double');% = 184; (* LONGREAL *) +c.chPhoto_Adapt = fread(fh, 1, 'uint8=>uint8');% = 192; (* BYTE *) +c.chSine_Kind = fread(fh, 1, 'uint8=>uint8');% = 193; (* BYTE *) +c.chChirp_PreChirp = fread(fh, 1, 'uint8=>uint8');% = 194; (* BYTE *) +c.chSine_Source = fread(fh, 1, 'uint8=>uint8');% = 195; (* BYTE *) +c.chSquare_NegSource = fread(fh, 1, 'uint8=>uint8');% = 196; (* BYTE *) +c.chSquare_PosSource = fread(fh, 1, 'uint8=>uint8');% = 197; (* BYTE *) +c.chChirp_Kind = fread(fh, 1, 'uint8=>uint8');% = 198; (* BYTE *) +c.chChirp_Source = fread(fh, 1, 'uint8=>uint8');% = 199; (* BYTE *) +c.chDacOffset = fread(fh, 1, 'double=>double') ;% = 200; (* LONGREAL *) +c.chAdcOffset = fread(fh, 1, 'double=>double') ;% = 208; (* LONGREAL *) +c.chTraceMathFormat = fread(fh, 1, 'uint8=>uint8');% = 216; (* BYTE *) +c.chHasChirp = fread(fh, 1, 'uint8=>logical');% = 217; (* BOOLEAN *) +c.chSquare_Kind = fread(fh, 1, 'uint8=>uint8');% = 218; (* BYTE *) +c.chFiller2 = fread(fh,13,'uint8=>char');% = 219; (* ARRAY[0..5] OF CHAR *) + +c.chSquare_Cycle = fread(fh, 1, 'double=>double') ;% = 232; (* LONGREAL *) +c.chSquare_PosAmpl = fread(fh, 1, 'double=>double') ;% = 240; (* LONGREAL *) +c.chCompressionOffset = fread(fh, 1, 'int32=>int32');% = 248; (* INT32 *) +c.chPhotoMode = fread(fh, 1, 'int32=>int32');% = 252; (* INT32 *) +c.chBreakLevel = fread(fh, 1, 'double=>double') ;% = 256; (* LONGREAL *) +c.chTraceMath = deblank(fread(fh,128,'uint8=>char')');% = 264; (* String128Type *) +c.chOldCRC = fread(fh, 1, 'int32=>int32');% = 268; (* CARD32 *) +c.chFiller3 = fread(fh, 1, 'int32=>int32');% = 392; (* INT32 *) +c.chCRC = fread(fh, 1, 'int32=>int32');% = 396; (* CARD32 *) +c.ChannelRecSize = 400;% (* = 50 * 8 *) +c=orderfields(c); + +end + +%-------------------------------------------------------------------------- +function ss=getStimSegment(obj) +%-------------------------------------------------------------------------- +fh = obj.fileData.fh; + +ss.seMark = fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) +ss.seClass = fread(fh, 1, 'uint8=>uint8');% = 4; (* BYTE *) +ss.seDoStore = fread(fh, 1, 'uint8=>logical');% = 5; (* BOOLEAN *) +ss.seVoltageIncMode = fread(fh, 1, 'uint8=>uint8');% = 6; (* BYTE *) +ss.seDurationIncMode = fread(fh, 1, 'uint8=>uint8');% = 7; (* BYTE *) +ss.seVoltage = fread(fh, 1, 'double=>double');% = 8; (* LONGREAL *) +ss.seVoltageSource = fread(fh, 1, 'int32=>int32');% = 16; (* INT32 *) +ss.seDeltaVFactor = fread(fh, 1, 'double=>double');% = 20; (* LONGREAL *) +ss.seDeltaVIncrement = fread(fh, 1, 'double=>double');% = 28; (* LONGREAL *) +ss.seDuration = fread(fh, 1, 'double=>double');% = 36; (* LONGREAL *) +ss.seDurationSource = fread(fh, 1, 'int32=>int32');% = 44; (* INT32 *) +ss.seDeltaTFactor = fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) +ss.seDeltaTIncrement = fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) +ss.seFiller1 = fread(fh, 1, 'int32=>int32');% = 64; (* INT32 *) +ss.seCRC = fread(fh, 1, 'int32=>int32');% = 68; (* CARD32 *) +ss.seScanRate = fread(fh, 1, 'double=>double');% = 72; (* LONGREAL *) +ss.StimSegmentRecSize = 80;% (* = 10 * 8 *) +ss=orderfields(ss); + +end diff --git a/@HEKA_Importer/readStimulusFileHEKA.m b/@HEKA_Importer/readStimulusFileHEKA.m index 31b8a72..e2e8758 100644 --- a/@HEKA_Importer/readStimulusFileHEKA.m +++ b/@HEKA_Importer/readStimulusFileHEKA.m @@ -108,77 +108,77 @@ function readStimulusFileHEKA(obj,Level) %-------------------------------------------------------------------------- fh = obj.fileData.fh; -c.chMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) -c.chLinkedChannel=fread(fh, 1, 'int32=>int32');% = 4; (* INT32 *) -c.chCompressionFactor=fread(fh, 1, 'int32=>int32');% = 8; (* INT32 *) -c.chYUnit=deblank(fread(fh, 8, 'uint8=>char')');% = 12; (* String8Type *) -c.chAdcChannel=fread(fh, 1, 'int16=>int16');% = 20; (* INT16 *) -c.chAdcMode=fread(fh, 1, 'uint8=>uint8');% = 22; (* BYTE *) -c.chDoWrite=fread(fh, 1, 'uint8=>logical');% = 23; (* BOOLEAN *) -c.stLeakStore=fread(fh, 1, 'uint8=>uint8');% = 24; (* BYTE *) -c.chAmplMode=fread(fh, 1, 'uint8=>uint8');% = 25; (* BYTE *) -c.chOwnSegTime=fread(fh, 1, 'uint8=>logical');% = 26; (* BOOLEAN *) -c.chSetLastSegVmemb=fread(fh, 1, 'uint8=>logical');% = 27; (* BOOLEAN *) -c.chDacChannel=fread(fh, 1, 'int16=>int16');% = 28; (* INT16 *) -c.chDacMode=fread(fh, 1, 'uint8=>uint8');% = 30; (* BYTE *) -c.chHasLockInSquare=fread(fh, 1, 'uint8=>uint8');% = 31; (* BYTE *) -c.chRelevantXSegment=fread(fh, 1, 'int32=>int32');% = 32; (* INT32 *) -c.chRelevantYSegment=fread(fh, 1, 'int32=>int32');% = 36; (* INT32 *) -c.chDacUnit=deblank(fread(fh, 8, 'uint8=>char')');% = 40; (* String8Type *) -c.chHolding=fread(fh, 1, 'double=>double') ;% = 48; (* LONGREAL *) -c.chLeakHolding=fread(fh, 1, 'double=>double') ;% = 56; (* LONGREAL *) -c.chLeakSize=fread(fh, 1, 'double=>double') ;% = 64; (* LONGREAL *) -c.chLeakHoldMode=fread(fh, 1, 'uint8=>uint8');% = 72; (* BYTE *) -c.chLeakAlternate=fread(fh, 1, 'uint8=>logical');% = 73; (* BOOLEAN *) -c.chAltLeakAveraging=fread(fh, 1, 'uint8=>logical');% = 74; (* BOOLEAN *) -c.chLeakPulseOn=fread(fh, 1, 'uint8=>logical');% = 75; (* BOOLEAN *) -c.chStimToDacID=fread(fh, 1, 'int16=>int16');% = 76; (* SET16 *) -c.chCompressionMode=fread(fh, 1, 'int16=>int16');% = 78; (* SET16 *) -c.chCompressionSkip=fread(fh, 1, 'int32=>int32');% = 80; (* INT32 *) -c.chDacBit=fread(fh, 1, 'int16=>int16');% = 84; (* INT16 *) -c.chHasLockInSine=fread(fh, 1, 'uint8=>logical');% = 86; (* BOOLEAN *) -c.chBreakMode=fread(fh, 1, 'uint8=>uint8');% = 87; (* BYTE *) -c.chZeroSeg=fread(fh, 1, 'int32=>int32');% = 88; (* INT32 *) -c.chFiller1=fread(fh, 1, 'int32=>int32');% = 92; (* INT32 *) -c.chSine_Cycle=fread(fh, 1, 'double=>double') ;% = 96; (* LONGREAL *) -c.chSine_Amplitude=fread(fh, 1, 'double=>double') ;% = 104; (* LONGREAL *) -c.chLockIn_VReversal=fread(fh, 1, 'double=>double') ;% = 112; (* LONGREAL *) -c.chChirp_StartFreq=fread(fh, 1, 'double=>double') ;% = 120; (* LONGREAL *) -c.chChirp_EndFreq=fread(fh, 1, 'double=>double') ;% = 128; (* LONGREAL *) -c.chChirp_MinPoints=fread(fh, 1, 'double=>double') ;% = 136; (* LONGREAL *) -c.chSquare_NegAmpl=fread(fh, 1, 'double=>double') ;% = 144; (* LONGREAL *) -c.chSquare_DurFactor=fread(fh, 1, 'double=>double') ;% = 152; (* LONGREAL *) -c.chLockIn_Skip=fread(fh, 1, 'int32=>int32');% = 160; (* INT32 *) -c.chPhoto_MaxCycles=fread(fh, 1, 'int32=>int32');% = 164; (* INT32 *) -c.chPhoto_SegmentNo=fread(fh, 1, 'int32=>int32');% = 168; (* INT32 *) -c.chLockIn_AvgCycles=fread(fh, 1, 'int32=>int32');% = 172; (* INT32 *) -c.chImaging_RoiNo=fread(fh, 1, 'int32=>int32');% = 176; (* INT32 *) -c.chChirp_Skip=fread(fh, 1, 'int32=>int32');% = 180; (* INT32 *) -c.chChirp_Amplitude=fread(fh, 1, 'double=>double') ;% = 184; (* LONGREAL *) -c.chPhoto_Adapt=fread(fh, 1, 'uint8=>uint8');% = 192; (* BYTE *) -c.chSine_Kind=fread(fh, 1, 'uint8=>uint8');% = 193; (* BYTE *) -c.chChirp_PreChirp=fread(fh, 1, 'uint8=>uint8');% = 194; (* BYTE *) -c.chSine_Source=fread(fh, 1, 'uint8=>uint8');% = 195; (* BYTE *) -c.chSquare_NegSource=fread(fh, 1, 'uint8=>uint8');% = 196; (* BYTE *) -c.chSquare_PosSource=fread(fh, 1, 'uint8=>uint8');% = 197; (* BYTE *) -c.chChirp_Kind=fread(fh, 1, 'uint8=>uint8');% = 198; (* BYTE *) -c.chChirp_Source=fread(fh, 1, 'uint8=>uint8');% = 199; (* BYTE *) -c.chDacOffset=fread(fh, 1, 'double=>double') ;% = 200; (* LONGREAL *) -c.chAdcOffset=fread(fh, 1, 'double=>double') ;% = 208; (* LONGREAL *) -c.chTraceMathFormat=fread(fh, 1, 'uint8=>uint8');% = 216; (* BYTE *) -c.chHasChirp=fread(fh, 1, 'uint8=>logical');% = 217; (* BOOLEAN *) -c.chSquare_Kind=fread(fh, 1, 'uint8=>uint8');% = 218; (* BYTE *) -c.chFiller2=fread(fh,13,'uint8=>char');% = 219; (* ARRAY[0..13] OF CHAR *) -c.chSquare_Cycle=fread(fh, 1, 'double=>double') ;% = 232; (* LONGREAL *) -c.chSquare_PosAmpl=fread(fh, 1, 'double=>double') ;% = 240; (* LONGREAL *) -c.chCompressionOffset=fread(fh, 1, 'int32=>int32');% = 248; (* INT32 *) -c.chPhotoMode=fread(fh, 1, 'int32=>int32');% = 252; (* INT32 *) -c.chBreakLevel=fread(fh, 1, 'double=>double') ;% = 256; (* LONGREAL *) -c.chTraceMath=deblank(fread(fh,128,'uint8=>char')');% = 264; (* String128Type *) -c.chOldCRC=fread(fh, 1, 'int32=>int32');% = 268; (* CARD32 *) -c.chFiller3=fread(fh, 1, 'int32=>int32');% = 392; (* INT32 *) -c.chCRC=fread(fh, 1, 'int32=>int32');% = 396; (* CARD32 *) -c.ChannelRecSize = 400;% (* = 50 * 8 *) +c.chMark = fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) +c.chLinkedChannel = fread(fh, 1, 'int32=>int32');% = 4; (* INT32 *) +c.chCompressionFactor = fread(fh, 1, 'int32=>int32');% = 8; (* INT32 *) +c.chYUnit = deblank(fread(fh, 8, 'uint8=>char')');% = 12; (* String8Type *) +c.chAdcChannel = fread(fh, 1, 'int16=>int16');% = 20; (* INT16 *) +c.chAdcMode = fread(fh, 1, 'uint8=>uint8');% = 22; (* BYTE *) +c.chDoWrite = fread(fh, 1, 'uint8=>logical');% = 23; (* BOOLEAN *) +c.stLeakStore = fread(fh, 1, 'uint8=>uint8');% = 24; (* BYTE *) +c.chAmplMode = fread(fh, 1, 'uint8=>uint8');% = 25; (* BYTE *) +c.chOwnSegTime = fread(fh, 1, 'uint8=>logical');% = 26; (* BOOLEAN *) +c.chSetLastSegVmemb = fread(fh, 1, 'uint8=>logical');% = 27; (* BOOLEAN *) +c.chDacChannel = fread(fh, 1, 'int16=>int16');% = 28; (* INT16 *) +c.chDacMode = fread(fh, 1, 'uint8=>uint8');% = 30; (* BYTE *) +c.chHasLockInSquare = fread(fh, 1, 'uint8=>uint8');% = 31; (* BYTE *) +c.chRelevantXSegment = fread(fh, 1, 'int32=>int32');% = 32; (* INT32 *) +c.chRelevantYSegment = fread(fh, 1, 'int32=>int32');% = 36; (* INT32 *) +c.chDacUnit = deblank(fread(fh, 8, 'uint8=>char')');% = 40; (* String8Type *) +c.chHolding = fread(fh, 1, 'double=>double') ;% = 48; (* LONGREAL *) +c.chLeakHolding = fread(fh, 1, 'double=>double') ;% = 56; (* LONGREAL *) +c.chLeakSize = fread(fh, 1, 'double=>double') ;% = 64; (* LONGREAL *) +c.chLeakHoldMode = fread(fh, 1, 'uint8=>uint8');% = 72; (* BYTE *) +c.chLeakAlternate = fread(fh, 1, 'uint8=>logical');% = 73; (* BOOLEAN *) +c.chAltLeakAveraging = fread(fh, 1, 'uint8=>logical');% = 74; (* BOOLEAN *) +c.chLeakPulseOn = fread(fh, 1, 'uint8=>logical');% = 75; (* BOOLEAN *) +c.chStimToDacID = fread(fh, 1, 'int16=>int16');% = 76; (* SET16 *) +c.chCompressionMode = fread(fh, 1, 'int16=>int16');% = 78; (* SET16 *) +c.chCompressionSkip = fread(fh, 1, 'int32=>int32');% = 80; (* INT32 *) +c.chDacBit = fread(fh, 1, 'int16=>int16');% = 84; (* INT16 *) +c.chHasLockInSine = fread(fh, 1, 'uint8=>logical');% = 86; (* BOOLEAN *) +c.chBreakMode = fread(fh, 1, 'uint8=>uint8');% = 87; (* BYTE *) +c.chZeroSeg = fread(fh, 1, 'int32=>int32');% = 88; (* INT32 *) +c.chStimSweep = fread(fh, 1, 'int32=>int32');% = 92; (* INT32 *) +c.chSine_Cycle = fread(fh, 1, 'double=>double') ;% = 96; (* LONGREAL *) +c.chSine_Amplitude = fread(fh, 1, 'double=>double') ;% = 104; (* LONGREAL *) +c.chLockIn_VReversal = fread(fh, 1, 'double=>double') ;% = 112; (* LONGREAL *) +c.chChirp_StartFreq = fread(fh, 1, 'double=>double') ;% = 120; (* LONGREAL *) +c.chChirp_EndFreq = fread(fh, 1, 'double=>double') ;% = 128; (* LONGREAL *) +c.chChirp_MinPoints = fread(fh, 1, 'double=>double') ;% = 136; (* LONGREAL *) +c.chSquare_NegAmpl = fread(fh, 1, 'double=>double') ;% = 144; (* LONGREAL *) +c.chSquare_DurFactor = fread(fh, 1, 'double=>double') ;% = 152; (* LONGREAL *) +c.chLockIn_Skip = fread(fh, 1, 'int32=>int32');% = 160; (* INT32 *) +c.chPhoto_MaxCycles = fread(fh, 1, 'int32=>int32');% = 164; (* INT32 *) +c.chPhoto_SegmentNo = fread(fh, 1, 'int32=>int32');% = 168; (* INT32 *) +c.chLockIn_AvgCycles = fread(fh, 1, 'int32=>int32');% = 172; (* INT32 *) +c.chImaging_RoiNo = fread(fh, 1, 'int32=>int32');% = 176; (* INT32 *) +c.chChirp_Skip = fread(fh, 1, 'int32=>int32');% = 180; (* INT32 *) +c.chChirp_Amplitude = fread(fh, 1, 'double=>double');% = 184; (* LONGREAL *) +c.chPhoto_Adapt = fread(fh, 1, 'uint8=>uint8');% = 192; (* BYTE *) +c.chSine_Kind = fread(fh, 1, 'uint8=>uint8');% = 193; (* BYTE *) +c.chChirp_PreChirp = fread(fh, 1, 'uint8=>uint8');% = 194; (* BYTE *) +c.chSine_Source = fread(fh, 1, 'uint8=>uint8');% = 195; (* BYTE *) +c.chSquare_NegSource = fread(fh, 1, 'uint8=>uint8');% = 196; (* BYTE *) +c.chSquare_PosSource = fread(fh, 1, 'uint8=>uint8');% = 197; (* BYTE *) +c.chChirp_Kind = fread(fh, 1, 'uint8=>uint8');% = 198; (* BYTE *) +c.chChirp_Source = fread(fh, 1, 'uint8=>uint8');% = 199; (* BYTE *) +c.chDacOffset = fread(fh, 1, 'double=>double') ;% = 200; (* LONGREAL *) +c.chAdcOffset = fread(fh, 1, 'double=>double') ;% = 208; (* LONGREAL *) +c.chTraceMathFormat = fread(fh, 1, 'uint8=>uint8');% = 216; (* BYTE *) +c.chHasChirp = fread(fh, 1, 'uint8=>logical');% = 217; (* BOOLEAN *) +c.chSquare_Kind = fread(fh, 1, 'uint8=>uint8');% = 218; (* BYTE *) + c.chFiller1 = fread(fh, 6, 'uint8=>char');% = 219; (* ARRAY[0..5] OF CHAR *) +c.chSquare_BaseIncr = fread(fh, 1, 'double=>double');% = 224; (* LONGREAL *) +c.chSquare_Cycle = fread(fh, 1, 'double=>double') ;% = 232; (* LONGREAL *) +c.chSquare_PosAmpl = fread(fh, 1, 'double=>double') ;% = 240; (* LONGREAL *) +c.chCompressionOffset = fread(fh, 1, 'int32=>int32');% = 248; (* INT32 *) +c.chPhotoMode = fread(fh, 1, 'int32=>int32');% = 252; (* INT32 *) +c.chBreakLevel = fread(fh, 1, 'double=>double') ;% = 256; (* LONGREAL *) +c.chTraceMath = deblank(fread(fh,128,'uint8=>char')');% = 264; (* String128Type *) + c.chFiller2 = fread(fh, 1, 'int32=>int32');% = 392; (* INT32 *) +c.chCRC = fread(fh, 1, 'int32=>int32');% = 396; (* CARD32 *) +c.ChannelRecSize = 400;% (* = 50 * 8 *) c=orderfields(c); end @@ -204,7 +204,7 @@ function readStimulusFileHEKA(obj,Level) ss.seFiller1 = fread(fh, 1, 'int32=>int32');% = 64; (* INT32 *) ss.seCRC = fread(fh, 1, 'int32=>int32');% = 68; (* CARD32 *) ss.seScanRate = fread(fh, 1, 'double=>double');% = 72; (* LONGREAL *) -ss.StimSegmentRecSize = 80;% (* = 10 * 8 *) +ss.StimSegmentRecSize = 80;% (* = 10 * 8 *) ss=orderfields(ss); end From 6dc6726df1828d05bca0d116245fd3e1869f30ee Mon Sep 17 00:00:00 2001 From: ChristianKeine Date: Mon, 24 Jun 2019 10:21:30 -0500 Subject: [PATCH 25/39] update stim record --- @HEKA_Importer/readStimulusFileHEKA.asv | 103 ++++++++++++------------ @HEKA_Importer/readStimulusFileHEKA.m | 95 +++++++++++----------- 2 files changed, 98 insertions(+), 100 deletions(-) diff --git a/@HEKA_Importer/readStimulusFileHEKA.asv b/@HEKA_Importer/readStimulusFileHEKA.asv index 20a0053..c4ba996 100644 --- a/@HEKA_Importer/readStimulusFileHEKA.asv +++ b/@HEKA_Importer/readStimulusFileHEKA.asv @@ -38,19 +38,19 @@ function p=getStimRoot(obj) %-------------------------------------------------------------------------- fh = obj.fileData.fh; -p.RoVersion=fread(fh, 1, 'int32=>int32'); -p.RoMark=fread(fh, 1, 'int32=>int32');% = 4; (* INT32 *) -p.RoVersionName=deblank(fread(fh, 32, 'uint8=>char')');% = 8; (* String32Type *) -p.RoMaxSamples=fread(fh, 1, 'int32=>int32'); % = 40; (* INT32 *) -p.RoFiller1 = fread(fh, 1, 'int32=>int32');% = 44; (* INT32 *) -p.RoParams = fread(fh, 10, 'double=>double');% = 48; (* ARRAY[0..9] OF LONGREAL *) +p.RoVersion = fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) +p.RoMark = fread(fh, 1, 'int32=>int32');% = 4; (* INT32 *) +p.RoVersionName = deblank(fread(fh, 32, 'uint8=>char')');% = 8; (* String32Type *) +p.RoMaxSamples = fread(fh, 1, 'int32=>int32'); % = 40; (* INT32 *) +p.RoFiller1 = fread(fh, 1, 'int32=>int32');% = 44; (* INT32 *) +p.RoParams = fread(fh, 10, 'double=>double');% = 48; (* ARRAY[0..9] OF LONGREAL *) for k=1:10 - p.RoParamText{k}=deblank(fread(fh, 32, 'uint8=>char')');% = 128; (* ARRAY[0..9],[0..31]OF CHAR *) + p.RoParamText{k}=deblank(fread(fh, 32, 'uint8=>char')');% = 128; (* ARRAY[0..9],[0..31]OF CHAR *) end -p.RoReserved = fread(fh, 32, 'int32=>int32');% = 448; (* INT32 *) -p.RoFiller2= fread(fh, 1, 'int32=>int32');% = 576; (* INT32 *) -p.RoCRC= fread(fh, 1, 'int32=>int32');% = 580; (* CARD32 *) -p.RootRecSize= 584; % (* = 73 * 8 *) +p.RoReserved = fread(fh, 32, 'int32=>int32');% = 448; (* INT32 *) +p.RoFiller2 = fread(fh, 1, 'int32=>int32');% = 576; (* INT32 *) +p.RoCRC = fread(fh, 1, 'int32=>int32');% = 580; (* CARD32 *) +p.RootRecSize = 584; % (* = 73 * 8 *) p=orderfields(p); end @@ -61,43 +61,43 @@ function s=getStimulation(obj) fh = obj.fileData.fh; % Stimulus level -s.stMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) -s.stEntryName=deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Type *) -s.stFileName=deblank(fread(fh, 32, 'uint8=>char')');% = 36; (* String32Type *) -s.stAnalName=deblank(fread(fh, 32, 'uint8=>char')');% = 68; (* String32Type *) -s.stDataStartSegment=fread(fh, 1, 'int32=>int32');% = 100; (* INT32 *) -s.stDataStartTime=fread(fh, 1, 'double=>double') ;% = 104; (* LONGREAL *) -s.stDataStartTimeMATLAB=obj.HI_time2date(s.stDataStartTime); -s.stSampleInterval=fread(fh, 1, 'double=>double') ;% = 112; (* LONGREAL *) -s.stSweepInterval=fread(fh, 1, 'double=>double') ;% = 120; (* LONGREAL *) -s.stLeakDelay=fread(fh, 1, 'double=>double') ;% = 128; (* LONGREAL *) -s.stFilterFactor=fread(fh, 1, 'double=>double') ;% = 136; (* LONGREAL *) -s.stNumberSweeps=fread(fh, 1, 'int32=>int32');% = 144; (* INT32 *) -s.stNumberLeaks=fread(fh, 1, 'int32=>int32');% = 148; (* INT32 *) -s.stNumberAverages=fread(fh, 1, 'int32=>int32');% = 152; (* INT32 *) -s.stActualAdcChannels=fread(fh, 1, 'int32=>int32');% = 156; (* INT32 *) -s.stActualDacChannels=fread(fh, 1, 'int32=>int32');% = 160; (* INT32 *) -s.stExtTrigger=fread(fh, 1, 'uint8=>uint8');% = 164; (* BYTE *) -s.stNoStartWait=fread(fh, 1, 'uint8=>logical');% = 165; (* BOOLEAN *) -s.stUseScanRates=fread(fh, 1, 'uint8=>logical');% = 166; (* BOOLEAN *) -s.stNoContAq=fread(fh, 1, 'uint8=>logical');% = 167; (* BOOLEAN *) -s.stHasLockIn=fread(fh, 1, 'uint8=>logical');% = 168; (* BOOLEAN *) -s.stOldStartMacKind=fread(fh, 1, 'uint8=>char');% = 169; (* CHAR *) -s.stOldEndMacKind=fread(fh, 1, 'uint8=>logical');% = 170; (* BOOLEAN *) -s.stAutoRange=fread(fh, 1, 'uint8=>uint8');% = 171; (* BYTE *) -s.stBreakNext=fread(fh, 1, 'uint8=>logical');% = 172; (* BOOLEAN *) -s.stIsExpanded=fread(fh, 1, 'uint8=>logical');% = 173; (* BOOLEAN *) -s.stLeakCompMode=fread(fh, 1, 'uint8=>logical');% = 174; (* BOOLEAN *) -s.stHasChirp=fread(fh, 1, 'uint8=>logical');% = 175; (* BOOLEAN *) -s.stOldStartMacro=deblank(fread(fh, 32, 'uint8=>char')');% = 176; (* String32Type *) -s.stOldEndMacro=deblank(fread(fh, 32, 'uint8=>char')');% = 208; (* String32Type *) -s.sIsGapFree=fread(fh, 1, 'uint8=>logical');% = 240; (* BOOLEAN *) -s.sHandledExternally=fread(fh, 1, 'uint8=>logical');% = 241; (* BOOLEAN *) -s.stFiller1=fread(fh, 1, 'uint8=>logical');% = 242; (* BOOLEAN *) -s.stFiller2=fread(fh, 1, 'uint8=>logical');% = 243; (* BOOLEAN *) -s.stCRC=fread(fh, 1, 'int32=>int32'); % = 244; (* CARD32 *) -s.stTag=deblank(fread(fh, 32, 'uint8=>char')');% = 248; (* String32Type *) -s.StimulationRecSize = 280;% (* = 35 * 8 *) +s.stMark = fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) +s.stEntryName = deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Type *) +s.stFileName = deblank(fread(fh, 32, 'uint8=>char')');% = 36; (* String32Type *) +s.stAnalName = deblank(fread(fh, 32, 'uint8=>char')');% = 68; (* String32Type *) +s.stDataStartSegment = fread(fh, 1, 'int32=>int32');% = 100; (* INT32 *) +s.stDataStartTime = fread(fh, 1, 'double=>double') ;% = 104; (* LONGREAL *) +s.stDataStartTimeMATLAB = obj.HI_time2date(s.stDataStartTime); +s.stSampleInterval = fread(fh, 1, 'double=>double') ;% = 112; (* LONGREAL *) +s.stSweepInterval = fread(fh, 1, 'double=>double') ;% = 120; (* LONGREAL *) +s.stLeakDelay = fread(fh, 1, 'double=>double') ;% = 128; (* LONGREAL *) +s.stFilterFactor = fread(fh, 1, 'double=>double') ;% = 136; (* LONGREAL *) +s.stNumberSweeps = fread(fh, 1, 'int32=>int32');% = 144; (* INT32 *) +s.stNumberLeaks = fread(fh, 1, 'int32=>int32');% = 148; (* INT32 *) +s.stNumberAverages = fread(fh, 1, 'int32=>int32');% = 152; (* INT32 *) +s.stActualAdcChannels = fread(fh, 1, 'int32=>int32');% = 156; (* INT32 *) +s.stActualDacChannels = fread(fh, 1, 'int32=>int32');% = 160; (* INT32 *) +s.stExtTrigger = fread(fh, 1, 'uint8=>uint8');% = 164; (* BYTE *) +s.stNoStartWait = fread(fh, 1, 'uint8=>logical');% = 165; (* BOOLEAN *) +s.stUseScanRates = fread(fh, 1, 'uint8=>logical');% = 166; (* BOOLEAN *) +s.stNoContAq = fread(fh, 1, 'uint8=>logical');% = 167; (* BOOLEAN *) +s.stHasLockIn = fread(fh, 1, 'uint8=>logical');% = 168; (* BOOLEAN *) +s.stOldStartMacKind = fread(fh, 1, 'uint8=>char');% = 169; (* CHAR *) +s.stOldEndMacKind = fread(fh, 1, 'uint8=>logical');% = 170; (* BOOLEAN *) +s.stAutoRange = fread(fh, 1, 'uint8=>uint8');% = 171; (* BYTE *) +s.stBreakNext = fread(fh, 1, 'uint8=>logical');% = 172; (* BOOLEAN *) +s.stIsExpanded = fread(fh, 1, 'uint8=>logical');% = 173; (* BOOLEAN *) +s.stLeakCompMode = fread(fh, 1, 'uint8=>logical');% = 174; (* BOOLEAN *) +s.stHasChirp = fread(fh, 1, 'uint8=>logical');% = 175; (* BOOLEAN *) +s.stOldStartMacro = deblank(fread(fh, 32, 'uint8=>char')');% = 176; (* String32Type *) +s.stOldEndMacro = deblank(fread(fh, 32, 'uint8=>char')');% = 208; (* String32Type *) +s.sIsGapFree = fread(fh, 1, 'uint8=>logical');% = 240; (* BOOLEAN *) +s.sHandledExternally = fread(fh, 1, 'uint8=>logical');% = 241; (* BOOLEAN *) + s.stFiller1 = fread(fh, 1, 'uint8=>logical');% = 242; (* BOOLEAN *) + s.stFiller2 = fread(fh, 1, 'uint8=>logical');% = 243; (* BOOLEAN *) +s.stCRC = fread(fh, 1, 'int32=>int32'); % = 244; (* CARD32 *) +s.stTag = deblank(fread(fh, 32, 'uint8=>char')');% = 248; (* String32Type *) +s.StimulationRecSize = 280;% (* = 35 * 8 *) s=orderfields(s); @@ -168,16 +168,15 @@ c.chAdcOffset = fread(fh, 1, 'double=>double') ;% = 208; (* LONGREAL *) c.chTraceMathFormat = fread(fh, 1, 'uint8=>uint8');% = 216; (* BYTE *) c.chHasChirp = fread(fh, 1, 'uint8=>logical');% = 217; (* BOOLEAN *) c.chSquare_Kind = fread(fh, 1, 'uint8=>uint8');% = 218; (* BYTE *) -c.chFiller2 = fread(fh,13,'uint8=>char');% = 219; (* ARRAY[0..5] OF CHAR *) - + c.chFiller1 = fread(fh, 6, 'uint8=>char');% = 219; (* ARRAY[0..5] OF CHAR *) +c.chSquare_BaseIncr = fread(fh, 1, 'double=>double');% = 224; (* LONGREAL *) c.chSquare_Cycle = fread(fh, 1, 'double=>double') ;% = 232; (* LONGREAL *) c.chSquare_PosAmpl = fread(fh, 1, 'double=>double') ;% = 240; (* LONGREAL *) c.chCompressionOffset = fread(fh, 1, 'int32=>int32');% = 248; (* INT32 *) c.chPhotoMode = fread(fh, 1, 'int32=>int32');% = 252; (* INT32 *) c.chBreakLevel = fread(fh, 1, 'double=>double') ;% = 256; (* LONGREAL *) c.chTraceMath = deblank(fread(fh,128,'uint8=>char')');% = 264; (* String128Type *) -c.chOldCRC = fread(fh, 1, 'int32=>int32');% = 268; (* CARD32 *) -c.chFiller3 = fread(fh, 1, 'int32=>int32');% = 392; (* INT32 *) + c.chFiller2 = fread(fh, 1, 'int32=>int32');% = 392; (* INT32 *) c.chCRC = fread(fh, 1, 'int32=>int32');% = 396; (* CARD32 *) c.ChannelRecSize = 400;% (* = 50 * 8 *) c=orderfields(c); diff --git a/@HEKA_Importer/readStimulusFileHEKA.m b/@HEKA_Importer/readStimulusFileHEKA.m index e2e8758..67ddbe3 100644 --- a/@HEKA_Importer/readStimulusFileHEKA.m +++ b/@HEKA_Importer/readStimulusFileHEKA.m @@ -38,19 +38,19 @@ function readStimulusFileHEKA(obj,Level) %-------------------------------------------------------------------------- fh = obj.fileData.fh; -p.RoVersion=fread(fh, 1, 'int32=>int32'); -p.RoMark=fread(fh, 1, 'int32=>int32');% = 4; (* INT32 *) -p.RoVersionName=deblank(fread(fh, 32, 'uint8=>char')');% = 8; (* String32Type *) -p.RoMaxSamples=fread(fh, 1, 'int32=>int32'); % = 40; (* INT32 *) -p.RoFiller1 = fread(fh, 1, 'int32=>int32');% = 44; (* INT32 *) -p.RoParams = fread(fh, 10, 'double=>double');% = 48; (* ARRAY[0..9] OF LONGREAL *) +p.RoVersion = fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) +p.RoMark = fread(fh, 1, 'int32=>int32');% = 4; (* INT32 *) +p.RoVersionName = deblank(fread(fh, 32, 'uint8=>char')');% = 8; (* String32Type *) +p.RoMaxSamples = fread(fh, 1, 'int32=>int32'); % = 40; (* INT32 *) +p.RoFiller1 = fread(fh, 1, 'int32=>int32');% = 44; (* INT32 *) +p.RoParams = fread(fh, 10, 'double=>double');% = 48; (* ARRAY[0..9] OF LONGREAL *) for k=1:10 - p.RoParamText{k}=deblank(fread(fh, 32, 'uint8=>char')');% = 128; (* ARRAY[0..9],[0..31]OF CHAR *) + p.RoParamText{k}=deblank(fread(fh, 32, 'uint8=>char')');% = 128; (* ARRAY[0..9],[0..31]OF CHAR *) end -p.RoReserved = fread(fh, 32, 'int32=>int32');% = 448; (* INT32 *) -p.RoFiller2= fread(fh, 1, 'int32=>int32');% = 576; (* INT32 *) -p.RoCRC= fread(fh, 1, 'int32=>int32');% = 580; (* CARD32 *) -p.RootRecSize= 584; % (* = 73 * 8 *) +p.RoReserved = fread(fh, 32, 'int32=>int32');% = 448; (* INT32 *) +p.RoFiller2 = fread(fh, 1, 'int32=>int32');% = 576; (* INT32 *) +p.RoCRC = fread(fh, 1, 'int32=>int32');% = 580; (* CARD32 *) +p.RootRecSize = 584; % (* = 73 * 8 *) p=orderfields(p); end @@ -61,43 +61,42 @@ function readStimulusFileHEKA(obj,Level) fh = obj.fileData.fh; % Stimulus level -s.stMark=fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) -s.stEntryName=deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Type *) -s.stFileName=deblank(fread(fh, 32, 'uint8=>char')');% = 36; (* String32Type *) -s.stAnalName=deblank(fread(fh, 32, 'uint8=>char')');% = 68; (* String32Type *) -s.stDataStartSegment=fread(fh, 1, 'int32=>int32');% = 100; (* INT32 *) -s.stDataStartTime=fread(fh, 1, 'double=>double') ;% = 104; (* LONGREAL *) -s.stDataStartTimeMATLAB=obj.HI_time2date(s.stDataStartTime); -s.stSampleInterval=fread(fh, 1, 'double=>double') ;% = 112; (* LONGREAL *) -s.stSweepInterval=fread(fh, 1, 'double=>double') ;% = 120; (* LONGREAL *) -s.stLeakDelay=fread(fh, 1, 'double=>double') ;% = 128; (* LONGREAL *) -s.stFilterFactor=fread(fh, 1, 'double=>double') ;% = 136; (* LONGREAL *) -s.stNumberSweeps=fread(fh, 1, 'int32=>int32');% = 144; (* INT32 *) -s.stNumberLeaks=fread(fh, 1, 'int32=>int32');% = 148; (* INT32 *) -s.stNumberAverages=fread(fh, 1, 'int32=>int32');% = 152; (* INT32 *) -s.stActualAdcChannels=fread(fh, 1, 'int32=>int32');% = 156; (* INT32 *) -s.stActualDacChannels=fread(fh, 1, 'int32=>int32');% = 160; (* INT32 *) -s.stExtTrigger=fread(fh, 1, 'uint8=>uint8');% = 164; (* BYTE *) -s.stNoStartWait=fread(fh, 1, 'uint8=>logical');% = 165; (* BOOLEAN *) -s.stUseScanRates=fread(fh, 1, 'uint8=>logical');% = 166; (* BOOLEAN *) -s.stNoContAq=fread(fh, 1, 'uint8=>logical');% = 167; (* BOOLEAN *) -s.stHasLockIn=fread(fh, 1, 'uint8=>logical');% = 168; (* BOOLEAN *) -s.stOldStartMacKind=fread(fh, 1, 'uint8=>char');% = 169; (* CHAR *) -s.stOldEndMacKind=fread(fh, 1, 'uint8=>logical');% = 170; (* BOOLEAN *) -s.stAutoRange=fread(fh, 1, 'uint8=>uint8');% = 171; (* BYTE *) -s.stBreakNext=fread(fh, 1, 'uint8=>logical');% = 172; (* BOOLEAN *) -s.stIsExpanded=fread(fh, 1, 'uint8=>logical');% = 173; (* BOOLEAN *) -s.stLeakCompMode=fread(fh, 1, 'uint8=>logical');% = 174; (* BOOLEAN *) -s.stHasChirp=fread(fh, 1, 'uint8=>logical');% = 175; (* BOOLEAN *) -s.stOldStartMacro=deblank(fread(fh, 32, 'uint8=>char')');% = 176; (* String32Type *) -s.stOldEndMacro=deblank(fread(fh, 32, 'uint8=>char')');% = 208; (* String32Type *) -s.sIsGapFree=fread(fh, 1, 'uint8=>logical');% = 240; (* BOOLEAN *) -s.sHandledExternally=fread(fh, 1, 'uint8=>logical');% = 241; (* BOOLEAN *) -s.stFiller1=fread(fh, 1, 'uint8=>logical');% = 242; (* BOOLEAN *) -s.stFiller2=fread(fh, 1, 'uint8=>logical');% = 243; (* BOOLEAN *) -s.stCRC=fread(fh, 1, 'int32=>int32'); % = 244; (* CARD32 *) -s.stTag=deblank(fread(fh, 32, 'uint8=>char')');% = 248; (* String32Type *) -s.StimulationRecSize = 280;% (* = 35 * 8 *) +s.stMark = fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) +s.stEntryName = deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Type *) +s.stFileName = deblank(fread(fh, 32, 'uint8=>char')');% = 36; (* String32Type *) +s.stAnalName = deblank(fread(fh, 32, 'uint8=>char')');% = 68; (* String32Type *) +s.stDataStartSegment = fread(fh, 1, 'int32=>int32');% = 100; (* INT32 *) +s.stDataStartTime = fread(fh, 1, 'double=>double') ;% = 104; (* LONGREAL *) +s.stDataStartTimeMATLAB = obj.HI_time2date(s.stDataStartTime); +s.stSampleInterval = fread(fh, 1, 'double=>double') ;% = 112; (* LONGREAL *) +s.stSweepInterval = fread(fh, 1, 'double=>double') ;% = 120; (* LONGREAL *) +s.stLeakDelay = fread(fh, 1, 'double=>double') ;% = 128; (* LONGREAL *) +s.stFilterFactor = fread(fh, 1, 'double=>double') ;% = 136; (* LONGREAL *) +s.stNumberSweeps = fread(fh, 1, 'int32=>int32');% = 144; (* INT32 *) +s.stNumberLeaks = fread(fh, 1, 'int32=>int32');% = 148; (* INT32 *) +s.stNumberAverages = fread(fh, 1, 'int32=>int32');% = 152; (* INT32 *) +s.stActualAdcChannels = fread(fh, 1, 'int32=>int32');% = 156; (* INT32 *) +s.stActualDacChannels = fread(fh, 1, 'int32=>int32');% = 160; (* INT32 *) +s.stExtTrigger = fread(fh, 1, 'uint8=>uint8');% = 164; (* BYTE *) +s.stNoStartWait = fread(fh, 1, 'uint8=>logical');% = 165; (* BOOLEAN *) +s.stUseScanRates = fread(fh, 1, 'uint8=>logical');% = 166; (* BOOLEAN *) +s.stNoContAq = fread(fh, 1, 'uint8=>logical');% = 167; (* BOOLEAN *) +s.stHasLockIn = fread(fh, 1, 'uint8=>logical');% = 168; (* BOOLEAN *) +s.stOldStartMacKind = fread(fh, 1, 'uint8=>char');% = 169; (* CHAR *) +s.stOldEndMacKind = fread(fh, 1, 'uint8=>logical');% = 170; (* BOOLEAN *) +s.stAutoRange = fread(fh, 1, 'uint8=>uint8');% = 171; (* BYTE *) +s.stBreakNext = fread(fh, 1, 'uint8=>logical');% = 172; (* BOOLEAN *) +s.stIsExpanded = fread(fh, 1, 'uint8=>logical');% = 173; (* BOOLEAN *) +s.stLeakCompMode = fread(fh, 1, 'uint8=>logical');% = 174; (* BOOLEAN *) +s.stHasChirp = fread(fh, 1, 'uint8=>logical');% = 175; (* BOOLEAN *) +s.stOldStartMacro = deblank(fread(fh, 32, 'uint8=>char')');% = 176; (* String32Type *) +s.stOldEndMacro = deblank(fread(fh, 32, 'uint8=>char')');% = 208; (* String32Type *) +s.sIsGapFree = fread(fh, 1, 'uint8=>logical');% = 240; (* BOOLEAN *) +s.sHandledExternally = fread(fh, 1, 'uint8=>logical');% = 241; (* BOOLEAN *) + s.stFiller1 = fread(fh, 1, 'uint8=>logical');% = 242; (* BOOLEAN *) + s.stFiller2 = fread(fh, 1, 'uint8=>logical');% = 243; (* BOOLEAN *) +s.stCRC = fread(fh, 1, 'int32=>int32'); % = 244; (* CARD32 *) +s.StimulationRecSize = 248;% (* = 35 * 8 *) s=orderfields(s); From 8ec709ea6f188b6fcb39986863b05dbca62d92f6 Mon Sep 17 00:00:00 2001 From: ChristianKeine Date: Mon, 24 Jun 2019 10:40:03 -0500 Subject: [PATCH 26/39] update stim import --- @HEKA_Importer/readPulseFileHEKA.m | 2 +- @HEKA_Importer/readStimulusFileHEKA.m | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/@HEKA_Importer/readPulseFileHEKA.m b/@HEKA_Importer/readPulseFileHEKA.m index 2b7d344..0b5c9ce 100644 --- a/@HEKA_Importer/readPulseFileHEKA.m +++ b/@HEKA_Importer/readPulseFileHEKA.m @@ -178,7 +178,7 @@ function readPulseFileHEKA(obj,Level) sw.SwTime = fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) sw.SwTimeMATLAB = obj.HI_time2date(sw.SwTime);% Also add in MATLAB datenum format sw.SwTimer = fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) -switch obj.fileDate.fileVersion +switch obj.fileData.fileVersion case 9 sw.SwSwUserParams = fread(fh, 4, 'double=>double');% = 64; (* ARRAY[0..3] OF LONGREAL *) case 1000 diff --git a/@HEKA_Importer/readStimulusFileHEKA.m b/@HEKA_Importer/readStimulusFileHEKA.m index 67ddbe3..7e7aab0 100644 --- a/@HEKA_Importer/readStimulusFileHEKA.m +++ b/@HEKA_Importer/readStimulusFileHEKA.m @@ -167,7 +167,7 @@ function readStimulusFileHEKA(obj,Level) c.chTraceMathFormat = fread(fh, 1, 'uint8=>uint8');% = 216; (* BYTE *) c.chHasChirp = fread(fh, 1, 'uint8=>logical');% = 217; (* BOOLEAN *) c.chSquare_Kind = fread(fh, 1, 'uint8=>uint8');% = 218; (* BYTE *) - c.chFiller1 = fread(fh, 6, 'uint8=>char');% = 219; (* ARRAY[0..5] OF CHAR *) + c.chFiller1 = fread(fh, 5, 'uint8=>char');% = 219; (* ARRAY[0..5] OF CHAR *) c.chSquare_BaseIncr = fread(fh, 1, 'double=>double');% = 224; (* LONGREAL *) c.chSquare_Cycle = fread(fh, 1, 'double=>double') ;% = 232; (* LONGREAL *) c.chSquare_PosAmpl = fread(fh, 1, 'double=>double') ;% = 240; (* LONGREAL *) @@ -175,6 +175,7 @@ function readStimulusFileHEKA(obj,Level) c.chPhotoMode = fread(fh, 1, 'int32=>int32');% = 252; (* INT32 *) c.chBreakLevel = fread(fh, 1, 'double=>double') ;% = 256; (* LONGREAL *) c.chTraceMath = deblank(fread(fh,128,'uint8=>char')');% = 264; (* String128Type *) +c.chOldCRC = fread(fh, 1, 'int32=>int32');% = 268; (* CARD32 *) c.chFiller2 = fread(fh, 1, 'int32=>int32');% = 392; (* INT32 *) c.chCRC = fread(fh, 1, 'int32=>int32');% = 396; (* CARD32 *) c.ChannelRecSize = 400;% (* = 50 * 8 *) From 19a1d53bfedbb7dc41f1648ad45c31eb4921de9d Mon Sep 17 00:00:00 2001 From: ChristianKeine Date: Mon, 24 Jun 2019 10:42:10 -0500 Subject: [PATCH 27/39] Update HI_extractHEKADataTree.m --- @HEKA_Importer/HI_extractHEKADataTree.m | 56 ++++++++----------------- 1 file changed, 18 insertions(+), 38 deletions(-) diff --git a/@HEKA_Importer/HI_extractHEKADataTree.m b/@HEKA_Importer/HI_extractHEKADataTree.m index 6c97564..d6b734a 100644 --- a/@HEKA_Importer/HI_extractHEKADataTree.m +++ b/@HEKA_Importer/HI_extractHEKADataTree.m @@ -24,8 +24,6 @@ function HI_extractHEKADataTree(obj) else hasDateTime = false; end - - dataTree = obj.trees.dataTree; @@ -131,7 +129,7 @@ function HI_extractHEKADataTree(obj) nSweeps(iR) = numel(Recs(iR).Sweeps); % replaced from Recs(iR).SeNumbersw due to occasional mismatch between data and metadata nChannels = numel(ChUnit{iR,:}); - + Rs{iR} = cell(1,nChannels); Rs_uncomp{iR} = cell(1,nChannels); RsFractionComp{iR} = cell(1,nChannels); @@ -144,44 +142,26 @@ function HI_extractHEKADataTree(obj) TimeStamp{iR} = cell(1,nChannels); end -% added export for each sweep and channel - -% testing: - - -for iCh = 1:nChannels - for iS = 1:nSweeps(iR) - Rs_uncomp{iR}{1,iCh}(1,iS) = Recs(iR).Sweeps(iS).Traces(iCh).TrGSeries; - Rs{iR}{1,iCh}(1,iS) = Rs_uncomp{iR}{1,iCh}(1,iS) - Recs(iR).Sweeps(iS).Traces(iCh).TrRsValue; - Cm{iR}{1,iCh}(1,iS) = Recs(iR).Sweeps(iS).Traces(iCh).TrCSlow; - Vhold{iR}{1,iCh}(1,iS) = Recs(iR).Sweeps(iS).Traces(iCh).TrTrHolding; - - if iCh == 1 - if hasDateTime - TimeStamp{iR}(iS) = datetime(Recs(iR).Sweeps(iS).SwTimeMATLAB); - else - TimeStamp{iR}{iS} = Recs(iR).Sweeps(iS).SwTimeMATLAB; - end + + for iCh = 1:nChannels + for iS = 1:nSweeps(iR) + Rs_uncomp{iR}{1,iCh}(1,iS) = Recs(iR).Sweeps(iS).Traces(iCh).TrGSeries; + Rs{iR}{1,iCh}(1,iS) = Rs_uncomp{iR}{1,iCh}(1,iS) - Recs(iR).Sweeps(iS).Traces(iCh).TrRsValue; + Cm{iR}{1,iCh}(1,iS) = Recs(iR).Sweeps(iS).Traces(iCh).TrCSlow; + Vhold{iR}{1,iCh}(1,iS) = Recs(iR).Sweeps(iS).Traces(iCh).TrTrHolding; + if iCh == 1 + if hasDateTime + TimeStamp{iR}(iS) = datetime(Recs(iR).Sweeps(iS).SwTimeMATLAB); + else + TimeStamp{iR}{iS} = Recs(iR).Sweeps(iS).SwTimeMATLAB; + end + + end end + RsFractionComp{iR}{1,iCh} = 1-Rs{iR}{1,iCh}./Rs_uncomp{iR}{1,iCh}; end - RsFractionComp{iR}{1,iCh} = 1-Rs{iR}{1,iCh}./Rs_uncomp{iR}{1,iCh}; -end - - -% for iS=1:nSweeps(iR) % replaced from Recs(iR).SeNumbersw due to occasional mismatch -% Rs_uncomp{iR}{1:nChannels} = 1./[Recs(iR).Sweeps(iS).Traces(:).TrGSeries]; -% Rs{iR}{1,iS} = Rs_uncomp{iR}{1,iS} - [Recs(iR).Sweeps(iS).Traces(:).TrRsValue]; -% Cm{iR}{1,iS} = [Recs(iR).Sweeps(iS).Traces(:).TrCSlow]; -% Vhold{iR}{1,iS} = [Recs(iR).Sweeps(iS).Traces(:).TrTrHolding]; -% RsFractionComp{iR}{1,iS} = 1-Rs{iR}{1,iS}./Rs_uncomp{iR}{1,iS}; -% -% if hasDateTime -% TimeStamp{iR}(iS) = datetime(Recs(iR).Sweeps(iS).SwTimeMATLAB); -% else -% TimeStamp{iR}{iS} = Recs(iR).Sweeps(iS).SwTimeMATLAB; -% end -% end + end From 1dad58ea374630352deace799bdcfa0cad1364f1 Mon Sep 17 00:00:00 2001 From: ChristianKeine Date: Mon, 24 Jun 2019 10:51:55 -0500 Subject: [PATCH 28/39] update --- @HEKA_Importer/HI_ImportHEKAtoMat.m | 38 +++--- @HEKA_Importer/old/HI_SplitSeries.m | 198 ---------------------------- 2 files changed, 18 insertions(+), 218 deletions(-) delete mode 100644 @HEKA_Importer/old/HI_SplitSeries.m diff --git a/@HEKA_Importer/HI_ImportHEKAtoMat.m b/@HEKA_Importer/HI_ImportHEKAtoMat.m index 3aca0fb..e9d809a 100644 --- a/@HEKA_Importer/HI_ImportHEKAtoMat.m +++ b/@HEKA_Importer/HI_ImportHEKAtoMat.m @@ -208,7 +208,7 @@ switch obj.fileData.fileExt case '.pul' - obj.readPulseFileHEKA(Level); + obj.import.readPulseFileHEKA(Level); case '.pgf' obj.readStimulusFileHEKA(Level); case '.sol' @@ -239,7 +239,7 @@ % Collect the series headers and row numbers for this group into a % structure array -[ser_s, ser_row, nseries]=getSeriesHeaders(dataTree, grp_row, grp); +[ser_row, nseries]=getSeriesHeaders(dataTree, grp_row, grp); % Pad for last series ser_row(nseries+1)=grp_row(grp+1); @@ -308,8 +308,7 @@ end end end - - + % Now scale the data to real world units % Note we also apply zero adjustment for col=1:size(data,2) @@ -323,7 +322,6 @@ end - if numel(unique(dataoffsets)) +% ser_s(nseries+1)=tree{k, 3}; %#ok ser_row(nseries+1)=k; %#ok nseries=nseries+1; end diff --git a/@HEKA_Importer/old/HI_SplitSeries.m b/@HEKA_Importer/old/HI_SplitSeries.m deleted file mode 100644 index 05af13b..0000000 --- a/@HEKA_Importer/old/HI_SplitSeries.m +++ /dev/null @@ -1,198 +0,0 @@ -function obj = HI_SplitSeries(obj,data,varargin) - -% HI_SplitSeries.m -% This function takes the collapsed data set (dCollapse) and splits it by -% group and series, assigning these as fields into the struct. -% -% EXAMPLE: -% [structA] = SplitSeries(tree, data, saveName, structA) -% [structA] = SplitSeries(tree, data, saveName, structA, stimTree) -% -% INPUTS: -% tree struct The metadata tree, from importing a HEKA -% Patchmaster .dat file. -% -% data cell A 1xm cell containing all series and traces -% from all channels, as output by -% ImportHEKAtoMat() and collapsed by -% ImportPatchData(). -% -% saveName char The name of the file from which the data -% was imported, the date by default. -% -% structA struct The output data structure to which new -% fields will be appended. May be empty. -% -% OPTIONAL INPUTS: -% stimTree cell The stimulus metadata tree, from importing -% a .dat file. -% -% OUTPUTS: -% structA struct Output data structure in same format, with -% newly appended fields representing groups. -% Each group is a struct, containing the -% original filename, the list of pgfs, and -% the data in a cell of dimensions (series, -% channel) for that group. -% -% Created by Sammy Katta on 27 May 2014. -% Modified by Christian Keine 01/2019. - -P = inputParser; -P.addRequired('data'); - -P.parse(data,varargin{:}); - -stimTree = obj.trees.stimTree; -dataTree = obj.trees.dataTree; - -% Find which rows in tree contain group, series, and sweep metadata -grLoc = find(~cellfun('isempty',dataTree(:,2))); -seLoc = find(~cellfun('isempty',dataTree(:,3))); - -if ~isempty(stimTree) - stLoc = find(~cellfun('isempty',stimTree(:,2))); - - % The number of entries with stimulus parameters should match the total - % number of series. - if length(seLoc) ~= length(stLoc) - fprintf('%s stimulus data does not match total number of series\n', saveName) - return - end -end - -% Figure out how many series are in each group/biological cell by pulling -% the SeSeriesCount field for the last series in the group, and initialize -% a cell array of that length to hold data from that group -serTot = 1; -% traceTot = 1; -dataRaw = cell(size(grLoc)); -SR = cell(size(grLoc)); -chNames = cell(size(grLoc)); - -for iGr = 1:length(grLoc) - % Strip hyphens/other characters that are invalid in field names - currGr = matlab.lang.makeValidName(dataTree{grLoc(iGr),2}.GrLabel); - - % Find number of series in each group but don't get tripped up by the - % last group. - if iGr size(dataTree,1) ||... - isempty(dataTree{seLoc(serTot)+2+nChan,5}) - isTrace = 0; - else - nChan = nChan + 1; - chanType{nChan} = matlab.lang.makeValidName(dataTree{seLoc(serTot)+1+nChan,5}.TrLabel); - chanUnit{nChan} = dataTree{seLoc(serTot)+1+nChan,5}.TrYUnit; - end - end - - % Assign data to proper location in cell array for that group. - % If there are multiple channels/traces per sweep for a given - % series, Patchmaster stores them as separate series, one after - % another, i.e., if the real series 5 recorded both current and - % voltage, data(5) will contain the current and data(6) will - % contain the voltage. - - % STRIP DOWN TO ACTUAL NUMBER OF CHANNELS AND REMOVE EMPTY CELLS - % FOR RESHAPING LATER - - chanType = chanType(1:nChan,:); - chanUnit = chanUnit(1:nChan,:); - - - % GET CHANNEL TYPE/NAME AND UNITS - grpType{iSer} = reshape(chanType,1,nChan); - grpUnit{iSer} = reshape(chanUnit,1,nChan); - - if ~isempty(stimTree) - % Pull out the relevant section of the stimTree for the series at - % hand. nChan may not be the same for stimTree if you have channels - % with DA output but no *stored* AD input (i.e., more channels in - % stimTree than in dataTree). - try - stLocEnd = stLoc(serTot+1)-1; - catch - stLocEnd = size(stimTree,1); - end - - grpStim{iSer} = stimTree(stLoc(serTot):stLocEnd,2:4); - - end - - % Move on to the next round - serTot = serTot+1; - end - - % Save data to the appropriate group in the nested output struct. - ephysData.(currGr).data = data{iGr}; - ephysData.(currGr).protocols = grpProt; - ephysData.(currGr).channel = grpType; - ephysData.(currGr).dataunit = grpUnit; - ephysData.(currGr).samplingFreq = grpFs; - ephysData.(currGr).startTimes = grpTimes; - ephysData.(currGr).ccHold = grpHolds; - - if ~isempty(stimTree) - ephysData.(currGr).stimTree = grpStim; - end - - %% ADD MINIMUM RANDOM NUMBER TO AVOID DISCRETIZATION; ADD TO ALL CHANNELS - addEPS = @(x) x+randn(size(x))*eps; - - - for iSer=1:nSer - ephysData.(currGr).data{iSer} = cellfun(addEPS,ephysData.(currGr).data{iSer},'UniformOutput',false); - end - - dataRaw{iGr,:} = ephysData.(currGr).data; - SR{iGr,:} = reshape([ephysData.(currGr).samplingFreq{:}], numel([ephysData.(currGr).samplingFreq{:}]),1); - chNames{iGr,:} = grpType; - -end - -obj.RecTable.dataRaw = vertcat(dataRaw{:}); -obj.RecTable.SR = vertcat(SR{:}); -obj.RecTable.chNames = vertcat(chNames{:}); -obj.RecTable = struct2table(obj.RecTable); - -end From 0b51060470fa85f1e569baec8aad6a727462e3a4 Mon Sep 17 00:00:00 2001 From: ChristianKeine Date: Mon, 24 Jun 2019 10:57:59 -0500 Subject: [PATCH 29/39] update import --- @HEKA_Importer/HI_ImportHEKAtoMat.m | 2 +- @HEKA_Importer/readSolutionFileHEKA.m | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/@HEKA_Importer/HI_ImportHEKAtoMat.m b/@HEKA_Importer/HI_ImportHEKAtoMat.m index e9d809a..221e14f 100644 --- a/@HEKA_Importer/HI_ImportHEKAtoMat.m +++ b/@HEKA_Importer/HI_ImportHEKAtoMat.m @@ -208,7 +208,7 @@ switch obj.fileData.fileExt case '.pul' - obj.import.readPulseFileHEKA(Level); + obj.readPulseFileHEKA(Level); case '.pgf' obj.readStimulusFileHEKA(Level); case '.sol' diff --git a/@HEKA_Importer/readSolutionFileHEKA.m b/@HEKA_Importer/readSolutionFileHEKA.m index 547a737..33c890f 100644 --- a/@HEKA_Importer/readSolutionFileHEKA.m +++ b/@HEKA_Importer/readSolutionFileHEKA.m @@ -1,7 +1,7 @@ function readSolutionFileHEKA(obj,Level) %-------------------------------------------------------------------------- % Gets one record of the tree and the number of children -s = getOneSolutionRecord(obj); +s = getOneSolutionRecord(obj,Level); obj.fileData.Tree{obj.fileData.Counter, Level+1} = s; obj.fileData.Position = obj.fileData.Position+obj.fileData.Sizes(Level+1); From 3e5d0304685187052285c75eae301ea8f4e4fab4 Mon Sep 17 00:00:00 2001 From: ChristianKeine Date: Mon, 24 Jun 2019 12:53:02 -0500 Subject: [PATCH 30/39] ... --- @HEKA_Importer/readPulseFileHEKA.asv | 460 ------------------------ @HEKA_Importer/readStimulusFileHEKA.asv | 210 ----------- 2 files changed, 670 deletions(-) delete mode 100644 @HEKA_Importer/readPulseFileHEKA.asv delete mode 100644 @HEKA_Importer/readStimulusFileHEKA.asv diff --git a/@HEKA_Importer/readPulseFileHEKA.asv b/@HEKA_Importer/readPulseFileHEKA.asv deleted file mode 100644 index 379e27e..0000000 --- a/@HEKA_Importer/readPulseFileHEKA.asv +++ /dev/null @@ -1,460 +0,0 @@ -function readPulseFileHEKA(obj,Level) -%-------------------------------------------------------------------------- -% Gets one record of the tree and the number of children - - - -s = getOneRecord(obj,Level); -obj.fileData.Tree{obj.fileData.Counter, Level+1} = s; - -obj.fileData.Position = obj.fileData.Position+obj.fileData.Sizes(Level+1); -fseek(obj.fileData.fh, obj.fileData.Position, 'bof'); -obj.fileData.nchild=fread(obj.fileData.fh, 1, 'int32=>int32'); -obj.fileData.Position=ftell(obj.fileData.fh); - -end - -%-------------------------------------------------------------------------- -function rec=getOneRecord(obj,Level) -%-------------------------------------------------------------------------- -% Gets one record -% Counter=Counter+1; -obj.fileData.Counter = obj.fileData.Counter+1; - -switch Level - case 0 - rec=getRoot(obj); - case 1 - rec=getGroup(obj); - case 2 - rec=getSeries(obj); - case 3 - rec=getSweep(obj); - case 4 - rec=getTrace(obj); - otherwise - error('Unexpected Level'); -end -end - -% The functions below return data as defined by the HEKA PatchMaster -% specification - -%-------------------------------------------------------------------------- -function p=getRoot(obj) -%-------------------------------------------------------------------------- -fh = obj.fileData.fh; - -p.RoVersion = fread(fh, 1, 'int32=>int32');% = 4; (* INT32 *) -p.RoMark = fread(fh, 1, 'int32=>int32');% = 4; (* INT32 *) -p.RoVersionName = deblank(fread(fh, 32, 'uint8=>char')');% = 8; (* String32Type *) -p.RoAuxFileName = deblank(fread(fh, 80, 'uint8=>char')');% = 40; (* String80Type *) -p.RoRootText = deblank(fread(fh, 400, 'uint8=>char')');% (* String400Type *) -p.RoStartTime = fread(fh, 1, 'double=>double') ;% = 520; (* LONGREAL *) -p.RoStartTimeMATLAB = obj.HI_time2date(p.RoStartTime); -p.RoMaxSamples = fread(fh, 1, 'int32=>int32'); % = 528; (* INT32 *) -p.RoCRC = fread(fh, 1, 'int32=>int32'); % = 532; (* CARD32 *) -p.RoFeatures = fread(fh, 1, 'int16=>int16'); % = 536; (* SET16 *) -p.RoFiller1 = fread(fh, 1, 'int16=>int16');% = 538; (* INT16 *) -p.RoFiller2 = fread(fh, 1, 'int32=>int32');% = 540; (* INT32 *) -p.RoTcEnumerator = fread(fh,32,'int16=>int16');% = 544; (* ARRAY[0..Max_TcKind_M1] OF INT16 *) -p.RoTcKind = fread(fh,32,'int8=>int8');% = 608; (* ARRAY[0..Max_TcKind_M1] OF INT8 *) -p.RootRecSize = 640;% (* = 80 * 8 *); -p=orderfields(p); - -obj.fileData.fileVersion = p.RoVersion; -end - -%-------------------------------------------------------------------------- -function g=getGroup(obj) -%-------------------------------------------------------------------------- -% Group -fh = obj.fileData.fh; - -g.GrMark = fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) -g.GrLabel = deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Size *) -g.GrText = deblank(fread(fh, 80, 'uint8=>char')');% = 36; (* String80Size *) -g.GrExperimentNumber = fread(fh, 1, 'int32=>int32');% = 116; (* INT32 *) -g.GrGroupCount = fread(fh, 1, 'int32=>int32');% = 120; (* INT32 *) -g.GrCRC = fread(fh, 1, 'int32=>int32');% = 124; (* CARD32 *) -g.GrMatrixWidth = fread(fh,1,'double=>double');% = 128; (* LONGREAL *) -g.GrMatrixHeight = fread(fh,1,'double=>double');% = 136; (* LONGREAL *) -g.GroupRecSize = 144; % (* = 18 * 8 *) - -g=orderfields(g); - -end - -%-------------------------------------------------------------------------- -function s=getSeries(obj) -%-------------------------------------------------------------------------- -fh = obj.fileData.fh; - -s.SeMark = fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) -s.SeLabel = deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Type *) -s.SeComment = deblank(fread(fh, 80, 'uint8=>char')');% = 36; (* String80Type *) -s.SeSeriesCount = fread(fh, 1, 'int32=>int32');% = 116; (* INT32 *) -s.SeNumbersw = fread(fh, 1, 'int32=>int32');% = 120; (* INT32 *) -switch obj.fileData.fileVersion - case 9 - s.SeAmplStateOffset = fread(fh, 1, 'int32=>int32');% = 124; (* INT32 * - s.SeAmplStateSeries = fread(fh, 1, 'int32=>int32');% = 128; (* INT32 * - case 1000 - s.SeAmplStateFlag = fread(fh,1,'int32=>int32');% = 124; (* INT32 *) // flag > 0 => load local oldAmpState, otherwise load from .amp File. - s.SeAmplStateRef = fread(fh,1,'int32=>int32'); % = 128; (* INT32 *) // ref = 0 => use local oldAmpState -end - -%% -s.SeMethodTag = fread(fh,1,'int32=>int32'); % = 132; (* INT32 *) -s.SeTime = fread(fh,1,'double=>double'); % = 136; (* LONGREAL *) -s.SeTimeMATLAB = obj.HI_time2date(s.SeTime); -s.SePageWidth = fread(fh, 1, 'double=>double') ;% = 144; (* LONGREAL *) - -switch obj.fileData.fileVersion - case 9 - for k=1:4 % = 152; (* ARRAY[0..1] OF UserParamDescrType = 4*40 *) - s.SeSwUserParamDescr(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% - s.SeSwUserParamDescr(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% - end - case 1000 - for k=1:2 % = 152; (* ARRAY[0..1] OF UserParamDescrType = 4*40 *) - s.SeUserDescr1(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% - s.SeUserDescr1(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% - end - s.SeFiller1 = deblank(fread(fh,80,'uint8=>char')'); % = 232; (* ARRAY[0..1] OF UserParamDescrType = 2*40 *) -end - -s.SeMethodName = deblank(fread(fh,32,'uint8=>char')');% = 312; (* String32Type *) - -switch obj.fileData.fileVersion - case 9 - s.SeSeUserParams1 = fread(fh ,4 ,'double=>double');% = 344; (* ARRAY[0..3] OF LONGREAL *) - s.SeLockInParams = getSeLockInParams(fh);% = 376; (* SeLockInSize = 96, see "Pulsed.de" *) - s.SeAmplifierState = getAmplifierState(fh);% = 472; (* AmplifierStateSize = 400 *) - case 1000 - s.SePhotoParams1 = fread(fh, 4, 'double=>double'); % = 344; (* ARRAY[0..3] OF LONGREAL = 4*8 *) - s.SeOldLockInParams = getSeLockInParams(fh);% = 376; (* SeOldLockInSize = 96, see "Pulsed.de" *) - s.SeOldAmpState = getAmplifierState(fh);% = 472; (* SeOldAmpState = 400 -> the AmplStateRecord is now stored in the .amp file *) -end - -s.SeUsername = deblank(fread(fh, 80, 'uint8=>char')');% = 872; (* String80Type *) -switch obj.fileData.fileVersion - case 9 - for k=1:4% = 952; (* ARRAY[0..3] OF UserParamDescrType = 4*40 *) - s.SeSeUserParamDescr1(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% - s.SeSeUserParamDescr1(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% - end - case 1000 - for k=1:4% = 952; (* ARRAY[0..3] OF UserParamDescrType = 4*40 *) - s.SePhotoParams2(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% - s.SePhotoParams2(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% - end -end - -s.SeFiller1 = fread(fh, 1, 'int32=>int32');% = 1112; (* INT32 *) -s.SeCRC = fread(fh, 1, 'int32=>int32');% = 1116; (* CARD32 *) -s.SeSeUserParams2 = fread(fh, 4, 'double=>double');% = 1120; (* ARRAY[0..3] OF LONGREAL *) -for k=1:4 % = 1152; (* ARRAY[0..3] OF UserParamDescrType = 4*40 *) - s.SeSeUserParamDescr2(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% - s.SeSeUserParamDescr2(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% -end - -s.SeScanParams = fread(fh, 96, 'uint8=>uint8');% = 1312; (* ScanParamsSize = 96 (ElProScan Extension) *) - -switch obj.fileData.fileVersion - case 9 - s.SeriesRecSize = 1408;% = 1408; (* = 176 * 8 *) - case 1000 - for k=1:8 % = 1408; (* ARRAY[0..7] OF UserParamDescrType = 8*40 *) - s.SeSeUserDescr2(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% - s.SeSeUserDescr2(k).Unit=deblank(fread(fh, 8, 'uint8=>char')'); - end - s.SeriesRecSize = 1728;% = 1728; -end - -s=orderfields(s); -s.Sweeps = []; % used to store all the sweeps within the recording structure later on - -end - -%-------------------------------------------------------------------------- -function sw=getSweep(obj) -%-------------------------------------------------------------------------- - -fh = obj.fileData.fh; - -sw.SwMark = fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) -sw.SwLabel = deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Type *) -sw.SwAuxDataFileOffset = fread(fh, 1, 'int32=>int32');% = 36; (* INT32 *) -sw.SwStimCount = fread(fh, 1, 'int32=>int32');% = 40; (* INT32 *) -sw.SwSweepCount = fread(fh, 1, 'int32=>int32');% = 44; (* INT32 *) -sw.SwTime = fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) -sw.SwTimeMATLAB = obj.HI_time2date(sw.SwTime);% Also add in MATLAB datenum format -sw.SwTimer = fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) - -switch obj.fileDate.fileVersion - case 9 - sw.SwSwUserParams = fread(fh, 4, 'double=>double');% = 64; (* ARRAY[0..3] OF LONGREAL *) - case 1000 - sw.SwSwUserParams = fread(fh, 2, 'double=>double');% = 64; (* ARRAY[0..1] OF LONGREAL *) - sw.SwPipPressure = fread(fh, 2, 'double=>double');% = 80; (* LONGREAL * - sw.SwRMSNoise = fread(fh,2,'double=>double'); % = 88; (* LONGREAL *) -end - -sw.SwSwUserParams = fread(fh, 2, 'double=>double');% = 64; (* ARRAY[0..1] OF LONGREAL *) -sw.SwTemperature = fread(fh, 1, 'double=>double');% = 96; (* LONGREAL *) -sw.SwOldIntSol = fread(fh, 1, 'int32=>int32');% = 104; (* INT32 *) -sw.SwOldExtSol = fread(fh, 1, 'int32=>int32');% = 108; (* INT32 *) -sw.SwDigitalIn = fread(fh, 1, 'int16=>int16');% = 112; (* SET16 *) -sw.SwSweepKind = fread(fh, 1, 'int16=>int16');% = 114; (* SET16 *) -sw.SwDigitalOut = fread(fh,1, 'int16=>int16');% = 116; (* SET16 *) -sw.SwFiller1 = fread(fh, 1, 'int16=>int16');% = 118; (* INT32 *) -sw.SwMarkers = fread(fh, 4, 'double=>double');% = 120; (* ARRAY[0..3] OF LONGREAL, see SwMarkersNo *) -sw.SwFiller2 = fread(fh, 1, 'int32=>int32');% = 152; (* INT32 *) -sw.SwCRC = fread(fh, 1, 'int32=>int32');% = 156; (* CARD32 *) -sw.SwSwHolding = fread(fh,16,'double=>double');% = 160; (* ARRAY[0..15] OF LONGREAL, see SwHoldingNo *) - -switch obj.fileData.fileVersion - case 9 - sw.SweepRecSize = 288;% = 288; (* = 36 * 8 *) - case 1000 - sw.SwSwUserParamEx = fread(fh,8,'double=>double'); % = 288; (* ARRAY[0..7] OF LONGREAL *) - sw.SweepRecSize = 352;% = 352; -end - -sw=orderfields(sw); -sw.Traces = []; % used to store all the traces/channels within the sweep structure later on -end - -%-------------------------------------------------------------------------- -function tr=getTrace(obj) -%-------------------------------------------------------------------------- -fh = obj.fileData.fh; - -tr.TrMark = fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) -tr.TrLabel = deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Type *) -tr.TrTraceCount = fread(fh, 1, 'int32=>int32');% = 36; (* INT32 *) -tr.TrData = fread(fh, 1, 'int32=>int32');% = 40; (* INT32 *) -tr.TrDataPoints = fread(fh, 1, 'int32=>int32');% = 44; (* INT32 *) -tr.TrInternalSolution = fread(fh, 1, 'int32=>int32');% = 48; (* INT32 *) -tr.TrAverageCount = fread(fh, 1, 'int32=>int32');% = 52; (* INT32 *) -tr.TrLeakCount = fread(fh, 1, 'int32=>int32');% = 56; (* INT32 *) -tr.TrLeakTraces = fread(fh, 1, 'int32=>int32');% = 60; (* INT32 *) -tr.TrDataKind = fread(fh, 1, 'uint16=>uint16');% = 64; (* SET16 *) NB Stored unsigned -tr.TrFiller1 = fread(fh, 1, 'int16=>int16');% = 66; (* SET16 *) -tr.TrRecordingMode = fread(fh, 1, 'uint8=>uint8');% = 68; (* BYTE *) -tr.TrAmplIndex = fread(fh, 1, 'uint8=>uint8');% = 69; (* CHAR *) -tr.TrDataFormat = fread(fh, 1, 'uint8=>uint8');% = 70; (* BYTE *) -tr.TrDataAbscissa = fread(fh, 1, 'uint8=>uint8');% = 71; (* BYTE *) -tr.TrDataScaler = fread(fh, 1, 'double=>double');% = 72; (* LONGREAL *) -tr.TrTimeOffset = fread(fh, 1, 'double=>double');% = 80; (* LONGREAL *) -tr.TrZeroData = fread(fh, 1, 'double=>double');% = 88; (* LONGREAL *) -tr.TrYUnit = deblank(fread(fh, 8, 'uint8=>char')');% = 96; (* String8Type *) -tr.TrXInterval = fread(fh, 1, 'double=>double');% = 104; (* LONGREAL *) -tr.TrXStart = fread(fh, 1, 'double=>double');% = 112; (* LONGREAL *) -% 17.04.10 TrXUnit bytes may include some trailing characters after NULL -% byte -tr.TrXUnit = deblank(fread(fh, 8, 'uint8=>char')');% = 120; (* String8Type *) -tr.TrYRange = fread(fh, 1, 'double=>double');% = 128; (* LONGREAL *) -tr.TrYOffset = fread(fh, 1, 'double=>double');% = 136; (* LONGREAL *) -tr.TrBandwidth = fread(fh, 1, 'double=>double');% = 144; (* LONGREAL *) -tr.TrPipetteResistance = fread(fh, 1, 'double=>double');% = 152; (* LONGREAL *) -tr.TrCellPotential = fread(fh, 1, 'double=>double');% = 160; (* LONGREAL *) -tr.TrSealResistance = fread(fh, 1, 'double=>double');% = 168; (* LONGREAL *) -tr.TrCSlow = fread(fh, 1, 'double=>double');% = 176; (* LONGREAL *) -tr.TrGSeries = fread(fh, 1, 'double=>double');% = 184; (* LONGREAL *) -tr.TrRsValue = fread(fh, 1, 'double=>double');% = 192; (* LONGREAL *) -tr.TrGLeak = fread(fh, 1, 'double=>double');% = 200; (* LONGREAL *) -tr.TrMConductance = fread(fh, 1, 'double=>double');% = 208; (* LONGREAL *) -tr.TrLinkDAChannel = fread(fh, 1, 'int32=>int32');% = 216; (* INT32 *) -tr.TrValidYrange = fread(fh, 1, 'uint8=>logical');% = 220; (* BOOLEAN *) -tr.TrAdcMode = fread(fh, 1, 'uint8=>uint8');% = 221; (* CHAR *) -tr.TrAdcChannel = fread(fh, 1, 'int16=>int16');% = 222; (* INT16 *) -tr.TrYmin = fread(fh, 1, 'double=>double');% = 224; (* LONGREAL *) -tr.TrYmax = fread(fh, 1, 'double=>double');% = 232; (* LONGREAL *) -tr.TrSourceChannel = fread(fh, 1, 'int32=>int32');% = 240; (* INT32 *) -tr.TrExternalSolution = fread(fh, 1, 'int32=>int32');% = 244; (* INT32 *) -tr.TrCM = fread(fh, 1, 'double=>double');% = 248; (* LONGREAL *) -tr.TrGM = fread(fh, 1, 'double=>double');% = 256; (* LONGREAL *) -tr.TrPhase = fread(fh, 1, 'double=>double');% = 264; (* LONGREAL *) -tr.TrDataCRC = fread(fh, 1, 'int32=>int32');% = 272; (* CARD32 *) -tr.TrCRC = fread(fh, 1, 'int32=>int32');% = 276; (* CARD32 *) -tr.TrGS = fread(fh, 1, 'double=>double');% = 280; (* LONGREAL *) -tr.TrSelfChannel = fread(fh, 1, 'int32=>int32');% = 288; (* INT32 *) - -tr.TrInterleaveSize = fread(fh, 1, 'int32=>int32');% = 292; (* INT32 *) -tr.TrInterleaveSkip = fread(fh, 1, 'int32=>int32');% = 296; (* INT32 *) -tr.TrImageIndex = fread(fh, 1, 'int32=>int32');% = 300; (* INT32 *) -tr.TrMarkers = fread(fh, 10, 'double=>double');% = 304; (* ARRAY[0..9] OF LONGREAL *) -tr.TrSECM_X = fread(fh, 1, 'double=>double');% = 384; (* LONGREAL *) -tr.TrSECM_Y = fread(fh, 1, 'double=>double');% = 392; (* LONGREAL *) -tr.TrSECM_Z = fread(fh, 1, 'double=>double');% = 400; (* LONGREAL *) -tr.TrTrHolding = fread(fh, 1, 'double=>double');% = 408; (* LONGREAL *) -tr.TrTcEnumerator = fread(fh, 1, 'int32=>int32');% = 416; (* INT32 *) -tr.TrXTrace = fread(fh, 1, 'int32=>int32');% = 420; (* INT32 *) -tr.TrIntSolValue = fread(fh, 1, 'double=>double');% = 424; (* LONGREAL *) -tr.TrExtSolValue = fread(fh, 1, 'double=>double');% = 432; (* LONGREAL *) -tr.TrIntSolName = deblank(fread(fh, 32, 'uint8=>char')');% = 440; (* String32Size *) -tr.TrExtSolName = deblank(fread(fh, 32, 'uint8=>char')');% = 472; (* String32Size *) -tr.TrDataPedestal = fread(fh, 1, 'double=>double');% = 504; (* LONGREAL *) - -tr.TraceRecSize=512;% (* = 64 * 8 *) - -tr=orderfields(tr); - -end - -function L=getSeLockInParams(fh) -%-------------------------------------------------------------------------- -offset=ftell(fh); -L.loExtCalPhase = fread(fh, 1, 'double=>double');% = 0; (* LONGREAL *) -L.loExtCalAtten = fread(fh, 1, 'double=>double');% = 8; (* LONGREAL *) -L.loPLPhase = fread(fh, 1, 'double=>double');% = 16; (* LONGREAL *) -L.loPLPhaseY1 = fread(fh, 1, 'double=>double');% = 24; (* LONGREAL *) -L.loPLPhaseY2 = fread(fh, 1, 'double=>double');% = 32; (* LONGREAL *) -L.loUsedPhaseShift = fread(fh, 1, 'double=>double');% = 40; (* LONGREAL *) -L.loUsedAttenuation = fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) - L.loSpare = fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) -L.loExtCalValid = fread(fh, 1, 'uint8=>logical');% = 64; (* BOOLEAN *) -L.loPLPhaseValid = fread(fh, 1, 'uint8=>logical');% = 65; (* BOOLEAN *) -L.loLockInMode = fread(fh, 1, 'uint8=>uint8');% = 66; (* BYTE *) -L.loCalMode = fread(fh, 1, 'uint8=>uint8');% = 67; (* BYTE *) - L.loSpare2 = fread(fh, 7, 'int32=>in32');% = 68; (* remaining *) -L.LockInParamsSize = 96; - -fseek(fh, offset+L.LockInParamsSize, 'bof'); - -end - -%-------------------------------------------------------------------------- -function A=getAmplifierState(fh) -%-------------------------------------------------------------------------- -offset=ftell(fh); -A.sStateVersion = fread(fh, 1, 'double=>double');% = 0; (* 8 = SizeStateVersion *) -A.sCurrentGain = fread(fh, 1, 'double=>double');% = 8; (* LONGREAL *) -A.sF2Bandwidth = fread(fh, 1, 'double=>double');% = 16; (* LONGREAL *) -A.sF2Frequency = fread(fh, 1, 'double=>double');% = 24; (* LONGREAL *) -A.sRsValue = fread(fh, 1, 'double=>double');% = 32; (* LONGREAL *) -A.sRsFraction = fread(fh, 1, 'double=>double');% = 40; (* LONGREAL *) -A.sGLeak = fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) -A.sCFastAmp1 = fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) -A.sCFastAmp2 = fread(fh, 1, 'double=>double');% = 64; (* LONGREAL *) -A.sCFastTau = fread(fh, 1, 'double=>double');% = 72; (* LONGREAL *) -A.sCSlow = fread(fh, 1, 'double=>double');% = 80; (* LONGREAL *) -A.sGSeries = fread(fh, 1, 'double=>double');% = 88; (* LONGREAL *) -A.sVCStimDacScale = fread(fh, 1, 'double=>double');% = 96; (* LONGREAL *) -A.sCCStimScale = fread(fh, 1, 'double=>double');% = 104; (* LONGREAL *) -A.sVHold = fread(fh, 1, 'double=>double');% = 112; (* LONGREAL *) -A.sLastVHold = fread(fh, 1, 'double=>double');% = 120; (* LONGREAL *) -A.sVpOffset = fread(fh, 1, 'double=>double');% = 128; (* LONGREAL *) -A.sVLiquidJunction = fread(fh, 1, 'double=>double');% = 136; (* LONGREAL *) -A.sCCIHold = fread(fh, 1, 'double=>double');% = 144; (* LONGREAL *) -A.sCSlowStimVolts = fread(fh, 1, 'double=>double');% = 152; (* LONGREAL *) -A.sCCTrackVHold = fread(fh, 1, 'double=>double');% = 160; (* LONGREAL *) -A.sTimeoutCSlow = fread(fh, 1, 'double=>double');% = 168; (* LONGREAL *) -A.sSearchDelay = fread(fh, 1, 'double=>double');% = 176; (* LONGREAL *) -A.sMConductance = fread(fh, 1, 'double=>double');% = 184; (* LONGREAL *) -A.sMCapacitance = fread(fh, 1, 'double=>double');% = 192; (* LONGREAL *) -A.sSerialNumber = fread(fh, 1, 'double=>double');% = 200; (* 8 = SizeSerialNumber *) - -A.sE9Boards = fread(fh, 1, 'int16=>int16');% = 208; (* INT16 *) -A.sCSlowCycles = fread(fh, 1, 'int16=>int16');% = 210; (* INT16 *) -A.sIMonAdc = fread(fh, 1, 'int16=>int16');% = 212; (* INT16 *) -A.sVMonAdc = fread(fh, 1, 'int16=>int16');% = 214; (* INT16 *) - -A.sMuxAdc = fread(fh, 1, 'int16=>int16');% = 216; (* INT16 *) -A.sTestDac = fread(fh, 1, 'int16=>int16');% = 218; (* INT16 *) -A.sStimDac = fread(fh, 1, 'int16=>int16');% = 220; (* INT16 *) -A.sStimDacOffset = fread(fh, 1, 'int16=>int16');% = 222; (* INT16 *) - -A.sMaxDigitalBit = fread(fh, 1, 'int16=>int16');% = 224; (* INT16 *) -A.sHasCFastHigh = fread(fh, 1, 'uint8=>uint8');% = 226; (* BYTE *) -A.sCFastHigh = fread(fh, 1, 'uint8=>uint8');% = 227; (* BYTE *) -A.sHasBathSense = fread(fh, 1, 'uint8=>uint8');% = 228; (* BYTE *) -A.sBathSense = fread(fh, 1, 'uint8=>uint8');% = 229; (* BYTE *) -A.sHasF2Bypass = fread(fh, 1, 'uint8=>uint8');% = 230; (* BYTE *) -A.sF2Mode = fread(fh, 1, 'uint8=>uint8');% = 231; (* BYTE *) - -A.sAmplKind = fread(fh, 1, 'uint8=>uint8');% = 232; (* BYTE *) -A.sIsEpc9N = fread(fh, 1, 'uint8=>uint8');% = 233; (* BYTE *) -A.sADBoard = fread(fh, 1, 'uint8=>uint8');% = 234; (* BYTE *) -A.sBoardVersion = fread(fh, 1, 'uint8=>uint8');% = 235; (* BYTE *) -A.sActiveE9Board = fread(fh, 1, 'uint8=>uint8');% = 236; (* BYTE *) -A.sMode = fread(fh, 1, 'uint8=>uint8');% = 237; (* BYTE *) -A.sRange = fread(fh, 1, 'uint8=>uint8');% = 238; (* BYTE *) -A.sF2Response = fread(fh, 1, 'uint8=>uint8');% = 239; (* BYTE *) - -A.sRsOn = fread(fh, 1, 'uint8=>uint8');% = 240; (* BYTE *) -A.sCSlowRange = fread(fh, 1, 'uint8=>uint8');% = 241; (* BYTE *) -A.sCCRange = fread(fh, 1, 'uint8=>uint8');% = 242; (* BYTE *) -A.sCCGain = fread(fh, 1, 'uint8=>uint8');% = 243; (* BYTE *) -A.sCSlowToTestDac = fread(fh, 1, 'uint8=>uint8');% = 244; (* BYTE *) -A.sStimPath = fread(fh, 1, 'uint8=>uint8');% = 245; (* BYTE *) -A.sCCTrackTau = fread(fh, 1, 'uint8=>uint8');% = 246; (* BYTE *) -A.sWasClipping = fread(fh, 1, 'uint8=>uint8');% = 247; (* BYTE *) - -A.sRepetitiveCSlow = fread(fh, 1, 'uint8=>uint8');% = 248; (* BYTE *) -A.sLastCSlowRange = fread(fh, 1, 'uint8=>uint8');% = 249; (* BYTE *) - A.sOld1 = fread(fh, 1, 'uint8=>uint8');% = 250; (* BYTE *) -A.sCanCCFast = fread(fh, 1, 'uint8=>uint8');% = 251; (* BYTE *) -A.sCanLowCCRange = fread(fh, 1, 'uint8=>uint8');% = 252; (* BYTE *) -A.sCanHighCCRange = fread(fh, 1, 'uint8=>uint8');% = 253; (* BYTE *) -A.sCanCCTrackingg = fread(fh, 1, 'uint8=>uint8');% = 254; (* BYTE *) -A.sCHasVmonPath = fread(fh, 1, 'uint8=>uint8');% = 255; (* BYTE *) - -A.sHasNewCCMode = fread(fh, 1, 'uint8=>uint8');% = 256; (* BYTE *) -A.sSelector = fread(fh, 1, 'uint8=>char');% = 257; (* CHAR *) -A.sHoldInverted = fread(fh, 1, 'uint8=>uint8');% = 258; (* BYTE *) -A.sAutoCFast = fread(fh, 1, 'uint8=>uint8');% = 259; (* BYTE *) -A.sAutoCSlow = fread(fh, 1, 'uint8=>uint8');% = 260; (* BYTE *) -A.sHasVmonX100 = fread(fh, 1, 'uint8=>uint8');% = 261; (* BYTE *) -A.sTestDacOn = fread(fh, 1, 'uint8=>uint8');% = 262; (* BYTE *) -A.sQMuxAdcOn = fread(fh, 1, 'uint8=>uint8');% = 263; (* BYTE *) - -A.sImon1Bandwidth = fread(fh, 1, 'double=>double');% = 264; (* LONGREAL *) -A.sStimScale = fread(fh, 1, 'double=>double');% = 272; (* LONGREAL *) - -A.sGain = fread(fh, 1, 'uint8=>uint8');% = 280; (* BYTE *) -A.sFilter1 = fread(fh, 1, 'uint8=>uint8');% = 281; (* BYTE *) -A.sStimFilterOn = fread(fh, 1, 'uint8=>uint8');% = 282; (* BYTE *) -A.sRsSlow = fread(fh, 1, 'uint8=>uint8');% = 283; (* BYTE *) - A.sOld2 = fread(fh, 1, 'uint8=>uint8');% = 284; (* BYTE *) -A.sCCCFastOn = fread(fh, 1, 'uint8=>uint8');% = 285; (* BYTE *) -A.sCCFastSpeed = fread(fh, 1, 'uint8=>uint8');% = 286; (* BYTE *) -A.sF2Source = fread(fh, 1, 'uint8=>uint8');% = 287; (* BYTE *) - -A.sTestRange = fread(fh, 1, 'uint8=>uint8');% = 288; (* BYTE *) -A.sTestDacPath = fread(fh, 1, 'uint8=>uint8');% = 289; (* BYTE *) -A.sMuxChannel = fread(fh, 1, 'uint8=>uint8');% = 290; (* BYTE *) -A.sMuxGain64 = fread(fh, 1, 'uint8=>uint8');% = 291; (* BYTE *) -A.sVmonX100 = fread(fh, 1, 'uint8=>uint8');% = 292; (* BYTE *) -A.sIsQuadro = fread(fh, 1, 'uint8=>uint8');% = 293; (* BYTE *) -A.sF1Mode = fread(fh, 1, 'uint8=>uint8');% = 294; (* BYTE *) - A.sOld3 = fread(fh, 1, 'uint8=>uint8');% = 295; (* BYTE *) - -A.sStimFilterHz = fread(fh, 1, 'double=>double');% = 296; (* LONGREAL *) -A.sRsTau = fread(fh, 1, 'double=>double');% = 304; (* LONGREAL *) -A.sDacToAdcDelay = fread(fh, 1, 'double=>double');% = 312; (* LONGREAL *) -A.sInputFilterTau = fread(fh, 1, 'double=>double');% = 320; (* LONGREAL *) -A.sOutputFilterTau = fread(fh, 1, 'double=>double');% = 328; (* LONGREAL *) -A.sVmonFactor = fread(fh, 1, 'double=>double');% = 336; (* LONGREAL *) -A.sCalibDate = fread(fh, 2, 'double=>double');% = 344; (* 16 = SizeCalibDate *) -A.sVmonOffset = fread(fh, 1, 'double=>double');% = 360; (* LONGREAL *) - -A.sEEPROMKind = fread(fh, 1, 'uint8=>uint8');% = 368; (* BYTE *) -A.sVrefX2 = fread(fh, 1, 'uint8=>uint8');% = 369; (* BYTE *) -A.sHasVrefX2AndF2Vmon = fread(fh, 1, 'uint8=>uint8');% = 370; (* BYTE *) -A.sSpare1 = fread(fh, 1, 'uint8=>uint8');% = 371; (* BYTE *) -A.sSpare2 = fread(fh, 1, 'uint8=>uint8');% = 372; (* BYTE *) -A.sSpare3 = fread(fh, 1, 'uint8=>uint8');% = 373; (* BYTE *) -A.sSpare4 = fread(fh, 1, 'uint8=>uint8');% = 374; (* BYTE *) -A.sSpare5 = fread(fh, 1, 'uint8=>uint8');% = 375; (* BYTE *) - -A.sCCStimDacScale = fread(fh, 1, 'double=>double');% = 376; (* LONGREAL *) -A.sVmonFiltBandwidth = fread(fh, 1, 'double=>double');% = 384; (* LONGREAL *) -A.sVmonFiltFrequency = fread(fh, 1, 'double=>double');% = 392; (* LONGREAL *) -A.AmplifierStateSize = 400;% (* = 50 * 8 *) - -fseek(fh, offset+A.AmplifierStateSize, 'bof'); - -end \ No newline at end of file diff --git a/@HEKA_Importer/readStimulusFileHEKA.asv b/@HEKA_Importer/readStimulusFileHEKA.asv deleted file mode 100644 index c4ba996..0000000 --- a/@HEKA_Importer/readStimulusFileHEKA.asv +++ /dev/null @@ -1,210 +0,0 @@ -function readStimulusFileHEKA(obj,Level) -%-------------------------------------------------------------------------- -% Gets one record of the tree and the number of children -s = getOneStimRecord(obj,Level); -obj.fileData.Tree{obj.fileData.Counter, Level+1} = s; -obj.fileData.Position = obj.fileData.Position+obj.fileData.Sizes(Level+1); -fseek(obj.fileData.fh, obj.fileData.Position, 'bof'); -obj.fileData.nchild=fread(obj.fileData.fh, 1, 'int32=>int32'); -obj.fileData.Position=ftell(obj.fileData.fh); -end - - -%-------------------------------------------------------------------------- -function rec=getOneStimRecord(obj,Level) -%-------------------------------------------------------------------------- -% Gets one record -obj.fileData.Counter = obj.fileData.Counter+1; -switch Level - case 0 - rec=getStimRoot(obj); - case 1 - rec=getStimulation(obj); - case 2 - rec=getChannel(obj); - case 3 - rec=getStimSegment(obj); - otherwise - error('Unexpected Level'); -end - -end - -% The functions below return data as defined by the HEKA PatchMaster -% specification - -%-------------------------------------------------------------------------- -function p=getStimRoot(obj) -%-------------------------------------------------------------------------- -fh = obj.fileData.fh; - -p.RoVersion = fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) -p.RoMark = fread(fh, 1, 'int32=>int32');% = 4; (* INT32 *) -p.RoVersionName = deblank(fread(fh, 32, 'uint8=>char')');% = 8; (* String32Type *) -p.RoMaxSamples = fread(fh, 1, 'int32=>int32'); % = 40; (* INT32 *) -p.RoFiller1 = fread(fh, 1, 'int32=>int32');% = 44; (* INT32 *) -p.RoParams = fread(fh, 10, 'double=>double');% = 48; (* ARRAY[0..9] OF LONGREAL *) -for k=1:10 - p.RoParamText{k}=deblank(fread(fh, 32, 'uint8=>char')');% = 128; (* ARRAY[0..9],[0..31]OF CHAR *) -end -p.RoReserved = fread(fh, 32, 'int32=>int32');% = 448; (* INT32 *) -p.RoFiller2 = fread(fh, 1, 'int32=>int32');% = 576; (* INT32 *) -p.RoCRC = fread(fh, 1, 'int32=>int32');% = 580; (* CARD32 *) -p.RootRecSize = 584; % (* = 73 * 8 *) -p=orderfields(p); - -end - -%-------------------------------------------------------------------------- -function s=getStimulation(obj) -%-------------------------------------------------------------------------- -fh = obj.fileData.fh; - -% Stimulus level -s.stMark = fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) -s.stEntryName = deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Type *) -s.stFileName = deblank(fread(fh, 32, 'uint8=>char')');% = 36; (* String32Type *) -s.stAnalName = deblank(fread(fh, 32, 'uint8=>char')');% = 68; (* String32Type *) -s.stDataStartSegment = fread(fh, 1, 'int32=>int32');% = 100; (* INT32 *) -s.stDataStartTime = fread(fh, 1, 'double=>double') ;% = 104; (* LONGREAL *) -s.stDataStartTimeMATLAB = obj.HI_time2date(s.stDataStartTime); -s.stSampleInterval = fread(fh, 1, 'double=>double') ;% = 112; (* LONGREAL *) -s.stSweepInterval = fread(fh, 1, 'double=>double') ;% = 120; (* LONGREAL *) -s.stLeakDelay = fread(fh, 1, 'double=>double') ;% = 128; (* LONGREAL *) -s.stFilterFactor = fread(fh, 1, 'double=>double') ;% = 136; (* LONGREAL *) -s.stNumberSweeps = fread(fh, 1, 'int32=>int32');% = 144; (* INT32 *) -s.stNumberLeaks = fread(fh, 1, 'int32=>int32');% = 148; (* INT32 *) -s.stNumberAverages = fread(fh, 1, 'int32=>int32');% = 152; (* INT32 *) -s.stActualAdcChannels = fread(fh, 1, 'int32=>int32');% = 156; (* INT32 *) -s.stActualDacChannels = fread(fh, 1, 'int32=>int32');% = 160; (* INT32 *) -s.stExtTrigger = fread(fh, 1, 'uint8=>uint8');% = 164; (* BYTE *) -s.stNoStartWait = fread(fh, 1, 'uint8=>logical');% = 165; (* BOOLEAN *) -s.stUseScanRates = fread(fh, 1, 'uint8=>logical');% = 166; (* BOOLEAN *) -s.stNoContAq = fread(fh, 1, 'uint8=>logical');% = 167; (* BOOLEAN *) -s.stHasLockIn = fread(fh, 1, 'uint8=>logical');% = 168; (* BOOLEAN *) -s.stOldStartMacKind = fread(fh, 1, 'uint8=>char');% = 169; (* CHAR *) -s.stOldEndMacKind = fread(fh, 1, 'uint8=>logical');% = 170; (* BOOLEAN *) -s.stAutoRange = fread(fh, 1, 'uint8=>uint8');% = 171; (* BYTE *) -s.stBreakNext = fread(fh, 1, 'uint8=>logical');% = 172; (* BOOLEAN *) -s.stIsExpanded = fread(fh, 1, 'uint8=>logical');% = 173; (* BOOLEAN *) -s.stLeakCompMode = fread(fh, 1, 'uint8=>logical');% = 174; (* BOOLEAN *) -s.stHasChirp = fread(fh, 1, 'uint8=>logical');% = 175; (* BOOLEAN *) -s.stOldStartMacro = deblank(fread(fh, 32, 'uint8=>char')');% = 176; (* String32Type *) -s.stOldEndMacro = deblank(fread(fh, 32, 'uint8=>char')');% = 208; (* String32Type *) -s.sIsGapFree = fread(fh, 1, 'uint8=>logical');% = 240; (* BOOLEAN *) -s.sHandledExternally = fread(fh, 1, 'uint8=>logical');% = 241; (* BOOLEAN *) - s.stFiller1 = fread(fh, 1, 'uint8=>logical');% = 242; (* BOOLEAN *) - s.stFiller2 = fread(fh, 1, 'uint8=>logical');% = 243; (* BOOLEAN *) -s.stCRC = fread(fh, 1, 'int32=>int32'); % = 244; (* CARD32 *) -s.stTag = deblank(fread(fh, 32, 'uint8=>char')');% = 248; (* String32Type *) -s.StimulationRecSize = 280;% (* = 35 * 8 *) - -s=orderfields(s); - -end - -%-------------------------------------------------------------------------- -function c=getChannel(obj) -%-------------------------------------------------------------------------- -fh = obj.fileData.fh; - -c.chMark = fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) -c.chLinkedChannel = fread(fh, 1, 'int32=>int32');% = 4; (* INT32 *) -c.chCompressionFactor = fread(fh, 1, 'int32=>int32');% = 8; (* INT32 *) -c.chYUnit = deblank(fread(fh, 8, 'uint8=>char')');% = 12; (* String8Type *) -c.chAdcChannel = fread(fh, 1, 'int16=>int16');% = 20; (* INT16 *) -c.chAdcMode = fread(fh, 1, 'uint8=>uint8');% = 22; (* BYTE *) -c.chDoWrite = fread(fh, 1, 'uint8=>logical');% = 23; (* BOOLEAN *) -c.stLeakStore = fread(fh, 1, 'uint8=>uint8');% = 24; (* BYTE *) -c.chAmplMode = fread(fh, 1, 'uint8=>uint8');% = 25; (* BYTE *) -c.chOwnSegTime = fread(fh, 1, 'uint8=>logical');% = 26; (* BOOLEAN *) -c.chSetLastSegVmemb = fread(fh, 1, 'uint8=>logical');% = 27; (* BOOLEAN *) -c.chDacChannel = fread(fh, 1, 'int16=>int16');% = 28; (* INT16 *) -c.chDacMode = fread(fh, 1, 'uint8=>uint8');% = 30; (* BYTE *) -c.chHasLockInSquare = fread(fh, 1, 'uint8=>uint8');% = 31; (* BYTE *) -c.chRelevantXSegment = fread(fh, 1, 'int32=>int32');% = 32; (* INT32 *) -c.chRelevantYSegment = fread(fh, 1, 'int32=>int32');% = 36; (* INT32 *) -c.chDacUnit = deblank(fread(fh, 8, 'uint8=>char')');% = 40; (* String8Type *) -c.chHolding = fread(fh, 1, 'double=>double') ;% = 48; (* LONGREAL *) -c.chLeakHolding = fread(fh, 1, 'double=>double') ;% = 56; (* LONGREAL *) -c.chLeakSize = fread(fh, 1, 'double=>double') ;% = 64; (* LONGREAL *) -c.chLeakHoldMode = fread(fh, 1, 'uint8=>uint8');% = 72; (* BYTE *) -c.chLeakAlternate = fread(fh, 1, 'uint8=>logical');% = 73; (* BOOLEAN *) -c.chAltLeakAveraging = fread(fh, 1, 'uint8=>logical');% = 74; (* BOOLEAN *) -c.chLeakPulseOn = fread(fh, 1, 'uint8=>logical');% = 75; (* BOOLEAN *) -c.chStimToDacID = fread(fh, 1, 'int16=>int16');% = 76; (* SET16 *) -c.chCompressionMode = fread(fh, 1, 'int16=>int16');% = 78; (* SET16 *) -c.chCompressionSkip = fread(fh, 1, 'int32=>int32');% = 80; (* INT32 *) -c.chDacBit = fread(fh, 1, 'int16=>int16');% = 84; (* INT16 *) -c.chHasLockInSine = fread(fh, 1, 'uint8=>logical');% = 86; (* BOOLEAN *) -c.chBreakMode = fread(fh, 1, 'uint8=>uint8');% = 87; (* BYTE *) -c.chZeroSeg = fread(fh, 1, 'int32=>int32');% = 88; (* INT32 *) -c.chStimSweep = fread(fh, 1, 'int32=>int32');% = 92; (* INT32 *) -c.chSine_Cycle = fread(fh, 1, 'double=>double') ;% = 96; (* LONGREAL *) -c.chSine_Amplitude = fread(fh, 1, 'double=>double') ;% = 104; (* LONGREAL *) -c.chLockIn_VReversal = fread(fh, 1, 'double=>double') ;% = 112; (* LONGREAL *) -c.chChirp_StartFreq = fread(fh, 1, 'double=>double') ;% = 120; (* LONGREAL *) -c.chChirp_EndFreq = fread(fh, 1, 'double=>double') ;% = 128; (* LONGREAL *) -c.chChirp_MinPoints = fread(fh, 1, 'double=>double') ;% = 136; (* LONGREAL *) -c.chSquare_NegAmpl = fread(fh, 1, 'double=>double') ;% = 144; (* LONGREAL *) -c.chSquare_DurFactor = fread(fh, 1, 'double=>double') ;% = 152; (* LONGREAL *) -c.chLockIn_Skip = fread(fh, 1, 'int32=>int32');% = 160; (* INT32 *) -c.chPhoto_MaxCycles = fread(fh, 1, 'int32=>int32');% = 164; (* INT32 *) -c.chPhoto_SegmentNo = fread(fh, 1, 'int32=>int32');% = 168; (* INT32 *) -c.chLockIn_AvgCycles = fread(fh, 1, 'int32=>int32');% = 172; (* INT32 *) -c.chImaging_RoiNo = fread(fh, 1, 'int32=>int32');% = 176; (* INT32 *) -c.chChirp_Skip = fread(fh, 1, 'int32=>int32');% = 180; (* INT32 *) -c.chChirp_Amplitude = fread(fh, 1, 'double=>double');% = 184; (* LONGREAL *) -c.chPhoto_Adapt = fread(fh, 1, 'uint8=>uint8');% = 192; (* BYTE *) -c.chSine_Kind = fread(fh, 1, 'uint8=>uint8');% = 193; (* BYTE *) -c.chChirp_PreChirp = fread(fh, 1, 'uint8=>uint8');% = 194; (* BYTE *) -c.chSine_Source = fread(fh, 1, 'uint8=>uint8');% = 195; (* BYTE *) -c.chSquare_NegSource = fread(fh, 1, 'uint8=>uint8');% = 196; (* BYTE *) -c.chSquare_PosSource = fread(fh, 1, 'uint8=>uint8');% = 197; (* BYTE *) -c.chChirp_Kind = fread(fh, 1, 'uint8=>uint8');% = 198; (* BYTE *) -c.chChirp_Source = fread(fh, 1, 'uint8=>uint8');% = 199; (* BYTE *) -c.chDacOffset = fread(fh, 1, 'double=>double') ;% = 200; (* LONGREAL *) -c.chAdcOffset = fread(fh, 1, 'double=>double') ;% = 208; (* LONGREAL *) -c.chTraceMathFormat = fread(fh, 1, 'uint8=>uint8');% = 216; (* BYTE *) -c.chHasChirp = fread(fh, 1, 'uint8=>logical');% = 217; (* BOOLEAN *) -c.chSquare_Kind = fread(fh, 1, 'uint8=>uint8');% = 218; (* BYTE *) - c.chFiller1 = fread(fh, 6, 'uint8=>char');% = 219; (* ARRAY[0..5] OF CHAR *) -c.chSquare_BaseIncr = fread(fh, 1, 'double=>double');% = 224; (* LONGREAL *) -c.chSquare_Cycle = fread(fh, 1, 'double=>double') ;% = 232; (* LONGREAL *) -c.chSquare_PosAmpl = fread(fh, 1, 'double=>double') ;% = 240; (* LONGREAL *) -c.chCompressionOffset = fread(fh, 1, 'int32=>int32');% = 248; (* INT32 *) -c.chPhotoMode = fread(fh, 1, 'int32=>int32');% = 252; (* INT32 *) -c.chBreakLevel = fread(fh, 1, 'double=>double') ;% = 256; (* LONGREAL *) -c.chTraceMath = deblank(fread(fh,128,'uint8=>char')');% = 264; (* String128Type *) - c.chFiller2 = fread(fh, 1, 'int32=>int32');% = 392; (* INT32 *) -c.chCRC = fread(fh, 1, 'int32=>int32');% = 396; (* CARD32 *) -c.ChannelRecSize = 400;% (* = 50 * 8 *) -c=orderfields(c); - -end - -%-------------------------------------------------------------------------- -function ss=getStimSegment(obj) -%-------------------------------------------------------------------------- -fh = obj.fileData.fh; - -ss.seMark = fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) -ss.seClass = fread(fh, 1, 'uint8=>uint8');% = 4; (* BYTE *) -ss.seDoStore = fread(fh, 1, 'uint8=>logical');% = 5; (* BOOLEAN *) -ss.seVoltageIncMode = fread(fh, 1, 'uint8=>uint8');% = 6; (* BYTE *) -ss.seDurationIncMode = fread(fh, 1, 'uint8=>uint8');% = 7; (* BYTE *) -ss.seVoltage = fread(fh, 1, 'double=>double');% = 8; (* LONGREAL *) -ss.seVoltageSource = fread(fh, 1, 'int32=>int32');% = 16; (* INT32 *) -ss.seDeltaVFactor = fread(fh, 1, 'double=>double');% = 20; (* LONGREAL *) -ss.seDeltaVIncrement = fread(fh, 1, 'double=>double');% = 28; (* LONGREAL *) -ss.seDuration = fread(fh, 1, 'double=>double');% = 36; (* LONGREAL *) -ss.seDurationSource = fread(fh, 1, 'int32=>int32');% = 44; (* INT32 *) -ss.seDeltaTFactor = fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) -ss.seDeltaTIncrement = fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) -ss.seFiller1 = fread(fh, 1, 'int32=>int32');% = 64; (* INT32 *) -ss.seCRC = fread(fh, 1, 'int32=>int32');% = 68; (* CARD32 *) -ss.seScanRate = fread(fh, 1, 'double=>double');% = 72; (* LONGREAL *) -ss.StimSegmentRecSize = 80;% (* = 10 * 8 *) -ss=orderfields(ss); - -end From a8449bb589a0b29df33cee6b45ebda287c389a7b Mon Sep 17 00:00:00 2001 From: ChristianKeine Date: Mon, 24 Jun 2019 13:15:32 -0500 Subject: [PATCH 31/39] Update HEKA_Importer.m --- @HEKA_Importer/HEKA_Importer.m | 1 - 1 file changed, 1 deletion(-) diff --git a/@HEKA_Importer/HEKA_Importer.m b/@HEKA_Importer/HEKA_Importer.m index 4d60477..6d2dedb 100644 --- a/@HEKA_Importer/HEKA_Importer.m +++ b/@HEKA_Importer/HEKA_Importer.m @@ -134,7 +134,6 @@ readStimulusFileHEKA(obj,Level); readAmplifierFileHEKA(obj,Level); readSolutionFileHEKA(obj,Level); - end %% Hide some of the handle class member functions for ease of use. From 47e6f43ee166b03f737f2b407d0a34047bfd4d0d Mon Sep 17 00:00:00 2001 From: ChristianKeine Date: Mon, 24 Jun 2019 13:35:19 -0500 Subject: [PATCH 32/39] Update README.md --- README.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 9912b62..41fdbf8 100644 --- a/README.md +++ b/README.md @@ -22,10 +22,13 @@ to load HEKA Patchmaster file "MyData.dat" located in "C:\PatchClamp\" run `HEKA Heka_Importer creates object containing the following properties: -- **trees**: structure containing the dataTree (from the .pul file), the stimTree (from the .pgf file) and solTree (from the .sol file). These tree structures are how HEKA saves the metadata for different recordings. For details on the HEKA file format check ftp://server.hekahome.de/pub/FileFormat/Patchmasterv9/. +- **trees**: structure containing the dataTree (from the .pul file), the stimTree (from the .pgf file) and solTree (from the .sol file). These tree structures are how HEKA saves the metadata for different recordings. For details on the HEKA file format check ftp://server.hekahome.de/pub/FileFormat/Patchmasterv9/ and ftp://server.hekahome.de/pub/FileFormat/Patchmasterv1000/. -- **opt**: structure containing different options when loading the file, currently it only contains the filepath of the HEKA Patchmaster file which was loaded and serves as placeholder for additional options in the future. +- **opt**: structure containing different options when loading the file, currently it only contains the filepath of the HEKA Patchmaster file which was loaded and some temporary information used during loading the files. -- **RecTable**: Matlab table containing the recordings and several parameters associated with them. Each row represents a different recording. The recorded data are stored in `RecTable.dataRaw` and sorted by channel within, e.g. `RecTable.dataRaw{1}{2}` contains all sweeps of the first series/recording for the second channel. The corresponding name of the channels is stored in `RecTable.chNames{1}`. +- **RecTable**: Matlab table containing the recordings and several parameters associated with them. Each row represents a different recording. The recorded data are stored in `RecTable.dataRaw` and sorted by channel within, e.g. `RecTable.dataRaw{1}{2}` contains all sweeps of the first series/recording for the second channel. The corresponding name of the channels is stored in `RecTable.chNames{1}`. Accordingly, the cell capacitance for each sweep of this recording is stored in `RecTable.Cm{1}{2}`. Note that this is slightly different from how Patchmaster stores the data internally. In Patchmaster, the data tree is nested by Series > Sweep > Channel, whereas the data table in Matlab will be sorted as Series > Channel > Sweep. - **solutions**: Matlab table containing the solutions and composition (chemicals & concentration) used during the experiments. This table is read-out from the solTree of the HEKA Patchmaster file and requires that the recordings were associated with a solution base (otherwise this variable will be empty). The names of solutions correspond to the columns "ExternalSolution" and "InternalSolution" of the RecTable. + +UPDATE: As of Patchmaster version 2x90.3 (including Patchmaster Next), HEKA made minor changes to how data is stored in the tree structures. The amplifier settings are now always stored in a separate ".amp" file (which is part of the DAT bundle file). In previous versions, such a separate file was created only for EPC/n amplifiers. +The HEKA_Import function has been updated accordingly and should work with older 2x90 versions and newer (>2x90.3/PMN) alike, but the amplifier settings might be stored differently. From 18e3cfeb0921e75625b9caaa771f2e8c4ed1811a Mon Sep 17 00:00:00 2001 From: ChristianKeine Date: Mon, 24 Jun 2019 13:47:39 -0500 Subject: [PATCH 33/39] minor fix --- @HEKA_Importer/HEKA_Importer.m | 19 ++++--- @HEKA_Importer/HI_ImportHEKAtoMat.m | 42 +++++++++------ @HEKA_Importer/HI_extractHEKADataTree.m | 6 ++- @HEKA_Importer/HI_extractHEKASolutionTree.m | 9 +++- @HEKA_Importer/HI_extractHEKAStimTree.m | 6 ++- @HEKA_Importer/HI_loadHEKAFile.m | 6 ++- ...rFileHEKA.m => HI_readAmplifierFileHEKA.m} | 35 ++++++++---- ...PulseFileHEKA.m => HI_readPulseFileHEKA.m} | 54 ++++++++++++------- ...onFileHEKA.m => HI_readSolutionFileHEKA.m} | 34 ++++++++---- ...usFileHEKA.m => HI_readStimulusFileHEKA.m} | 36 +++++++++---- @HEKA_Importer/HI_time2date.m | 14 ++++- 11 files changed, 181 insertions(+), 80 deletions(-) rename @HEKA_Importer/{readAmplifierFileHEKA.m => HI_readAmplifierFileHEKA.m} (92%) rename @HEKA_Importer/{readPulseFileHEKA.m => HI_readPulseFileHEKA.m} (94%) rename @HEKA_Importer/{readSolutionFileHEKA.m => HI_readSolutionFileHEKA.m} (72%) rename @HEKA_Importer/{readStimulusFileHEKA.m => HI_readStimulusFileHEKA.m} (92%) diff --git a/@HEKA_Importer/HEKA_Importer.m b/@HEKA_Importer/HEKA_Importer.m index 6d2dedb..66fe6ee 100644 --- a/@HEKA_Importer/HEKA_Importer.m +++ b/@HEKA_Importer/HEKA_Importer.m @@ -71,11 +71,15 @@ % columns "ExternalSolution" and "InternalSolution" % of the RecTable. % -% See also HEKA_Importer.HI_loadHEKAFile -% HEKA_Importer.HI_ImportHEKAtoMat -% HEKA_Importer.HI_extractHEKAStimTree +% See also HEKA_Importer +% HEKA_Importer.HI_loadHEKAFile % HEKA_Importer.HI_extractHEKASolutionTree +% HEKA_Importer.HI_extractHEKAStimTree % HEKA_Importer.HI_extractHEKADataTree +% HEKA_Importer.HI_readPulseFileHEKA +% HEKA_Importer.HI_readStimulusFileHEKA +% HEKA_Importer.HI_readAmplifierFileHEKA +% HEKA_Importer.HI_readSolutionFileHEKA properties (Access = public) @@ -83,7 +87,6 @@ opt RecTable % contains recordings in table with various parameters, e.g. Rs, Cm, nSweeps ect. solutions = [] - fileData = []; end @@ -130,10 +133,10 @@ HI_extractHEKASolutionTree(obj); str = HI_time2date(obj,t); - readPulseFileHEKA(obj,Level); - readStimulusFileHEKA(obj,Level); - readAmplifierFileHEKA(obj,Level); - readSolutionFileHEKA(obj,Level); + HI_readPulseFileHEKA(obj,Level); + HI_readStimulusFileHEKA(obj,Level); + HI_readAmplifierFileHEKA(obj,Level); + HI_readSolutionFileHEKA(obj,Level); end %% Hide some of the handle class member functions for ease of use. diff --git a/@HEKA_Importer/HI_ImportHEKAtoMat.m b/@HEKA_Importer/HI_ImportHEKAtoMat.m index 221e14f..d65a7cd 100644 --- a/@HEKA_Importer/HI_ImportHEKAtoMat.m +++ b/@HEKA_Importer/HI_ImportHEKAtoMat.m @@ -34,7 +34,10 @@ % HEKA_Importer.HI_extractHEKASolutionTree % HEKA_Importer.HI_extractHEKAStimTree % HEKA_Importer.HI_extractHEKADataTree - +% HEKA_Importer.HI_readPulseFileHEKA +% HEKA_Importer.HI_readStimulusFileHEKA +% HEKA_Importer.HI_readAmplifierFileHEKA +% HEKA_Importer.HI_readSolutionFileHEKA [pathname, filename, ext]=fileparts(obj.opt.filepath); @@ -88,10 +91,10 @@ Position=ftell(fh); % Get the tree structures form the file sections - obj.fileData.fh = fh; - obj.fileData.Sizes = Sizes; - obj.fileData.Position = Position; - obj.fileData.fileExt = iidx{1}; + obj.opt.fileData.fh = fh; + obj.opt.fileData.Sizes = Sizes; + obj.opt.fileData.Position = Position; + obj.opt.fileData.fileExt = iidx{1}; obj.trees.(treeName{strcmp(iidx, fileExt)})=getTree(obj); @@ -100,6 +103,12 @@ end end +% clean-up remaining temporary data +try + obj.opt.fileData = rmfield(obj.opt.fileData,{'Sizes','Position','fileExt','Counter','Tree','Level','nchild'}); +catch +end + %% GET DATA if isBundled % Set offset for data @@ -194,9 +203,9 @@ %-------------------------------------------------------------------------- % Main entry point for loading tree -obj.fileData.Counter = 0; -obj.fileData.Tree = {}; -obj.fileData.Level = 0; +obj.opt.fileData.Counter = 0; +obj.opt.fileData.Tree = {}; +obj.opt.fileData.Level = 0; Tree = getTreeReentrant(obj,0); end @@ -206,23 +215,26 @@ %-------------------------------------------------------------------------- % Recursive routine called from LoadTree -switch obj.fileData.fileExt +switch obj.opt.fileData.fileExt case '.pul' - obj.readPulseFileHEKA(Level); + obj.HI_readPulseFileHEKA(Level); case '.pgf' - obj.readStimulusFileHEKA(Level); + obj.HI_readStimulusFileHEKA(Level); case '.sol' - obj.readSolutionFileHEKA(Level); + obj.HI_readSolutionFileHEKA(Level); case '.amp' - obj.readAmplifierFileHEKA(Level); + obj.HI_readAmplifierFileHEKA(Level); end -for k=1:double(obj.fileData.nchild) +for k=1:double(obj.opt.fileData.nchild) getTreeReentrant(obj,Level+1); end -Tree = obj.fileData.Tree; +Tree = obj.opt.fileData.Tree; + + + end diff --git a/@HEKA_Importer/HI_extractHEKADataTree.m b/@HEKA_Importer/HI_extractHEKADataTree.m index d6b734a..9d88e3c 100644 --- a/@HEKA_Importer/HI_extractHEKADataTree.m +++ b/@HEKA_Importer/HI_extractHEKADataTree.m @@ -7,9 +7,13 @@ function HI_extractHEKADataTree(obj) % % See also HEKA_Importer % HEKA_Importer.HI_loadHEKAFile -% HEKA_Importer.HI_ImportHEKAtoMat % HEKA_Importer.HI_extractHEKASolutionTree % HEKA_Importer.HI_extractHEKAStimTree +% HEKA_Importer.HI_extractHEKADataTree +% HEKA_Importer.HI_readPulseFileHEKA +% HEKA_Importer.HI_readStimulusFileHEKA +% HEKA_Importer.HI_readAmplifierFileHEKA +% HEKA_Importer.HI_readSolutionFileHEKA %1: Root %2: Group/Experiment diff --git a/@HEKA_Importer/HI_extractHEKASolutionTree.m b/@HEKA_Importer/HI_extractHEKASolutionTree.m index 229e18e..6fe2fb2 100644 --- a/@HEKA_Importer/HI_extractHEKASolutionTree.m +++ b/@HEKA_Importer/HI_extractHEKASolutionTree.m @@ -9,9 +9,14 @@ function HI_extractHEKASolutionTree(obj) % % See also HEKA_Importer % HEKA_Importer.HI_loadHEKAFile -% HEKA_Importer.HI_ImportHEKAtoMat -% HEKA_Importer.HI_extractHEKADataTree +% HEKA_Importer.HI_extractHEKASolutionTree % HEKA_Importer.HI_extractHEKAStimTree +% HEKA_Importer.HI_extractHEKADataTree +% HEKA_Importer.HI_readPulseFileHEKA +% HEKA_Importer.HI_readStimulusFileHEKA +% HEKA_Importer.HI_readAmplifierFileHEKA +% HEKA_Importer.HI_readSolutionFileHEKA + %1: Root %2: Solution %3: Chemicals diff --git a/@HEKA_Importer/HI_extractHEKAStimTree.m b/@HEKA_Importer/HI_extractHEKAStimTree.m index 4d2c8dd..c5a5e6f 100644 --- a/@HEKA_Importer/HI_extractHEKAStimTree.m +++ b/@HEKA_Importer/HI_extractHEKAStimTree.m @@ -7,9 +7,13 @@ function HI_extractHEKAStimTree(obj) % % See also HEKA_Importer % HEKA_Importer.HI_loadHEKAFile -% HEKA_Importer.HI_ImportHEKAtoMat % HEKA_Importer.HI_extractHEKASolutionTree +% HEKA_Importer.HI_extractHEKAStimTree % HEKA_Importer.HI_extractHEKADataTree +% HEKA_Importer.HI_readPulseFileHEKA +% HEKA_Importer.HI_readStimulusFileHEKA +% HEKA_Importer.HI_readAmplifierFileHEKA +% HEKA_Importer.HI_readSolutionFileHEKA % TODO: Add support for more complex stimuli, e.g. ramps, alternating etc. diff --git a/@HEKA_Importer/HI_loadHEKAFile.m b/@HEKA_Importer/HI_loadHEKAFile.m index 5796b56..2e7ed87 100644 --- a/@HEKA_Importer/HI_loadHEKAFile.m +++ b/@HEKA_Importer/HI_loadHEKAFile.m @@ -5,10 +5,14 @@ function HI_loadHEKAFile(obj) % for more information. % % See also HEKA_Importer -% HEKA_Importer.HI_ImportHEKAtoMat +% HEKA_Importer.HI_loadHEKAFile % HEKA_Importer.HI_extractHEKASolutionTree % HEKA_Importer.HI_extractHEKAStimTree % HEKA_Importer.HI_extractHEKADataTree +% HEKA_Importer.HI_readPulseFileHEKA +% HEKA_Importer.HI_readStimulusFileHEKA +% HEKA_Importer.HI_readAmplifierFileHEKA +% HEKA_Importer.HI_readSolutionFileHEKA % CHECK IF FILE EXISTS if ~exist(obj.opt.filepath,'file') diff --git a/@HEKA_Importer/readAmplifierFileHEKA.m b/@HEKA_Importer/HI_readAmplifierFileHEKA.m similarity index 92% rename from @HEKA_Importer/readAmplifierFileHEKA.m rename to @HEKA_Importer/HI_readAmplifierFileHEKA.m index 04ee255..5d13a20 100644 --- a/@HEKA_Importer/readAmplifierFileHEKA.m +++ b/@HEKA_Importer/HI_readAmplifierFileHEKA.m @@ -1,14 +1,29 @@ -function readAmplifierFileHEKA(obj,Level) +function HI_readAmplifierFileHEKA(obj,Level) + +% extracts data stored in the "*.amp" file, or the corresponding portion of +% the bundled ".dat" file +% +% See also HEKA_Importer +% HEKA_Importer.HI_loadHEKAFile +% HEKA_Importer.HI_extractHEKASolutionTree +% HEKA_Importer.HI_extractHEKAStimTree +% HEKA_Importer.HI_extractHEKADataTree +% HEKA_Importer.HI_readPulseFileHEKA +% HEKA_Importer.HI_readStimulusFileHEKA +% HEKA_Importer.HI_readAmplifierFileHEKA +% HEKA_Importer.HI_readSolutionFileHEKA + + %-------------------------------------------------------------------------- % Gets one record of the tree and the number of children s = getOneAmplifierRecord(obj,Level); -obj.fileData.Tree{obj.fileData.Counter, Level+1} = s; +obj.opt.fileData.Tree{obj.opt.fileData.Counter, Level+1} = s; -obj.fileData.Position = obj.fileData.Position+obj.fileData.Sizes(Level+1); -fseek(obj.fileData.fh, obj.fileData.Position, 'bof'); -obj.fileData.nchild=fread(obj.fileData.fh, 1, 'int32=>int32'); -obj.fileData.Position=ftell(obj.fileData.fh); +obj.opt.fileData.Position = obj.opt.fileData.Position+obj.opt.fileData.Sizes(Level+1); +fseek(obj.opt.fileData.fh, obj.opt.fileData.Position, 'bof'); +obj.opt.fileData.nchild=fread(obj.opt.fileData.fh, 1, 'int32=>int32'); +obj.opt.fileData.Position=ftell(obj.opt.fileData.fh); end @@ -16,7 +31,7 @@ function readAmplifierFileHEKA(obj,Level) function rec=getOneAmplifierRecord(obj,Level) %-------------------------------------------------------------------------- % Gets one record -obj.fileData.Counter = obj.fileData.Counter+1; +obj.opt.fileData.Counter = obj.opt.fileData.Counter+1; switch Level case 0 rec=getAmplifierRootRecord(obj); @@ -33,7 +48,7 @@ function readAmplifierFileHEKA(obj,Level) %-------------------------------------------------------------------------- function p=getAmplifierRootRecord(obj) %-------------------------------------------------------------------------- -fh = obj.fileData.fh; +fh = obj.opt.fileData.fh; p.RoVersion = fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) p.RoMark = fread(fh, 1, 'int32=>int32');% = 4; (* INT32 *) @@ -53,7 +68,7 @@ function readAmplifierFileHEKA(obj,Level) %-------------------------------------------------------------------------- function s=getAmplifierSeriesRecord(obj) %-------------------------------------------------------------------------- -fh = obj.fileData.fh; +fh = obj.opt.fileData.fh; s.SeMark = fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) s.SeSeriesCount = fread(fh, 1, 'int32=>int32');% = 4; (* INT32 *) @@ -68,7 +83,7 @@ function readAmplifierFileHEKA(obj,Level) %-------------------------------------------------------------------------- function a=getAmplifierStateRecord(obj) %-------------------------------------------------------------------------- -fh = obj.fileData.fh; +fh = obj.opt.fileData.fh; a.AmMark = fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) a.AmStateCount = fread(fh, 1, 'int32=>int32');% = 4; (* INT32 *) diff --git a/@HEKA_Importer/readPulseFileHEKA.m b/@HEKA_Importer/HI_readPulseFileHEKA.m similarity index 94% rename from @HEKA_Importer/readPulseFileHEKA.m rename to @HEKA_Importer/HI_readPulseFileHEKA.m index 0b5c9ce..89f148b 100644 --- a/@HEKA_Importer/readPulseFileHEKA.m +++ b/@HEKA_Importer/HI_readPulseFileHEKA.m @@ -1,13 +1,27 @@ -function readPulseFileHEKA(obj,Level) +function HI_readPulseFileHEKA(obj,Level) + +% extracts data stored in the "*.pul" file, or the corresponding portion of +% the bundled ".dat" file +% +% See also HEKA_Importer +% HEKA_Importer.HI_loadHEKAFile +% HEKA_Importer.HI_extractHEKASolutionTree +% HEKA_Importer.HI_extractHEKAStimTree +% HEKA_Importer.HI_extractHEKADataTree +% HEKA_Importer.HI_readPulseFileHEKA +% HEKA_Importer.HI_readStimulusFileHEKA +% HEKA_Importer.HI_readAmplifierFileHEKA +% HEKA_Importer.HI_readSolutionFileHEKA + %-------------------------------------------------------------------------- % Gets one record of the tree and the number of children s = getOneRecord(obj,Level); -obj.fileData.Tree{obj.fileData.Counter, Level+1} = s; +obj.opt.fileData.Tree{obj.opt.fileData.Counter, Level+1} = s; -obj.fileData.Position = obj.fileData.Position+obj.fileData.Sizes(Level+1); -fseek(obj.fileData.fh, obj.fileData.Position, 'bof'); -obj.fileData.nchild=fread(obj.fileData.fh, 1, 'int32=>int32'); -obj.fileData.Position=ftell(obj.fileData.fh); +obj.opt.fileData.Position = obj.opt.fileData.Position+obj.opt.fileData.Sizes(Level+1); +fseek(obj.opt.fileData.fh, obj.opt.fileData.Position, 'bof'); +obj.opt.fileData.nchild=fread(obj.opt.fileData.fh, 1, 'int32=>int32'); +obj.opt.fileData.Position=ftell(obj.opt.fileData.fh); end @@ -15,7 +29,7 @@ function readPulseFileHEKA(obj,Level) function rec=getOneRecord(obj,Level) %-------------------------------------------------------------------------- % Gets one record -obj.fileData.Counter = obj.fileData.Counter+1; +obj.opt.fileData.Counter = obj.opt.fileData.Counter+1; switch Level case 0 @@ -39,7 +53,7 @@ function readPulseFileHEKA(obj,Level) %-------------------------------------------------------------------------- function p=getRoot(obj) %-------------------------------------------------------------------------- -fh = obj.fileData.fh; +fh = obj.opt.fileData.fh; p.RoVersion = fread(fh, 1, 'int32=>int32');% = 4; (* INT32 *) p.RoMark = fread(fh, 1, 'int32=>int32');% = 4; (* INT32 *) @@ -58,14 +72,14 @@ function readPulseFileHEKA(obj,Level) p.RootRecSize = 640;% (* = 80 * 8 *); p=orderfields(p); -obj.fileData.fileVersion = p.RoVersion; +obj.opt.fileData.fileVersion = p.RoVersion; end %-------------------------------------------------------------------------- function g=getGroup(obj) %-------------------------------------------------------------------------- % Group -fh = obj.fileData.fh; +fh = obj.opt.fileData.fh; g.GrMark = fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) g.GrLabel = deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Size *) @@ -84,14 +98,14 @@ function readPulseFileHEKA(obj,Level) %-------------------------------------------------------------------------- function s=getSeries(obj) %-------------------------------------------------------------------------- -fh = obj.fileData.fh; +fh = obj.opt.fileData.fh; s.SeMark = fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) s.SeLabel = deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Type *) s.SeComment = deblank(fread(fh, 80, 'uint8=>char')');% = 36; (* String80Type *) s.SeSeriesCount = fread(fh, 1, 'int32=>int32');% = 116; (* INT32 *) s.SeNumbersw = fread(fh, 1, 'int32=>int32');% = 120; (* INT32 *) -switch obj.fileData.fileVersion +switch obj.opt.fileData.fileVersion case 9 s.SeAmplStateOffset = fread(fh, 1, 'int32=>int32');% = 124; (* INT32 * s.SeAmplStateSeries = fread(fh, 1, 'int32=>int32');% = 128; (* INT32 * @@ -103,7 +117,7 @@ function readPulseFileHEKA(obj,Level) s.SeTime = fread(fh,1,'double=>double'); % = 136; (* LONGREAL *) s.SeTimeMATLAB = obj.HI_time2date(s.SeTime); s.SePageWidth = fread(fh, 1, 'double=>double') ;% = 144; (* LONGREAL *) -switch obj.fileData.fileVersion +switch obj.opt.fileData.fileVersion case 9 for k=1:4 % = 152; (* ARRAY[0..1] OF UserParamDescrType = 4*40 *) s.SeSwUserParamDescr(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% @@ -117,7 +131,7 @@ function readPulseFileHEKA(obj,Level) s.SeFiller1 = deblank(fread(fh,80,'uint8=>char')'); % = 232; (* ARRAY[0..1] OF UserParamDescrType = 2*40 *) end s.SeMethodName = deblank(fread(fh,32,'uint8=>char')');% = 312; (* String32Type *) -switch obj.fileData.fileVersion +switch obj.opt.fileData.fileVersion case 9 s.SeSeUserParams1 = fread(fh ,4 ,'double=>double');% = 344; (* ARRAY[0..3] OF LONGREAL *) s.SeLockInParams = getSeLockInParams(fh);% = 376; (* SeLockInSize = 96, see "Pulsed.de" *) @@ -128,7 +142,7 @@ function readPulseFileHEKA(obj,Level) s.SeOldAmpState = getAmplifierState(fh);% = 472; (* SeOldAmpState = 400 -> the AmplStateRecord is now stored in the .amp file *) end s.SeUsername = deblank(fread(fh, 80, 'uint8=>char')');% = 872; (* String80Type *) -switch obj.fileData.fileVersion +switch obj.opt.fileData.fileVersion case 9 for k=1:4% = 952; (* ARRAY[0..3] OF UserParamDescrType = 4*40 *) s.SeSeUserParamDescr1(k).Name=deblank(fread(fh, 32, 'uint8=>char')');% @@ -148,7 +162,7 @@ function readPulseFileHEKA(obj,Level) s.SeSeUserParamDescr2(k).Unit=deblank(fread(fh, 8, 'uint8=>char')');% end s.SeScanParams = fread(fh, 96, 'uint8=>uint8');% = 1312; (* ScanParamsSize = 96 (ElProScan Extension) *) -switch obj.fileData.fileVersion +switch obj.opt.fileData.fileVersion case 9 s.SeriesRecSize = 1408;% = 1408; (* = 176 * 8 *) case 1000 @@ -168,7 +182,7 @@ function readPulseFileHEKA(obj,Level) function sw=getSweep(obj) %-------------------------------------------------------------------------- -fh = obj.fileData.fh; +fh = obj.opt.fileData.fh; sw.SwMark = fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) sw.SwLabel = deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Type *) @@ -178,7 +192,7 @@ function readPulseFileHEKA(obj,Level) sw.SwTime = fread(fh, 1, 'double=>double');% = 48; (* LONGREAL *) sw.SwTimeMATLAB = obj.HI_time2date(sw.SwTime);% Also add in MATLAB datenum format sw.SwTimer = fread(fh, 1, 'double=>double');% = 56; (* LONGREAL *) -switch obj.fileData.fileVersion +switch obj.opt.fileData.fileVersion case 9 sw.SwSwUserParams = fread(fh, 4, 'double=>double');% = 64; (* ARRAY[0..3] OF LONGREAL *) case 1000 @@ -198,7 +212,7 @@ function readPulseFileHEKA(obj,Level) sw.SwFiller2 = fread(fh, 1, 'int32=>int32');% = 152; (* INT32 *) sw.SwCRC = fread(fh, 1, 'int32=>int32');% = 156; (* CARD32 *) sw.SwSwHolding = fread(fh,16,'double=>double');% = 160; (* ARRAY[0..15] OF LONGREAL, see SwHoldingNo *) -switch obj.fileData.fileVersion +switch obj.opt.fileData.fileVersion case 9 sw.SweepRecSize = 288;% = 288; (* = 36 * 8 *) case 1000 @@ -212,7 +226,7 @@ function readPulseFileHEKA(obj,Level) %-------------------------------------------------------------------------- function tr=getTrace(obj) %-------------------------------------------------------------------------- -fh = obj.fileData.fh; +fh = obj.opt.fileData.fh; tr.TrMark = fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) tr.TrLabel = deblank(fread(fh, 32, 'uint8=>char')');% = 4; (* String32Type *) diff --git a/@HEKA_Importer/readSolutionFileHEKA.m b/@HEKA_Importer/HI_readSolutionFileHEKA.m similarity index 72% rename from @HEKA_Importer/readSolutionFileHEKA.m rename to @HEKA_Importer/HI_readSolutionFileHEKA.m index 33c890f..8c1a309 100644 --- a/@HEKA_Importer/readSolutionFileHEKA.m +++ b/@HEKA_Importer/HI_readSolutionFileHEKA.m @@ -1,13 +1,27 @@ -function readSolutionFileHEKA(obj,Level) +function HI_readSolutionFileHEKA(obj,Level) + +% extracts data stored in the "*.sol" file, or the corresponding portion of +% the bundled ".dat" file +% +% See also HEKA_Importer +% HEKA_Importer.HI_loadHEKAFile +% HEKA_Importer.HI_extractHEKASolutionTree +% HEKA_Importer.HI_extractHEKAStimTree +% HEKA_Importer.HI_extractHEKADataTree +% HEKA_Importer.HI_readPulseFileHEKA +% HEKA_Importer.HI_readStimulusFileHEKA +% HEKA_Importer.HI_readAmplifierFileHEKA +% HEKA_Importer.HI_readSolutionFileHEKA + %-------------------------------------------------------------------------- % Gets one record of the tree and the number of children s = getOneSolutionRecord(obj,Level); -obj.fileData.Tree{obj.fileData.Counter, Level+1} = s; +obj.opt.fileData.Tree{obj.opt.fileData.Counter, Level+1} = s; -obj.fileData.Position = obj.fileData.Position+obj.fileData.Sizes(Level+1); -fseek(obj.fileData.fh, obj.fileData.Position, 'bof'); -obj.fileData.nchild=fread(obj.fileData.fh, 1, 'int32=>int32'); -obj.fileData.Position=ftell(obj.fileData.fh); +obj.opt.fileData.Position = obj.opt.fileData.Position+obj.opt.fileData.Sizes(Level+1); +fseek(obj.opt.fileData.fh, obj.opt.fileData.Position, 'bof'); +obj.opt.fileData.nchild=fread(obj.opt.fileData.fh, 1, 'int32=>int32'); +obj.opt.fileData.Position=ftell(obj.opt.fileData.fh); end @@ -16,7 +30,7 @@ function readSolutionFileHEKA(obj,Level) function rec=getOneSolutionRecord(obj,Level) %-------------------------------------------------------------------------- % Gets one record -obj.fileData.Counter = obj.fileData.Counter+1; +obj.opt.fileData.Counter = obj.opt.fileData.Counter+1; switch Level case 0 rec=getSolutionRoot(obj); @@ -34,7 +48,7 @@ function readSolutionFileHEKA(obj,Level) %-------------------------------------------------------------------------- function p=getSolutionRoot(obj) %-------------------------------------------------------------------------- -fh = obj.fileData.fh; +fh = obj.opt.fileData.fh; p.RoVersion = fread(fh, 1, 'int16=>int16'); % = 0; (* INT16 *) p.RoDataBaseName = deblank(fread(fh, 80, 'uint8=>char')');% = 2; (* SolutionNameSize *) @@ -49,7 +63,7 @@ function readSolutionFileHEKA(obj,Level) %-------------------------------------------------------------------------- function s=getSolutionRecord(obj) %-------------------------------------------------------------------------- -fh = obj.fileData.fh; +fh = obj.opt.fileData.fh; s.SoNumber = fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) s.SoName = deblank(fread(fh, 80, 'uint8=>char')');% = 4; (* SolutionNameSize *) @@ -68,7 +82,7 @@ function readSolutionFileHEKA(obj,Level) %-------------------------------------------------------------------------- function c=getChemicalRecord(obj) %-------------------------------------------------------------------------- -fh = obj.fileData.fh; +fh = obj.opt.fileData.fh; c.ChConcentration = fread(fh, 1, 'real*4=>double');% = 0; (* REAL *) c.ChName = deblank(fread(fh, 30, 'uint8=>char')');% = 4; (* ChemicalNameSize *) diff --git a/@HEKA_Importer/readStimulusFileHEKA.m b/@HEKA_Importer/HI_readStimulusFileHEKA.m similarity index 92% rename from @HEKA_Importer/readStimulusFileHEKA.m rename to @HEKA_Importer/HI_readStimulusFileHEKA.m index 7e7aab0..43bb83f 100644 --- a/@HEKA_Importer/readStimulusFileHEKA.m +++ b/@HEKA_Importer/HI_readStimulusFileHEKA.m @@ -1,12 +1,26 @@ -function readStimulusFileHEKA(obj,Level) +function HI_readStimulusFileHEKA(obj,Level) +% +% extracts data stored in the "*.pgf" file, or the corresponding portion of +% the bundled ".dat" file +% +%% See also HEKA_Importer +% HEKA_Importer.HI_loadHEKAFile +% HEKA_Importer.HI_extractHEKASolutionTree +% HEKA_Importer.HI_extractHEKAStimTree +% HEKA_Importer.HI_extractHEKADataTree +% HEKA_Importer.HI_readPulseFileHEKA +% HEKA_Importer.HI_readStimulusFileHEKA +% HEKA_Importer.HI_readAmplifierFileHEKA +% HEKA_Importer.HI_readSolutionFileHEKA + %-------------------------------------------------------------------------- % Gets one record of the tree and the number of children s = getOneStimRecord(obj,Level); -obj.fileData.Tree{obj.fileData.Counter, Level+1} = s; -obj.fileData.Position = obj.fileData.Position+obj.fileData.Sizes(Level+1); -fseek(obj.fileData.fh, obj.fileData.Position, 'bof'); -obj.fileData.nchild=fread(obj.fileData.fh, 1, 'int32=>int32'); -obj.fileData.Position=ftell(obj.fileData.fh); +obj.opt.fileData.Tree{obj.opt.fileData.Counter, Level+1} = s; +obj.opt.fileData.Position = obj.opt.fileData.Position+obj.opt.fileData.Sizes(Level+1); +fseek(obj.opt.fileData.fh, obj.opt.fileData.Position, 'bof'); +obj.opt.fileData.nchild=fread(obj.opt.fileData.fh, 1, 'int32=>int32'); +obj.opt.fileData.Position=ftell(obj.opt.fileData.fh); end @@ -14,7 +28,7 @@ function readStimulusFileHEKA(obj,Level) function rec=getOneStimRecord(obj,Level) %-------------------------------------------------------------------------- % Gets one record -obj.fileData.Counter = obj.fileData.Counter+1; +obj.opt.fileData.Counter = obj.opt.fileData.Counter+1; switch Level case 0 rec=getStimRoot(obj); @@ -36,7 +50,7 @@ function readStimulusFileHEKA(obj,Level) %-------------------------------------------------------------------------- function p=getStimRoot(obj) %-------------------------------------------------------------------------- -fh = obj.fileData.fh; +fh = obj.opt.fileData.fh; p.RoVersion = fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) p.RoMark = fread(fh, 1, 'int32=>int32');% = 4; (* INT32 *) @@ -58,7 +72,7 @@ function readStimulusFileHEKA(obj,Level) %-------------------------------------------------------------------------- function s=getStimulation(obj) %-------------------------------------------------------------------------- -fh = obj.fileData.fh; +fh = obj.opt.fileData.fh; % Stimulus level s.stMark = fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) @@ -105,7 +119,7 @@ function readStimulusFileHEKA(obj,Level) %-------------------------------------------------------------------------- function c=getChannel(obj) %-------------------------------------------------------------------------- -fh = obj.fileData.fh; +fh = obj.opt.fileData.fh; c.chMark = fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) c.chLinkedChannel = fread(fh, 1, 'int32=>int32');% = 4; (* INT32 *) @@ -186,7 +200,7 @@ function readStimulusFileHEKA(obj,Level) %-------------------------------------------------------------------------- function ss=getStimSegment(obj) %-------------------------------------------------------------------------- -fh = obj.fileData.fh; +fh = obj.opt.fileData.fh; ss.seMark = fread(fh, 1, 'int32=>int32');% = 0; (* INT32 *) ss.seClass = fread(fh, 1, 'uint8=>uint8');% = 4; (* BYTE *) diff --git a/@HEKA_Importer/HI_time2date.m b/@HEKA_Importer/HI_time2date.m index c5a9139..1f3e54f 100644 --- a/@HEKA_Importer/HI_time2date.m +++ b/@HEKA_Importer/HI_time2date.m @@ -1,5 +1,17 @@ -%-------------------------------------------------------------------------- function str=HI_time2date(obj,t) + +% converts time stored in HEKA file to Matlab time format. +% +% See also HEKA_Importer +% HEKA_Importer.HI_loadHEKAFile +% HEKA_Importer.HI_extractHEKASolutionTree +% HEKA_Importer.HI_extractHEKAStimTree +% HEKA_Importer.HI_extractHEKADataTree +% HEKA_Importer.HI_readPulseFileHEKA +% HEKA_Importer.HI_readStimulusFileHEKA +% HEKA_Importer.HI_readAmplifierFileHEKA +% HEKA_Importer.HI_readSolutionFileHEKA + %-------------------------------------------------------------------------- t=t-1580970496; if t<0 From 62364f6ba5ae5a1093d72c831538171c18a5cf42 Mon Sep 17 00:00:00 2001 From: ChristianKeine Date: Mon, 24 Jun 2019 15:49:38 -0500 Subject: [PATCH 34/39] Update HEKA_Importer.m --- @HEKA_Importer/HEKA_Importer.m | 295 ++++++++++++++++----------------- 1 file changed, 147 insertions(+), 148 deletions(-) diff --git a/@HEKA_Importer/HEKA_Importer.m b/@HEKA_Importer/HEKA_Importer.m index 66fe6ee..7b4a64b 100644 --- a/@HEKA_Importer/HEKA_Importer.m +++ b/@HEKA_Importer/HEKA_Importer.m @@ -1,136 +1,135 @@ classdef HEKA_Importer < handle - -% Class to import HEKA Patchmaster files into Matlab. -% The core functionality is based on the HEKA importer from sigTool -% (https://doi.org/10.1016/j.neuron.2015.10.042 and -% https://github.com/irondukepublishing/sigTOOL) with modifications -% from Sammy Katta (https://github.com/sammykatta/Matlab-PatchMaster). -% -% This stand-alone importer works independently of sigTool and will -% additionally extract the stimulus (reconstructed from the pgf) -% and solutions (when solution base was active during recording). -% -% The recordings will be sorted into a table together with various -% parameters e.g series resistance (Rs), cell membrane capacitance (Cm), -% holding potential (Vhold), stimulus and solutions. -% -% Note: Currently, not all possible stimuli are supported. -% If your stimulus contains ramps or alternating segments, it will not be -% reconstructed properly. However, it should work fine for most stimuli -% and support for new stimuli will be added in the future. -% -% >> How to use: -% -% - INPUTS: -% -% - filepath char/string full file path and name of HEKA Patchmaster -% file that is to be loaded, -% e.g. to load HEKA Patchmaster file -% "MyData.dat" located in "C:\PatchClamp\" -% run "HEKA_Importer('C:\PatchClamp\MyData.dat')" -% -% *Alternative:* run "HEKA_Importer.GUI" which will open the file dialog -% box from which the Patchmaster file can be selected. -% -% - OUTPUTS: -% Heka_Importer creates object containing the following properties: -% -% - trees struct structure containing the dataTree -% (from the .pul file), the stimTree -% (from the .pgf file)and solTree -% (from the .sol file). These tree structures -% are how HEKA saves the metadata for -% different recordings. For details on the -% HEKA file format check -% ftp://server.hekahome.de/pub/FileFormat/Patchmasterv9/. -% -% - opt: struct structure containing different options when -% loading the file, currently it only contains -% the filepath of the HEKA Patchmaster file -% which was loaded and serves as placeholder -% for additional options in the future. -% -% - RecTable: table Matlab table containing the recordings and -% several parameters associated with them. -% Each row represents a different recording. -% The recorded data are stored in RecTable.dataRaw -% and sorted by channel within, e.g. -% "RecTable.dataRaw{1}{2}" contains all sweeps -% of the first series/recording for the second -% channel. The corresponding name of the -% channels is stored in "RecTable.chNames{1}". -% -% - solutions: table Matlab table containing the solutions and -% composition (chemicals & concentration) -% used during the experiments. This table is -% read-out from the solTree of the HEKA -% Patchmaster file and requires that the -% recordings were associated with a solution -% base (otherwise this variable will be empty). -% The names of solutions correspond to the -% columns "ExternalSolution" and "InternalSolution" -% of the RecTable. -% -% See also HEKA_Importer -% HEKA_Importer.HI_loadHEKAFile -% HEKA_Importer.HI_extractHEKASolutionTree -% HEKA_Importer.HI_extractHEKAStimTree -% HEKA_Importer.HI_extractHEKADataTree -% HEKA_Importer.HI_readPulseFileHEKA -% HEKA_Importer.HI_readStimulusFileHEKA -% HEKA_Importer.HI_readAmplifierFileHEKA -% HEKA_Importer.HI_readSolutionFileHEKA - - properties (Access = public) - - trees = []; % contains tree structure from Patchmaster files: dataTree, stimTree (stimulus parameters), and solTree (solutions) - opt - RecTable % contains recordings in table with various parameters, e.g. Rs, Cm, nSweeps ect. - solutions = [] - end - - - properties (Access = private) - % PLACEHOLDER - - end - - %% - methods (Access = public) - function obj = HEKA_Importer(filepath,varargin) %CONSTRUCTOR - - P = inputParser; - P.addRequired('filepath',@ischar) - P.parse(filepath,varargin{:}); - obj.opt = P.Results; - - obj.HI_loadHEKAFile; - + + % Class to import HEKA Patchmaster files into Matlab. + % The core functionality is based on the HEKA importer from sigTool + % (https://doi.org/10.1016/j.neuron.2015.10.042 and + % https://github.com/irondukepublishing/sigTOOL) with modifications + % from Sammy Katta (https://github.com/sammykatta/Matlab-PatchMaster). + % + % This stand-alone importer works independently of sigTool and will + % additionally extract the stimulus (reconstructed from the pgf) + % and solutions (when solution base was active during recording). + % + % The recordings will be sorted into a table together with various + % parameters e.g series resistance (Rs), cell membrane capacitance (Cm), + % holding potential (Vhold), stimulus and solutions. + % + % Note: Currently, not all possible stimuli are supported. + % If your stimulus contains ramps or alternating segments, it will not be + % reconstructed properly. However, it should work fine for most stimuli + % and support for new stimuli will be added in the future. + % + % >> How to use: + % + % - INPUTS: + % + % - filepath char/string full file path and name of HEKA Patchmaster + % file that is to be loaded, + % e.g. to load HEKA Patchmaster file + % "MyData.dat" located in "C:\PatchClamp\" + % run "HEKA_Importer('C:\PatchClamp\MyData.dat')" + % + % *Alternative:* run "HEKA_Importer.GUI" which will open the file dialog + % box from which the Patchmaster file can be selected. + % + % - OUTPUTS: + % Heka_Importer creates object containing the following properties: + % + % - trees struct structure containing the dataTree + % (from the .pul file), the stimTree + % (from the .pgf file)and solTree + % (from the .sol file). These tree structures + % are how HEKA saves the metadata for + % different recordings. For details on the + % HEKA file format check + % ftp://server.hekahome.de/pub/FileFormat/Patchmasterv9/. + % + % - opt: struct structure containing different options when + % loading the file, currently it only contains + % the filepath of the HEKA Patchmaster file + % which was loaded and serves as placeholder + % for additional options in the future. + % + % - RecTable: table Matlab table containing the recordings and + % several parameters associated with them. + % Each row represents a different recording. + % The recorded data are stored in RecTable.dataRaw + % and sorted by channel within, e.g. + % "RecTable.dataRaw{1}{2}" contains all sweeps + % of the first series/recording for the second + % channel. The corresponding name of the + % channels is stored in "RecTable.chNames{1}". + % + % - solutions: table Matlab table containing the solutions and + % composition (chemicals & concentration) + % used during the experiments. This table is + % read-out from the solTree of the HEKA + % Patchmaster file and requires that the + % recordings were associated with a solution + % base (otherwise this variable will be empty). + % The names of solutions correspond to the + % columns "ExternalSolution" and "InternalSolution" + % of the RecTable. + % + % See also HEKA_Importer + % HEKA_Importer.HI_loadHEKAFile + % HEKA_Importer.HI_extractHEKASolutionTree + % HEKA_Importer.HI_extractHEKAStimTree + % HEKA_Importer.HI_extractHEKADataTree + % HEKA_Importer.HI_readPulseFileHEKA + % HEKA_Importer.HI_readStimulusFileHEKA + % HEKA_Importer.HI_readAmplifierFileHEKA + % HEKA_Importer.HI_readSolutionFileHEKA + + properties (Access = public) + + trees = []; % contains tree structure from Patchmaster files: dataTree, stimTree (stimulus parameters), and solTree (solutions) + opt + RecTable % contains recordings in table with various parameters, e.g. Rs, Cm, nSweeps ect. + solutions = [] + end + + + properties (Access = private) + % PLACEHOLDER + + end + + %% + methods (Access = public) + function obj = HEKA_Importer(filepath,varargin) %CONSTRUCTOR + + P = inputParser; + P.addRequired('filepath',@ischar) + P.parse(filepath,varargin{:}); + obj.opt = P.Results; + + obj.HI_loadHEKAFile; + end - - end - - methods (Static, Hidden=false) - - function obj = GUI() % OPEN GUI TO SELECT RECORDING - - [file,path] = uigetfile({'*.dat','HEKA PATCHMASTER FILE'},'Select HEKA Patchmaster file to import',... - 'MultiSelect','off'); - - obj = HEKA_Importer(fullfile(path,file)); - - end - - end - - - methods (Access = private) - - HI_loadHEKAFile(obj,varargin); - HI_ImportHEKAtoMat(obj) - HI_extractHEKADataTree(obj); - HI_extractHEKAStimTree(obj); - HI_extractHEKASolutionTree(obj); + + end + + methods (Static, Hidden=false) + + function obj = GUI() % OPEN GUI TO SELECT RECORDING + + [file,path] = uigetfile({'*.dat','HEKA PATCHMASTER FILE'},'Select HEKA Patchmaster file to import',... + 'MultiSelect','off'); + + obj = HEKA_Importer(fullfile(path,file)); + + end + + end + + methods (Access = private) + + HI_loadHEKAFile(obj,varargin); + HI_ImportHEKAtoMat(obj) + HI_extractHEKADataTree(obj); + HI_extractHEKAStimTree(obj); + HI_extractHEKASolutionTree(obj); str = HI_time2date(obj,t); HI_readPulseFileHEKA(obj,Level); @@ -138,23 +137,23 @@ HI_readAmplifierFileHEKA(obj,Level); HI_readSolutionFileHEKA(obj,Level); end - - %% Hide some of the handle class member functions for ease of use. - methods (Hidden=true) - function notify(~) - end - function addlistener(~) - end - function findobj(~) - end - function findprop(~) - end - function listener(~) - end - function delete(~) - end - - end + + %% Hide some of the handle class member functions for ease of use. + methods (Hidden=true) + function notify(~) + end + function addlistener(~) + end + function findobj(~) + end + function findprop(~) + end + function listener(~) + end + function delete(~) + end + + end end From aed35ab42182d63e67f9d23dadc77b97492ab1d1 Mon Sep 17 00:00:00 2001 From: ChristianKeine Date: Tue, 25 Jun 2019 16:26:03 -0500 Subject: [PATCH 35/39] Update StimFile_v9.txt --- @HEKA_Importer/HEKA_FileFormat/FileFormat_2x90/StimFile_v9.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/@HEKA_Importer/HEKA_FileFormat/FileFormat_2x90/StimFile_v9.txt b/@HEKA_Importer/HEKA_FileFormat/FileFormat_2x90/StimFile_v9.txt index 778f417..2d9518a 100644 --- a/@HEKA_Importer/HEKA_FileFormat/FileFormat_2x90/StimFile_v9.txt +++ b/@HEKA_Importer/HEKA_FileFormat/FileFormat_2x90/StimFile_v9.txt @@ -194,6 +194,7 @@ chHasChirp = 217; (* BOOLEAN *) chSquare_Kind = 218; (* BYTE *) chFiller1 = 219; (* ARRAY[0..5] OF CHAR *) + chSquare_BaseIncr = 224; (* LONGREAL *) chSquare_Cycle = 232; (* LONGREAL *) chSquare_PosAmpl = 240; (* LONGREAL *) From 13afff258f1834eb72eb628012cb66df8beefbd1 Mon Sep 17 00:00:00 2001 From: ChristianKeine Date: Tue, 25 Jun 2019 16:37:21 -0500 Subject: [PATCH 36/39] Update HI_extractHEKADataTree.m --- @HEKA_Importer/HI_extractHEKADataTree.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/@HEKA_Importer/HI_extractHEKADataTree.m b/@HEKA_Importer/HI_extractHEKADataTree.m index 9d88e3c..f145db9 100644 --- a/@HEKA_Importer/HI_extractHEKADataTree.m +++ b/@HEKA_Importer/HI_extractHEKADataTree.m @@ -149,7 +149,7 @@ function HI_extractHEKADataTree(obj) for iCh = 1:nChannels for iS = 1:nSweeps(iR) - Rs_uncomp{iR}{1,iCh}(1,iS) = Recs(iR).Sweeps(iS).Traces(iCh).TrGSeries; + Rs_uncomp{iR}{1,iCh}(1,iS) = 1/Recs(iR).Sweeps(iS).Traces(iCh).TrGSeries; Rs{iR}{1,iCh}(1,iS) = Rs_uncomp{iR}{1,iCh}(1,iS) - Recs(iR).Sweeps(iS).Traces(iCh).TrRsValue; Cm{iR}{1,iCh}(1,iS) = Recs(iR).Sweeps(iS).Traces(iCh).TrCSlow; Vhold{iR}{1,iCh}(1,iS) = Recs(iR).Sweeps(iS).Traces(iCh).TrTrHolding; From eaefdbd68f48b7f3a3069dc907cba643de233da5 Mon Sep 17 00:00:00 2001 From: ChristianKeine Date: Tue, 25 Jun 2019 16:44:01 -0500 Subject: [PATCH 37/39] Update HI_readPulseFileHEKA.m --- @HEKA_Importer/HI_readPulseFileHEKA.m | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/@HEKA_Importer/HI_readPulseFileHEKA.m b/@HEKA_Importer/HI_readPulseFileHEKA.m index 89f148b..4033fc8 100644 --- a/@HEKA_Importer/HI_readPulseFileHEKA.m +++ b/@HEKA_Importer/HI_readPulseFileHEKA.m @@ -197,10 +197,9 @@ function HI_readPulseFileHEKA(obj,Level) sw.SwSwUserParams = fread(fh, 4, 'double=>double');% = 64; (* ARRAY[0..3] OF LONGREAL *) case 1000 sw.SwSwUserParams = fread(fh, 2, 'double=>double');% = 64; (* ARRAY[0..1] OF LONGREAL *) - sw.SwPipPressure = fread(fh, 2, 'double=>double');% = 80; (* LONGREAL * - sw.SwRMSNoise = fread(fh,2,'double=>double'); % = 88; (* LONGREAL *) + sw.SwPipPressure = fread(fh, 1, 'double=>double');% = 80; (* LONGREAL * + sw.SwRMSNoise = fread(fh,1,'double=>double'); % = 88; (* LONGREAL *) end -sw.SwSwUserParams = fread(fh, 2, 'double=>double');% = 64; (* ARRAY[0..1] OF LONGREAL *) sw.SwTemperature = fread(fh, 1, 'double=>double');% = 96; (* LONGREAL *) sw.SwOldIntSol = fread(fh, 1, 'int32=>int32');% = 104; (* INT32 *) sw.SwOldExtSol = fread(fh, 1, 'int32=>int32');% = 108; (* INT32 *) From a9d4762a1dc436fa8b69854cc8dc39cebadd0638 Mon Sep 17 00:00:00 2001 From: ChristianKeine Date: Tue, 25 Jun 2019 22:05:21 -0500 Subject: [PATCH 38/39] minor fix --- @HEKA_Importer/HI_extractHEKADataTree.m | 2 +- @HEKA_Importer/HI_readPulseFileHEKA.m | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/@HEKA_Importer/HI_extractHEKADataTree.m b/@HEKA_Importer/HI_extractHEKADataTree.m index f145db9..4345282 100644 --- a/@HEKA_Importer/HI_extractHEKADataTree.m +++ b/@HEKA_Importer/HI_extractHEKADataTree.m @@ -60,7 +60,7 @@ function HI_extractHEKADataTree(obj) recIDs = find(~cellfun(@isempty,dataTree(:,3))); recIDs = recIDs(recIDs>thisExpID & recIDsint32'); +if obj.opt.fileData.nchild >10 + +end obj.opt.fileData.Position=ftell(obj.opt.fileData.fh); end From 367aba14fbbb3240feb53c125cc36183915b91a0 Mon Sep 17 00:00:00 2001 From: ChristianKeine Date: Fri, 28 Jun 2019 17:33:41 -0500 Subject: [PATCH 39/39] Update HI_extractHEKADataTree.m --- @HEKA_Importer/HI_extractHEKADataTree.m | 1 - 1 file changed, 1 deletion(-) diff --git a/@HEKA_Importer/HI_extractHEKADataTree.m b/@HEKA_Importer/HI_extractHEKADataTree.m index 4345282..a28bc43 100644 --- a/@HEKA_Importer/HI_extractHEKADataTree.m +++ b/@HEKA_Importer/HI_extractHEKADataTree.m @@ -22,7 +22,6 @@ function HI_extractHEKADataTree(obj) %5: Trace/Channel %check if datetime functions exist - if ~isempty(which('datetime')) && ~isempty(which('NaT')) hasDateTime = true; else