Skip to content

Commit 7d5423e

Browse files
committed
Improve generic handling of event data
1 parent 6ad62f2 commit 7d5423e

6 files changed

Lines changed: 233 additions & 58 deletions

File tree

Source/Processors/Channel/InfoObjects.cpp

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,29 @@ uint16 InfoObjectCommon::getSourceTypeIndex() const
170170
return m_sourceTypeIndex;
171171
}
172172

173+
bool InfoObjectCommon::operator==(const InfoObjectCommon& other) const
174+
{
175+
return isEqual(other);
176+
}
177+
178+
bool InfoObjectCommon::isEqual(const InfoObjectCommon& other) const
179+
{
180+
return isEqual(other, false);
181+
}
182+
183+
bool InfoObjectCommon::isSimilar(const InfoObjectCommon& other) const
184+
{
185+
return isEqual(other, true);
186+
}
187+
188+
bool InfoObjectCommon::isEqual(const InfoObjectCommon& other, bool similar) const
189+
{
190+
if (getInfoObjectType() != other.getInfoObjectType()) return false;
191+
if (m_sampleRate != other.m_sampleRate) return false;
192+
if (!similar && getIdentifier().trim() != other.getIdentifier().trim()) return false;
193+
return checkEqual(other, similar);
194+
}
195+
173196
//DataChannel
174197

175198
DataChannel::DataChannel(DataChannelTypes type, float sampleRate, GenericProcessor* source, uint16 subproc) :
@@ -297,6 +320,16 @@ void DataChannel::setDefaultNameAndDescription()
297320
setIdentifier("genericdata.continuous");
298321
}
299322

323+
bool DataChannel::checkEqual(const InfoObjectCommon& other, bool similar) const
324+
{
325+
const DataChannel& o = dynamic_cast<const DataChannel&>(other);
326+
if (m_bitVolts != o.m_bitVolts) return false;
327+
if (!similar && m_unitName != o.m_unitName) return false;
328+
if (similar)
329+
return hasSimilarMetadata(o);
330+
else return hasSameMetadata(o);
331+
}
332+
300333
//EventChannel
301334
EventChannel::EventChannel(EventChannelTypes type, unsigned int nChannels, unsigned int dataLength, float sampleRate, GenericProcessor* source, uint16 subproc)
302335
: InfoObjectCommon(source->eventChannelCount++, source->eventChannelTypeCount[type]++, sampleRate, source, subproc),
@@ -418,6 +451,56 @@ void EventChannel::setDefaultNameAndDescription()
418451
setIdentifier("genericevent");
419452
}
420453

454+
455+
BaseType EventChannel::getEquivalentMetaDataType(const EventChannel& ev)
456+
{
457+
switch (ev.getChannelType())
458+
{
459+
case EventChannel::TEXT:
460+
return MetaDataDescriptor::CHAR;
461+
case EventChannel::INT8_ARRAY:
462+
return MetaDataDescriptor::INT8;
463+
case EventChannel::UINT8_ARRAY:
464+
return MetaDataDescriptor::UINT8;
465+
case EventChannel::INT16_ARRAY:
466+
return MetaDataDescriptor::INT16;
467+
case EventChannel::UINT16_ARRAY:
468+
return MetaDataDescriptor::UINT16;
469+
case EventChannel::INT32_ARRAY:
470+
return MetaDataDescriptor::INT32;
471+
case EventChannel::UINT32_ARRAY:
472+
return MetaDataDescriptor::UINT32;
473+
case EventChannel::INT64_ARRAY:
474+
return MetaDataDescriptor::INT64;
475+
case EventChannel::UINT64_ARRAY:
476+
return MetaDataDescriptor::UINT64;
477+
case EventChannel::FLOAT_ARRAY:
478+
return MetaDataDescriptor::FLOAT;
479+
case EventChannel::DOUBLE_ARRAY:
480+
return MetaDataDescriptor::DOUBLE;
481+
default:
482+
return MetaDataDescriptor::UINT8;
483+
}
484+
}
485+
486+
BaseType EventChannel::getEquivalentMetaDataType() const
487+
{
488+
return getEquivalentMetaDataType(*this);
489+
}
490+
491+
bool EventChannel::checkEqual(const InfoObjectCommon& other, bool similar) const
492+
{
493+
const EventChannel& o = dynamic_cast<const EventChannel&>(other);
494+
if (m_type != o.m_type) return false;
495+
if (m_numChannels != o.m_numChannels) return false;
496+
if (m_length != o.m_length) return false;
497+
if (similar && !hasSimilarMetadata(o)) return false;
498+
if (!similar && !hasSameMetadata(o)) return false;
499+
if (similar && !hasSimilarEventMetadata(o)) return false;
500+
if (!similar && !hasSameEventMetadata(o)) return false;
501+
return true;
502+
}
503+
421504
//SpikeChannel
422505

423506
SpikeChannel::SpikeChannel(ElectrodeTypes type, GenericProcessor* source, const Array<const DataChannel*>& sourceChannels, uint16 subproc)
@@ -549,6 +632,27 @@ void SpikeChannel::setDefaultNameAndDescription()
549632
setIdentifier("spikesource");
550633
}
551634

635+
bool SpikeChannel::checkEqual(const InfoObjectCommon& other, bool similar) const
636+
{
637+
const SpikeChannel& o = dynamic_cast<const SpikeChannel&>(other);
638+
if (m_type != o.m_type) return false;
639+
if (m_numPostSamples != o.m_numPostSamples) return false;
640+
if (m_numPreSamples != o.m_numPreSamples) return false;
641+
642+
int nChans = m_channelBitVolts.size();
643+
if (nChans != o.m_channelBitVolts.size()) return false;
644+
for (int i = 0; i < nChans; i++)
645+
{
646+
if (m_channelBitVolts[i] != o.m_channelBitVolts[i]) return false;
647+
}
648+
649+
if (similar && !hasSimilarMetadata(o)) return false;
650+
if (!similar && !hasSameMetadata(o)) return false;
651+
if (similar && !hasSimilarEventMetadata(o)) return false;
652+
if (!similar && !hasSameEventMetadata(o)) return false;
653+
return true;
654+
}
655+
552656
//ConfigurationObject
553657
ConfigurationObject::ConfigurationObject(String identifier, GenericProcessor* source, uint16 subproc)
554658
: SourceProcessorInfo(source, subproc)

Source/Processors/Channel/InfoObjects.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,13 @@ class PLUGIN_API InfoObjectCommon :
171171

172172
virtual InfoObjectType getInfoObjectType() const = 0;
173173

174+
bool isEqual(const InfoObjectCommon& other) const;
175+
bool isSimilar(const InfoObjectCommon& other) const;
176+
bool operator==(const InfoObjectCommon& other) const;
177+
174178
private:
179+
bool isEqual(const InfoObjectCommon& other, bool similar) const;
180+
virtual bool checkEqual(const InfoObjectCommon& other, bool similar) const = 0;
175181
/** Index of the object in the source processor */
176182
const uint16 m_sourceIndex;
177183
/** Index of this particular subtype in the source processor */
@@ -251,6 +257,7 @@ class PLUGIN_API DataChannel
251257
InfoObjectType getInfoObjectType() const override;
252258
void setDefaultNameAndDescription() override;
253259
private:
260+
bool checkEqual(const InfoObjectCommon& other, bool similar) const override;
254261
const DataChannelTypes m_type;
255262
float m_bitVolts{ 1.0f };
256263
bool m_isEnabled{ true };
@@ -341,9 +348,16 @@ class PLUGIN_API EventChannel :
341348
/** Gets the size in bytes of an element depending of the type*/
342349
static size_t getTypeByteSize(EventChannelTypes type);
343350

351+
/** Handy method to get an equivalente metadata value type for the main event data*/
352+
static BaseType getEquivalentMetaDataType(const EventChannel& ev);
353+
354+
/** Handy method to get an equivalente metadata value type for the main event data*/
355+
BaseType getEquivalentMetaDataType() const;
356+
344357
InfoObjectType getInfoObjectType() const override;
345358
void setDefaultNameAndDescription() override;
346359
private:
360+
bool checkEqual(const InfoObjectCommon& other, bool similar) const override;
347361
const EventChannelTypes m_type;
348362
unsigned int m_numChannels{ 1 };
349363
size_t m_dataSize{ 1 };
@@ -413,6 +427,7 @@ class PLUGIN_API SpikeChannel :
413427
InfoObjectType getInfoObjectType() const override;
414428
void setDefaultNameAndDescription() override;
415429
private:
430+
bool checkEqual(const InfoObjectCommon& other, bool similar) const override;
416431
const ElectrodeTypes m_type;
417432
Array<sourceChannelInfo> m_sourceInfo;
418433
unsigned int m_numPreSamples{ 8 };

Source/Processors/Channel/MetaData.cpp

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,14 +76,22 @@ String MetaDataDescriptor::getName() const { return m_name; }
7676
String MetaDataDescriptor::getDescription() const { return m_description; }
7777
String MetaDataDescriptor::getIdentifier() const { return m_identifier; }
7878

79-
bool MetaDataDescriptor::isEqual(const MetaDataDescriptor& other) const
79+
bool MetaDataDescriptor::isSimilar(const MetaDataDescriptor& other) const
8080
{
8181
if ((m_type == other.m_type) && (m_length == other.m_length))
8282
return true;
8383
else
8484
return false;
8585
}
8686

87+
bool MetaDataDescriptor::isEqual(const MetaDataDescriptor& other) const
88+
{
89+
if ((m_type == other.m_type) && (m_length == other.m_length) && m_identifier.trim() == other.m_identifier.trim())
90+
return true;
91+
else
92+
return false;
93+
}
94+
8795
bool MetaDataDescriptor::operator==(const MetaDataDescriptor& other) const
8896
{
8997
return isEqual(other);
@@ -335,6 +343,36 @@ int MetaDataInfoObject::findMetaData(MetaDataDescriptor::MetaDataTypes type, uns
335343
return -1;
336344
}
337345

346+
bool MetaDataInfoObject::hasSameMetadata(const MetaDataInfoObject& other) const
347+
{
348+
return checkMetaDataCoincidence(other, false);
349+
}
350+
351+
bool MetaDataInfoObject::hasSimilarMetadata(const MetaDataInfoObject& other) const
352+
{
353+
return checkMetaDataCoincidence(other, true);
354+
}
355+
356+
bool MetaDataInfoObject::checkMetaDataCoincidence(const MetaDataInfoObject& other, bool similar) const
357+
{
358+
int nMetaData = m_metaDataDescriptorArray.size();
359+
if (nMetaData != other.m_metaDataDescriptorArray.size()) return false;
360+
for (int i = 0; i < nMetaData; i++)
361+
{
362+
MetaDataDescriptorPtr md = m_metaDataDescriptorArray[i];
363+
MetaDataDescriptorPtr mdo = other.m_metaDataDescriptorArray[i];
364+
if (similar)
365+
{
366+
if (!md->isSimilar(*mdo)) return false;
367+
}
368+
else
369+
{
370+
if (!md->isEqual(*mdo)) return false;
371+
}
372+
}
373+
return true;
374+
}
375+
338376
//MetaDataEventObject
339377

340378
MetaDataEventObject::MetaDataEventObject() {}
@@ -398,6 +436,36 @@ int MetaDataEventObject::findEventMetaData(MetaDataDescriptor::MetaDataTypes typ
398436
return -1;
399437
}
400438

439+
bool MetaDataEventObject::hasSameEventMetadata(const MetaDataEventObject& other) const
440+
{
441+
return checkMetaDataCoincidence(other, false);
442+
}
443+
444+
bool MetaDataEventObject::hasSimilarEventMetadata(const MetaDataEventObject& other) const
445+
{
446+
return checkMetaDataCoincidence(other, true);
447+
}
448+
449+
bool MetaDataEventObject::checkMetaDataCoincidence(const MetaDataEventObject& other, bool similar) const
450+
{
451+
int nMetaData = m_eventMetaDataDescriptorArray.size();
452+
if (nMetaData != other.m_eventMetaDataDescriptorArray.size()) return false;
453+
for (int i = 0; i < nMetaData; i++)
454+
{
455+
MetaDataDescriptorPtr md = m_eventMetaDataDescriptorArray[i];
456+
MetaDataDescriptorPtr mdo = other.m_eventMetaDataDescriptorArray[i];
457+
if (similar)
458+
{
459+
if (!md->isSimilar(*mdo)) return false;
460+
}
461+
else
462+
{
463+
if (!md->isEqual(*mdo)) return false;
464+
}
465+
}
466+
return true;
467+
}
468+
401469
size_t MetaDataEventObject::getMaxEventMetaDataSize() const
402470
{
403471
return m_maxSize;

Source/Processors/Channel/MetaData.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,12 @@ class PLUGIN_API MetaDataDescriptor
8585
/** Gets the machine-readable identifier for this field */
8686
String getIdentifier() const;
8787

88+
/** Returns true if both descriptors have the same type, length and identifier */
8889
bool isEqual(const MetaDataDescriptor& other) const;
90+
/** Returns true if both descriptors have the same type, length and identifier */
8991
bool operator==(const MetaDataDescriptor& other) const;
92+
/** Returns true if both descriptors have the same type and length, regardless of the identifier */
93+
bool isSimilar(const MetaDataDescriptor& other) const;
9094

9195
static size_t getTypeSize(MetaDataTypes type);
9296
private:
@@ -184,9 +188,13 @@ class PLUGIN_API MetaDataInfoObject
184188
const MetaDataValue* getMetaDataValue(int index) const;
185189
int findMetaData(MetaDataDescriptor::MetaDataTypes type, unsigned int length, String identifier = String::empty) const;
186190
const int getMetaDataCount() const;
191+
bool hasSameMetadata(const MetaDataInfoObject& other) const;
192+
bool hasSimilarMetadata(const MetaDataInfoObject& other) const;
187193
protected:
188194
MetaDataDescriptorArray m_metaDataDescriptorArray;
189195
MetaDataValueArray m_metaDataValueArray;
196+
private:
197+
bool checkMetaDataCoincidence(const MetaDataInfoObject& other, bool similar) const;
190198
};
191199

192200
class PLUGIN_API MetaDataEventLock
@@ -215,11 +223,15 @@ class PLUGIN_API MetaDataEventObject : public MetaDataEventLock
215223
int getEventMetaDataCount() const;
216224
//gets the largest metadata size, which can be useful to reserve buffers in advance
217225
size_t getMaxEventMetaDataSize() const;
226+
bool hasSameEventMetadata(const MetaDataEventObject& other) const;
227+
bool hasSimilarEventMetadata(const MetaDataEventObject& other) const;
218228
protected:
219229
MetaDataDescriptorArray m_eventMetaDataDescriptorArray;
220230
MetaDataEventObject();
221231
size_t m_totalSize{ 0 };
222232
size_t m_maxSize{ 0 };
233+
private:
234+
bool checkMetaDataCoincidence(const MetaDataEventObject& other, bool similar) const;
223235
};
224236

225237
//And the base from which event objects can hold their metadata before serializing
@@ -239,4 +251,6 @@ class PLUGIN_API MetaDataEvent
239251
//Helper function to compare identifier strings
240252
bool compareIdentifierStrings(const String& identifier, const String& compareWith);
241253

254+
typedef MetaDataDescriptor::MetaDataTypes BaseType;
255+
242256
#endif

0 commit comments

Comments
 (0)