Skip to content

Commit

Permalink
Merge pull request #275 from tudat-team/feature/station_position_auto…
Browse files Browse the repository at this point in the history
…mation

Feature/station position automation
  • Loading branch information
DominicDirkx authored Jan 15, 2025
2 parents e49661a + 8b42cd8 commit 49f49f7
Show file tree
Hide file tree
Showing 11 changed files with 196 additions and 85 deletions.
6 changes: 3 additions & 3 deletions include/tudat/basics/utilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -1027,13 +1027,13 @@ std::vector< ScalarType > convertVectors(ConvertFunc convertFunc, const std::vec


template<typename T, typename U>
std::map<T, U> getMapFromFile(std::string fileName, char commentSymbol='#', std::string separators="\t");
std::map<T, U> getMapFromFile(std::string fileName, char commentSymbol='#', std::string separators="\t", const int skipNumberOfEntries = 0 );

template<>
std::map<std::string, Eigen::Vector3d> getMapFromFile<std::string, Eigen::Vector3d>(std::string fileName, char commentSymbol, std::string separators);
std::map<std::string, Eigen::Vector3d> getMapFromFile<std::string, Eigen::Vector3d>(std::string fileName, char commentSymbol, std::string separators, const int skipNumberOfEntries);

template<>
std::map<std::string, std::string> getMapFromFile<std::string, std::string>(std::string fileName, char commentSymbol, std::string separators);
std::map<std::string, std::string> getMapFromFile<std::string, std::string>(std::string fileName, char commentSymbol, std::string separators, const int skipNumberOfEntries);

/*!
* Utility function to get a value from a string map where the keys are all uppercase
Expand Down
28 changes: 22 additions & 6 deletions include/tudat/io/readTrackingTxtFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,12 @@ static const std::map<std::string, std::shared_ptr<TrackingFileFieldConverter>>

};

enum TrackingTxtFileReadFilterType
{
no_tracking_txt_file_filter,
ifms_tracking_txt_file_filter
};

/*!
* Class to extract the raw data from a file with the appropriate conversion to doubles. Data fields that do not have an
* appropriate converter are simply stored as raw strings.
Expand All @@ -287,17 +293,18 @@ class TrackingTxtFileContents
const std::vector<std::string> columnTypes,
const char commentSymbol = '#',
const std::string valueSeparators = ",: \t",
const bool ignoreOmittedColumns = false )
const bool ignoreOmittedColumns = false,
const TrackingTxtFileReadFilterType dataFilterMethod = no_tracking_txt_file_filter )
: fileName_(fileName), columnFieldTypes_(columnTypes), commentSymbol_(commentSymbol),
valueSeparators_(valueSeparators), ignoreOmittedColumns_( ignoreOmittedColumns )
{
parseData();
parseData( dataFilterMethod );
}

private:

//! Main parsing sequence to read and process the file
void parseData();
void parseData( const TrackingTxtFileReadFilterType dataFilterMethod );

/*!
* Read out the raw data map from a filestream
Expand All @@ -311,10 +318,12 @@ class TrackingTxtFileContents
*/
void addLineToRawDataMap(std::string& rawLine);

/*!
bool validateCurrentLineProcessing( const TrackingTxtFileReadFilterType dataFilterMethod, const std::vector<std::string>& rawVector );

/*!
* Use the appropriate converters to convert the raw data to the correct double representations
*/
void convertDataMap();
void convertDataMap( const TrackingTxtFileReadFilterType dataFilterMethod );

// Getters
public:
Expand Down Expand Up @@ -381,6 +390,8 @@ class TrackingTxtFileContents
//! Get all available data types (either as metadata or individually per row)
const std::vector<TrackingDataType> getAllAvailableDataTypes();

void subtractColumnType( const TrackingDataType& columnToSubtractFrom, const TrackingDataType& columnToSubtract );

private:
//! Path of the file name of interest
std::string fileName_ = "None";
Expand Down Expand Up @@ -430,7 +441,7 @@ static inline std::shared_ptr<TrackingTxtFileContents> createTrackingTxtFileCont
}


inline std::shared_ptr< TrackingTxtFileContents> readIfmsFile(const std::string& fileName)
inline std::shared_ptr< TrackingTxtFileContents> readIfmsFile(const std::string& fileName, const bool applyTroposphereCorrection = true )
{
std::vector<std::string>
columnTypes({"sample_number",
Expand All @@ -448,6 +459,11 @@ inline std::shared_ptr< TrackingTxtFileContents> readIfmsFile(const std::string&

auto rawFileContents = createTrackingTxtFileContents(fileName, columnTypes, '#', ", \t",true);
rawFileContents->addMetaData( TrackingDataType::file_name, fileName );
if( applyTroposphereCorrection )
{
rawFileContents->subtractColumnType( input_output::TrackingDataType::doppler_averaged_frequency, input_output::TrackingDataType::doppler_troposphere_correction );

}
return rawFileContents;
}

Expand Down
28 changes: 5 additions & 23 deletions include/tudat/simulation/environment_setup/defaultBodies.h
Original file line number Diff line number Diff line change
Expand Up @@ -253,31 +253,9 @@ inline std::map< int, std::vector< std::string > > getDefaultDsnStationNamesPerC
*/
Eigen::Vector3d getApproximateGroundStationPosition( std::string stationName );

//static std::map< std::string, Eigen::Vector3d >& getApproximateGroundStationPositionsFromFile();

std::map< std::string, Eigen::Vector3d >& getVlbiStationPositions( );

//
////! Get map of approximate ground station positions
//const std::map<std::string, Eigen::Vector3d>& getApproximateGroundStationPositionsFromFile();
//
////! Get approximate ground station position
//Eigen::Vector3d getApproximateGroundStationPositionFromFile( std::string stationName );
//
////! Get approximate ground station velocity
//Eigen::Vector3d getApproximateGroundStationVelocityFromFile(std::string stationName );
//
//const std::map<std::string,std::string>& getGroundStationCodesFromFile();
//
////! Get long name or return original
//template<typename T>
//std::string getGroundStationCodeFromFile(T shortStationName){
// return "DSS-" + std::to_string(static_cast<int>(shortStationName)); // TODO : TEMPORARY - Remove this - Add these to the file instead
//// return getGroundStationCodeFromFile(std::to_string(static_cast<int>(shortStationName)));
//}

//template<>
//std::string getGroundStationCodeFromFile<std::string>(std::string shortStationName);
std::map< std::string, Eigen::Vector3d >& getVlbiStationVelocities( );

/*!
* Returns the settings for DSN ground stations. The settings are specified according to table 2 and 3 of DSN 810-005,
Expand All @@ -288,6 +266,10 @@ std::map< std::string, Eigen::Vector3d >& getVlbiStationPositions( );
*/
std::vector< std::shared_ptr< GroundStationSettings > > getDsnStationSettings( );

std::vector< std::shared_ptr< GroundStationSettings > > getEvnStationSettings( );

std::vector< std::shared_ptr< GroundStationSettings > > getRadioTelescopeStationSettings( );


} // namespace simulation_setup

Expand Down
12 changes: 12 additions & 0 deletions include/tudat/simulation/estimation_setup/createObservationModel.h
Original file line number Diff line number Diff line change
Expand Up @@ -760,6 +760,18 @@ class TwoWayDopplerObservationSettings : public ObservationModelSettings
biasSettings ),
normalizeWithSpeedOfLight_( normalizeWithSpeedOfLight )
{
if( linkEnds.getLinkEnds( ).count( transmitter ) == 0 )
{
throw std::runtime_error( "Error when creating 2-way Doppler model, no transmitter found" );
}
if( linkEnds.getLinkEnds( ).count( receiver ) == 0 )
{
throw std::runtime_error( "Error when creating 2-way Doppler model, no receiver found" );
}
if( linkEnds.getLinkEnds( ).count( retransmitter ) == 0 )
{
throw std::runtime_error( "Error when creating 2-way Doppler model, no retransmitter found" );
}
uplinkOneWayDopplerSettings_ = std::make_shared< OneWayDopplerObservationSettings >(
getUplinkFromTwoWayLinkEnds( linkEnds ),
lightTimeCorrectionsList,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -767,14 +767,15 @@ std::shared_ptr< observation_models::ObservationCollection< ObservationScalarTyp
const std::string& groundStationName,
const FrequencyBands& receptionBand,
const FrequencyBands& transmissionBand,
const bool applyTroposphereCorrection = true,
const std::map< std::string, Eigen::Vector3d >& earthFixedGroundStationPositions =
simulation_setup::getCombinedApproximateGroundStationPositions( ) )
{
std::vector< std::shared_ptr< input_output::TrackingTxtFileContents > > rawIfmsDataList;

for( std::string ifmsFileName : ifmsFileNames )
{
rawIfmsDataList.push_back( input_output::readIfmsFile( ifmsFileName ) );
rawIfmsDataList.push_back( input_output::readIfmsFile( ifmsFileName, applyTroposphereCorrection ) );
}

std::vector< std::shared_ptr< ProcessedTrackingTxtFileContents< ObservationScalarType, TimeType > > > processedIfmsFiles;
Expand Down
13 changes: 7 additions & 6 deletions src/basics/utilities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ boost::array< boost::multi_array< double, 3 >::index, 3 > getMultiArrayIndexArra
template< >
std::map<std::string, Eigen::Vector3d> getMapFromFile<std::string, Eigen::Vector3d>(std::string fileName,
char commentSymbol,
std::string separators)
std::string separators,
const int skipNumberOfEntries)
{
std::ifstream file(fileName);
if (!file.good()) {
Expand All @@ -88,9 +89,9 @@ std::map<std::string, Eigen::Vector3d> getMapFromFile<std::string, Eigen::Vector
boost::is_any_of(separators),
boost::algorithm::token_compress_on);
try {
namesAndPositions[currentSplitLine.at(0)] = Eigen::Vector3d(std::stod(currentSplitLine.at(1)),
std::stod(currentSplitLine.at(2)),
std::stod(currentSplitLine.at(3)));
namesAndPositions[currentSplitLine.at(0)] = Eigen::Vector3d(std::stod(currentSplitLine.at(1 + skipNumberOfEntries)),
std::stod(currentSplitLine.at(2 + skipNumberOfEntries)),
std::stod(currentSplitLine.at(3 + skipNumberOfEntries)));
} catch (...) {
continue;
}// Ignore lines that cannot be read
Expand All @@ -112,7 +113,7 @@ std::map<std::string, Eigen::Vector3d> getMapFromFile<std::string, Eigen::Vector
* @return map with string to 3d vector
*/
template< >
std::map<std::string, std::string> getMapFromFile<std::string, std::string>(std::string fileName, char commentSymbol, std::string separators)
std::map<std::string, std::string> getMapFromFile<std::string, std::string>(std::string fileName, char commentSymbol, std::string separators, const int skipNumberOfEntries)
{
std::ifstream file(fileName);
if (!file.good()) {
Expand All @@ -129,7 +130,7 @@ std::map<std::string, std::string> getMapFromFile<std::string, std::string>(std:
boost::is_any_of(separators),
boost::algorithm::token_compress_on);
try {
namesAndPositions[currentSplitLine.at(0)] = currentSplitLine.at(1);
namesAndPositions[currentSplitLine.at(0)] = currentSplitLine.at(1 + skipNumberOfEntries );
} catch (...) {
continue;
}// Ignore lines that cannot be read
Expand Down
103 changes: 84 additions & 19 deletions src/io/readTrackingTxtFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@ namespace tudat
namespace input_output
{

void TrackingTxtFileContents::parseData()
void TrackingTxtFileContents::parseData( const TrackingTxtFileReadFilterType dataFilterMethod )
{
std::ifstream dataFile(fileName_);
if (!dataFile.good()) {
throw std::runtime_error("Error when opening Tracking txt file: file " + fileName_ + " could not be opened.");
}
readRawDataMap(dataFile);
convertDataMap();
convertDataMap(dataFilterMethod);
}

void TrackingTxtFileContents::readRawDataMap(std::ifstream& dataFile)
Expand Down Expand Up @@ -75,29 +75,70 @@ void TrackingTxtFileContents::addLineToRawDataMap(std::string& rawLine)
}
}

void TrackingTxtFileContents::convertDataMap()
bool TrackingTxtFileContents::validateCurrentLineProcessing( const TrackingTxtFileReadFilterType dataFilterMethod, const std::vector<std::string>& rawVector )
{
// Loop over all the column types to convert them to doubles
for (std::string columnType : columnFieldTypes_) {
bool addLine = true;

// If the columnType (requested by the user) does not have a known converter in tudat, it is skipped here and only stored as raw string
if (!trackingFileFieldConverterMap.count(columnType)) {
std::cout << "Warning: '" << columnType << "' is not recognised as a column type by Tudat. The data is available in the raw format.\n";
continue;
if( dataFilterMethod == ifms_tracking_txt_file_filter )
{
for( unsigned int i = 0; i < rawVector.size( ); i++ )
{
bool currentEntryIsValid = false;
if( rawVector.at( 0 ) != "-" )
{
currentEntryIsValid = true;
}
else
{
for ( unsigned int j = 1; j < rawVector.at( j ).size( ); j++ )
{
if( ( rawVector.at( j ) != "9" ) && ( rawVector.at( j ) != "." ) )
{
currentEntryIsValid = true;
break;
}
}
}
if( currentEntryIsValid == false )
{
addLine = false;
break;
}
}
}

// Get the raw vector, correct converter and target data type represented by the doubles
std::shared_ptr<TrackingFileFieldConverter> converter = trackingFileFieldConverterMap.at(columnType);
const std::vector<std::string>& rawVector = rawDataMap_.at(columnType);
const TrackingDataType& dataType = converter->getTrackingDataType();
return addLine;
}

void TrackingTxtFileContents::convertDataMap( const TrackingTxtFileReadFilterType dataFilterMethod )
{
// Loop over all the column types to convert them to doubles
for (std::string columnType : columnFieldTypes_)
{

// If the columnType (requested by the user) does not have a known converter in tudat, it is skipped here and only stored as raw string
if (!trackingFileFieldConverterMap.count(columnType))
{
std::cout << "Warning: '" << columnType << "' is not recognised as a column type by Tudat. The data is available in the raw format.\n";
continue;
}

// Get the raw vector, correct converter and target data type represented by the doubles
std::shared_ptr<TrackingFileFieldConverter> converter = trackingFileFieldConverterMap.at(columnType);
const std::vector<std::string>& rawVector = rawDataMap_.at(columnType);
const TrackingDataType& dataType = converter->getTrackingDataType();

// Convert and store double vector
std::vector<double> dataVector;
for (std::string rawValue : rawVector) {
dataVector.push_back(converter->toDouble(rawValue));
// Convert and store double vector
if( validateCurrentLineProcessing( dataFilterMethod, rawVector ) )
{
std::vector<double> dataVector;
for ( std::string rawValue: rawVector )
{
dataVector.push_back( converter->toDouble( rawValue ));
}
doubleDataMap_[ dataType ] = dataVector;
}
}
doubleDataMap_[dataType] = dataVector;
}
}

const std::vector<double> TrackingTxtFileContents::getDoubleDataColumn(TrackingDataType dataType, double defaultVal)
Expand Down Expand Up @@ -150,6 +191,30 @@ const std::vector<TrackingDataType> TrackingTxtFileContents::getAllAvailableData
return columnTypes;
}

void TrackingTxtFileContents::subtractColumnType( const TrackingDataType& columnToSubtractFrom, const TrackingDataType& columnToSubtract )
{
if( doubleDataMap_.count( columnToSubtractFrom ) == 0 )
{
throw std::runtime_error( "Error when subtracing data for tracking text file, column type " + std::to_string( static_cast< int >( columnToSubtractFrom ) ) + " not found." );
}

if( doubleDataMap_.count( columnToSubtract ) == 0 )
{
throw std::runtime_error( "Error when subtracing data for tracking text file, column type " + std::to_string( static_cast< int >( columnToSubtract ) ) + " not found." );
}

if( doubleDataMap_.at( columnToSubtractFrom ).size( ) != doubleDataMap_.at( columnToSubtract ).size( ) )
{
throw std::runtime_error( "Error when subtracing data for tracking text file, column types " +
std::to_string( static_cast< int >( columnToSubtract ) ) + " and " + std::to_string( static_cast< int >( columnToSubtractFrom ) ) + " do not have same size." );
}

for( int i = 0; i < doubleDataMap_.at( columnToSubtractFrom ).size( ); i++ )
{
doubleDataMap_[ columnToSubtractFrom ][ i ] -= doubleDataMap_[ columnToSubtract ][ i ];
}
}

} // namespace input_output

} // namespace tudat
Loading

0 comments on commit 49f49f7

Please sign in to comment.