source: fact/tools/matlabread/matlabread.cc@ 9841

Last change on this file since 9841 was 102, checked in by ogrimm, 15 years ago
Calling matlabread with empty filename allows fast browsing through previously opened file
File size: 8.5 KB
Line 
1// Function to read rawdata into Matlab
2//
3// Use 'make' on console to generate RawDataCTX.o.
4// Use 'mex matlabread.cc RawDataCTX.o' in Matlab to compile.
5//
6// When called with an empy filename, the previously open data file will be used.
7//
8// Oliver Grimm, September 2009
9
10
11#include <unistd.h>
12#include <string.h>
13
14#include "/ihp/local/Matlab08/extern/include/mex.h"
15#include "../../drsdaq/RawDataCTX.h"
16
17
18// static declaration keep variable alive over invocations of mex file
19static RawDataCTX *RD = NULL;
20
21// Exit function called when Matlab is terminated (RD==NULL is OK for delete)
22void ExitFcn() {
23 delete RD;
24}
25
26// Interface function to Matlab
27void mexFunction (int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
28
29 mexAtExit(*ExitFcn); // Exit function to call when matlab terminates
30
31 if (RD == NULL) RD = new RawDataCTX(true); // Instantiate without console output
32
33 // Check inputs and output arguments
34 if (nrhs<1 || nrhs>2 || (nrhs==2 && !mxIsDouble(prhs[1])) || nlhs<1 || nlhs>5) {
35 mexErrMsgTxt("Usage: [Data TrigCells RHeader BStructs EHeader] = matlabread('Filename', EventNo)");
36 }
37
38 char *Filename = mxArrayToString(prhs[0]);
39 if (Filename == NULL) mexErrMsgTxt("Could not create filename string.");
40
41 if (strlen(Filename) != 0) {
42 switch (RD->OpenDataFile(Filename), NULL) {
43 case CTX_FOPEN: mexErrMsgTxt("Could not open file.");
44 case CTX_RHEADER: mexErrMsgTxt("Could not read run header.");
45 case CTX_BSTRUCT: mexErrMsgTxt("Could not read board structures.");
46 }
47 if (RD->RHeader->MagicNum == MAGICNUM_OPEN) {
48 mexWarnMsgTxt("Magic number in run header indicates that the file has not "
49 "been closed properly.");
50 }
51 if (RD->RHeader->MagicNum == MAGICNUM_ERROR) {
52 mexWarnMsgTxt("Magic number in run header indicates that an error occurred "
53 "while writing the file.");
54 }
55 }
56 mxFree(Filename);
57
58 // ...some abbrevation for convenience
59 unsigned int Boards = RD->RHeader->NBoards;
60 unsigned int Channels = RD->RHeader->NChannels;
61 unsigned int Chips = RD->RHeader->NChips;
62 unsigned int Samples = RD->RHeader->Samples;
63
64 // Read event
65 if(RD->ReadEvent(mxIsDouble(prhs[1]) ? (int) mxGetScalar(prhs[1]):0, NULL) != CTX_OK) {
66 mexErrMsgTxt("Could not read event.");
67 }
68
69 // Dummy loop to allow different return values (break will be issued depending on nlhs)
70 while(true) {
71
72 // ========= Data array ==========
73
74 plhs[0] = mxCreateDoubleMatrix(Boards*Chips*Channels*Samples, 1, mxREAL);
75 unsigned int Count = 0;
76 for(unsigned int i=0; i<Boards; i++) {
77 for(unsigned int j=0; j<Chips*Channels*Samples; j++) {
78 *(mxGetPr(plhs[0])+Count) = (double) *((short *) (RD->Data+Boards*Chips*sizeof(int)) + Count++) * RD->BStruct[i].ScaleFactor;
79 }
80 }
81 // Resize into boards, channels and samples array
82 mwSize Dimensions[] = {Samples, Chips*Channels, Boards};
83 mxSetDimensions(plhs[0], Dimensions, sizeof(Dimensions)/sizeof(mwSize));
84
85 if (nlhs==1) break;
86
87 // ========= Trigger cell array ==========
88
89 plhs[1] = mxCreateDoubleMatrix(Chips, Boards, mxREAL);
90 for(unsigned int i=0; i<Boards*Chips; i++) {
91 *(mxGetPr(plhs[1])+i) = *((int *) (RD->Data+i*sizeof(int)));
92 }
93 if (nlhs==2) break;
94
95 // ========= Run header structure ==========
96
97 const char *RH_Fields[] = {"MagicNum", "DataFormat", "RunHeaderSize", "EventHeaderSize", "BoardStructureSize", "SoftwareRevision", "Identification", "Type","RunNumber", "FileNumber", "Description", "NBoards", "NChips", "NChannels", "Samples", "Offset", "Events", "NBytes", "StartSecond", "StartMicrosecond", "EndSecond", "EndMicrosecond"};
98 const mwSize RH_Dim[] = {1, 1};
99 plhs[2] = mxCreateStructArray(sizeof(RH_Dim)/sizeof(mwSize), RH_Dim, sizeof(RH_Fields)/sizeof(char *), RH_Fields);
100 mxArray *Data[sizeof(RH_Fields)/sizeof(char *)];
101
102 Data[0] = mxCreateNumericMatrix(1, 1, mxUINT32_CLASS, mxREAL);
103 memcpy(mxGetPr(Data[0]), &RD->RHeader->MagicNum, 4);
104 Data[1] = mxCreateNumericMatrix(1, 1, mxUINT32_CLASS, mxREAL);
105 memcpy(mxGetPr(Data[1]), &RD->RHeader->DataFormat, 4);
106 Data[2] = mxCreateNumericMatrix(1, 1, mxUINT32_CLASS, mxREAL);
107 memcpy(mxGetPr(Data[2]), &RD->RHeader->RunHeaderSize, 4);
108 Data[3] = mxCreateNumericMatrix(1, 1, mxUINT32_CLASS, mxREAL);
109 memcpy(mxGetPr(Data[3]), &RD->RHeader->EventHeaderSize, 4);
110 Data[4] = mxCreateNumericMatrix(1, 1, mxUINT32_CLASS, mxREAL);
111 memcpy(mxGetPr(Data[4]), &RD->RHeader->BoardStructureSize, 4);
112 Data[5] = mxCreateNumericMatrix(1, 1, mxINT32_CLASS, mxREAL);
113 memcpy(mxGetPr(Data[5]), &RD->RHeader->SoftwareRevision, 4);
114 Data[6] = mxCreateNumericMatrix(1, 1, mxUINT32_CLASS, mxREAL);
115 memcpy(mxGetPr(Data[6]), &RD->RHeader->Identification, 4);
116 Data[7] = mxCreateNumericMatrix(1, 1, mxUINT32_CLASS, mxREAL);
117 memcpy(mxGetPr(Data[7]), &RD->RHeader->Type, 4);
118 Data[8] = mxCreateNumericMatrix(1, 1, mxUINT32_CLASS, mxREAL);
119 memcpy(mxGetPr(Data[8]), &RD->RHeader->RunNumber, 4);
120 Data[9] = mxCreateNumericMatrix(1, 1, mxUINT32_CLASS, mxREAL);
121 memcpy(mxGetPr(Data[9]), &RD->RHeader->FileNumber, 4);
122 Data[10] = mxCreateString(RD->RHeader->Description);
123 Data[11] = mxCreateNumericMatrix(1, 1, mxUINT32_CLASS, mxREAL);
124 memcpy(mxGetPr(Data[11]), &RD->RHeader->NBoards, 4);
125 Data[12] = mxCreateNumericMatrix(1, 1, mxUINT32_CLASS, mxREAL);
126 memcpy(mxGetPr(Data[12]), &RD->RHeader->NChips, 4);
127 Data[13] = mxCreateNumericMatrix(1, 1, mxUINT32_CLASS, mxREAL);
128 memcpy(mxGetPr(Data[13]), &RD->RHeader->NChannels, 4);
129 Data[14] = mxCreateNumericMatrix(1, 1, mxUINT32_CLASS, mxREAL);
130 memcpy(mxGetPr(Data[14]), &RD->RHeader->Samples, 4);
131 Data[15] = mxCreateNumericMatrix(1, 1, mxUINT32_CLASS, mxREAL);
132 memcpy(mxGetPr(Data[15]), &RD->RHeader->Offset, 4);
133 Data[16] = mxCreateNumericMatrix(1, 1, mxUINT32_CLASS, mxREAL);
134 memcpy(mxGetPr(Data[16]), &RD->RHeader->Events, 4);
135 Data[17] = mxCreateNumericMatrix(1, 1, mxUINT32_CLASS, mxREAL);
136 memcpy(mxGetPr(Data[17]), &RD->RHeader->NBytes, 4);
137 Data[18] = mxCreateNumericMatrix(1, 1, mxUINT32_CLASS, mxREAL);
138 memcpy(mxGetPr(Data[18]), &RD->RHeader->StartSecond, 4);
139 Data[19] = mxCreateNumericMatrix(1, 1, mxUINT32_CLASS, mxREAL);
140 memcpy(mxGetPr(Data[19]), &RD->RHeader->StartMicrosecond, 4);
141 Data[20] = mxCreateNumericMatrix(1, 1, mxUINT32_CLASS, mxREAL);
142 memcpy(mxGetPr(Data[20]), &RD->RHeader->EndSecond, 4);
143 Data[21] = mxCreateNumericMatrix(1, 1, mxUINT32_CLASS, mxREAL);
144 memcpy(mxGetPr(Data[21]), &RD->RHeader->EndMicrosecond, 4);
145
146 for (int i=0; i<sizeof(RH_Fields)/sizeof(char *); i++) {
147 mxSetField(plhs[2], 0, RH_Fields[i], Data[i]);
148 }
149
150 if (nlhs==3) break;
151
152 // ========= Board structures ==========
153
154 const char *BS_Fields[] = {"SerialNo","NomFreq","BoardTemp","ScaleFactor"};
155 const mwSize BS_Dim[] = {1, Boards};
156 plhs[3] = mxCreateStructArray(sizeof(BS_Dim)/sizeof(mwSize), BS_Dim, sizeof(BS_Fields)/sizeof(char *), BS_Fields);
157 mxArray* (*BSData)[sizeof(BS_Fields)/sizeof(char *)] = new mxArray* [Boards][sizeof(BS_Fields)/sizeof(char *)];
158
159 for (int j=0; j<Boards; j++) {
160 BSData[j][0] = mxCreateNumericMatrix(1, 1, mxUINT32_CLASS, mxREAL);
161 BSData[j][1] = mxCreateNumericMatrix(1, 1, mxSINGLE_CLASS, mxREAL);
162 BSData[j][2] = mxCreateNumericMatrix(1, 1, mxSINGLE_CLASS, mxREAL);
163 BSData[j][3] = mxCreateNumericMatrix(1, 1, mxSINGLE_CLASS, mxREAL);
164
165 memcpy(mxGetPr(BSData[j][0]), &RD->BStruct[j].SerialNo, 4);
166 memcpy(mxGetPr(BSData[j][1]), &RD->BStruct[j].NomFreq, 4);
167 memcpy(mxGetPr(BSData[j][2]), &RD->BStruct[j].BoardTemp, 4);
168 memcpy(mxGetPr(BSData[j][3]), &RD->BStruct[j].ScaleFactor, 4);
169
170 for (int i=0; i<sizeof(BS_Fields)/sizeof(char *); i++) {
171 mxSetField(plhs[3], j, BS_Fields[i], BSData[j][i]);
172 }
173 }
174 if (nlhs==4) break;
175
176 // ========= Event header structure ==========
177
178 const char *EH_Fields[] = {"EventNumber", "Second", "Microsecond", "TriggerType", "EventSize"};
179 const mwSize EH_Dim[] = {1, 1};
180 plhs[4] = mxCreateStructArray(sizeof(EH_Dim)/sizeof(mwSize), EH_Dim, sizeof(EH_Fields)/sizeof(char *), EH_Fields);
181 mxArray *EHData[sizeof(EH_Fields)/sizeof(char *)];
182
183 for (int i=0; i<sizeof(EH_Fields)/sizeof(char *); i++) {
184 EHData[i] = mxCreateNumericMatrix(1, 1, mxUINT32_CLASS, mxREAL);
185 }
186 memcpy(mxGetPr(EHData[0]), &RD->EHeader->EventNumber, 4);
187 memcpy(mxGetPr(EHData[1]), &RD->EHeader->Second, 4);
188 memcpy(mxGetPr(EHData[2]), &RD->EHeader->Microsecond, 4);
189 memcpy(mxGetPr(EHData[3]), &RD->EHeader->TriggerType, 4);
190 memcpy(mxGetPr(EHData[4]), &RD->EHeader->EventSize, 4);
191 for (int i=0; i<sizeof(EH_Fields)/sizeof(char *); i++) {
192 mxSetField(plhs[4], 0, EH_Fields[i], EHData[i]);
193 }
194 if (nlhs>=5) break;
195
196 } // Dummy while loop
197}
Note: See TracBrowser for help on using the repository browser.