void directory_model::open_item(QModelIndex index) { if (index.model() != this) return; QString text = index.data().toString(); if (text == "..") go_up(); list<file_info>::iterator file_it = _files.begin(); advance(file_it, index.row()); if (file_it->directory) { if (file_it->link) // directory link { string name, to; if (_sys->parse_link(file_it->name, name, to)) { fs::path p = _path / name; _path_history[p] = *file_it; // save before change change_directory(p, true); } } else // directory change_directory(_path / text.toStdString()); } }
void directory_model::remove_item(QItemSelectionModel * selection) { if (selection->model() != this) return; QModelIndexList indexes = selection->selection().indexes(); vector<list<file_info>::const_iterator> remove_iter_list; remove_iter_list.reserve(indexes.size()); // first, remove from fs for (QModelIndex & index : selection->selection().indexes()) { int row = index.row(); list<file_info>::const_iterator file_it = _files.begin(); advance(file_it, row); remove_iter_list.push_back(file_it); _sys->rm(_path / file_it->name); } beginResetModel(); for (auto it : remove_iter_list) _files.erase(it); endResetModel(); }
auto remove_evens_and_double_odds(list<int>& data) { for(auto cur = data.begin(); cur != data.end();) if (*cur & 0x1) cur = data.insert(cur, *cur), advance(cur, 2); else cur = data.erase(cur); }
int main() { forward_list<int> vi = {0,1,2,3,4,5,6,7,8,9}; auto iter = vi.begin(), prev = vi.before_begin(); while (iter != vi.end()) { if (*iter % 2) { iter = vi.insert_after(prev, *iter); advance(iter, 2); advance(prev, 2); } else iter = vi.erase_after(prev); } for (auto i : vi) cout << i << " "; return 0; }
int main() { auto insert_point = data.begin(); advance(insert_point, 2); istringstream iss("10 20 30"); copy(istream_iterator<int>(iss), istream_iterator<int>(), inserter(data, insert_point)); copy(data.begin(), data.end(), ostream_iterator<int>(cout, " ")); cout << endl; }
QVariant directory_model::data(QModelIndex const & index, int role) const { switch (role) { case Qt::EditRole: case Qt::DisplayRole: { if (index.column() == 0 && index.row() < _files.size()) { list<file_info>::const_iterator it = _files.begin(); advance(it, index.row()); return QString::fromUtf8(it->name.c_str()); } break; } case Qt::DecorationRole: { if (index.column() == 0 && index.row() < _files.size()) { QVariant result; list<file_info>::const_iterator it = _files.begin(); advance(it, index.row()); if (it->directory) result.setValue(get_icon("folder")); else if (it->executable) result.setValue(get_icon("application-x-executable")); else result.setValue(get_icon("document-new")); return result; } break; } } // switch return QVariant{}; }
void IFPWidget::displayFrame(int fnum) { IFPAnimation* anim = anims[ui.animList->currentRow()]; IFPAnimation::ObjectIterator it = anim->getObjectBegin(); advance(it, ui.objList->currentRow()); IFPObject* obj = *it; IFPObject::FrameIterator fit = obj->getFrameBegin(); advance(fit, fnum); IFPRotFrame* frame = *fit; Quaternion rot = frame->getRotation(); ui.frameRotLabel->setText(tr("%1, %2, %3, %4").arg(rot.getX()).arg(rot.getY()).arg(rot.getZ()) .arg(rot.getW())); ui.frameTimeLabel->setText(QString("%1").arg(frame->getTime())); if (obj->getFrameType() == IFPObject::RotTransFrame) { IFPRotTransFrame* rtframe = (IFPRotTransFrame*) frame; Vector3 trans = rtframe->getTranslation(); ui.frameTransLabel->setText(tr("%1, %2, %3").arg(trans.getX()).arg(trans.getY()).arg(trans.getZ())); ui.frameScaleLabel->setText(tr("-")); } else if (obj->getFrameType() == IFPObject::RotTransScaleFrame) { IFPRotTransScaleFrame* rtsframe = (IFPRotTransScaleFrame*) frame; Vector3 trans = rtsframe->getTranslation(); Vector3 scale = rtsframe->getScale(); ui.frameTransLabel->setText(tr("%1, %2, %3").arg(trans.getX()).arg(trans.getY()).arg(trans.getZ())); ui.frameScaleLabel->setText(tr("%1, %2, %3").arg(scale.getX()).arg(scale.getY()).arg(scale.getZ())); } else { ui.frameTransLabel->setText(tr("-")); ui.frameScaleLabel->setText(tr("-")); } }
bool directory_model::setData(QModelIndex const & index, QVariant const & value, int role) { if (role != Qt::EditRole || index.column() != 0 || index.row() >= _files.size()) return false; string newname = value.toString().toStdString(); list<file_info>::iterator file_it = _files.begin(); advance(file_it, index.row()); if (newname == file_it->name) return false; rename(file_it->name, newname); file_it->name = newname; emit dataChanged(index, index); return true; }
void IFPWidget::currentObjectChanged(int row) { if (row == -1) { ui.frameTypeLabel->setText(tr("-")); ui.boneIDLabel->setText(tr("-")); return; } IFPAnimation* anim = anims[ui.animList->currentRow()]; IFPAnimation::ObjectIterator it = anim->getObjectBegin(); advance(it, row); IFPObject* obj = *it; switch (obj->getFrameType()) { case IFPObject::RotFrame: ui.frameTypeLabel->setText(tr("Rotation Frames (Child Frames)")); break; case IFPObject::RotTransFrame: ui.frameTypeLabel->setText(tr("Rotation/Translation Frames (Root Frames)")); break; case IFPObject::RotTransScaleFrame: ui.frameTypeLabel->setText(tr("Rotation/Translation/Scale Frames")); break; case IFPObject::Unknown2Frame: ui.frameTypeLabel->setText(tr("Unknown (FrameType = 2)")); break; } ui.boneIDLabel->setText(QString("%1").arg(obj->getBoneID())); printf("Object has %d frames\n", obj->getFrameCount()); ui.frameNumSpinner->setRange(0, obj->getFrameCount()-1); ui.frameNumSlider->setRange(0, obj->getFrameCount()-1); ui.frameNumSpinner->setValue(0); ui.frameNumSlider->setValue(0); displayFrame(0); }
void Objects::Slideshow::render( double timestamp ) { using Graphics::spriteGroup; using Graphics::sprites; using std::advance; // Can't do the initialisation of self_lastUpdate anywhere else if ( self_lastUpdate == 0 ) self_lastUpdate = timestamp; // Iterate slides if ( self_timeout > 0 and timestamp - self_lastUpdate > self_timeout) { self_lastUpdate = timestamp; self_slidePos++; if ( self_slidePos == Graphics::sprites[ self_spriteGroup ] . size() ) self_slidePos = 0; } spriteGroup::iterator drawIter = sprites[ self_spriteGroup ].begin(); advance( drawIter, self_slidePos ); // If there's a sprite at our iterator. (If the group is empty then // begin() is also end() and so not a sprite) if ( drawIter != sprites[ self_spriteGroup ] . end() ) { if ( self_coordType == Objects::NORM ) drawIter -> second -> draw(self_x, self_y, self_w, self_h); if ( self_coordType == Objects::NON_NORM ) drawIter -> second -> draw( (int)self_x, (int)self_y, (int)self_w, (int)self_h); } }
void STLRepository::read( const shared_ptr< Query > query, const function< void ( const shared_ptr< Query > ) >& callback ) { Resources values; Resources resources; const auto keys = query->get_keys( ); unique_lock< mutex> lock( m_resources_lock ); if ( not keys.empty( ) ) { for ( const auto& key : keys ) { auto resource = find_if( m_resources.begin( ), m_resources.end( ), [ &key ]( const Resource & resource ) { if ( resource.count( "key" ) == 0 ) { return false; } return String::lowercase( key ) == String::lowercase( String::to_string( resource.lower_bound( "key" )->second ) ); } ); if ( resource == m_resources.end( ) ) { query->set_error_code( 40004 ); return callback( query ); } resources.push_back( *resource ); } } else { resources = m_resources; } lock.unlock( ); filter( resources, query->get_inclusive_filters( ), query->get_exclusive_filters( ) ); //just pass query const auto& index = query->get_index( ); const auto& limit = query->get_limit( ); if ( index < resources.size( ) and limit not_eq 0 ) { auto start = resources.begin( ); advance( start, index ); while ( start not_eq resources.end( ) and limit not_eq values.size( ) ) { values.push_back( *start ); start++; } } include( query->get_include( ), values ); auto results = fields( values, query ); query->set_resultset( results ); callback( query ); }
void Objects::Gridshow::render( double timestamp ) { // Can't set it to current time for first time anywhere else. if ( self_lastUpdate == 0 ) self_lastUpdate = timestamp; // This loops the slides. if ( self_timeout > 0 and timestamp - self_lastUpdate > self_timeout) { self_slidePos += self_numCells; size_t groupSize = Graphics::sprites[self_spriteGroup].size(); if ( self_slidePos >= groupSize ) self_slidePos = 0; self_lastUpdate = timestamp; } using Graphics::Sprite; using Graphics::sprites; using Graphics::spriteGroup; using std::advance; //Drawing loop - start at the current sprite spriteGroup::iterator drawIter = sprites[self_spriteGroup].begin(); advance( drawIter, self_slidePos ); int gridX = 0; int gridY = 0; //We draw "self_numCells" sprites for (int i = 0; i < self_numCells; i++) { // If the iterator no longer gives us a real sprite, then break if ( drawIter == Graphics::sprites[self_spriteGroup] . end() ) break; Sprite* cellSprite = drawIter -> second; // No need for error message, as you should already know that it's NULL // by previous errors if ( cellSprite == NULL ) continue; if ( self_coordType == Objects::NON_NORM ) { int cellX = self_x + gridX * self_w; int cellY = self_y + gridY * self_h; cellSprite -> draw( cellX, cellY, (int)self_w, (int) self_h ); } if ( self_coordType == Objects::NORM ) { double cellX = self_x + gridX * self_w; double cellY = self_y + gridY * self_h; cellSprite -> draw( cellX, cellY, self_w, self_h ); } //Do appropriate moving of drawing position gridX++; if (gridX >= self_cellsWide) { gridX = 0; gridY++; } // Move to next sprite drawIter++; } }
file_info & directory_model::get_file(int row) { auto it = _files.begin(); advance(it, row); return *it; }
//! Execute random walk simulator application mode. void executeRandomWalkSimulator( const std::string databasePath, const tudat::input_output::parsed_data_vector_utilities::ParsedDataVectorPtr parsedData ) { /////////////////////////////////////////////////////////////////////////// // Declare using-statements. using std::advance; using std::cerr; using std::cout; using std::endl; using std::max_element; using std::min_element; using std::numeric_limits; using std::ofstream; using std::ostringstream; using std::setprecision; using std::string; using boost::iequals; using namespace boost::filesystem; using boost::make_shared; using namespace assist::astrodynamics; using namespace assist::basics; using namespace assist::mathematics; using namespace tudat::basic_astrodynamics::orbital_element_conversions; using namespace tudat::basic_mathematics::mathematical_constants; using namespace tudat::input_output; using namespace tudat::input_output::dictionary; using namespace tudat::statistics; using namespace stomi::astrodynamics; using namespace stomi::database; using namespace stomi::input_output; /////////////////////////////////////////////////////////////////////////// // Extract input parameters. // Get dictionary. const DictionaryPointer dictionary = getRandomWalkSimulatorDictionary( ); // Print database path to console. cout << "Database " << databasePath << endl; // Extract required parameters. const string randomWalkRunName = extractParameterValue< string >( parsedData->begin( ), parsedData->end( ), findEntry( dictionary, "RANDOMWALKRUN" ) ); cout << "Random walk run " << randomWalkRunName << endl; // Extract optional parameters. const int numberOfThreads = extractParameterValue< int >( parsedData->begin( ), parsedData->end( ), findEntry( dictionary, "NUMBEROFTHREADS" ), 1 ); cout << "Number of threads " << numberOfThreads << endl; const string outputMode = extractParameterValue< string >( parsedData->begin( ), parsedData->end( ), findEntry( dictionary, "OUTPUTMODE" ), "DATABASE" ); cout << "Output mode " << outputMode << endl; const string fileOutputDirectory = extractParameterValue< string >( parsedData->begin( ), parsedData->end( ), findEntry( dictionary, "FILEOUTPUTDIRECTORY" ), "" ) + "/"; cout << "File output directory " << fileOutputDirectory << endl; const string randomWalkSimulations = extractParameterValue< string >( parsedData->begin( ), parsedData->end( ), findEntry( dictionary, "RANDOMWALKSIMULATIONS" ), "ALL" ); cout << "Random walk simulations " << randomWalkSimulations << endl; const string randomWalkRunTableName = extractParameterValue< string >( parsedData->begin( ), parsedData->end( ), findEntry( dictionary, "RANDOMWALKRUNTABLENAME" ), "random_walk_run" ); cout << "Random walk run table " << randomWalkRunTableName << endl; const string randomWalkInputTableName = extractParameterValue< string >( parsedData->begin( ), parsedData->end( ), findEntry( dictionary, "RANDOMWALKINPUTTABLENAME" ), "random_walk_input" ); cout << "Random walk input table " << randomWalkInputTableName << endl; const string randomWalkPerturberTableName = extractParameterValue< string >( parsedData->begin( ), parsedData->end( ), findEntry( dictionary, "RANDOMWALKPERTURBERTABLENAME" ), "random_walk_perturbers" ); cout << "Random walk perturber table " << randomWalkPerturberTableName << endl; const string randomWalkOutputTableName = extractParameterValue< string >( parsedData->begin( ), parsedData->end( ), findEntry( dictionary, "RANDOMWALKOUTPUTTABLENAME" ), "random_walk_output" ); cout << "Random walk output table " << randomWalkOutputTableName << endl; const string testParticleCaseTableName = extractParameterValue< string >( parsedData->begin( ), parsedData->end( ), findEntry( dictionary, "TESTPARTICLECASETABLENAME" ), "test_particle_case" ); cout << "Test particle case table " << testParticleCaseTableName << endl; const string testParticleKickTableName = extractParameterValue< string >( parsedData->begin( ), parsedData->end( ), findEntry( dictionary, "TESTPARTICLEKICKTABLENAME" ), "test_particle_kicks" ); cout << "Test particle kick table " << testParticleKickTableName << endl; // Retrieve and store random walk run data from database. RandomWalkRunPointer randomWalkRun; // Random walk run data is extracted in local scope from the database, with overwritten // parameters extracted from the input file, to ensure that none of these parameters are used // globally elsewhere in this file. { const RandomWalkRunPointer retrievedRandomWalkRun = getRandomWalkRun( databasePath, randomWalkRunName, randomWalkRunTableName ); const double perturberRingNumberDensity = extractParameterValue< double >( parsedData->begin( ), parsedData->end( ), findEntry( dictionary, "PERTURBERRINGNUMBERDENSITY" ), retrievedRandomWalkRun->perturberRingNumberDensity ); cout << "Perturber ring number density " << perturberRingNumberDensity << " perturbers per R_Hill" << endl; const double perturberRingMass = extractParameterValue< double >( parsedData->begin( ), parsedData->end( ), findEntry( dictionary, "PERTURBERRINGMASS" ), retrievedRandomWalkRun->perturberRingMass ); cout << "Perturber ring mass " << perturberRingMass << " M_PerturbedBody" << endl; const double observationPeriod = extractParameterValue< double >( parsedData->begin( ), parsedData->end( ), findEntry( dictionary, "OBSERVATIONPERIOD" ), retrievedRandomWalkRun->observationPeriod, &convertJulianYearsToSeconds ); cout << "Observation period " << convertSecondsToJulianYears( observationPeriod ) << " yrs" << endl; const unsigned int numberOfEpochWindows = extractParameterValue< unsigned int >( parsedData->begin( ), parsedData->end( ), findEntry( dictionary, "NUMBEROFEPOCHWINDOWS" ), retrievedRandomWalkRun->numberOfEpochWindows ); cout << "Number of epoch windows " << numberOfEpochWindows << endl; const double epochWindowSize = extractParameterValue< double >( parsedData->begin( ), parsedData->end( ), findEntry( dictionary, "EPOCHWINDOWSIZE" ), retrievedRandomWalkRun->epochWindowSize, &convertJulianDaysToSeconds ); cout << "Epoch window size " << convertSecondsToJulianDays( epochWindowSize ) << " days" << endl; // Store random walk run data with possible overwritten data. randomWalkRun = make_shared< RandomWalkRun >( retrievedRandomWalkRun->randomWalkRunId, randomWalkRunName, retrievedRandomWalkRun->testParticleCaseId, perturberRingNumberDensity, perturberRingMass, observationPeriod, numberOfEpochWindows, epochWindowSize ); } // Check that all required parameters have been set. checkRequiredParameters( dictionary ); /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// // Fetch test particle case and random walk input data from database. cout << endl; cout << "****************************************************************************" << endl; cout << "Database operations" << endl; cout << "****************************************************************************" << endl; cout << endl; // Generate output message. cout << "Fetching test particle case data from database ..." << endl; // Retrieve and store test particle case data. const TestParticleCasePointer testParticleCaseData = getTestParticleCase( databasePath, randomWalkRun->testParticleCaseId, testParticleCaseTableName ); // Generate output message to indicate that test particle case data was fetched successfully. cout << "Test particle case data fetched successfully from database!" << endl; // Generate output message. cout << "Fetching random walk input data from database ..." << endl; // Check if all incomplete random walk simulations are to be executed and fetch the random // walk input table, else only fetch the requested random walk simulation IDs. RandomWalkInputTable randomWalkInputTable; if ( iequals( randomWalkSimulations, "ALL" ) ) { cout << "Fetching all incomplete random walk Monte Carlo runs ..." << endl; // Get entire random walk input table from database. randomWalkInputTable = getCompleteRandomWalkInputTable( databasePath, randomWalkRun->randomWalkRunId, randomWalkInputTableName, randomWalkPerturberTableName ); } else { cout << "Fetching all requested random walk Monte Carlo runs ..." << endl; // Get selected random walk input table from database. randomWalkInputTable = getSelectedRandomWalkInputTable( databasePath, randomWalkRun->randomWalkRunId, randomWalkSimulations, randomWalkInputTableName, randomWalkPerturberTableName ); } // Generate output message to indicate that the input table was fetched successfully. cout << "Random walk input data (" << randomWalkInputTable.size( ) << " rows) fetched successfully from database!" << endl; /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// // Compute derived parameters. cout << endl; cout << "****************************************************************************" << endl; cout << "Derived parameters" << endl; cout << "****************************************************************************" << endl; cout << endl; // Compute epoch window spacing [s]. const double epochWindowSpacing = randomWalkRun->observationPeriod / ( randomWalkRun->numberOfEpochWindows - 1 ); cout << "Epoch window spacing " << convertSecondsToJulianDays( epochWindowSpacing ) << " days" << endl; // Compute mass of perturbed body [kg]. const double perturbedBodyMass = computeMassOfSphere( testParticleCaseData->perturbedBodyRadius, testParticleCaseData->perturbedBodyBulkDensity ); cout << "Perturbed body mass " << perturbedBodyMass << " kg" << endl; // Compute perturbed body's gravitational parameter [m^3 s^-2]. const double perturbedBodyGravitationalParameter = computeGravitationalParameter( perturbedBodyMass ); cout << "Perturbed body gravitational parameter " << perturbedBodyGravitationalParameter << " m^3 s^-2" << endl; // Compute perturber population using density and semi-major axis distribution limits. // Note, in the floor() function, adding 0.5 is a workaround for the fact that there is no // round() function in C++03 (it is available in C++11). ConvertHillRadiiToMeters convertHillRadiiToMeters( testParticleCaseData->centralBodyGravitationalParameter, perturbedBodyGravitationalParameter, testParticleCaseData->perturbedBodyStateInKeplerianElementsAtT0( semiMajorAxisIndex ) ); const double perturberRingNumberDensityInMeters = randomWalkRun->perturberRingNumberDensity / convertHillRadiiToMeters( 1.0 ); const unsigned int perturberPopulation = std::floor( 2.0 * testParticleCaseData->semiMajorAxisDistributionLimit * perturberRingNumberDensityInMeters + 0.5 ); cout << "Perturber population " << perturberPopulation << endl; // Compute perturber mass ratio. // Note, for the random walk simulations, the mass ratio is equal for all perturbers. const double perturberMassRatio = randomWalkRun->perturberRingMass / perturberPopulation; cout << "Perturber mass ratio " << perturberMassRatio << endl; /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// // Execute Monte Carlo simulation. cout << endl; cout << "****************************************************************************" << endl; cout << "Simulation loop" << endl; cout << "****************************************************************************" << endl; cout << endl; // Execute simulation loop. cout << "Starting simulation loop ... " << endl; cout << randomWalkInputTable.size( ) << " random walk simulations queued for execution ..." << endl; cout << endl; // Loop over input table. #pragma omp parallel for num_threads( numberOfThreads ) for ( unsigned int i = 0; i < randomWalkInputTable.size( ); i++ ) { /////////////////////////////////////////////////////////////////////////// // Set input table iterator and emit output message. // Set input table iterator for current simulation wrt to start of input table and counter. RandomWalkInputTable::iterator iteratorRandomWalkInputTable = randomWalkInputTable.begin( ); advance( iteratorRandomWalkInputTable, i ); // Emit output message. #pragma omp critical( outputToConsole ) { cout << "Random walk simulation " << iteratorRandomWalkInputTable->randomWalkSimulationId << " on thread " << omp_get_thread_num( ) + 1 << " / " << omp_get_num_threads( ) << endl; } /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// // Fetch test particle kick table based on test particle simulation IDs for random walk // simulation. TestParticleKickTable testParticleKickTable; #pragma omp critical( databaseOperations ) { testParticleKickTable = getTestParticleKickTable( databasePath, testParticleCaseData->randomWalkSimulationPeriod, iteratorRandomWalkInputTable->testParticleSimulationIds, testParticleKickTableName ); } // Check if output mode is set to "FILE". // If so, open output file and write test particle kick table data. // Check if the output directory exists: if not, create it. if ( iequals( outputMode, "FILE" ) ) { // Check if output directory exists. if ( !exists( fileOutputDirectory ) ) { cerr << "Directory does not exist. Will be created." << endl; create_directories( fileOutputDirectory ); } // Declare file handler. ofstream testParticleKickTableFile; // Set up and write file header to file. ostringstream testParticleKickTableFilename; testParticleKickTableFilename << fileOutputDirectory << "randomWalkSimulation" << iteratorRandomWalkInputTable->randomWalkSimulationId << "_testParticleKickTable.csv"; testParticleKickTableFile.open( testParticleKickTableFilename.str( ).c_str( ) ); testParticleKickTableFile << "kickId,simulationId,conjunctionEpoch,conjunctionDistance," << "preConjunctionEpoch,preConjunctionDistance," << "preConjunctionSemiMajorAxis,preConjunctionEccentricity," << "preConjunctionInclination,preConjunctionArgumentOfPeriapsis," << "preConjunctionLongitudeOfAscendingNode,preConjunctionTrueAnomaly" << "postConjunctionEpoch,postConjunctionDistance," << "postConjunctionSemiMajorAxis,postConjunctionEccentricity," << "postConjunctionInclination,postConjunctionArgumentOfPeriapsis," << "postConjunctionLongitudeOfAscendingNode,postConjunctionTrueAnomaly" << endl; testParticleKickTableFile << "# [-],[-],[s],[m],[s],[m],[m],[-],[rad],[rad],[rad],[rad]," << "[s],[m],[m],[-],[rad],[rad],[rad],[rad]" << endl; // Write test particle kick table to file. for ( TestParticleKickTable::iterator iteratorTestParticleKicks = testParticleKickTable.begin( ); iteratorTestParticleKicks != testParticleKickTable.end( ); iteratorTestParticleKicks++ ) { testParticleKickTableFile << iteratorTestParticleKicks->testParticleKickId << "," << iteratorTestParticleKicks->testParticleSimulationId << ","; testParticleKickTableFile << setprecision( numeric_limits< double >::digits10 ) << iteratorTestParticleKicks->conjunctionEpoch << "," << iteratorTestParticleKicks->conjunctionDistance << "," << iteratorTestParticleKicks->preConjunctionEpoch << "," << iteratorTestParticleKicks->preConjunctionDistance << "," << iteratorTestParticleKicks->preConjunctionStateInKeplerianElements( semiMajorAxisIndex ) << "," << iteratorTestParticleKicks->preConjunctionStateInKeplerianElements( eccentricityIndex ) << "," << iteratorTestParticleKicks->preConjunctionStateInKeplerianElements( inclinationIndex ) << "," << iteratorTestParticleKicks->preConjunctionStateInKeplerianElements( argumentOfPeriapsisIndex ) << "," << iteratorTestParticleKicks->preConjunctionStateInKeplerianElements( longitudeOfAscendingNodeIndex ) << "," << iteratorTestParticleKicks->preConjunctionStateInKeplerianElements( trueAnomalyIndex ) << "," << iteratorTestParticleKicks->postConjunctionEpoch << "," << iteratorTestParticleKicks->postConjunctionDistance << "," << iteratorTestParticleKicks->postConjunctionStateInKeplerianElements( semiMajorAxisIndex ) << "," << iteratorTestParticleKicks->postConjunctionStateInKeplerianElements( eccentricityIndex ) << "," << iteratorTestParticleKicks->postConjunctionStateInKeplerianElements( inclinationIndex ) << "," << iteratorTestParticleKicks->postConjunctionStateInKeplerianElements( argumentOfPeriapsisIndex ) << "," << iteratorTestParticleKicks->postConjunctionStateInKeplerianElements( longitudeOfAscendingNodeIndex ) << "," << iteratorTestParticleKicks->postConjunctionStateInKeplerianElements( trueAnomalyIndex ) << endl; } // Close file handler. testParticleKickTableFile.close( ); } /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// // Execute random walk simulation. // Declare perturbed body propagation history. This stores the propagation history of the // action variables only (semi-major axis, eccentricity, inclination). DoubleKeyVector3dValueMap keplerianActionElementsHistory; // Set perturbed body initial state (actions) in Keplerian elements. keplerianActionElementsHistory[ 0.0 ] = testParticleCaseData->perturbedBodyStateInKeplerianElementsAtT0.segment( 0, 3 ); // Declare iterator to previous state in Keplerian elements. DoubleKeyVector3dValueMap::iterator iteratorPreviousKeplerianElements = keplerianActionElementsHistory.begin( ); // Loop through aggregate kick table and execute kicks on perturbed body. for ( TestParticleKickTable::iterator iteratorKickTable = testParticleKickTable.begin( ); iteratorKickTable != testParticleKickTable.end( ); iteratorKickTable++ ) { // Execute kick and store results in propagation history. keplerianActionElementsHistory[ iteratorKickTable->conjunctionEpoch ] = executeKick( iteratorPreviousKeplerianElements->second, iteratorKickTable, perturberMassRatio ); advance( iteratorPreviousKeplerianElements, 1 ); } // Check if output mode is set to "FILE". // If so, open output file and write header content. if ( iequals( outputMode, "FILE" ) ) { ostringstream keplerianActionElementsFilename; keplerianActionElementsFilename << "randomWalkSimulation" << iteratorRandomWalkInputTable->randomWalkSimulationId << "_keplerianActionElements.csv"; ostringstream keplerianActionElementsFileHeader; keplerianActionElementsFileHeader << "epoch,semiMajorAxis,eccentricity,inclination" << endl; keplerianActionElementsFileHeader << "# [s],[m],[-],[rad]" << endl; writeDataMapToTextFile( keplerianActionElementsHistory, keplerianActionElementsFilename.str( ), fileOutputDirectory, keplerianActionElementsFileHeader.str( ), numeric_limits< double >::digits10, numeric_limits< double >::digits10, "," ); } /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// // Compute average longitude residual and maximum longitude residual change in observation // period. // Declare average longitude residual in observation period [-]. double averageLongitudeResidual = TUDAT_NAN; // Declare maximum longitude residual change in observation period [-]. double maximumLongitudeResidualChange = TUDAT_NAN; // Declare map of average longitude residuals per window [rad]. DoubleKeyDoubleValueMap averageLongitudeResiduals; { // Populate temporary map with epochs and semi-major axes. DoubleKeyDoubleValueMap semiMajorAxisHistory; for ( DoubleKeyVector3dValueMap::iterator iteratorKeplerianActionElements = keplerianActionElementsHistory.begin( ); iteratorKeplerianActionElements != keplerianActionElementsHistory.end( ); iteratorKeplerianActionElements++ ) { semiMajorAxisHistory[ iteratorKeplerianActionElements->first ] = iteratorKeplerianActionElements->second( semiMajorAxisIndex ); } // Compute longitude history. DoubleKeyDoubleValueMap longitudeHistory = computeLongitudeHistory( semiMajorAxisHistory, testParticleCaseData->centralBodyGravitationalParameter ); // Compute reduced longitude history (data is reduced to only the epoch windows). DoubleKeyDoubleValueMap reducedLongitudeHistory = reduceLongitudeHistory( longitudeHistory, iteratorRandomWalkInputTable->observationPeriodStartEpoch, epochWindowSpacing, randomWalkRun->epochWindowSize, randomWalkRun->numberOfEpochWindows ); // Set input data for simple linear regression. SimpleLinearRegression longitudeHistoryRegression( reducedLongitudeHistory ); // Compute linear fit. longitudeHistoryRegression.computeFit( ); // Store longitude residuals history. DoubleKeyDoubleValueMap longitudeResidualsHistory; // Generate longitude history residuals by subtracting linear fit from data. for ( DoubleKeyDoubleValueMap::iterator iteratorReducedLongitudeHistory = reducedLongitudeHistory.begin( ); iteratorReducedLongitudeHistory != reducedLongitudeHistory.end( ); iteratorReducedLongitudeHistory++ ) { longitudeResidualsHistory[ iteratorReducedLongitudeHistory->first ] = iteratorReducedLongitudeHistory->second - longitudeHistoryRegression.getCoefficientOfConstantTerm( ) - longitudeHistoryRegression.getCoefficientOfLinearTerm( ) * iteratorReducedLongitudeHistory->first; } // Loop over observation period and compute average longitude residuals per epoch window. for ( int windowNumber = 0; windowNumber < randomWalkRun->numberOfEpochWindows; windowNumber++ ) { const double epochWindowCenter = iteratorRandomWalkInputTable->observationPeriodStartEpoch + windowNumber * epochWindowSpacing; averageLongitudeResiduals[ epochWindowCenter ] = computeStepFunctionWindowAverage( longitudeResidualsHistory, epochWindowCenter - 0.5 * randomWalkRun->epochWindowSize, epochWindowCenter + 0.5 * randomWalkRun->epochWindowSize ); } // Compute average longitude residual during propagation history. double sumLongitudeResiduals = 0.0; for ( DoubleKeyDoubleValueMap::iterator iteratorAverageLongitudeResiduals = averageLongitudeResiduals.begin( ); iteratorAverageLongitudeResiduals != averageLongitudeResiduals.end( ); iteratorAverageLongitudeResiduals++ ) { sumLongitudeResiduals += iteratorAverageLongitudeResiduals->second; } averageLongitudeResidual = sumLongitudeResiduals / randomWalkRun->numberOfEpochWindows; // Compute maximum longitude residual change during propagation history. maximumLongitudeResidualChange = ( max_element( averageLongitudeResiduals.begin( ), averageLongitudeResiduals.end( ), CompareDoubleKeyDoubleValueMapValues( ) ) )->second - ( min_element( averageLongitudeResiduals.begin( ), averageLongitudeResiduals.end( ), CompareDoubleKeyDoubleValueMapValues( ) ) )->second; // Check if output mode is set to "FILE". // If so, open output file and write header content. if ( iequals( outputMode, "FILE" ) ) { ostringstream longitudeHistoryFilename; longitudeHistoryFilename << "randomWalkSimulation" << iteratorRandomWalkInputTable->randomWalkSimulationId << "_longitudeHistory.csv"; ostringstream longitudeHistoryFileHeader; longitudeHistoryFileHeader << "epoch,longitude" << endl; longitudeHistoryFileHeader << "# [s],[rad]" << endl; writeDataMapToTextFile( longitudeHistory, longitudeHistoryFilename.str( ), fileOutputDirectory, longitudeHistoryFileHeader.str( ), numeric_limits< double >::digits10, numeric_limits< double >::digits10, "," ); ostringstream reducedLongitudeHistoryFilename; reducedLongitudeHistoryFilename << "randomWalkSimulation" << iteratorRandomWalkInputTable->randomWalkSimulationId << "_reducedLongitudeHistory.csv"; ostringstream reducedLongitudeHistoryFileHeader; reducedLongitudeHistoryFileHeader << "epoch,longitude" << endl; reducedLongitudeHistoryFileHeader << "# [s],[rad]" << endl; writeDataMapToTextFile( reducedLongitudeHistory, reducedLongitudeHistoryFilename.str( ), fileOutputDirectory, reducedLongitudeHistoryFileHeader.str( ), numeric_limits< double >::digits10, numeric_limits< double >::digits10, "," ); ostringstream longitudeResidualsFilename; longitudeResidualsFilename << "randomWalkSimulation" << iteratorRandomWalkInputTable->randomWalkSimulationId << "_longitudeResiduals.csv"; ostringstream longitudeResidualsFileHeader; longitudeResidualsFileHeader << "epoch,longitudeResidual" << endl; longitudeResidualsFileHeader << "# [s],[rad]" << endl; writeDataMapToTextFile( longitudeResidualsHistory, longitudeResidualsFilename.str( ), fileOutputDirectory, longitudeResidualsFileHeader.str( ), numeric_limits< double >::digits10, numeric_limits< double >::digits10, "," ); } } /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// // Compute average eccentricity and maximum eccentricity change in observation window. // Declare average eccentricity in observation period [-]. double averageEccentricity = TUDAT_NAN; // Declare maximum eccentricity change in observation period [-]. double maximumEccentricityChange = TUDAT_NAN; // Declare map of average eccentricities per window [-]. DoubleKeyDoubleValueMap averageEccentricities; { // Populate temporary map with epochs and eccentricities. DoubleKeyDoubleValueMap eccentricityHistory; for ( DoubleKeyVector3dValueMap::iterator iteratorKeplerianActionElements = keplerianActionElementsHistory.begin( ); iteratorKeplerianActionElements != keplerianActionElementsHistory.end( ); iteratorKeplerianActionElements++ ) { eccentricityHistory[ iteratorKeplerianActionElements->first ] = iteratorKeplerianActionElements->second( eccentricityIndex ); } // Loop over observation period and compute average eccentricities per epoch window. for ( int windowNumber = 0; windowNumber < randomWalkRun->numberOfEpochWindows; windowNumber++ ) { const double epochWindowCenter = iteratorRandomWalkInputTable->observationPeriodStartEpoch + windowNumber * epochWindowSpacing; averageEccentricities[ epochWindowCenter ] = computeStepFunctionWindowAverage( eccentricityHistory, epochWindowCenter - 0.5 * randomWalkRun->epochWindowSize, epochWindowCenter + 0.5 * randomWalkRun->epochWindowSize ); } // Compute average eccentricity during propagation history. double sumEccentricities = 0.0; for ( DoubleKeyDoubleValueMap::iterator iteratorAverageEccentricities = averageEccentricities.begin( ); iteratorAverageEccentricities != averageEccentricities.end( ); iteratorAverageEccentricities++ ) { sumEccentricities += iteratorAverageEccentricities->second; } averageEccentricity = sumEccentricities / randomWalkRun->numberOfEpochWindows; // Compute maximum eccentricity change during propagation history. maximumEccentricityChange = ( max_element( averageEccentricities.begin( ), averageEccentricities.end( ), CompareDoubleKeyDoubleValueMapValues( ) ) )->second - ( min_element( averageEccentricities.begin( ), averageEccentricities.end( ), CompareDoubleKeyDoubleValueMapValues( ) ) )->second; } /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// // Compute average inclination and maximum inclination change in observation window. // Declare average inclination in observation period [rad]. double averageInclination = TUDAT_NAN; // Declare maximum inclination change in observation period [rad]. double maximumInclinationChange = TUDAT_NAN; // Declare map of average inclinations per window [rad]. DoubleKeyDoubleValueMap averageInclinations; { // Populate temporary map with epochs and inclinations. DoubleKeyDoubleValueMap inclinationHistory; for ( DoubleKeyVector3dValueMap::iterator iteratorKeplerianActionElements = keplerianActionElementsHistory.begin( ); iteratorKeplerianActionElements != keplerianActionElementsHistory.end( ); iteratorKeplerianActionElements++ ) { inclinationHistory[ iteratorKeplerianActionElements->first ] = iteratorKeplerianActionElements->second( inclinationIndex ); } // Loop over observation period and compute average inclinations per epoch window. for ( int windowNumber = 0; windowNumber < randomWalkRun->numberOfEpochWindows; windowNumber++ ) { const double epochWindowCenter = iteratorRandomWalkInputTable->observationPeriodStartEpoch + windowNumber * epochWindowSpacing; averageInclinations[ epochWindowCenter ] = computeStepFunctionWindowAverage( inclinationHistory, epochWindowCenter - randomWalkRun->epochWindowSize * 0.5, epochWindowCenter + randomWalkRun->epochWindowSize * 0.5 ); } // Compute average inclination during propagation history. double sumInclinations = 0.0; for ( DoubleKeyDoubleValueMap::iterator iteratorAverageInclinations = averageInclinations.begin( ); iteratorAverageInclinations != averageInclinations.end( ); iteratorAverageInclinations++ ) { sumInclinations += iteratorAverageInclinations->second; } averageInclination = sumInclinations / randomWalkRun->numberOfEpochWindows; // Compute maximum inclination change during propagation history. maximumInclinationChange = ( max_element( averageInclinations.begin( ), averageInclinations.end( ), CompareDoubleKeyDoubleValueMapValues( ) ) )->second - ( min_element( averageInclinations.begin( ), averageInclinations.end( ), CompareDoubleKeyDoubleValueMapValues( ) ) )->second; } /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// // Write epoch-windoow average values to file. // Check if output mode is set to "FILE". // If so, open output file and write header content. if ( iequals( outputMode, "FILE" ) ) { // Declare file handler. ofstream epochWindowAveragesFile; ostringstream epochWindowAveragesFilename; epochWindowAveragesFilename << fileOutputDirectory << "randomWalkRun" << iteratorRandomWalkInputTable->randomWalkSimulationId << "_epochWindowAverages.csv"; epochWindowAveragesFile.open( epochWindowAveragesFilename.str( ).c_str( ) ); epochWindowAveragesFile << "epoch,longitudeResidual,eccentricity,inclination" << endl; epochWindowAveragesFile << "# [s],[rad],[-],[rad]" << endl; // Loop through epoch-window averages and write data to file. DoubleKeyDoubleValueMap::iterator iteratorEpochWindowAverageLongitudeResiduals = averageLongitudeResiduals.begin( ); DoubleKeyDoubleValueMap::iterator iteratorEpochWindowAverageEccentricities = averageEccentricities.begin( ); DoubleKeyDoubleValueMap::iterator iteratorEpochWindowAverageInclinations = averageInclinations.begin( ); for ( int i = 0; i < randomWalkRun->numberOfEpochWindows; i++ ) { epochWindowAveragesFile << setprecision( numeric_limits< double >::digits10 ) << iteratorEpochWindowAverageLongitudeResiduals->first << "," << iteratorEpochWindowAverageLongitudeResiduals->second << "," << iteratorEpochWindowAverageEccentricities->second << "," << iteratorEpochWindowAverageInclinations->second << endl; iteratorEpochWindowAverageLongitudeResiduals++; iteratorEpochWindowAverageEccentricities++; iteratorEpochWindowAverageInclinations++; } // Close file handler. epochWindowAveragesFile.close( ); } /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// // Write random walk output to database. To avoid locking of the database, this section is // thread-critical, so will be executed one-by-one by multiple threads. // Check if output mode is set to "DATABASE". if ( iequals( outputMode, "DATABASE" ) ) { #pragma omp critical( databaseOperations ) { // Populate output table in database. populateRandomWalkOutputTable( databasePath, iteratorRandomWalkInputTable->randomWalkSimulationId, averageLongitudeResidual, maximumLongitudeResidualChange, averageEccentricity, maximumEccentricityChange, averageInclination, maximumInclinationChange, randomWalkOutputTableName, randomWalkInputTableName ); } } ///////////////////////////////////////////////////////////////// } // simulation for-loop /////////////////////////////////////////////////////////////////// }
BidirectionalIterator wait_some(BidirectionalIterator first, BidirectionalIterator last) { using std::advance; if (first == last) return first; typedef typename std::iterator_traits<BidirectionalIterator>::difference_type difference_type; bool all_trivial_requests = true; difference_type n = 0; BidirectionalIterator current = first; BidirectionalIterator start_of_completed = last; while (true) { // Check if we have found a completed request. if (optional<status> result = current->test()) { using std::iter_swap; // We're expanding the set of completed requests --start_of_completed; // If we have hit the end of the list of pending requests, we're // done. if (current == start_of_completed) return start_of_completed; // Swap the request we just completed with the last request that // has not yet been tested. iter_swap(current, start_of_completed); continue; } // Check if this request (and all others before it) are "trivial" // requests, e.g., they can be represented with a single // MPI_Request. all_trivial_requests = all_trivial_requests && !current->m_handler && current->m_requests[1] == MPI_REQUEST_NULL; // Move to the next request. ++n; if (++current == start_of_completed) { // If we have satisfied some requests, we're done. if (start_of_completed != last) return start_of_completed; // We have reached the end of the list. If all requests thus far // have been trivial, we can call MPI_Waitsome directly, because // it may be more efficient than our busy-wait semantics. if (all_trivial_requests) { std::vector<MPI_Request> requests; std::vector<int> indices(n); requests.reserve(n); for (current = first; current != last; ++current) requests.push_back(current->m_requests[0]); // Let MPI wait until some of these operations complete. int num_completed; BOOST_MPI_CHECK_RESULT(MPI_Waitsome, (n, &requests[0], &num_completed, &indices[0], MPI_STATUSES_IGNORE)); // Translate the index-based result of MPI_Waitsome into a // partitioning on the requests. int current_offset = 0; current = first; for (int index = 0; index < num_completed; ++index) { using std::iter_swap; // Move "current" to the request object at this index advance(current, indices[index] - current_offset); current_offset = indices[index]; // Finish up the request and swap it into the "completed // requests" partition. current->m_requests[0] = requests[indices[index]]; --start_of_completed; iter_swap(current, start_of_completed); } // We have satisfied some requests, so we are done. return start_of_completed; } // There are some nontrivial requests, so we must continue our // busy waiting loop. n = 0; current = first; } } // We cannot ever get here BOOST_ASSERT(false); }
std::pair<status, ForwardIterator> wait_any(ForwardIterator first, ForwardIterator last) { using std::advance; BOOST_ASSERT(first != last); typedef typename std::iterator_traits<ForwardIterator>::difference_type difference_type; bool all_trivial_requests = true; difference_type n = 0; ForwardIterator current = first; while (true) { // Check if we have found a completed request. If so, return it. if (current->m_requests[0] != MPI_REQUEST_NULL && (current->m_requests[1] != MPI_REQUEST_NULL || current->m_handler)) { if (optional<status> result = current->test()) return std::make_pair(*result, current); } // Check if this request (and all others before it) are "trivial" // requests, e.g., they can be represented with a single // MPI_Request. all_trivial_requests = all_trivial_requests && !current->m_handler && current->m_requests[1] == MPI_REQUEST_NULL; // Move to the next request. ++n; if (++current == last) { // We have reached the end of the list. If all requests thus far // have been trivial, we can call MPI_Waitany directly, because // it may be more efficient than our busy-wait semantics. if (all_trivial_requests) { std::vector<MPI_Request> requests; requests.reserve(n); for (current = first; current != last; ++current) requests.push_back(current->m_requests[0]); // Let MPI wait until one of these operations completes. int index; status stat; BOOST_MPI_CHECK_RESULT(MPI_Waitany, (n, &requests[0], &index, &stat.m_status)); // We don't have a notion of empty requests or status objects, // so this is an error. if (index == MPI_UNDEFINED) boost::throw_exception(exception("MPI_Waitany", MPI_ERR_REQUEST)); // Find the iterator corresponding to the completed request. current = first; advance(current, index); current->m_requests[0] = requests[index]; return std::make_pair(stat, current); } // There are some nontrivial requests, so we must continue our // busy waiting loop. n = 0; current = first; all_trivial_requests = true; } } // We cannot ever get here BOOST_ASSERT(false); }
//! Execute random walk database generator. void executeRandomWalkDatabaseGenerator( const std::string databasePath, const tudat::input_output::parsed_data_vector_utilities::ParsedDataVectorPtr parsedData ) { /////////////////////////////////////////////////////////////////////////// // Declare using-statements. using std::advance; using std::cout; using std::endl; using std::generate; using std::ostringstream; using std::numeric_limits; using std::runtime_error; using std::setprecision; using std::string; using std::vector; using namespace boost::filesystem; using namespace boost::random; using namespace SQLite; using namespace assist::astrodynamics; // using namespace assist::input_output; using namespace tudat::basic_astrodynamics::orbital_element_conversions; using namespace tudat::basic_mathematics; using namespace tudat::input_output::dictionary; using namespace stomi::database; using namespace stomi::input_output; /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// // Extract input parameters. // Get dictionary. const DictionaryPointer dictionary = getRandomWalkDatabaseGeneratorDictionary( ); // Print database path to console. cout << "Database " << databasePath << endl; // Extract required parameters. const string randomWalkRunName = extractParameterValue< string >( parsedData->begin( ), parsedData->end( ), findEntry( dictionary, "RANDOMWALKRUN" ) ); cout << "Run " << randomWalkRunName << endl; const string testParticleCaseName = extractParameterValue< string >( parsedData->begin( ), parsedData->end( ), findEntry( dictionary, "TESTPARTICLECASE" ) ); cout << "Test particle case " << testParticleCaseName << endl; const unsigned int monteCarloPopulation = extractParameterValue< unsigned int >( parsedData->begin( ), parsedData->end( ), findEntry( dictionary, "MONTECARLOPOPULATION" ) ); cout << "Monte Carlo population " << monteCarloPopulation << endl; const double perturberRingNumberDensity = extractParameterValue< double >( parsedData->begin( ), parsedData->end( ), findEntry( dictionary, "PERTURBERRINGNUMBERDENSITY" ) ); cout << "Perturber ring number density " << perturberRingNumberDensity << " perturbers per R_Hill" << endl; const double perturberRingMass = extractParameterValue< double >( parsedData->begin( ), parsedData->end( ), findEntry( dictionary, "PERTURBERRINGMASS" ) ); cout << "Perturber ring mass " << perturberRingMass << " M_PerturbedBody" << endl; const double observationPeriod = extractParameterValue< double >( parsedData->begin( ), parsedData->end( ), findEntry( dictionary, "OBSERVATIONPERIOD" ), TUDAT_NAN, &convertJulianYearsToSeconds ); cout << "Observation period " << convertSecondsToJulianYears( observationPeriod ) << " yrs" << endl; const unsigned int numberOfEpochWindows = extractParameterValue< unsigned int >( parsedData->begin( ), parsedData->end( ), findEntry( dictionary, "NUMBEROFEPOCHWINDOWS" ) ); cout << "Number of epoch windows " << numberOfEpochWindows << endl; const double epochWindowSize = extractParameterValue< double >( parsedData->begin( ), parsedData->end( ), findEntry( dictionary, "EPOCHWINDOWSIZE" ), TUDAT_NAN, &convertJulianDaysToSeconds ); cout << "Epoch window size " << convertSecondsToJulianDays( epochWindowSize ) << " days" << endl; // Extract optional parameters (parameters that take on default values if they are not // specified in the configuration file). const string randomWalkRunTable = extractParameterValue< string >( parsedData->begin( ), parsedData->end( ), findEntry( dictionary, "RANDOMWALKRUNTABLENAME" ), "random_walk_run" ); cout << "Random walk run table " << randomWalkRunTable << endl; const string randomWalkInputTableName = extractParameterValue< string >( parsedData->begin( ), parsedData->end( ), findEntry( dictionary, "RANDOMWALKINPUTTABLENAME" ), "random_walk_input" ); cout << "Random walk input table " << randomWalkInputTableName << endl; const string randomWalkPerturberTableName = extractParameterValue< string >( parsedData->begin( ), parsedData->end( ), findEntry( dictionary, "RANDOMWALKPERTURBERTABLENAME" ), "random_walk_perturbers" ); cout << "Random walk perturber table " << randomWalkPerturberTableName << endl; const string randomWalkOutputTableName = extractParameterValue< string >( parsedData->begin( ), parsedData->end( ), findEntry( dictionary, "RANDOMWALKOUTPUTTABLENAME" ), "random_walk_output" ); cout << "Random walk output table " << randomWalkOutputTableName << endl; const string testParticleCaseTableName = extractParameterValue< string >( parsedData->begin( ), parsedData->end( ), findEntry( dictionary, "TESTPARTICLECASETABLENAME" ), "test_particle_case" ); cout << "Test particle case table " << testParticleCaseTableName << endl; const string testParticleInputTableName = extractParameterValue< string >( parsedData->begin( ), parsedData->end( ), findEntry( dictionary, "TESTPARTICLEINPUTTABLENAME" ), "test_particle_input" ); cout << "Test particle input table " << testParticleInputTableName << endl; // Check that all required parameters have been set. checkRequiredParameters( dictionary ); /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// cout << endl; cout << "****************************************************************************" << endl; cout << "Database operations" << endl; cout << "****************************************************************************" << endl; cout << endl; // Open (and if necessary create) database. // Check if database file already exists. bool isDatabaseCreated = false; if ( exists( databasePath ) ) { cout << "Opening existing database at " << databasePath << " ..." << endl; } else { isDatabaseCreated = true; cout << "WARNING: Database does not exist!" << endl; cout << "Creating database at " << databasePath << " ..." << endl; } // Create/open database. Database database( databasePath.c_str( ), SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE ); cout << "SQLite database file '" << database.getFilename( ).c_str( ); if ( isDatabaseCreated ) { cout << "' created &"; } cout << " opened successfully ..." << endl; // Fetch test particle case and input data from database. // Generate output message. cout << "Fetching test particle case data from database ..." << endl; // Retrieve and store test particle case data. const TestParticleCasePointer testParticleCaseData = getTestParticleCase( databasePath, testParticleCaseName, testParticleCaseTableName ); // Generate output message to indicate that test particle case data was fetched successfully. cout << "Test particle case data fetched successfully from database!" << endl; // Generate output message. cout << "Fetching test particle input data from database ..." << endl; // Get entire test particle input table from database. Only test particle simulations that // are complete are fetched for the given test particle case ID. const TestParticleInputTable testParticleInputTable = getCompleteTestParticleInputTable( databasePath, testParticleCaseData->testParticleCaseId, testParticleInputTableName, true ); // Generate output message to indicate that test particle input table was fetched successfully. cout << "Test particle input data (" << testParticleInputTable.size( ) << " rows) fetched successfully from database!" << endl; /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// // Compute derived parameters. // Compute mass of perturbed body [kg]. const double perturbedBodyMass = computeMassOfSphere( testParticleCaseData->perturbedBodyRadius, testParticleCaseData->perturbedBodyBulkDensity ); // Compute perturbed body's gravitational parameter [m^3 s^-2]. const double perturbedBodyGravitationalParameter = computeGravitationalParameter( perturbedBodyMass ); // Compute perturber population using density and semi-major axis distribution limits. // Note, in the floor() function, adding 0.5 is a workaround for the fact that there is no // round() function in C++03 (it is available in C++11). ConvertHillRadiiToMeters convertHillRadiiToMeters( testParticleCaseData->centralBodyGravitationalParameter, perturbedBodyGravitationalParameter, testParticleCaseData->perturbedBodyStateInKeplerianElementsAtT0( semiMajorAxisIndex ) ); const double perturberRingNumberDensityInMeters = perturberRingNumberDensity / convertHillRadiiToMeters( 1.0 ); const unsigned int perturberPopulation = std::floor( 2.0 * testParticleCaseData->semiMajorAxisDistributionLimit * perturberRingNumberDensityInMeters + 0.5 ); // Check if desired perturber population is greater than number of completed simulations // fetched, from the database input table, throw a run-time error. if ( perturberPopulation > testParticleInputTable.size( ) ) { throw runtime_error( "ERROR: Perturber population > Number of completed test particle simulations" ); } /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// // Define random number generators. // Define a random number generator and initialize it with a reproducible seed (current cpu // time). GlobalRandomNumberGeneratorType randomNumberGenerator = getGlobalRandomNumberGenerator( ); // Define an uniform random number distribution to randomly select the start epoch of the // observation period during random walk simulation. uniform_real_distribution< > observationPeriodStartDistribution( epochWindowSize / 2.0, testParticleCaseData->randomWalkSimulationPeriod - observationPeriod - epochWindowSize / 2.0 ); // Define variate generator for the first epoch in the observation period. variate_generator< GlobalRandomNumberGeneratorType&, uniform_real_distribution< > > generateObservationPeriodStartEpoch( randomNumberGenerator, observationPeriodStartDistribution ); // Define an uniform random number distribution for test particle simulation ID indices in // input table. uniform_int_distribution< > testParticleSimulationIdIndexDistribution( 0, testParticleInputTable.size( ) - 1 ); // Define variate generator for test particle simulation ID indices using the random number // generator and uniform distribution of test particle simulation ID indices in input table. variate_generator< GlobalRandomNumberGeneratorType&, uniform_int_distribution< > > generateTestParticleSimulationId( randomNumberGenerator, testParticleSimulationIdIndexDistribution ); /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// // Set up random walk run table. if ( !database.tableExists( randomWalkRunTable.c_str( ) ) ) { cout << "Table '" << randomWalkRunTable << "' does not exist ..." << endl; cout << "Creating table ... " << endl; // Create table. ostringstream randomWalkRunTableCreate; randomWalkRunTableCreate << "CREATE TABLE IF NOT EXISTS " << randomWalkRunTable << " (" << "\"randomWalkRunId\" INTEGER PRIMARY KEY NOT NULL," << "\"randomWalkRunName\" TEXT NOT NULL," << "\"testParticleCaseId\" INTEGER NOT NULL," << "\"perturberRingNumberDensity\" INTEGER NOT NULL," << "\"perturberRingMass\" INTEGER NOT NULL," << "\"observationPeriod\" REAL NOT NULL," << "\"numberOfEpochWindows\" INTEGER NOT NULL," << "\"epochWindowSize\" REAL NOT NULL);"; // Execute command to create table. database.exec( randomWalkRunTableCreate.str( ).c_str( ) ); // Check that the table was created successfully. if ( database.tableExists( randomWalkRunTable.c_str( ) ) ) { cout << "Table '" << randomWalkRunTable << "' successfully created!" << endl; } else { ostringstream tableCreateError; tableCreateError << "ERROR: Creating table '" << randomWalkRunTable << "'' failed!"; throw runtime_error( tableCreateError.str( ).c_str( ) ); } } else { cout << "Table '" << randomWalkRunTable << "' already exists ... skipping creating table ..." << endl; } // Check data present in table. // Check if run is already present in table. ostringstream randomWalkRunCheck; randomWalkRunCheck << "SELECT COUNT(*) FROM " << randomWalkRunTable << " WHERE \"randomWalkRunName\" = \"" << randomWalkRunName << "\""; int numberOfRunRows = database.execAndGet( randomWalkRunCheck.str( ).c_str( ) ); if ( numberOfRunRows > 1 ) { ostringstream numberOfRunRowsError; numberOfRunRowsError << "ERROR: Table '" << randomWalkRunTable << "' contains " << numberOfRunRows << " rows for random walk run '" << randomWalkRunName << "'!"; throw runtime_error( numberOfRunRowsError.str( ).c_str( ) ); } else if ( numberOfRunRows == 1 ) { cout << "Table '" << randomWalkRunTable << "' contains 1 row of data for run '" << randomWalkRunName << "' ... " << "skipping populating table ... " << endl; } // Write random walk run data to table. else if ( numberOfRunRows == 0 ) { cout << "No data present in table '" << randomWalkRunTable << "' for random walk run '" << randomWalkRunName << "' ... " << endl; cout << "Populating table ... " << endl; // Create stringstream with random walk run data insert command. // For floating-point values, ensure the data is written to the stream at full precision. ostringstream randomWalkRunDataInsert; randomWalkRunDataInsert << "INSERT INTO " << randomWalkRunTable << " VALUES (" << "NULL," << "\"" << randomWalkRunName << "\"," << testParticleCaseData->testParticleCaseId << ","; randomWalkRunDataInsert << setprecision( numeric_limits< double >::digits10 ) << perturberRingNumberDensity << "," << perturberRingMass << "," << observationPeriod << ","; randomWalkRunDataInsert << numberOfEpochWindows << ","; randomWalkRunDataInsert << setprecision( numeric_limits< double >::digits10 ) << epochWindowSize << ");"; // Insert random walk run data. database.exec( randomWalkRunDataInsert.str( ).c_str( ) ); // Check that there is only one row present in the table. numberOfRunRows = database.execAndGet( randomWalkRunCheck.str( ).c_str( ) ); if ( numberOfRunRows == 1 ) { cout << "Table '" << randomWalkRunTable << "' populated successfully!" << endl; } else { ostringstream numberOfRunRowsError; numberOfRunRowsError << "ERROR: Table '" << randomWalkRunTable << "' contains " << numberOfRunRows << " rows for random walk run '" << randomWalkRunName << "'!"; throw runtime_error( numberOfRunRowsError.str( ).c_str( ) ); } } // Retrieve and output run id. ostringstream randomWalkRunIdQuery; randomWalkRunIdQuery << "SELECT \"randomWalkRunId\" FROM " << randomWalkRunTable << " WHERE \"randomWalkRunName\" = \"" << randomWalkRunName << "\""; const int randomWalkRunId = database.execAndGet( randomWalkRunIdQuery.str( ).c_str( ) ); cout << "Run ID is " << randomWalkRunId << " for random walk run '" << randomWalkRunName << "'" << endl; /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// // Set up random walk perturber table. if ( !database.tableExists( randomWalkPerturberTableName.c_str( ) ) ) { cout << "Table '" << randomWalkPerturberTableName << "' does not exist ..." << endl; cout << "Creating table ... " << endl; // Create table. ostringstream randomWalkPerturberTableCreate; randomWalkPerturberTableCreate << "CREATE TABLE IF NOT EXISTS " << randomWalkPerturberTableName << " (" << "\"randomWalkPerturberId\" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL," << "\"randomWalkSimulationId\" INTEGER NOT NULL," << "\"testParticleSimulationId\" INTEGER NOT NULL);"; // Execute command to create table. database.exec( randomWalkPerturberTableCreate.str( ).c_str( ) ); // Check that the table was created successfully. if ( database.tableExists( randomWalkPerturberTableName.c_str( ) ) ) { cout << "Table '" << randomWalkPerturberTableName << "' successfully created!" << endl; } else { ostringstream tableCreateError; tableCreateError << "ERROR: Creating table '" << randomWalkPerturberTableName << "'' failed!"; throw runtime_error( tableCreateError.str( ).c_str( ) ); } } else { cout << "Table '" << randomWalkPerturberTableName << "' already exists ... skipping creating table ..." << endl; } /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// // Set up random walk input table. if ( !database.tableExists( randomWalkInputTableName.c_str( ) ) ) { cout << "Table '" << randomWalkInputTableName << "' does not exist ..." << endl; cout << "Creating table ... " << endl; // Create table. ostringstream randomWalkInputTableCreate; randomWalkInputTableCreate << "CREATE TABLE IF NOT EXISTS " << randomWalkInputTableName << " (" << "\"randomWalkSimulationId\" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL," << "\"randomWalkRunId\" INTEGER NOT NULL," << "\"completed\" INTEGER NOT NULL," << "\"observationPeriodStartEpoch\" REAL NOT NULL);"; // Execute command to create table. database.exec( randomWalkInputTableCreate.str( ).c_str( ) ); // Check that the table was created successfully. if ( database.tableExists( randomWalkInputTableName.c_str( ) ) ) { cout << "Table '" << randomWalkInputTableName << "' successfully created!" << endl; } else { ostringstream tableCreateError; tableCreateError << "ERROR: Creating table '" << randomWalkInputTableName << "'' failed!"; throw runtime_error( tableCreateError.str( ).c_str( ) ); } } else { cout << "Table '" << randomWalkInputTableName << "' already exists ... skipping creating table ..." << endl; } // Check data present in table. // Check how many rows are present in table. ostringstream randomWalkInputRowCount; randomWalkInputRowCount << "SELECT COUNT(*) FROM " << randomWalkInputTableName << " WHERE \"randomWalkRunId\" == " << randomWalkRunId; const int inputTableRows = database.execAndGet( randomWalkInputRowCount.str( ).c_str( ) ); if ( inputTableRows > 0 ) { cout << "Table '" << randomWalkInputTableName << "' contains " << inputTableRows << " rows for random walk run '" << randomWalkRunName << "' ... skipping populating table ..." << endl; } else { // Populate table. // Table containing list of random walk perturbers is populated simultaneously. cout << "Populating input table with " << monteCarloPopulation << " new random walk simulations ... " << endl; cout << "Populating perturber table with " << monteCarloPopulation << " new data for random walk simulations ... " << endl; // Set up database transaction. Transaction randomWalkInputTableTransaction( database ); // Set up random walk input table insert statement. ostringstream randomWalkInputTableInsert; randomWalkInputTableInsert << "INSERT INTO " << randomWalkInputTableName << " VALUES (NULL, " << randomWalkRunId << ", 0, :observationPeriodStartEpoch);"; // Compile a SQL query. Statement randomWalkInputTableInsertQuery( database, randomWalkInputTableInsert.str( ).c_str( ) ); // Set up random walk perturber table insert statement. ostringstream randomWalkPerturberTableInsert; randomWalkPerturberTableInsert << "INSERT INTO " << randomWalkPerturberTableName << " VALUES (NULL, :randomWalkSimulationId" << ", :testParticleSimulationId);"; // Compile a SQL query. Statement randomWalkPerturberTableInsertQuery( database, randomWalkPerturberTableInsert.str( ).c_str( ) ); // Generate random walk input data and populate table. // Also populate perturber table for each random walk simulation. for ( unsigned int randomWalkSimulation = 0; randomWalkSimulation < monteCarloPopulation; randomWalkSimulation++ ) { // Bind values to prepared SQLite statement. randomWalkInputTableInsertQuery.bind( ":observationPeriodStartEpoch", generateObservationPeriodStartEpoch( ) ); // Execute insert query. randomWalkInputTableInsertQuery.exec( ); // Reset query. randomWalkInputTableInsertQuery.reset( ); // Get row ID for last input row inserted in table. const int lastInputTableRowId = database.getLastInsertRowid( ); // Get random walk simulation ID corresponding to row ID. ostringstream randomWalkSimulationRowIdQuery; randomWalkSimulationRowIdQuery << "SELECT \"randomWalkSimulationId\" FROM " << randomWalkInputTableName << " WHERE rowid == " << lastInputTableRowId; const int randomWalkSimulationId = database.execAndGet( randomWalkSimulationRowIdQuery.str( ).c_str( ) ); // Select test particle simulation ID indices to generate list of random walk // perturbers. // Declare vector containing test particle simulation IDs. vector< unsigned int > testParticleSimulationIdIndices( perturberPopulation ); // Generate vector of randomly selected test particle simulation IDs. generate( testParticleSimulationIdIndices.begin( ), testParticleSimulationIdIndices.end( ), generateTestParticleSimulationId ); // Check if the test particle simulation IDs are unique, and if not, generate new // random number. for ( unsigned int i = 0; i < testParticleSimulationIdIndices.size( ); i++ ) { for ( unsigned int j = 0; j < testParticleSimulationIdIndices.size( ); j++ ) { // If inner and outer loop point to the same element, skip. if ( i == j ) { continue; } // Else, check if the elements are equal, and if they are generate a new // test particle simulation ID index and restart looping. else if ( testParticleSimulationIdIndices.at( j ) == testParticleSimulationIdIndices.at( i ) ) { testParticleSimulationIdIndices.at( j ) = generateTestParticleSimulationId( ); i = 0; break; } } } // Loop through list of test particle simulation ID indices and write data to // random walk perturber table. for ( unsigned int k = 0; k < testParticleSimulationIdIndices.size( ); k++ ) { // Bind values to prepared SQLite statement. randomWalkPerturberTableInsertQuery.bind( ":randomWalkSimulationId", randomWalkSimulationId ); TestParticleInputTable::iterator iteratorTestParticleInputTable = testParticleInputTable.begin( ); advance( iteratorTestParticleInputTable, testParticleSimulationIdIndices.at( k ) ); randomWalkPerturberTableInsertQuery.bind( ":testParticleSimulationId", iteratorTestParticleInputTable->testParticleSimulationId ); // Execute insert query. randomWalkPerturberTableInsertQuery.exec( ); // Reset query. randomWalkPerturberTableInsertQuery.reset( ); } } // Commit transaction. randomWalkInputTableTransaction.commit( ); } /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// // Set up random walk output table. if ( !database.tableExists( randomWalkOutputTableName.c_str( ) ) ) { cout << "Table '" << randomWalkOutputTableName << "' does not exist ..." << endl; cout << "Creating table ... " << endl; // Create table. ostringstream randomWalkOutputTableCreate; randomWalkOutputTableCreate << "CREATE TABLE IF NOT EXISTS " << randomWalkOutputTableName << " (" << "\"randomWalkOutputId\" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL," << "\"randomWalkSimulationId\" INTEGER NOT NULL," << "\"averageLongitudeResidual\" REAL NOT NULL," << "\"maximumLongitudeResidualChange\" REAL NOT NULL," << "\"averageEccentricity\" REAL NOT NULL," << "\"maximumEccentricityChange\" REAL NOT NULL," << "\"averageInclination\" REAL NOT NULL," << "\"maximumInclinationChange\" REAL NOT NULL);"; // Execute command to create table. database.exec( randomWalkOutputTableCreate.str( ).c_str( ) ); // Check that the table was created successfully. if ( database.tableExists( randomWalkOutputTableName.c_str( ) ) ) { cout << "Table '" << randomWalkOutputTableName << "' successfully created!" << endl; } else { ostringstream tableCreateError; tableCreateError << "ERROR: Creating table '" << randomWalkOutputTableName << "'' failed!"; throw runtime_error( tableCreateError.str( ).c_str( ) ); } } else { cout << "Table '" << randomWalkOutputTableName << "' already exists ... skipping creating table ..." << endl; } /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// // Close database. // Database will be automatically closed after the application is terminated. // (when object goes out of scope its destructor will be called). cout << "SQLite database file '" << database.getFilename( ).c_str( ) << "' closed successfully ..." << endl; /////////////////////////////////////////////////////////////////////////// }