Develop and Download Open Source Software

Browse CVS Repository

Contents of /satellite/neuromanager/MultiChannelData.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.13 - (show annotations) (download) (as text)
Sat Feb 4 13:11:21 2006 UTC (18 years, 2 months ago) by orrisroot
Branch: MAIN
CVS Tags: HEAD
Changes since 1.12: +1 -1 lines
File MIME type: text/x-c++src
FILE REMOVED
imported satellite4 base library sources.
moved base class of multi channel data class 'CMultiChannelData' to dll.

1 /* --------------------------------------------------------------------- */
2 /* NeuroManager - A spike train analysis tool */
3 /* Copyright (c) 2005-2006 RIKEN, Japan. All rights reserved. */
4 /* http://satellite.sourceforge.jp/ */
5 /* --------------------------------------------------------------------- */
6 /* This program is free software; you can redistribute it and/or */
7 /* modify it under the terms of the GNU General Public License */
8 /* as published by the Free Software Foundation; either version 2 */
9 /* of the License, or (at your option) any later version. */
10 /* */
11 /* This program is distributed in the hope that it will be useful, */
12 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
13 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
14 /* GNU General Public License for more details. */
15 /* */
16 /* You should have received a copy of the GNU General Public License */
17 /* along with this program; see the file COPYING.txt. If not, write */
18 /* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth */
19 /* Floor, Boston, MA 02110-1301, USA. */
20 /* --------------------------------------------------------------------- */
21
22 /* $Id: MultiChannelData.cpp,v 1.12 2006/02/02 07:33:27 orrisroot Exp $ */
23
24 // MultiChannelData.cpp : implementation of the CMultiChannelData class
25 //
26
27 #include "stdafx.h"
28 #include "MultiChannelData.h"
29
30 #include <math.h>
31
32 #define MULTICHANNELDATA_MUTEX "CMultiChannelData_Mutex"
33
34
35 CMultiChannelData::CMultiChannelData()
36 {
37 InitValues();
38 // create mutex
39 m_pMutex = new CMutex( FALSE, MULTICHANNELDATA_MUTEX );
40 }
41
42 CMultiChannelData::~CMultiChannelData()
43 {
44 if ( m_bIsMapped )
45 {
46 UnmappingBinaryFile();
47 }
48 // delete mutex
49 delete m_pMutex;
50 InitValues();
51 }
52
53 void CMultiChannelData::InitValues()
54 {
55 // user defined value
56 m_qwYRangeCalcPoint = 200000;
57 // data infomation
58 m_strDataFile = _T( "" );
59 m_dSamplingRate = 0.0;
60 m_uiChannelNumber = 0;
61 m_qwLength = 0;
62 m_uiBitLength = 0;
63 m_bByteSwap = FALSE;
64 m_dwaOffset.RemoveAll();
65 m_daGain.RemoveAll();
66 m_dYAxisRange.RemoveAll();
67
68 // for performance tuning
69 m_uiAttachedChannel = 0;
70 m_dAttachedGain = 0.0;
71
72 // for file mapping
73 m_bIsMapped = FALSE;
74 m_dwMapSizeHigh = 0;
75 m_dwMapSizeLow = 0;
76 m_hDataFile = NULL;
77 m_hMapping = NULL;
78 m_pMappingView = NULL;
79 m_pMutex = NULL;
80
81 m_dwMapViewOffsetHigh = 0;
82 m_dwMapViewOffsetLow = 0;
83 m_sizetMapViewPageCurrent = 0;
84 m_sizetMapViewPageMax = 0;
85 m_sizetMapViewSize = 0;
86 m_sizetMapViewSizeLastPage = 0;
87 m_sizetMapViewSizePage = 0;
88 m_sizetMapViewSizeLimit = 134217728; /* max 128MB - 1024*1024*128 */
89
90 }
91
92 void CMultiChannelData::CalcYAxisRange()
93 {
94 ASSERT( m_bIsMapped );
95 double d, max;
96 QWORD calclen = ( m_qwYRangeCalcPoint < m_qwLength ) ? m_qwYRangeCalcPoint : m_qwLength ;
97 m_dYAxisRange.RemoveAll();
98 // lock mutex
99 m_pMutex->Lock();
100 for ( UINT ch = 0; ch < m_uiChannelNumber; ch++ )
101 {
102 max = 0.0;
103 m_uiAttachedChannel = ch;
104 m_dAttachedGain = ( double ) m_daGain.GetAt( ch );
105 for ( QWORD i = 0; i < calclen; i++ )
106 {
107 d = fabs( _getdata( i ) );
108 if ( max < d )
109 max = d;
110 }
111 m_dYAxisRange.Add( max );
112 m_uiAttachedChannel = 0;
113 m_dAttachedGain = 0.0;
114 }
115 // unlock mutex
116 m_pMutex->Unlock();
117 }
118
119 double CMultiChannelData::GetYAxisRange( UINT ch )
120 {
121 ASSERT( m_bIsMapped );
122 return ( double ) m_dYAxisRange.GetAt( ch );
123 }
124
125 void CMultiChannelData::SwapData( char *data, int siz )
126 {
127 int i;
128 char c;
129 int half = siz / 2;
130 int j = siz - 1;
131 for ( i = 0; i < half; i++ )
132 {
133 c = data[ i ];
134 data[ i ] = data[ j - i ];
135 data[ j - i ] = c;
136 }
137 }
138
139 double CMultiChannelData::_getdata( QWORD pos )
140 {
141 double ret = 0.0;
142 QWORD dataOffset = pos * m_uiChannelNumber + m_uiAttachedChannel;
143 QWORD rawOffset = dataOffset * m_uiBitLength;
144 SIZE_T newPage = ( SIZE_T ) ( rawOffset / m_sizetMapViewSizePage );
145 if ( newPage != m_sizetMapViewPageCurrent )
146 {
147 // move mapping page
148 SIZE_T newSize;
149 if ( newPage == m_sizetMapViewPageMax )
150 newSize = m_sizetMapViewSizeLastPage;
151 else
152 newSize = m_sizetMapViewSizePage;
153 SIZE_T newOffset = newPage * m_sizetMapViewSizePage;
154 DWORD newOffsetHigh = HIDWORD( newOffset );
155 DWORD newOffsetLow = LODWORD( newOffset );
156 // close mapping view handle
157 ::UnmapViewOfFile( m_pMappingView );
158 // map view
159 m_pMappingView = ( LPBYTE ) ::MapViewOfFile( m_hMapping, FILE_MAP_READ,
160 newOffsetHigh, newOffsetLow, newSize );
161 if ( m_pMappingView == NULL )
162 {
163 CString str;
164 str.Format( "Fatal Error : %s %d", __FILE__, __LINE__ );
165 AfxMessageBox( str, MB_OK );
166 // TODO: exit
167 }
168 m_dwMapViewOffsetHigh = newOffsetHigh;
169 m_dwMapViewOffsetLow = newOffsetLow;
170 m_sizetMapViewSize = newSize;
171 m_sizetMapViewPageCurrent = newPage;
172 }
173 if ( m_sizetMapViewPageCurrent != 0 )
174 {
175 QWORD fix = MAKEQWORD( m_dwMapViewOffsetLow, m_dwMapViewOffsetHigh ) / m_uiBitLength;
176 dataOffset -= fix;
177 }
178 switch ( m_uiBitLength )
179 {
180 case 2:
181 {
182 short * sptr = ( short* ) m_pMappingView;
183 short sd = sptr[ dataOffset ];
184 if ( m_bByteSwap )
185 SwapData( ( char* ) & sd, 2 );
186 ret = m_dAttachedGain * ( double ) sd;
187 }
188 break;
189 case 4:
190 {
191 int *iptr = ( int* ) m_pMappingView;
192 int id = iptr[ dataOffset ];
193 if ( m_bByteSwap )
194 SwapData( ( char* ) & id, 4 );
195 ret = m_dAttachedGain * ( double ) id;
196 }
197 break;
198 case 8:
199 {
200 double *dptr = ( double* ) m_pMappingView;
201 double dd = dptr[ dataOffset ];
202 if ( m_bByteSwap )
203 SwapData( ( char* ) & dd, 8 );
204 ret = m_dAttachedGain * dd;
205 }
206 break;
207 default:
208 break;
209 }
210 return ret;
211 }
212
213 void CMultiChannelData::AttachData( UINT ch )
214 {
215 // lock mutex
216 m_pMutex->Lock();
217 m_uiAttachedChannel = ch;
218 m_dAttachedGain = ( double ) m_daGain.GetAt( ch );
219 }
220
221 void CMultiChannelData::DetachData()
222 {
223 m_uiAttachedChannel = 0;
224 m_dAttachedGain = 0.0;
225 // unlock mutex
226 m_pMutex->Unlock();
227 }
228
229 double CMultiChannelData::GetData( QWORD pos )
230 {
231 ASSERT( m_bIsMapped );
232 return _getdata( pos );
233 }
234
235 double CMultiChannelData::GetPosTime( QWORD pos ) const
236 {
237 ASSERT( m_bIsMapped );
238 return ( double ) pos / m_dSamplingRate;
239 }
240
241
242 void CMultiChannelData::PrintDataInfo()
243 {
244 CString str = FormatDataInfo();
245 MessageBox( NULL, str, _T( "data information" ), MB_OK );
246 }
247
248
249 CString CMultiChannelData::FormatDataInfo()
250 {
251 CString str, tmp;
252 tmp.Format( _T( "is Mapped : %s\n" ), ( m_bIsMapped ? _T( "TRUE" ) : _T( "FALSE" ) ) );
253 str = tmp;
254 tmp.Format( _T( "Samping Rate : %f\n" ), m_dSamplingRate );
255 str += tmp;
256 tmp.Format( _T( "Channel No. : %u\n" ), m_uiChannelNumber );
257 str += tmp;
258 tmp.Format( _T( "Data Length : %I64d\n" ), m_qwLength );
259 str += tmp;
260 INT_PTR size = m_dwaOffset.GetSize();
261 for ( INT_PTR i = 0; i < size; i++ )
262 {
263 tmp.Format( _T( "Data Offset[%d] : %d\n" ), i, m_dwaOffset.GetAt( i ) );
264 str += tmp;
265 }
266 tmp.Format( _T( "Bit Length : %d\n" ), m_uiBitLength );
267 str += tmp;
268 tmp.Format( _T( "Byte Swap : %s\n" ), ( m_bByteSwap ? _T( "TRUE" ) : _T( "FALSE" ) ) );
269 str += tmp;
270 return str;
271 }
272
273 BOOL CMultiChannelData::MappingBinaryFile()
274 {
275 // lock mutex
276 m_pMutex->Lock();
277 // error check
278 if ( m_strDataFile.IsEmpty() )
279 {
280 m_pMutex->Unlock();
281 return FALSE;
282 }
283 if ( m_bIsMapped )
284 {
285 // unlock mutex
286 m_pMutex->Unlock();
287 return FALSE;
288 }
289 if ( m_uiBitLength == 0 )
290 {
291 // unlock mutex
292 m_pMutex->Unlock();
293 return FALSE;
294 }
295 // file open
296 m_hDataFile = ::CreateFile( m_strDataFile, GENERIC_READ,
297 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
298 if ( m_hDataFile == INVALID_HANDLE_VALUE )
299 {
300 m_hDataFile = NULL;
301 // unlock mutex
302 m_pMutex->Unlock();
303 return FALSE;
304 }
305 BY_HANDLE_FILE_INFORMATION bhfi;
306 if ( !GetFileInformationByHandle( m_hDataFile, &bhfi ) )
307 {
308 ::CloseHandle( m_hDataFile );
309 m_hDataFile = NULL;
310 // unlock mutex
311 m_pMutex->Unlock();
312 return FALSE;
313 }
314 m_dwMapSizeHigh = bhfi.nFileSizeHigh;
315 m_dwMapSizeLow = bhfi.nFileSizeLow;
316 // create file mapping object
317 m_hMapping = ::CreateFileMapping( m_hDataFile, NULL, PAGE_READONLY,
318 m_dwMapSizeHigh, m_dwMapSizeLow, NULL );
319 if ( m_hMapping == NULL )
320 {
321 ::CloseHandle( m_hDataFile );
322 m_hDataFile = NULL;
323 // unlock mutex
324 m_pMutex->Unlock();
325 return FALSE;
326 }
327 // calcurate block size of mapping view memory
328 SIZE_T nFileSize = ( ( SIZE_T ) m_dwMapSizeHigh << 32 ) + m_dwMapSizeLow;
329 m_sizetMapViewPageMax = nFileSize / m_sizetMapViewSizeLimit;
330 m_sizetMapViewSizeLastPage = nFileSize % m_sizetMapViewSizeLimit;
331 if ( m_sizetMapViewPageMax == 0 )
332 m_sizetMapViewSizePage = m_dwMapSizeLow;
333 else
334 m_sizetMapViewSizePage = m_sizetMapViewSizeLimit;
335 m_sizetMapViewPageCurrent = 0;
336
337 // map file
338 m_pMappingView = ( LPBYTE ) ::MapViewOfFile( m_hMapping, FILE_MAP_READ,
339 m_dwMapViewOffsetHigh, m_dwMapViewOffsetLow, m_sizetMapViewSizePage );
340 if ( m_pMappingView == NULL )
341 {
342 ::UnmapViewOfFile( m_hMapping );
343 m_hMapping = NULL;
344 m_dwMapSizeHigh = 0;
345 m_dwMapSizeLow = 0;
346 m_dwMapViewOffsetHigh = 0;
347 m_dwMapViewOffsetLow = 0;
348 m_sizetMapViewPageCurrent = 0;
349 m_sizetMapViewPageMax = 0;
350 m_sizetMapViewSize = 0;
351 m_sizetMapViewSizeLastPage = 0;
352 m_sizetMapViewSizePage = 0;
353 ::CloseHandle( m_hDataFile );
354 m_hDataFile = NULL;
355 // unlock mutex
356 m_pMutex->Unlock();
357 return FALSE;
358 }
359 // set mapping status
360 m_bIsMapped = TRUE;
361 // unlock mutex
362 m_pMutex->Unlock();
363 return TRUE;
364 }
365
366 BOOL CMultiChannelData::UnmappingBinaryFile()
367 {
368 // lock mutex
369 m_pMutex->Lock();
370 if ( !m_bIsMapped )
371 {
372 // unlock mutex
373 m_pMutex->Unlock();
374 return FALSE;
375 }
376 // unmap file
377 ::UnmapViewOfFile( m_pMappingView );
378 m_pMappingView = NULL;
379 // close file mapping object
380 ::CloseHandle( m_hMapping );
381 m_hMapping = NULL;
382 m_dwMapSizeHigh = 0;
383 m_dwMapSizeLow = 0;
384 m_dwMapViewOffsetHigh = 0;
385 m_dwMapViewOffsetLow = 0;
386 m_sizetMapViewPageCurrent = 0;
387 m_sizetMapViewPageMax = 0;
388 m_sizetMapViewSize = 0;
389 m_sizetMapViewSizeLastPage = 0;
390 m_sizetMapViewSizePage = 0;
391 // close file
392 ::CloseHandle( m_hDataFile );
393 m_hDataFile = NULL;
394 // unset mapping status
395 m_bIsMapped = FALSE;
396 // unlock mutex
397 m_pMutex->Unlock();
398 return TRUE;
399 }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26