Skip to content

Commit

Permalink
Properly handle redundant device descriptor packets
Browse files Browse the repository at this point in the history
There are certain cases when SMS will send device descriptor packets
more than once per run.  Need to ignore the descriptions for devices we
already have (because Mantid will throw an exception if you try to add a
property to a workspace that already has one of the same name).

Refs #5857
  • Loading branch information
rgmiller committed Sep 27, 2012
1 parent 6a8ce32 commit e3c3ebb
Showing 1 changed file with 47 additions and 37 deletions.
84 changes: 47 additions & 37 deletions Code/Mantid/Framework/DataHandling/src/SNSLiveEventDataListener.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -518,14 +518,18 @@ namespace DataHandling
const Poco::XML::Node*pvNode = node->firstChild();
std::string pvName;
std::string pvId;
unsigned pvIdNum;
std::string pvUnits;
std::string pvType;
while (pvNode != NULL)
{
if (pvNode->nodeName() == "pv_name")
pvName = pvNode->firstChild()->nodeValue();
else if (pvNode->nodeName() == "pv_id")
{
pvId = pvNode->firstChild()->nodeValue();
std::istringstream(pvId) >> pvIdNum;
}
else if (pvNode->nodeName() == "pv_type")
pvType = pvNode->firstChild()->nodeValue();
else if (pvNode->nodeName() == "pv_units")
Expand All @@ -546,48 +550,53 @@ namespace DataHandling
}
else
{
// create the property in the workspace - this is a little bit kludgy because
// the type is specified as a string in the XML, but we pass the actual keyword
// to the template declaration. Hense all the if...else if...else stuff...
Property *prop = NULL;
if (pvType == "double")
{
prop = new TimeSeriesProperty<double>(pvName);
}
else if ( (pvType == "integer") ||
(pvType == "unsigned") ||
(pvType.find("enum_") == 0) )
// Note: Mantid doesn't currently support unsigned int properties
// Note: We're treating enums as ints (at least for now)
// Note: ADARA doesn't currently define an integer variable value packet (only unsigned)
{
prop = new TimeSeriesProperty<int>(pvName);
}
else if (pvType == "string")
{
prop = new TimeSeriesProperty<std::string>(pvName);
}
else
{
// invalid type string
g_log.warning() << "Ignoring process variable " << pvName << " because it had an unrecognized type ("
<< pvType << ")." << std::endl;
}

if (prop)
// Check the nameMap - we may have already received a description for this
// device. (SMS will re-send DeviceDescriptor packets under certain
// circumstances.)
NameMapType::const_iterator it = m_nameMap.find( std::make_pair(pkt.devId(), pvIdNum));
if (it == m_nameMap.end())
{
if (pvUnits.size() > 0)
// create the property in the workspace - this is a little bit kludgy because
// the type is specified as a string in the XML, but we pass the actual keyword
// to the template declaration. Hense all the if...else if...else stuff...
Property *prop = NULL;
if (pvType == "double")
{
prop->setUnits( pvUnits);
prop = new TimeSeriesProperty<double>(pvName);
}
else if ( (pvType == "integer") ||
(pvType == "unsigned") ||
(pvType.find("enum_") == 0) )
// Note: Mantid doesn't currently support unsigned int properties
// Note: We're treating enums as ints (at least for now)
// Note: ADARA doesn't currently define an integer variable value packet (only unsigned)
{
prop = new TimeSeriesProperty<int>(pvName);
}
else if (pvType == "string")
{
prop = new TimeSeriesProperty<std::string>(pvName);
}
else
{
// invalid type string
g_log.warning() << "Ignoring process variable " << pvName << " because it had an unrecognized type ("
<< pvType << ")." << std::endl;
}

m_buffer->mutableRun().addLogData(prop);
if (prop)
{
if (pvUnits.size() > 0)
{
prop->setUnits( pvUnits);
}

// Add the pv id, device id and pv name to the name map so we can find the
// name when we process the variable value packets
unsigned pvIdNum;
std::istringstream(pvId) >> pvIdNum;
m_nameMap[ std::make_pair( pkt.devId(), pvIdNum)] = pvName;
m_buffer->mutableRun().addLogData(prop);

// Add the pv id, device id and pv name to the name map so we can find the
// name when we process the variable value packets
m_nameMap[ std::make_pair( pkt.devId(), pvIdNum)] = pvName;
}
}
}
}
Expand Down Expand Up @@ -708,6 +717,7 @@ namespace DataHandling
// Note: we can get away with not locking a mutex here because the
// background thread is still paused.
m_workspaceInitialized = false;
m_nameMap.clear();
m_buffer = boost::dynamic_pointer_cast<DataObjects::EventWorkspace>
(WorkspaceFactory::Instance().create("EventWorkspace", 1, 1, 1));
}
Expand Down

0 comments on commit e3c3ebb

Please sign in to comment.