Medial Code Documentation
Loading...
Searching...
No Matches
MedSignals.h
1//
2// MedSignals.h : Signal types definitions
3//
4#define __INFRAMED_DLL
5#ifndef __MEDSIGNALS__H__
6#define __MEDSIGNALS__H__
7
8#include <string>
9#include <vector>
10#include <map>
11#include <algorithm>
13#include <iostream>
14#include <memory>
15#include <cstring>
16#include <array>
17
18using namespace std;
19
20#define N_SignalTypes
21#define GENERIC_SIG_VEC_MAX_CHANNELS 30
22
23
24#ifndef USE_LEGACY_USV
25class GenericSigVec;
27typedef class GenericSigVec UniversalSigVec;
28typedef class GenericSigVec_mem UniversalSigVec_mem;
29#else // legacy USV
32typedef class UniversalSigVec_legacy UniversalSigVec;
33typedef class UniversalSigVec_mem_legacy UniversalSigVec_mem;
34#endif
35
36
37enum SigType {
38 T_Value = 0, // 0 :: single float Value
39 T_DateVal, // 1 :: date (32 bit space yyyymmdd reccomended) , float value (MOST COMMON !)
40 T_TimeVal, // 2 :: date-time tag (64 bit space), float value
41 T_DateRangeVal, // 3 :: date start, date end, float value
42 T_TimeStamp, // 4 :: 64 bits of data (mainly for time stamps)
43 T_TimeRangeVal, // 5 :: time-time + value
44 T_DateVal2, // 6 :: date, float value, unsigned short additional value (specially tailored to drug code + drug period - to save a lot of space)
45 T_TimeLongVal, // 7 :: date-time (64 bit) + long long value
46 T_DateShort2, // 8 :: date (32 bits) + 2 short values (perfect for BP for example).
47 T_ValShort2, // 9 :: 2 short values
48 T_ValShort4, // 10 :: 4 short values
49 T_CompactDateVal, // 11 :: 2 unsigned shorts - first is a compact date (in 16 bits), second in an unsigned short value
50 T_DateRangeVal2, // 12 :: date start, date end, 2 float values
51 T_DateFloat2, // 13 :: date + 2 float values
52 T_TimeRange, // 14 :: time-time
53 T_TimeShort4, // 15 :: time + 4 shorts
54 T_Generic, // 16 :: generic signal
55 T_Last
56}; // :: next free slot for type id
57
58namespace MedRep {
59 int get_type_size(SigType t);
60 int get_type_channels(SigType t, int &time_unit, int &n_time_chans, int &n_val_chans);
61 int get_type_channels(const string& sigSpec, int &time_unit, int &n_time_chans, int &n_val_chans);
62 template <class T> int get_type_channels_info(int &time_unit, int &n_time_chans, int &n_val_chans) {
63 time_unit = T::time_unit();
64 n_time_chans = T::n_time_channels();
65 n_val_chans = T::n_val_channels();
66 return 0;
67 }
68}
69
70//======================================================================
71// UnifiedSig - unifiying API's for signals
72// This has only virtual functions and functions built with them
73// Never add a data member to UnifiedSig !
74//======================================================================
76public:
77
78 // channels numbers
79 inline int n_time_channels() { return 0; }
80 inline int n_val_channels() { return 0; }
81
82 // time unit & unitless time
83 inline int time_unit() { return 0; }
84 inline int Time(int chan) { return 0; }
85
86 // value channels float
87 inline float Val(int chan) { return 0; }
88 inline void SetVal(int chan, float _val) {}
89
90 // Following functions are implemented based on the functions above (and save lots of coding hence)
91 // time channels int
92 inline int Date(int chan) { return med_time_converter.convert_times(time_unit(), MedTime::Date, Time(chan)); }
93 inline int Years(int chan) { return med_time_converter.convert_times(time_unit(), MedTime::Years, Time(chan)); }
94 inline int Months(int chan) { return med_time_converter.convert_times(time_unit(), MedTime::Months, Time(chan)); }
95 inline int Days(int chan) { return med_time_converter.convert_times(time_unit(), MedTime::Days, Time(chan)); }
96 inline int Hours(int chan) { return med_time_converter.convert_times(time_unit(), MedTime::Hours, Time(chan)); }
97 inline int Minutes(int chan) { return med_time_converter.convert_times(time_unit(), MedTime::Minutes, Time(chan)); }
98
99
100 // channel 0 easy access
101 inline int Date() { return Date(0); }
102 inline int Years() { return Years(0); }
103 inline int Months() { return Months(0); }
104 inline int Days() { return Days(0); }
105 inline int Hours() { return Hours(0); }
106 inline int Minutes() { return Minutes(0); }
107 inline float Val() { return Val(0); }
108};
109
110//=============================================================================================
111// General Fill in function
112//=============================================================================================
113int MedSignalsSingleElemFill(int sig_type, char *buf, int *time_data, float *val_data);
114
115
116//===================================
117// SVal
118//===================================
119class SVal : public UnifiedSig {
120public:
121 float val;
122
123 // unified API extension
124 static inline int n_time_channels() { return 0; }
125 static inline int n_val_channels() { return 1; }
126 static inline int time_unit() { return 0; }
127 inline int Time(int chan) { return 0; }
128 inline float Val(int chan) { return val; }
129 inline void SetVal(int chan, float _val) { val = _val; };
130
131 inline void Set(float _val) { val = _val; }
132 inline void Set(int *times, float *vals) { val = vals[0]; }
133
134 bool operator<(const SVal& s) { return (this->val < s.val); }
135 bool operator==(const SVal& s) { return (this->val == s.val); }
136
137 friend ostream& operator<<(ostream& os, const SVal& s) { os << s.val; return os; }
138};
139
140
141//===================================
142// SDateVal
143//===================================
144class SDateVal : public UnifiedSig {
145public:
146 int date;
147 float val;
148
149 // unified API extention
150 static inline int n_time_channels() { return 1; }
151 static inline int n_val_channels() { return 1; }
152 static inline int time_unit() { return MedTime::Date; }
153 inline int Time(int chan) { return date; }
154 inline float Val(int chan) { return val; }
155 inline void SetVal(int chan, float _val) { val = _val; };
156
157 inline void Set(int _date, float _val) { date = _date; val = _val; }
158 inline void Set(int *times, float *vals) { date = times[0]; val = vals[0]; }
159
160 bool operator<(const SDateVal& s) { if (this->date < s.date) return true; if (this->date > s.date) return false; return (this->val < s.val); }
161 bool operator==(const SDateVal& s) { return (this->val == s.val && this->date == s.date); }
162
163 friend ostream& operator<<(ostream& os, const SDateVal& s) { os << s.date << ":" << s.val; return os; }
164};
165
166//===================================
167// STimeVal
168//===================================
169class STimeVal : public UnifiedSig {
170public:
171 long long time;
172 float val;
173
174 // unified API extention
175 static inline int n_time_channels() { return 1; }
176 static inline int n_val_channels() { return 1; }
177 static inline int time_unit() { return MedTime::Minutes; }
178 inline int Time(int chan) { return (int)time; } // assuming minutes span are within the size of an int
179 inline float Val(int chan) { return val; }
180 inline void SetVal(int chan, float _val) { val = _val; };
181
182 inline void Set(long long _time, float _val) { time = _time; val = _val; }
183 inline void Set(int *times, float *vals) { time = (long long)times[0]; val = vals[0]; }
184
185 bool operator<(const STimeVal& s) { if (this->time < s.time) return true; if (this->time > s.time) return false; return (this->val < s.val); }
186 bool operator==(const STimeVal& s) { return (this->val == s.val && this->time == s.time); }
187
188 friend ostream& operator<<(ostream& os, const STimeVal& s) { os << s.time << ":" << s.val; return os; }
189
190};
191
192//===================================
193// SDateRangeVal
194//===================================
195class SDateRangeVal : public UnifiedSig {
196public:
197 int date_start;
198 int date_end;
199 float val;
200
201 // unified API extention
202 static inline int n_time_channels() { return 2; }
203 static inline int n_val_channels() { return 1; }
204 static inline int time_unit() { return MedTime::Date; }
205 inline int Time(int chan) { return ((chan) ? (date_end) : (date_start)); } // assuming minutes span are within the size of an int
206 inline float Val(int chan) { return val; }
207 inline void SetVal(int chan, float _val) { val = _val; };
208
209 inline void Set(int _date_start, int _date_end, float _val) { date_start = _date_start; date_end = _date_end; val = _val; }
210 inline void Set(int *times, float *vals) { date_start = times[0]; date_end = times[1]; val = vals[0]; }
211
212 bool operator<(const SDateRangeVal& s) {
213 if (this->date_start < s.date_start) return true;
214 if (this->date_start > s.date_start) return false;
215 if (this->date_end < s.date_end) return true;
216 if (this->date_end > s.date_end) return false;
217 return (this->val < s.val);
218 }
219 bool operator==(const SDateRangeVal& s) { return (this->val == s.val && this->date_start == s.date_start && this->date_end == s.date_end); }
220
221 friend ostream& operator<<(ostream& os, const SDateRangeVal& s) { os << s.date_start << "-" << s.date_end << ":" << s.val; return os; }
222
223};
224
225//===================================
226// SDateRangeVal2
227//===================================
229public:
230 int date_start;
231 int date_end;
232 float val;
233 float val2;
234
235 // unified API extention
236 static inline int n_time_channels() { return 2; }
237 static inline int n_val_channels() { return 2; }
238 static inline int time_unit() { return MedTime::Date; }
239 inline int Time(int chan) { return ((chan) ? (date_end) : (date_start)); } // assuming minutes span are within the size of an int
240 inline float Val(int chan) { return ((chan) ? (float)val2 : (float)val); }
241 inline void SetVal(int chan, float _val) { (chan) ? val2 = _val : val = _val; };
242
243 inline void Set(int _date_start, int _date_end, float _val, float _val2) { date_start = _date_start; date_end = _date_end; val = _val; val2 = _val2; }
244 inline void Set(int *times, float *vals) { date_start = times[0]; date_end = times[1]; val = vals[0]; val2 = vals[1]; }
245
246 bool operator<(const SDateRangeVal2& s) {
247 if (this->date_start < s.date_start) return true;
248 if (this->date_start > s.date_start) return false;
249 if (this->date_end < s.date_end) return true;
250 if (this->date_end > s.date_end) return false;
251 if (this->val < s.val) return true;
252 if (this->val > s.val) return false;
253 return (this->val2 < s.val2);
254 }
255 bool operator==(const SDateRangeVal2& s) { return (this->val == s.val && this->val2 == s.val2 && this->date_start == s.date_start && this->date_end == s.date_end); }
256
257 friend ostream& operator<<(ostream& os, const SDateRangeVal2& s) { os << s.date_start << "-" << s.date_end << ":" << s.val << "," << s.val2; return os; }
258
259};
260
261//===================================
262// SDateFloat2
263//===================================
264class SDateFloat2 : public UnifiedSig {
265public:
266 int date;
267 float val;
268 float val2;
269
270 // unified API extention
271 static inline int n_time_channels() { return 1; }
272 static inline int n_val_channels() { return 2; }
273 static inline int time_unit() { return MedTime::Date; }
274 inline int Time(int chan) { return date; } // assuming minutes span are within the size of an int
275 inline float Val(int chan) { return ((chan) ? (float)val2 : (float)val); }
276 inline void SetVal(int chan, float _val) { (chan) ? val2 = _val : val = _val; };
277
278 inline void Set(int _date, float _val, float _val2) { date = _date; val = _val; val2 = _val2; }
279 inline void Set(int *times, float *vals) { date = times[0]; val = vals[0]; val2 = vals[1]; }
280
281 bool operator<(const SDateFloat2& s) {
282 if (this->date < s.date) return true;
283 if (this->date > s.date) return false;
284 if (this->val < s.val) return true;
285 if (this->val > s.val) return false;
286 return (this->val2 < s.val2);
287 }
288 bool operator==(const SDateFloat2& s) { return (this->val == s.val && this->val2 == s.val2 && this->date == s.date); }
289
290 friend ostream& operator<<(ostream& os, const SDateFloat2& s) { os << s.date << ":" << s.val << "," << s.val2; return os; }
291
292};
293
294//===================================
295// STimeRangeVal
296//===================================
297class STimeRangeVal : public UnifiedSig {
298public:
299 long long time_start;
300 long long time_end;
301 float val;
302
303 // unified API extention
304 static inline int n_time_channels() { return 2; }
305 static inline int n_val_channels() { return 1; }
306 static inline int time_unit() { return MedTime::Minutes; }
307 inline int Time(int chan) { return ((chan) ? ((int)time_end) : ((int)time_start)); } // assuming minutes span are within the size of an int
308 inline float Val(int chan) { return val; }
309 inline void SetVal(int chan, float _val) { val = _val; };
310
311 inline void Set(long long _time_start, long long _time_end, float _val) { time_start = _time_start; time_end = _time_end; val = _val; }
312 inline void Set(int *times, float *vals) { time_start = (long long)times[0]; time_end = (long long)times[1]; val = vals[0]; }
313
314 bool operator<(const STimeRangeVal& s) {
315 if (this->time_start < s.time_start) return true;
316 if (this->time_start > s.time_start) return false;
317 if (this->time_end < s.time_end) return true;
318 if (this->time_end > s.time_end) return false;
319 return (this->val < s.val);
320 }
321 bool operator==(const STimeRangeVal& s) { return (this->val == s.val && this->time_start == s.time_start && this->time_end == s.time_end); }
322
323 friend ostream& operator<<(ostream& os, const STimeRangeVal& s) { os << s.time_start << "-" << s.time_end << ":" << s.val; return os; }
324
325};
326
327//===================================
328// STimeRange - 14
329//===================================
330class STimeRange : public UnifiedSig {
331public:
332 long long time_start;
333 long long time_end;
334
335 // unified API extention
336 static inline int n_time_channels() { return 2; }
337 static inline int n_val_channels() { return 0; }
338 static inline int time_unit() { return MedTime::Minutes; }
339 inline int Time(int chan) { return ((chan) ? ((int)time_end) : ((int)time_start)); } // assuming minutes span are within the size of an int
340 inline float Val(int chan) { return 0; }
341 inline void SetVal(int chan, float _val) { return; };
342
343 inline void Set(long long _time_start, long long _time_end) { time_start = _time_start; time_end = _time_end; }
344 inline void Set(int *times, float *vals) { time_start = (long long)times[0]; time_end = (long long)times[1]; }
345
346 bool operator<(const STimeRange& s) {
347 if (this->time_start < s.time_start) return true;
348 if (this->time_start > s.time_start) return false;
349 if (this->time_end < s.time_end) return true;
350 return false;
351 }
352 bool operator==(const STimeRange& s) { return (this->time_start == s.time_start && this->time_end == s.time_end); }
353
354 friend ostream& operator<<(ostream& os, const STimeRange& s) { os << s.time_start << "-" << s.time_end; return os; }
355
356};
357
358//===================================
359// SDateShort4
360//===================================
361class STimeShort4 : public UnifiedSig {
362public:
363 long long time;
364 unsigned short val1;
365 unsigned short val2;
366 unsigned short val3;
367 unsigned short val4;
368
369 // unified API extention
370 static inline int n_time_channels() { return 1; }
371 static inline int n_val_channels() { return 4; }
372 static inline int time_unit() { return MedTime::Minutes; }
373 inline int Time(int chan) { return (int)time; } // assuming minutes span are within the size of an int
374 inline float Val(int chan) {
375 switch (chan) {
376 case 0: return val1;
377 case 1: return val2;
378 case 2: return val3;
379 case 3: return val4;
380 }
381 return 0;
382 }
383 inline void SetVal(int chan, float _val) {
384 switch (chan) {
385 case 0: val1 = (unsigned short)_val; return;
386 case 1: val2 = (unsigned short)_val; return;
387 case 2: val3 = (unsigned short)_val; return;
388 case 3: val4 = (unsigned short)_val; return;
389 }
390 };
391
392 inline void Set(int _time, short _val1, short _val2, short _val3, short _val4) { time = _time; val1 = _val1; val2 = _val2; val3 = _val3; val4 = _val4; }
393 inline void Set(int *times, float *vals) {
394 time = times[0];
395 val1 = (unsigned short)vals[0];
396 val2 = (unsigned short)vals[1];
397 val3 = (unsigned short)vals[2];
398 val4 = (unsigned short)vals[3];
399 }
400
401 bool operator<(const STimeShort4& s) {
402 if (this->time < s.time) return true;
403 if (this->time > s.time) return false;
404 if (this->val1 < s.val1) return true;
405 if (this->val1 > s.val1) return false;
406 if (this->val2 < s.val2) return true;
407 if (this->val2 > s.val2) return false;
408 if (this->val3 < s.val3) return true;
409 if (this->val3 > s.val3) return false;
410 return (this->val4 < s.val4);
411 }
412 bool operator==(const STimeShort4& s) {
413 return (this->time == s.time
414 && this->val1 == s.val1
415 && this->val2 == s.val2
416 && this->val3 == s.val3
417 && this->val4 == s.val4);
418 }
419
420 friend ostream& operator<<(ostream& os, const STimeShort4& s) {
421 os << s.time << ":"
422 << s.val1 << ","
423 << s.val2 << ","
424 << s.val3 << ","
425 << s.val4;
426 return os;
427 }
428};
429
430
431
432//===================================
433// STimeStamp
434//===================================
435class STimeStamp : public UnifiedSig {
436public:
437 long long time;
438
439 // unified API extention
440 static inline int n_time_channels() { return 1; }
441 static inline int n_val_channels() { return 0; }
442 static inline int time_unit() { return MedTime::Minutes; }
443 inline int Time(int chan) { return (int)time; } // assuming minutes span are within the size of an int
444 inline float Val(int chan) { return 0; }
445 inline void SetVal(int chan, float _val) { return; };
446
447 inline void Set(long long _time) { time = _time; }
448 inline void Set(int *times, float *vals) { time = (long long)times[0]; }
449
450 bool operator<(const STimeStamp& s) { if (this->time < s.time) return true; return false; }
451 bool operator==(const STimeStamp& s) { return (this->time == s.time); }
452
453 friend ostream& operator<<(ostream& os, const STimeStamp& s) { os << s.time; return os; }
454
455};
456
457//===================================
458// SDateVal2
459//===================================
460class SDateVal2 : public UnifiedSig {
461public:
462 int date;
463 float val;
464 unsigned short val2;
465
466 // unified API extention
467 static inline int n_time_channels() { return 1; }
468 static inline int n_val_channels() { return 2; }
469 static inline int time_unit() { return MedTime::Date; }
470 inline int Time(int chan) { return date; } // assuming minutes span are within the size of an int
471 inline float Val(int chan) { return ((chan) ? (float)val2 : (float)val); }
472 inline void SetVal(int chan, float _val) { (chan) ? val2 = (unsigned short)_val : val = _val; };
473
474 inline void Set(int _date, float _val, unsigned short _val2) { date = _date; val = _val; val2 = _val2; }
475 inline void Set(int *times, float *vals) { date = times[0]; val = vals[0]; val2 = (unsigned short)vals[1]; }
476
477 bool operator<(const SDateVal2& s) {
478 if (this->date < s.date) return true;
479 if (this->date > s.date) return false;
480 if (this->val < s.val) return true;
481 if (this->val > s.val) return false;
482 return (this->val2 < s.val2);
483 }
484 bool operator==(const SDateVal2& s) { return (this->date == s.date && this->val == s.val && this->val2 == s.val2); }
485
486 friend ostream& operator<<(ostream& os, const SDateVal2& s) { os << s.date << ":" << s.val << "," << s.val2; return os; }
487
488};
489
490//===================================
491// STimeLongVal
492//===================================
493class STimeLongVal : public UnifiedSig {
494public:
495 long long time;
496 long long val;
497
498 // unified API extention
499 static inline int n_time_channels() { return 1; }
500 static inline int n_val_channels() { return 1; }
501 static inline int time_unit() { return MedTime::Minutes; }
502 inline int Time(int chan) { return (int)time; } // assuming minutes span are within the size of an int
503 inline float Val(int chan) { return (float)val; }
504 inline void SetVal(int chan, float _val) { val = (long long)_val; };
505
506 inline void Set(long long _time, long long _val) { time = _time; val = _val; }
507 // Waiting with unified here until we support long version of values.
508 inline void Set(int *times, float *vals) { time = (long long)times[0]; val = (long long)vals[0]; }
509
510 bool operator<(const STimeLongVal& s) {
511 if (this->time < s.time) return true;
512 if (this->time > s.time) return false;
513 return (this->val < s.val);
514 }
515 bool operator==(const STimeLongVal& s) { return (this->time == s.time && this->val == s.val); }
516
517 friend ostream& operator<<(ostream& os, const STimeLongVal& s) { os << s.time << ":" << s.val; return os; }
518
519};
520
521//===================================
522// SDateShort2
523//===================================
524class SDateShort2 : public UnifiedSig {
525public:
526 int date;
527 short val1;
528 short val2;
529
530 // unified API extention
531 static inline int n_time_channels() { return 1; }
532 static inline int n_val_channels() { return 2; }
533 static inline int time_unit() { return MedTime::Date; }
534 inline int Time(int chan) { return date; } // assuming minutes span are within the size of an int
535 inline float Val(int chan) { return ((chan) ? (float)val2 : (float)val1); }
536 inline void SetVal(int chan, float _val) { (chan) ? val2 = (short)_val : val1 = (short)_val; };
537
538 inline void Set(int _date, short _val1, short _val2) { date = _date; val1 = _val1; val2 = _val2; }
539 inline void Set(int *times, float *vals) { date = times[0]; val1 = (short)vals[0]; val2 = (short)vals[1]; }
540
541 bool operator<(const SDateShort2& s) {
542 if (this->date < s.date) return true;
543 if (this->date > s.date) return false;
544 if (this->val1 < s.val1) return true;
545 if (this->val1 > s.val1) return false;
546 return (this->val2 < s.val2);
547 }
548 bool operator==(const SDateShort2& s) { return (this->date == s.date && this->val1 == s.val1 && this->val2 == s.val2); }
549
550 friend ostream& operator<<(ostream& os, const SDateShort2& s) { os << s.date << ":" << s.val1 << "," << s.val2; return os; }
551};
552
553//===================================
554// SValShort2
555//===================================
556class SValShort2 : public UnifiedSig {
557public:
558 short val1;
559 short val2;
560 // unified API extention
561 static inline int n_time_channels() { return 0; }
562 static inline int n_val_channels() { return 2; }
563 static inline int time_unit() { return 0; }
564 inline int Time(int chan) { return 0; }
565 inline float Val(int chan) { return ((chan) ? (float)val2 : (float)val1); }
566 inline void SetVal(int chan, float _val) { (chan) ? val2 = (short)_val : val1 = (short)_val; };
567
568 inline void Set(short _val1, short _val2) { val1 = _val1; val2 = _val2; }
569 inline void Set(int *times, float *vals) { val1 = (short)vals[0]; val2 = (short)vals[1]; }
570
571 bool operator<(const SValShort2& s) {
572 if (this->val1 < s.val1) return true;
573 if (this->val1 > s.val1) return false;
574 return (this->val2 < s.val2);
575 }
576 bool operator==(const SValShort2& s) { return (this->val1 == s.val1 && this->val2 == s.val2); }
577
578 friend ostream& operator<<(ostream& os, const SValShort2& s) { os << s.val1 << "," << s.val2; return os; }
579
580};
581
582
583//===================================
584// SValShort4
585//===================================
586class SValShort4 : public UnifiedSig {
587public:
588 short val1;
589 short val2;
590 short val3;
591 short val4;
592
593 // unified API extention
594 static inline int n_time_channels() { return 0; }
595 static inline int n_val_channels() { return 4; }
596 static inline int time_unit() { return 0; }
597 inline int Time(int chan) { return 0; }
598
599 inline float Val(int chan) {
600 switch (chan) {
601 case 0: return val1;
602 case 1: return val2;
603 case 2: return val3;
604 case 3: return val4;
605 }
606 return 0;
607 }
608 inline void SetVal(int chan, float _val) {
609 switch (chan) {
610 case 0: val1 = (short)_val; return;
611 case 1: val2 = (short)_val; return;
612 case 2: val3 = (short)_val; return;
613 case 3: val4 = (short)_val; return;
614 }
615 };
616
617 inline void Set(short _val1, short _val2, short _val3, short _val4) { val1 = _val1; val2 = _val2; val3 = _val3; val4 = _val4; }
618 inline void Set(int *times, float *vals) { val1 = (short)vals[0]; val2 = (short)vals[1]; val3 = (short)vals[2]; val4 = (short)vals[3]; }
619
620 bool operator<(const SValShort4& s) {
621 if (this->val1 < s.val1) return true;
622 if (this->val1 > s.val1) return false;
623 if (this->val2 < s.val2) return true;
624 if (this->val1 > s.val1) return false;
625 if (this->val3 < s.val3) return true;
626 if (this->val1 > s.val1) return false;
627 return (this->val4 < s.val4);
628 }
629 bool operator==(const SValShort4& s) { return (this->val1 == s.val1 && this->val2 == s.val2 && this->val3 == s.val3 && this->val4 == s.val4); }
630 friend ostream& operator<<(ostream& os, const SValShort4& s) { os << s.val1 << "," << s.val2 << "," << s.val3 << "," << s.val4; return os; }
631
632};
633
634
635template <class T> void SetSignalElement(void *elem_buf, int *times, float *vals) { (*(T *)elem_buf).Set(times, vals); }
636template <class T> int MedSignalsCompareSig(const void *a, const void *b) { if (*(T*)a < *(T*)b) return -1; if (*(T*)a == *(T*)b) return 0; return 1; }
637template <class T> int MedSignalsPrintVec(ostream& os, T *vec, int n_elem);
638int MedSignalsPrintVecByType(ostream &os, int sig_type, void* vec, int len);
639
640//===================================
641// SCompactDateVal
642//===================================
644public:
645 unsigned short compact_date; // kept as: top 7 bits cY, then 4 bits M, then 5 bits day. Year is cY+1923 (format lasts until 2050)
646 unsigned short val;
647
648 // No unified support until we support compact_date as a date in MedTime
649 // unified API extention
650 static inline int n_time_channels() { return 1; }
651 static inline int n_val_channels() { return 1; }
652 static inline int time_unit() { return MedTime::Date; }
653 inline int Time(int chan) { return (int)compact_date; } // assuming minutes span are within the size of an int
654 inline float Val(int chan) { return (float)val; }
655 inline void SetVal(int chan, float _val) { val = (unsigned short)_val; };
656};
657
658
659//====================================================================
660// UniversalSigVec :
661// -----------------
662// A unified wrapper for signals to allow getting times and values
663// from signals in a unified API.
664//====================================================================
665template <class T> class UnifiedSignalsAPIs {
666public:
667
668 static inline int Time_ch_vec(int idx, int chan, void *data) { return ((T *)data)[idx].Time(chan); }
669 static inline float Val_ch_vec(int idx, int chan, void *data) { return ((T *)data)[idx].Val(chan); }
670 static inline void SetVal_ch_vec(int idx, int chan, float _val, void *data) { ((T *)data)[idx].SetVal(chan, _val); }
671 static inline void Set(int idx, int *_times, float *_vals, void *data) { ((T *)data)[idx].Set(_times, _vals); }
672 static inline size_t size() { return sizeof(T); }
673};
674
675//==========================================
676// Compact date to normal date conversions.
677//==========================================
678inline unsigned short date_to_compact_date(int date) {
679 int d = date % 100; int m = (date - d) / 100 % 100; int y = max(date / 10000, 1923); y = y - 1923; unsigned short cd = (y << 9) + (m << 5) + d; return cd;
680}
681
682inline int compact_date_to_date(unsigned short cd) {
683 int d = cd & 0x1f; int m = (cd >> 5) & 0xf; int y = (m >> 9); int date = y * 10000 + m * 100 + d; return date;
684}
685
686//=============================================================================================================
688public:
689 std::array<int, GENERIC_SIG_VEC_MAX_CHANNELS> time_channel_offsets;
690 std::array<int, GENERIC_SIG_VEC_MAX_CHANNELS> val_channel_offsets;
691 std::array<unsigned char, GENERIC_SIG_VEC_MAX_CHANNELS> time_channel_types;
692 std::array<unsigned char, GENERIC_SIG_VEC_MAX_CHANNELS> val_channel_types;
693
694 int sid;
695 string name;
696 int type;
697 int bytes_len;
698 string description;
699 string generic_signal_spec;
700 int fno; // currently each signal is in a single data and index file. This helps make things faster and is doable.
701 int shift;
702 float factor;
703 int time_unit;
704 int n_time_channels;
705 int n_val_channels;
706 int virtual_sig = 0; // flag to tell if the signal was defined in the signals files OR if it was defined as a virtual signal
707 std::array<int, GENERIC_SIG_VEC_MAX_CHANNELS> is_categorical_per_val_channel ; // when 1, channel doens't hold numerical values but rather pointers to a dict
708 std::array<string, GENERIC_SIG_VEC_MAX_CHANNELS> unit_of_measurement_per_val_channel;
709
710 SignalInfo() { fno = -1; time_channel_types.fill(0); val_channel_types.fill(0); time_channel_offsets.fill(0); val_channel_offsets.fill(0); is_categorical_per_val_channel.fill(0); unit_of_measurement_per_val_channel.fill(""); };
711
712 void set_gsv_spec(const string &gsv_spec_str);
713
714};
715class MedRepository;
716//===================================================================
717// Signals file handler
718//===================================================================
720 int _allocate_new_signal(const string &sig_name);
721public:
722 vector<string> fnames;
723 string signals_to_files;
724 map<string, int> Name2Sid;
725 map<int, string> Sid2Name;
726 vector<SignalInfo> Sid2Info;
727 vector<string> signals_names;
728 vector<int> signals_ids;
729 vector<int> sid2serial; // inverse of signal_ids, -1: empty slots
730 MedRepository* my_repo = NULL; // backward pointer to the owning repo
731
732 void clear() { fnames.clear(); Name2Sid.clear(); Sid2Name.clear(); signals_names.clear(); signals_ids.clear(); }
733
734 int read(const string &fname);
735 int read(vector<string> &sfnames);
736 int read(string path, vector<string> &sfnames);
737
738 inline int sid(const string &name);
739 string name(int sid);
740 int type(const string &name);
741 int type(int sid);
742 string desc(const string &name);
743 string desc(int sid);
744 int fno(const string &sig_name);
745 int fno(int sid);
746 int has_any_categorical_channel(const string &sig_name);
747 int has_any_categorical_channel(int sid);
748 int is_categorical_channel(const string &sig_name, int val_channel);
749 int is_categorical_channel(int sid, int val_channel);
750 string unit_of_measurement(const string &name, int val_channel);
751 string unit_of_measurement(int sid, int val_channel);
752 // this option allows adding new signals definitions to the class, that were not defined in the files.
753 // this is useful when using repositories to calculate new features, etc.
754 int insert_virtual_signal(const string &sig_name, int type);
755 int insert_virtual_signal(const string &sig_name, const string& signalSpec);
756 int get_sids(vector<string> &sigs, vector<int> &sids);
757};
758
759
761public:
762 void *data;
763 int len; // type len (not bytes len)
764
765 //--------------------------------------------------------------------------------------
766 // function pointers - to be set before using the relevant type (use the init function)
767 //--------------------------------------------------------------------------------------
768 // channels numbers
769 int(*n_time_channels)();
770 int(*n_val_channels)();
771
772 // time unit & unitless time
773 int time_unit() const { return _time_unit; };
774 int(*Time_ch_vec)(int, int, void *); // Time(idx,chan)
775
776 // value channels float
777 float(*Val_ch_vec)(int, int, void *);
778 void(*SetVal_ch_vec)(int, int, float, void *);
779
780 // Set() - setting a specific index in data, given all its time channels and val channels
781 // channels are given as an array (of the proper length) or NULL for 0 length channels.
782 void(*Set)(int, int *, float *, void *);
783
784 size_t(*size)();
785
786 // init function : call before using a certain type
787 void init(const SignalInfo &info);
788 //void init(int _type) { return init((SigType)_type); }
789
790 //--------------------------------------------------------------------------------------
791 // Following are based on the pointed functions above
792 //--------------------------------------------------------------------------------------
793 // Following functions are implemented based on the functions above (and save lots of coding hence)
794 // time channels int
795 inline int Time(int idx, int chan) const { return Time_ch_vec(idx, chan, data); }
796 inline float Val(int idx, int chan) const { return Val_ch_vec(idx, chan, data); }
797
798 // channel 0 easy API
799 inline int Time(int idx) const { return Time(idx, 0); }
800 inline float Val(int idx) const { return Val(idx, 0); }
801
802 inline int TimeU(int idx, int to_time_unit) const { return med_time_converter.convert_times(time_unit(), to_time_unit, Time(idx)); }
803 inline int Date(int idx) const { return med_time_converter.convert_times(time_unit(), MedTime::Date, Time(idx)); }
804 inline int Years(int idx) const { return med_time_converter.convert_times(time_unit(), MedTime::Years, Time(idx)); }
805 inline int Months(int idx) const { return med_time_converter.convert_times(time_unit(), MedTime::Months, Time(idx)); }
806 inline int Days(int idx) const { return med_time_converter.convert_times(time_unit(), MedTime::Days, Time(idx)); }
807 inline int Hours(int idx) const { return med_time_converter.convert_times(time_unit(), MedTime::Hours, Time(idx)); }
808 inline int Minutes(int idx) const { return med_time_converter.convert_times(time_unit(), MedTime::Minutes, Time(idx)); }
809
810 // general channel API
811 inline int TimeU(int idx, int chan, int to_time_unit) const { return med_time_converter.convert_times(time_unit(), to_time_unit, Time(idx, chan)); }
812 inline int Date(int idx, int chan) const { return med_time_converter.convert_times(time_unit(), MedTime::Date, Time(idx, chan)); }
813 inline int Years(int idx, int chan) const { return med_time_converter.convert_times(time_unit(), MedTime::Years, Time(idx, chan)); }
814 inline int Months(int idx, int chan) const { return med_time_converter.convert_times(time_unit(), MedTime::Months, Time(idx, chan)); }
815 inline int Days(int idx, int chan) const { return med_time_converter.convert_times(time_unit(), MedTime::Days, Time(idx, chan)); }
816 inline int Hours(int idx, int chan) const { return med_time_converter.convert_times(time_unit(), MedTime::Hours, Time(idx, chan)); }
817 inline int Minutes(int idx, int chan) const { return med_time_converter.convert_times(time_unit(), MedTime::Minutes, Time(idx, chan)); }
818
819 template <class S> void set_funcs() {
820 n_time_channels = &S::n_time_channels;
821 n_val_channels = &S::n_val_channels;
827 }
828
829 SigType get_type() const { return type; }
830
831 // helper functions for common operations
832 //----------------------------------------
833 // returns the first index i in the usv that has Time(i, time_chan) > time_bound, if none : return -1
834 int get_index_gt_time_bound(int time_chan, int time_bound);
835 // returns the first index i in the usv that has Time(i, time_chan) >= time_bound, if none : return -1
836 int get_index_ge_time_bound(int time_chan, int time_bound);
837
838protected:
839 SigType type = T_Last; // type of the embedded signal
840 int _time_unit = MedTime::Undefined;
841};
842
848public:
849 bool manage;
851 manage = false;
852 }
853
855 if (len > 0 && data != NULL && manage) {
856 delete[](char *)data;
857 data = NULL;
858 len = 0;
859 }
860 }
861
862 void set(const UniversalSigVec_legacy &s) {
863 data = s.data;
864 len = s.len;
865 manage = false;
866 n_time_channels = s.n_time_channels;
867 n_val_channels = s.n_val_channels;
868 Set = s.Set;
869 SetVal_ch_vec = s.SetVal_ch_vec;
870 size = s.size;
871 Time_ch_vec = s.Time_ch_vec;
872 _time_unit = s.time_unit();
873 Val_ch_vec = s.Val_ch_vec;
874 type = s.get_type();
875 }
876};
877
878
879// small helper class to help in the sorting
881 vector<unsigned char> data;
882};
883
884
885//=============================================================================================
886// Inline/templated functions
887//=============================================================================================
888inline int MedSignals::sid(const string &name)
889{
890 if (Name2Sid.find(name) == Name2Sid.end())
891 return -1;
892 return Name2Sid[name];
893};
894
895//-----------------------------------------------------------------------------------------------
896//template <class T> int MedRep:get_type_channels_info(int &time_unit, int &n_time_chans, int &n_val_chans)
897//{
898// T t;
899//
900// time_unit = t.time_unit();
901// n_time_chans = t.n_time_channels();
902// n_val_chans = t.n_val_channels();
903//
904// return 0;
905//}
906
907
908template <class T> int MedSignalsPrintVec(ostream& os, T *vec, int n_elem)
909{
910 for (int i = 0; i < n_elem; i++)
911 os << vec[i] << " ";
912 return 0;
913}
914
916public:
918 {
919 public:
920 static constexpr const unsigned char UNDEFINED = 0b00000000;
921 static constexpr const unsigned char SIGNED = 0b00000001;
922 static constexpr const unsigned char UINT8 = 0b00000010; //unsigned char
923 static constexpr const unsigned char UINT16 = 0b00000100; //unsigned short
924 static constexpr const unsigned char UINT32 = 0b00001000; //unsigned int
925 static constexpr const unsigned char UINT64 = 0b00010000; //unsigned long long
926 static constexpr const unsigned char INT8 = 0b00000011; //char
927 static constexpr const unsigned char INT16 = 0b00000101; //short
928 static constexpr const unsigned char INT32 = 0b00001001; //int
929 static constexpr const unsigned char INT64 = 0b00010001; //long long
930 static constexpr const unsigned char FLOAT32 = 0b00100000; //float
931 static constexpr const unsigned char FLOAT64 = 0b01000000; //double
932 static constexpr const unsigned char FLOAT80 = 0b10000000; //long double
933 static unsigned char encode(char c, bool isSigned = false) {
934 unsigned char _is_signed = isSigned ? type_enc::SIGNED : 0;
935 switch (c) {
936 case 'c': return _is_signed | type_enc::UINT8;
937 case 's': return _is_signed | type_enc::UINT16;
938 case 'i': return _is_signed | type_enc::UINT32;
939 case 'l': return _is_signed | type_enc::UINT64;
940 case 'f': return type_enc::FLOAT32;
941 case 'd': return type_enc::FLOAT64;
942 case 'D': return type_enc::FLOAT80;
943 }
944 return type_enc::UNDEFINED;
945 }
946 static char decode(unsigned char c, bool isSigned = false) {
947 switch (c) {
948 case type_enc::INT8:
949 case type_enc::UINT8: return 'c';
950 case type_enc::INT16:
951 case type_enc::UINT16: return 's';
952 case type_enc::INT32:
953 case type_enc::UINT32: return 'i';
954 case type_enc::INT64:
955 case type_enc::UINT64: return 'l';
956 case type_enc::FLOAT32: return 'f';
957 case type_enc::FLOAT64: return 'd';
958 case type_enc::FLOAT80: return 'D';
959 }
960 return 0;
961 }
962 static int bytes_len(unsigned char enct) {
963 switch (enct) {
964 case type_enc::INT32: return sizeof(int);
965 case type_enc::INT64: return sizeof(long long);
966 case type_enc::UINT16: return sizeof(unsigned short);
967 case type_enc::UINT8: return sizeof(unsigned char);
968 case type_enc::UINT32: return sizeof(unsigned int);
969 case type_enc::UINT64: return sizeof(unsigned long long);
970 case type_enc::INT8: return sizeof(char);
971 case type_enc::INT16: return sizeof(short);
972 case type_enc::FLOAT32: return sizeof(float);
973 case type_enc::FLOAT64: return sizeof(double);
974 case type_enc::FLOAT80: return sizeof(long double);
975 }
976 return 0;
977 }
978 static bool is_signed(unsigned char c) {
979 return c == FLOAT32 || c == FLOAT64 || c == FLOAT80 || c & SIGNED;
980 }
981 };
982 void *data;
983 int len; // type len (not bytes len)
984
985 int n_time_channels() const { return n_time; };
986 int n_val_channels() const { return n_val; };
987
988 // time unit & unitless time
989 int time_unit() const { return _time_unit; };
990 int Time_ch_vec(int idx, int chan, void * data_) const { return Time<int>(idx, chan, data); } // Time(idx,chan)
991 void SetVal_ch_vec(int idx, int chan, float _val, void *data_) { setVal(idx, chan, _val, data_); };
992
993 inline void Set(int idx, int *times, float *vals) { Set(idx, times, vals, data); }
994
995 inline void Set(int idx, int *times, float *vals, void* data_)
996 {
997 for (int chan = 0; chan < n_time; ++chan)
998 setTime(idx, chan, times[chan], (char*)data_);
999
1000 for (int chan = 0; chan < n_val; ++chan)
1001 setVal(idx, chan, vals[chan], (char*)data_);
1002 }
1003
1004 size_t size() const { return struct_size; }
1005
1006 void init(const SignalInfo &info) {
1007 if (sid == info.sid) return;
1008 _time_unit = info.time_unit;
1009 time_channel_offsets = info.time_channel_offsets;
1010 val_channel_offsets = info.val_channel_offsets;
1011 time_channel_types = info.time_channel_types;
1012 val_channel_types = info.val_channel_types;
1013
1014 struct_size = info.bytes_len;
1015 n_time = info.n_time_channels;
1016 n_val = info.n_val_channels;
1017
1018 sid = info.sid;
1019 }
1020
1021 int struct_size;
1022 int n_time;
1023 int n_val;
1024
1025 std::array<int, GENERIC_SIG_VEC_MAX_CHANNELS> time_channel_offsets;
1026 std::array<int, GENERIC_SIG_VEC_MAX_CHANNELS> val_channel_offsets;
1027 std::array<unsigned char, GENERIC_SIG_VEC_MAX_CHANNELS> time_channel_types;
1028 std::array<unsigned char, GENERIC_SIG_VEC_MAX_CHANNELS> val_channel_types;
1029
1030 int sid;
1031
1032 void set_data(void* _data, int _len) {
1033 data = _data;
1034 len = _len;
1035 }
1036 GenericSigVec() : data(nullptr), sid(-1), len(0), struct_size(0), n_time(0), n_val(0) { time_channel_offsets.fill(0); val_channel_offsets.fill(0); time_channel_types.fill(0); val_channel_types.fill(0); }
1037 GenericSigVec(const string& signalSpec, int time_unit = MedTime::Undefined) : GenericSigVec() { _time_unit = time_unit; init_from_spec(signalSpec); }
1038 GenericSigVec(SigType sigtype, int time_unit = MedTime::Undefined) : GenericSigVec() { _time_unit = time_unit; init_from_sigtype(sigtype); }
1039 GenericSigVec(const GenericSigVec& other) { *this = other; }
1040
1041 void copy_signal_metadata(const GenericSigVec& other) {
1042 struct_size = other.struct_size;
1043 sid = other.sid;
1044 n_time = other.n_time;
1045 n_val = other.n_val;
1046 _time_unit = other._time_unit;
1047 time_channel_offsets = other.time_channel_offsets;
1048 time_channel_types = other.time_channel_types;
1049 val_channel_offsets = other.val_channel_offsets;
1050 val_channel_types = other.val_channel_types;
1051 }
1052
1053 GenericSigVec& operator=(const GenericSigVec& other) {
1054 data = other.data;
1055 len = other.len;
1056 copy_signal_metadata(other);
1057 return *this;
1058 }
1059
1060 void init_from_spec(const string& signalSpec);
1061 void init_from_sigtype(SigType sigtype);
1062 void init_from_repo(MedRepository& repo, int sid);
1063
1064 template<typename T = int>
1065 T Time(int idx, int chan) const { return Time<T>(idx, chan, data); }
1066
1067 template<typename T = int>
1068 T Time(int idx, int chan, const void* data_) const {
1069 auto field_ptr = ((const char*)data_) + idx * struct_size + time_channel_offsets[chan];
1070 switch (time_channel_types[chan]) {
1071 case type_enc::INT32: return (T)(*(int*)(field_ptr));
1072 case type_enc::INT64: return (T)(*(long long*)(field_ptr));
1073 case type_enc::UINT16: return (T)(*(unsigned short*)(field_ptr));
1074 case type_enc::UINT8: return (T)(*(unsigned char*)(field_ptr));
1075 case type_enc::UINT32: return (T)(*(unsigned int*)(field_ptr));
1076 case type_enc::UINT64: return (T)(*(unsigned long long*)(field_ptr));
1077 case type_enc::INT8: return (T)(*(char*)(field_ptr));
1078 case type_enc::INT16: return (T)(*(short*)(field_ptr));
1079 case type_enc::FLOAT32: return (T)(*(float*)(field_ptr));
1080 case type_enc::FLOAT64: return (T)(*(double*)(field_ptr));
1081 case type_enc::FLOAT80: return (T)(*(long double*)(field_ptr));
1082 }
1083 return 0;
1084 }
1085
1086 template<typename T = int>
1087 void setTime(int idx, int chan, T new_val) { setTime<T>(idx, chan, new_val, data); }
1088
1089 template<typename T = int>
1090 void setTime(int idx, int chan, T new_val, void* data_) {
1091 auto field_ptr = ((char*)data_) + idx * struct_size + time_channel_offsets[chan];
1092 switch (time_channel_types[chan]) {
1093 case type_enc::INT32: (*(int*)(field_ptr)) = (int)new_val; return;
1094 case type_enc::INT64: (*(long long*)(field_ptr)) = (long long)new_val; return;
1095 case type_enc::UINT16: (*(unsigned short*)(field_ptr)) = (unsigned short)new_val; return;
1096 case type_enc::UINT8: (*(unsigned char*)(field_ptr)) = (unsigned char)new_val; return;
1097 case type_enc::UINT32: (*(unsigned int*)(field_ptr)) = (unsigned int)new_val; return;
1098 case type_enc::UINT64: (*(unsigned long long*)(field_ptr)) = (unsigned long long)new_val; return;
1099 case type_enc::INT8: (*(char*)(field_ptr)) = (char)new_val; return;
1100 case type_enc::INT16: (*(short*)(field_ptr)) = (short)new_val; return;
1101 case type_enc::FLOAT32: (*(float*)(field_ptr)) = (float)new_val; return;
1102 case type_enc::FLOAT64: (*(double*)(field_ptr)) = (double)new_val; return;
1103 case type_enc::FLOAT80: (*(long double*)(field_ptr)) = (long double)new_val; return;
1104 }
1105 }
1106
1107 template<typename T = float>
1108 T Val(int idx, int chan) const { return Val<T>(idx, chan, data); }
1109
1110 template<typename T = float>
1111 T Val(int idx) const { return Val<T>(idx, 0, data); }
1112
1113 template<typename T = float>
1114 T Val(int idx, int chan, const void* data_) const {
1115 auto field_ptr = ((char*)data_) + idx * struct_size + val_channel_offsets[chan];
1116 switch (val_channel_types[chan]) {
1117 case type_enc::FLOAT32: return (T)(*(float*)(field_ptr));
1118 case type_enc::INT16: return (T)(*(short*)(field_ptr));
1119 case type_enc::UINT16: return (T)(*(unsigned short*)(field_ptr));
1120 case type_enc::UINT8: return (T)(*(unsigned char*)(field_ptr));
1121 case type_enc::UINT32: return (T)(*(unsigned int*)(field_ptr));
1122 case type_enc::UINT64: return (T)(*(unsigned long long*)(field_ptr));
1123 case type_enc::INT8: return (T)(*(char*)(field_ptr));
1124 case type_enc::INT32: return (T)(*(int*)(field_ptr));
1125 case type_enc::INT64: return (T)(*(long long*)(field_ptr));
1126 case type_enc::FLOAT64: return (T)(*(double*)(field_ptr));
1127 case type_enc::FLOAT80: return (T)(*(long double*)(field_ptr));
1128 }
1129 return 0;
1130 }
1131
1132 template<typename T = float>
1133 void setVal(int idx, int chan, T new_val) { setVal<T>(idx, chan, new_val, data); }
1134
1135 template<typename T = float>
1136 void setVal(int idx, int chan, T new_val, void* data_) {
1137 auto field_ptr = ((char*)data_) + idx * struct_size + val_channel_offsets[chan];
1138 switch (val_channel_types[chan]) {
1139 case type_enc::FLOAT32: (*(float*)(field_ptr)) = (float)new_val; return;
1140 case type_enc::INT16: (*(short*)(field_ptr)) = (short)new_val; return;
1141 case type_enc::UINT16: (*(unsigned short*)(field_ptr)) = (unsigned short)new_val; return;
1142 case type_enc::UINT8: (*(unsigned char*)(field_ptr)) = (unsigned char)new_val; return;
1143 case type_enc::UINT32: (*(unsigned int*)(field_ptr)) = (unsigned int)new_val; return;
1144 case type_enc::UINT64: (*(unsigned long long*)(field_ptr)) = (unsigned long long)new_val; return;
1145 case type_enc::INT8: (*(char*)(field_ptr)) = (char)new_val; return;
1146 case type_enc::INT32: (*(int*)(field_ptr)) = (int)new_val; return;
1147 case type_enc::INT64: (*(long long*)(field_ptr)) = (long long)new_val; return;
1148 case type_enc::FLOAT64: (*(double*)(field_ptr)) = (double)new_val; return;
1149 case type_enc::FLOAT80: (*(long double*)(field_ptr)) = (long double)new_val; return;
1150 }
1151 }
1152
1153 // channel 0 easy API
1154 inline int Time(int idx) const { return Time(idx, 0); }
1155 inline float Val(int idx) const { return Val(idx, 0); }
1156
1157 inline int TimeU(int idx, int to_time_unit) const { return med_time_converter.convert_times(time_unit(), to_time_unit, Time(idx)); }
1158 inline int Date(int idx) const { return med_time_converter.convert_times(time_unit(), MedTime::Date, Time(idx)); }
1159 inline int Years(int idx) const { return med_time_converter.convert_times(time_unit(), MedTime::Years, Time(idx)); }
1160 inline int Months(int idx) const { return med_time_converter.convert_times(time_unit(), MedTime::Months, Time(idx)); }
1161 inline int Days(int idx) const { return med_time_converter.convert_times(time_unit(), MedTime::Days, Time(idx)); }
1162 inline int Hours(int idx) const { return med_time_converter.convert_times(time_unit(), MedTime::Hours, Time(idx)); }
1163 inline int Minutes(int idx) const { return med_time_converter.convert_times(time_unit(), MedTime::Minutes, Time(idx)); }
1164
1165 // general channel API
1166 inline int TimeU(int idx, int chan, int to_time_unit) const { return med_time_converter.convert_times(time_unit(), to_time_unit, Time(idx, chan)); }
1167 inline int Date(int idx, int chan) const { return med_time_converter.convert_times(time_unit(), MedTime::Date, Time(idx, chan)); }
1168 inline int Years(int idx, int chan) const { return med_time_converter.convert_times(time_unit(), MedTime::Years, Time(idx, chan)); }
1169 inline int Months(int idx, int chan) const { return med_time_converter.convert_times(time_unit(), MedTime::Months, Time(idx, chan)); }
1170 inline int Days(int idx, int chan) const { return med_time_converter.convert_times(time_unit(), MedTime::Days, Time(idx, chan)); }
1171 inline int Hours(int idx, int chan) const { return med_time_converter.convert_times(time_unit(), MedTime::Hours, Time(idx, chan)); }
1172 inline int Minutes(int idx, int chan) const { return med_time_converter.convert_times(time_unit(), MedTime::Minutes, Time(idx, chan)); }
1173
1174 template <class S> void set_funcs() const { /* Do nothing */ }
1175
1176 SigType get_type() const { return type; }
1177
1178 // helper functions for common operations
1179 //----------------------------------------
1180 // returns the first index i in the usv that has Time(i, time_chan) > time_bound, if none : return -1
1181 int get_index_gt_time_bound(int time_chan, int time_bound);
1182 // returns the first index i in the usv that has Time(i, time_chan) >= time_bound, if none : return -1
1183 int get_index_ge_time_bound(int time_chan, int time_bound);
1184
1185 bool compareTimeLt(const void* data1, int idx1, const void* data2, int idx2) const {
1186 for (int tchan = 0; tchan < n_time; tchan++) {
1187 if (this->Time(idx1, tchan, data1) > this->Time(idx2, tchan, data2))
1188 return false;
1189 if (this->Time(idx1, tchan, data1) < this->Time(idx2, tchan, data2))
1190 return true;
1191 }
1192 for (int vchan = 0; vchan < n_val; vchan++) {
1193 if (this->Val(idx1, vchan, data1) > this->Val(idx2, vchan, data2))
1194 return false;
1195 if (this->Val(idx1, vchan, data1) < this->Val(idx2, vchan, data2))
1196 return true;
1197 }
1198 return false;
1199 }
1200
1201 int compare_elements(const void* elem1, const void* elem2) {
1202 if (compareTimeLt(elem1, 0, elem2, 0)) return - 1;
1203 return 0;
1204 }
1205
1206
1207 bool compare_gsv_elements(const GSVElement &e1, const GSVElement &e2) {
1208 return compareTimeLt(&e1.data[0], 0, &e2.data[0], 0);
1209 }
1210
1211 int inplace_sort_data(const void *data, int nelem) {
1212 vector<GSVElement> dc(nelem);
1213 unsigned char* p_data = (unsigned char *)data;
1214 int k = 0;
1215 for (int i = 0; i < nelem; i++) {
1216 dc[i].data.resize(this->struct_size);
1217 for (int j = 0; j < this->struct_size; j++)
1218 dc[i].data[j] = p_data[k++];
1219 }
1220
1221 std::sort(dc.begin(), dc.end(), [this](GSVElement l, GSVElement r) {return compare_gsv_elements(l, r); });
1222
1223 k = 0;
1224 for (int i = 0; i < nelem; i++) {
1225 dc[i].data.resize(this->struct_size);
1226 for (int j = 0; j < this->struct_size; j++)
1227 p_data[k++] = dc[i].data[j];
1228 }
1229
1230 return 0;
1231 //qsort(data, nelem, this->struct_size, &this->compare_elements);
1232 }
1233
1234 bool compareData(int idx, const GenericSigVec& other_gsv, int other_idx) const {
1235 return std::memcmp(((const char*)data) + idx * struct_size, ((const char*)other_gsv.data) + other_idx * struct_size, struct_size) == 0;
1236 }
1237
1238 static string get_type_generic_spec(SigType t);
1239
1240 string get_signal_generic_spec() const;
1241
1242protected:
1243 const SigType type = T_Generic; // type of the generic signal
1244 int _time_unit = MedTime::Undefined;
1245};
1246
1252public:
1253 bool manage;
1256 manage = false;
1257 }
1258
1260 if (len > 0 && data != NULL && manage) {
1261 delete[](char *)data;
1262 data = NULL;
1263 len = 0;
1264 }
1265 }
1266
1267 void set(const GenericSigVec &s) {
1268 manage = false;
1269 GenericSigVec::operator=(s);
1270 }
1271};
1272
1273#endif
MedTime.h.
Definition MedSignals.h:918
Managed memory version of UniversalSigVec.
Definition MedSignals.h:1251
string signal_spec
if true manages the memory
Definition MedSignals.h:1254
Definition MedSignals.h:915
Definition InfraMed.h:303
Definition MedSignals.h:719
static const int Minutes
minutes since 1900/01/01
Definition MedTime.h:30
static const int Undefined
undefined time unit
Definition MedTime.h:24
int convert_times(int from_type, int to_type, int in_time)
Converts time formats.
Definition MedTime.cpp:284
static const int Days
days since 1900/01/01
Definition MedTime.h:28
static const int Years
years since 1900 (not since 0!)
Definition MedTime.h:26
static const int Hours
hours since 1900/01/01
Definition MedTime.h:29
static const int Months
months since 1900/01/01
Definition MedTime.h:27
static const int Date
dates are in full regular format YYYYMMDD
Definition MedTime.h:25
Definition MedSignals.h:643
Definition MedSignals.h:264
Definition MedSignals.h:228
Definition MedSignals.h:195
Definition MedSignals.h:524
Definition MedSignals.h:460
Definition MedSignals.h:144
Definition MedSignals.h:493
Definition MedSignals.h:297
Definition MedSignals.h:330
Definition MedSignals.h:361
Definition MedSignals.h:435
Definition MedSignals.h:169
Definition MedSignals.h:556
Definition MedSignals.h:586
Definition MedSignals.h:119
Definition MedSignals.h:687
Definition MedSignals.h:75
Definition MedSignals.h:665
Definition MedSignals.h:760
Managed memory version of UniversalSigVec.
Definition MedSignals.h:847
Definition StdDeque.h:58
Definition MedSignals.h:880