diff --git a/isis/src/control/objs/ControlNet/ControlNet.cpp b/isis/src/control/objs/ControlNet/ControlNet.cpp index 6c204b30eb716d7cf0cdc068a72652f8865f754b..9c3a06ebe3c344225ac88ac12f089b671b6e3587 100644 --- a/isis/src/control/objs/ControlNet/ControlNet.cpp +++ b/isis/src/control/objs/ControlNet/ControlNet.cpp @@ -237,14 +237,24 @@ namespace Isis { * parent prematurely to be able to set the radii * in ControlPoint. * @history 2017-12-21 Jesse Mapel - Modified to use the ControlNetVersioner. - * + * @history 2018-04-05 Adam Goins - Added a check to the versionedReader targetRadii + * group to set radii values to those ingested from the versioner + * if they exist. Otherwise, we call SetTarget with the targetname. */ void ControlNet::ReadControl(const QString &filename, Progress *progress) { FileName cnetFileName(filename); ControlNetVersioner versionedReader(cnetFileName, progress); - - SetTarget( versionedReader.targetName() ); + if ( versionedReader.hasTargetRadii() ) { + p_targetName = versionedReader.targetName(); + p_targetRadii.clear(); + foreach (Distance distance, versionedReader.targetRadii()) { + p_targetRadii.push_back(distance); + } + } + else { + SetTarget( versionedReader.targetName() ); + } p_networkId = versionedReader.netId(); p_userName = versionedReader.userName(); p_created = versionedReader.creationDate(); @@ -346,8 +356,8 @@ namespace Isis { /** - * Adds a whole point to the control net graph. - * + * Adds a whole point to the control net graph. + * * @throws IException::Programmer "NULL measure passed to ControlNet::AddControlCubeGraphNode!" * @throws IException::Programmer "Control measure with NULL parent passed to * ControlNet::AddControlCubeGraphNode!" diff --git a/isis/src/control/objs/ControlNet/ControlNet.h b/isis/src/control/objs/ControlNet/ControlNet.h index 56b9f3bead79667853001f1dea34bec2694ad7cd..5ae923fbb948664c0e450fae647fd12c126e3486 100644 --- a/isis/src/control/objs/ControlNet/ControlNet.h +++ b/isis/src/control/objs/ControlNet/ControlNet.h @@ -212,7 +212,11 @@ namespace Isis { * @history 2017-01-19 Jesse Mapel - Added a method to get all of the valid measures in an * image. Previously, this had to be done throug the graph. * @history 2018-01-26 Kristin Berry - Added pointAdded() function to eliminate redundant measure - * adds to the control network. + * adds to the control network. + * @history 2018-04-05 Adam Goins - Added a check to the versionedReader targetRadii + * group to set radii values to those ingested from the versioner + * if they exist. Otherwise, we call SetTarget with the targetname. + * Fixes #5361. */ class ControlNet : public QObject { Q_OBJECT diff --git a/isis/src/control/objs/ControlNet/ControlNet.truth b/isis/src/control/objs/ControlNet/ControlNet.truth index 13ef6e7272d3f04b3b627134210ad082582a58b9..caa915ff646a406d8487be8b9ef4db5a01aeefe1 100644 --- a/isis/src/control/objs/ControlNet/ControlNet.truth +++ b/isis/src/control/objs/ControlNet/ControlNet.truth @@ -147,6 +147,7 @@ Object = ControlNetwork Created = 2010-07-10T12:50:15 LastModified = 2010-07-10T12:50:55 Description = "UnitTest of ControlNetwork" + TargetRadii = (3396190.0, 3396190.0, 3376200.0) Version = 5 Object = ControlPoint diff --git a/isis/src/control/objs/ControlNetVersioner/ControlNetFileHeaderV0005.proto b/isis/src/control/objs/ControlNetVersioner/ControlNetFileHeaderV0005.proto index d04e6ca50192996502979d04aff06a18883fe063..424fad3c98ec62f99f7bbcd2f3bdc1b3ac92aafa 100644 --- a/isis/src/control/objs/ControlNetVersioner/ControlNetFileHeaderV0005.proto +++ b/isis/src/control/objs/ControlNetVersioner/ControlNetFileHeaderV0005.proto @@ -9,6 +9,6 @@ message ControlNetFileHeaderV0005 { optional string lastModified = 4; optional string description = 5; optional string userName = 6; - optional int32 numPoints = 7; + optional int32 numPoints = 7; + repeated double targetRadii = 10; } - diff --git a/isis/src/control/objs/ControlNetVersioner/ControlNetVersioner.cpp b/isis/src/control/objs/ControlNetVersioner/ControlNetVersioner.cpp index f02c607873ca0537c9562ce24ad9341501adb3cd..b261b4c94f5c1c6470c2950034fca9d34d43c030 100644 --- a/isis/src/control/objs/ControlNetVersioner/ControlNetVersioner.cpp +++ b/isis/src/control/objs/ControlNetVersioner/ControlNetVersioner.cpp @@ -63,6 +63,14 @@ namespace Isis { header.lastModified = net->GetLastModified(); header.description = net->Description(); header.userName = net->GetUserName(); + + std::vector netRadii = net->GetTargetRadii(); + if ( netRadii.size() >= 3 && + netRadii[0].isValid() && + netRadii[1].isValid() && + netRadii[2].isValid() ) { + header.targetRadii = net->GetTargetRadii(); + } createHeader(header); } @@ -158,6 +166,25 @@ namespace Isis { } + /** + * Returns true if the targetRadii in the header has values. + * + * @return @b boolean True if the targetRadii in the header is populated. + */ + bool ControlNetVersioner::hasTargetRadii() const { + return m_header.targetRadii.empty() ? false : true; + } + + /** + * Returns the targetRadii Distance vector located in the header. + * + * @return @b std::vector A vector containing the target body radii. + */ + std::vector ControlNetVersioner::targetRadii() const { + return m_header.targetRadii; + } + + /** * Returns the number of points that have been read in or are ready to write out. * @@ -202,24 +229,20 @@ namespace Isis { network += PvlKeyword("Created", m_header.created); network += PvlKeyword("LastModified", m_header.lastModified); network += PvlKeyword("Description", m_header.description); + + // Grab TargetRadii if they exist. + if (!m_header.targetRadii.empty()) { + PvlKeyword pvlRadii("TargetRadii"); + for (uint i = 0; i < m_header.targetRadii.size(); i++) { + pvlRadii += toString(m_header.targetRadii[i].meters()); + } + network += pvlRadii; + } // optionally add username to output? // This is the Pvl version we're converting to network += PvlKeyword("Version", "5"); - // Get Target Radii from naif kernel - PvlGroup pvlRadii; - QString target = (QString)network.findKeyword("TargetName",Pvl::Traverse); - if ( target != "" ) { - try { - NaifStatus::CheckErrors(); - pvlRadii = Target::radiiGroup(target); - } - catch (IException) { - // leave pvlRadii empty if target is not recognized by NAIF - } - } - foreach (ControlPoint *controlPoint, m_points) { PvlObject pvlPoint("ControlPoint"); @@ -341,11 +364,11 @@ namespace Isis { matrix += toString(aprioriCovarianceMatrix(1, 2)); matrix += toString(aprioriCovarianceMatrix(2, 2)); - if ( pvlRadii.hasKeyword("EquatorialRadius") && pvlRadii.hasKeyword("PolarRadius") ) { + if ( !m_header.targetRadii.empty() ) { - aprioriSurfacePoint.SetRadii( Distance(pvlRadii["EquatorialRadius"], Distance::Meters), - Distance(pvlRadii["EquatorialRadius"], Distance::Meters), - Distance(pvlRadii["PolarRadius"], Distance::Meters) ); + aprioriSurfacePoint.SetRadii( m_header.targetRadii[0], + m_header.targetRadii[1], + m_header.targetRadii[2] ); if ( aprioriSurfacePoint.GetLatSigmaDistance().meters() != Isis::Null && aprioriSurfacePoint.GetLonSigmaDistance().meters() != Isis::Null @@ -424,11 +447,11 @@ namespace Isis { matrix += toString(adjustedCovarianceMatrix(1, 2)); matrix += toString(adjustedCovarianceMatrix(2, 2)); - if ( pvlRadii.hasKeyword("EquatorialRadius") && pvlRadii.hasKeyword("PolarRadius") ) { + if ( !m_header.targetRadii.empty() ) { - adjustedSurfacePoint.SetRadii(Distance(pvlRadii["EquatorialRadius"], Distance::Meters), - Distance(pvlRadii["EquatorialRadius"], Distance::Meters), - Distance(pvlRadii["PolarRadius"], Distance::Meters) ); + adjustedSurfacePoint.SetRadii( m_header.targetRadii[0], + m_header.targetRadii[1], + m_header.targetRadii[2] ); if ( adjustedSurfacePoint.GetLatSigmaDistance().meters() != Isis::Null && adjustedSurfacePoint.GetLonSigmaDistance().meters() != Isis::Null @@ -716,6 +739,7 @@ namespace Isis { try { PvlObject pointObject = network.object(objectIndex); ControlPointV0002 point(pointObject); + m_points.append( createPoint(point) ); if (progress) { @@ -847,6 +871,16 @@ namespace Isis { header.lastModified = network.findKeyword("LastModified")[0]; header.description = network.findKeyword("Description")[0]; header.userName = network.findKeyword("UserName")[0]; + if (network.hasKeyword("TargetRadii")) { + header.targetRadii.clear(); + for (int i = 0; i < network.findKeyword("TargetRadii").size(); i++) { + Distance distance = Distance(toDouble(network.findKeyword("TargetRadii")[i]), + Distance::Meters); + if ( distance.isValid() ) { + header.targetRadii.push_back(distance); + } + } + } createHeader(header); } catch (IException &e) { @@ -1170,6 +1204,7 @@ namespace Isis { void ControlNetVersioner::readProtobufV0005(const Pvl &header, const FileName netFile, Progress *progress) { + // read the header protobuf object const PvlObject &protoBufferInfo = header.findObject("ProtoBuffer"); const PvlObject &protoBufferCore = protoBufferInfo.findObject("Core"); @@ -1228,6 +1263,15 @@ namespace Isis { header.lastModified = protoHeader.lastmodified().c_str(); header.description = protoHeader.description().c_str(); header.userName = protoHeader.username().c_str(); + if ( protoHeader.targetradii_size() >= 3 ) { + header.targetRadii.clear(); + for (int i = 0; i < protoHeader.targetradii_size(); i++) { + Distance distance = Distance(protoHeader.targetradii(i), Distance::Meters); + if ( distance.isValid() ) { + header.targetRadii.push_back(distance); + } + } + } createHeader(header); } catch (IException &e) { @@ -1278,7 +1322,7 @@ namespace Isis { uint32_t size; pointCodedInStream.ReadRaw(reinterpret_cast(&size), sizeof(size)); - + size = lsb.Uint32_t(&size); CodedInputStream::Limit oldPointLimit = pointCodedInStream.PushLimit(size); @@ -1357,6 +1401,7 @@ namespace Isis { * @return @b ControlPoint* The ControlPoint constructed from the given point. */ ControlPoint *ControlNetVersioner::createPoint(ControlPointV0003 &point) { + ControlPointFileEntryV0002 protoPoint = point.pointData(); ControlPoint *controlPoint = new ControlPoint; @@ -1521,16 +1566,19 @@ namespace Isis { controlPoint->SetAdjustedSurfacePoint(adjustedSurfacePoint); } + if ( !m_header.targetRadii.empty() && + m_header.targetRadii[0].isValid() && + m_header.targetRadii[1].isValid() && + m_header.targetRadii[2].isValid() ) { - if ( m_header.equatorialRadius.isValid() && m_header.polarRadius.isValid() ) { SurfacePoint aprioriSurfacePoint = controlPoint->GetAprioriSurfacePoint(); SurfacePoint adjustedSurfacePoint = controlPoint->GetAdjustedSurfacePoint(); - aprioriSurfacePoint.SetRadii(m_header.equatorialRadius, - m_header.equatorialRadius, - m_header.polarRadius); - adjustedSurfacePoint.SetRadii(m_header.equatorialRadius, - m_header.equatorialRadius, - m_header.polarRadius); + aprioriSurfacePoint.SetRadii(m_header.targetRadii[0], + m_header.targetRadii[1], + m_header.targetRadii[2]); + adjustedSurfacePoint.SetRadii(m_header.targetRadii[0], + m_header.targetRadii[1], + m_header.targetRadii[2]); controlPoint->SetAdjustedSurfacePoint(adjustedSurfacePoint); controlPoint->SetAprioriSurfacePoint(aprioriSurfacePoint); } @@ -1670,12 +1718,22 @@ namespace Isis { m_header.targetName = "Mars"; } - if ( !m_header.targetName.isEmpty() ) { + if ( m_header.targetRadii.empty() ) { try { - // attempt to get target radii values... - PvlGroup pvlRadii = Target::radiiGroup(m_header.targetName); - m_header.equatorialRadius.setMeters(pvlRadii["EquatorialRadius"]); - m_header.polarRadius.setMeters(pvlRadii["PolarRadius"]); + // attempt to get target radii values... + // The target body raii values are read from the PvlV0005 and BinaryV0005 + // Networks. In the event these values weren't read (from an older network) + // then we must grab them from the Target::radii group. + if ( !m_header.targetName.isEmpty() ) { + + PvlGroup pvlRadii = Target::radiiGroup(m_header.targetName); + m_header.targetRadii.push_back(Distance(pvlRadii["EquatorialRadius"], + Distance::Meters)); + m_header.targetRadii.push_back(Distance(pvlRadii["EquatorialRadius"], + Distance::Meters)); + m_header.targetRadii.push_back(Distance(pvlRadii["PolarRadius"], + Distance::Meters)); + } } catch (IException &e) { // do nothing @@ -1725,6 +1783,12 @@ namespace Isis { protobufHeader.set_description(m_header.description.toLatin1().data()); protobufHeader.set_username(m_header.userName.toLatin1().data()); + if ( !m_header.targetRadii.empty() ) { + for (uint i = 0; i < m_header.targetRadii.size(); i++) { + protobufHeader.add_targetradii(m_header.targetRadii[i].meters()); + } + } + streampos coreHeaderSize = protobufHeader.ByteSize(); Pvl p; @@ -1748,12 +1812,20 @@ namespace Isis { netInfo.addComment("This group is for informational purposes only"); netInfo += PvlKeyword("NetworkId", protobufHeader.networkid().c_str()); netInfo += PvlKeyword("TargetName", protobufHeader.targetname().c_str()); + + // Grab TargetRadii if they exist. + if (!m_header.targetRadii.empty()) { + PvlKeyword pvlRadii("TargetRadii"); + for (uint i = 0; i < m_header.targetRadii.size(); i++) { + pvlRadii += toString(m_header.targetRadii[i].meters()); + } + netInfo += pvlRadii; + } netInfo += PvlKeyword("UserName", protobufHeader.username().c_str()); netInfo += PvlKeyword("Created", protobufHeader.created().c_str()); netInfo += PvlKeyword("LastModified", protobufHeader.lastmodified().c_str()); netInfo += PvlKeyword("Description", protobufHeader.description().c_str()); netInfo += PvlKeyword("NumberOfPoints", toString(numPoints)); - netInfo += PvlKeyword("NumberOfMeasures", toString(numMeasures)); netInfo += PvlKeyword("Version", "5"); protoObj.addGroup(netInfo); @@ -1789,6 +1861,12 @@ namespace Isis { protobufHeader.set_description(m_header.description.toLatin1().data()); protobufHeader.set_username(m_header.userName.toLatin1().data()); + if ( !m_header.targetRadii.empty() ) { + for (uint i = 0; i < m_header.targetRadii.size(); i++) { + protobufHeader.add_targetradii(m_header.targetRadii[i].meters()); + } + } + // Write out the header if ( !protobufHeader.SerializeToOstream(output) ) { QString msg = "Failed to write output control network file."; diff --git a/isis/src/control/objs/ControlNetVersioner/ControlNetVersioner.h b/isis/src/control/objs/ControlNetVersioner/ControlNetVersioner.h index 14f15a7e01179b3b1e34dcaae323059ea7448e04..03f3484408a7559b50f5264ea696070a83f9dc74 100644 --- a/isis/src/control/objs/ControlNetVersioner/ControlNetVersioner.h +++ b/isis/src/control/objs/ControlNetVersioner/ControlNetVersioner.h @@ -403,6 +403,12 @@ namespace Isis { * describing the different file format versions. * @history 2018-01-30 Adam Goins - Ensured point sizes are written/read as lsb by using * EndianSwapper. + * @history 2018-03-28 Adam Goins - Added targetRadii groups to the header. Changed the + * versioner to write these values out in a targetRadii group for + * both binary V0005 and PvlV0005 networks. Fixes #5361. + * @history 2018-04-05 Adam Goins - Added hasTargetRadii() and targetRadii() to the versioner + * so that these values can be grabbed from a ControlNet on read. + * Also Fixes #5361. */ class ControlNetVersioner { @@ -417,6 +423,8 @@ namespace Isis { QString lastModificationDate() const; QString description() const; QString userName() const; + bool hasTargetRadii() const; + std::vector targetRadii() const; int numPoints() const; ControlPoint *takeFirstPoint(); @@ -471,12 +479,9 @@ namespace Isis { * The equatorial radius of the target body * used to convert from spherical to rectangular coordinates */ - Distance equatorialRadius; - /** - * The equatorial radius of the target body - * used to convert from spherical to rectangular coordinates - */ - Distance polarRadius; + + std::vector targetRadii; + }; //! Typedef for consistent naming of containers for version 2 diff --git a/isis/src/control/objs/ControlNetVersioner/ControlNetVersioner.truth b/isis/src/control/objs/ControlNetVersioner/ControlNetVersioner.truth index 956be921b7b9d6f1a0aff1cb670ee89a19e4f8d2..af4a14e71a77d131815baea9b758b3ae5846130a 100644 --- a/isis/src/control/objs/ControlNetVersioner/ControlNetVersioner.truth +++ b/isis/src/control/objs/ControlNetVersioner/ControlNetVersioner.truth @@ -20,6 +20,7 @@ Object = ControlNetwork Created = Null LastModified = Null Description = Null + TargetRadii = (3396190.0, 3396190.0, 3376200.0) Version = 5 Object = ControlPoint @@ -76,6 +77,7 @@ Object = ControlNetwork Created = Null LastModified = Null Description = "Test Network" + TargetRadii = (2575000.0, 2575000.0, 2575000.0) Version = 5 Object = ControlPoint @@ -132,6 +134,7 @@ Object = ControlNetwork Created = 2010-07-10T12:50:15 LastModified = 2010-07-10T12:50:55 Description = "UnitTest of ControlNetwork" + TargetRadii = (3396190.0, 3396190.0, 3376200.0) Version = 5 Object = ControlPoint @@ -329,6 +332,7 @@ Object = ControlNetwork Created = 2012-01-04T12:09:57 LastModified = 2012-01-04T12:09:57 Description = "Themis Day IR Network: Lunae Palus, Lat(0,30) Lon(270-315)" + TargetRadii = (3396190.0, 3396190.0, 3376200.0) Version = 5 Object = ControlPoint @@ -559,7 +563,12 @@ After reading and writing to a binary form does Pvl match? Conversion to Pvl stays consistent Reading/Writing control network is consistent Check conversions between the binary format and the pvl format. -The conversion methods for pvl->bin and bin->pvl are correct. +8c8,9 +< Version = 3 +--- +> TargetRadii = (3396190.0, 3396190.0, 3376200.0) +> Version = 5 +The conversion from pvl to binary is incorrect. Reading: $control/testData/unitTest_ControlNetVersioner_PvlNetwork5_PvlV0003.pvl...