K3b::AudioDataSource* K3b::AudioDataSource::split( const K3b::Msf& pos ) { if( pos < length() ) { K3b::AudioDataSource* s = copy(); s->setStartOffset( startOffset() + pos ); s->setEndOffset( endOffset() ); setEndOffset( startOffset() + pos ); s->moveAfter( this ); emitChange(); return s; } else return 0; }
void K3b::AudioDataSource::fixupOffsets() { // no length available yet if( originalLength() == 0 ) return; if( startOffset() >= originalLength() ) { setStartOffset( 0 ); } if( endOffset() > originalLength() ) { setEndOffset( 0 ); // whole source } if( endOffset() > 0 && endOffset() <= startOffset() ) { setEndOffset( startOffset() ); } }
bool K3bAudioCdTrackSource::initParanoia() { if( !m_initialized ) { if( !m_cdParanoiaLib ) m_cdParanoiaLib = K3bCdparanoiaLib::create(); if( m_cdParanoiaLib ) { m_lastUsedDevice = searchForAudioCD(); // ask here for the cd since searchForAudioCD() may also be called from outside if( !m_lastUsedDevice ) { // could not find the CD, so ask for it QString s = i18n("Please insert Audio CD %1%2") .arg(m_discId, 0, 16) .arg(m_cddbEntry.cdTitle.isEmpty() || m_cddbEntry.cdArtist.isEmpty() ? QString::null : " (" + m_cddbEntry.cdArtist + " - " + m_cddbEntry.cdTitle + ")"); while( K3bDevice::Device* dev = K3bThreadWidget::selectDevice( track()->doc()->view(), s ) ) { if( searchForAudioCD( dev ) ) { m_lastUsedDevice = dev; break; } } } // user canceled if( !m_lastUsedDevice ) return false; k3bcore->blockDevice( m_lastUsedDevice ); if( m_toc.isEmpty() ) m_toc = m_lastUsedDevice->readToc(); if( !m_cdParanoiaLib->initParanoia( m_lastUsedDevice, m_toc ) ) { k3bcore->unblockDevice( m_lastUsedDevice ); return false; } if( doc() ) { m_cdParanoiaLib->setParanoiaMode( doc()->audioRippingParanoiaMode() ); m_cdParanoiaLib->setNeverSkip( !doc()->audioRippingIgnoreReadErrors() ); m_cdParanoiaLib->setMaxRetries( doc()->audioRippingRetries() ); } m_cdParanoiaLib->initReading( m_toc[m_cdTrackNumber-1].firstSector().lba() + startOffset().lba() + m_position.lba(), m_toc[m_cdTrackNumber-1].firstSector().lba() + lastSector().lba() ); // we only block during the initialization because we cannot determine the end of the reading process :( k3bcore->unblockDevice( m_lastUsedDevice ); m_initialized = true; kdDebug() << "(K3bAudioCdTrackSource) initialized." << endl; } } return m_initialized; }
void KeplerBtDynamics::keyPressed(int key) { switch (key) { case 'e': { btVector3 startOffset(ofRandom(-295,295),ofRandom(100, 500),ofRandom(-295,295)); spawnKepler(startOffset); } } }
void BirdOptimizer::spawnBigBird() { btVector3 startOffset(0, 5, 0); if ((m_giveBirdThisId % kNumBirdsPerGeneration) == 0) { m_numGeneration++; evaluateCurrentGenerationBirds(); } m_currentBirdLocalParam = new BigBirdLocalParams(); m_currentBirdLocalParam->birdId = m_giveBirdThisId++; m_currentBirdLocalParam->startTransform.setIdentity(); m_currentBirdLocalParam->startTransform.setOrigin(startOffset); m_currentBirdLocalParam->hoistTransform.setIdentity(); m_currentBirdLocalParam->hoistTransform.setOrigin(startOffset); m_currentBirdData = new proto::BigBirdConstructionData(); m_currentBirdData->set_hoistanglexy(10.f); m_currentBirdData->set_hoistanglezxy(90.f); m_currentBirdData->set_pelvishalflength(0.5f); m_currentBirdData->set_winghalflength(0.5f); m_currentBirdData->set_hoistmass(0.0f); m_currentBirdData->set_pelvismass(2.0f); m_currentBirdData->set_wingmass(0.5f); make_Vector3d(btVector3(0.f, 0.f, 0.f), m_currentBirdData->mutable_pelvisrelpostoattachwing()); make_Vector3d(btVector3(0.f, 0.f, 0.f), m_currentBirdData->mutable_featherrelpostoattachfeather()); m_currentBirdData->set_wingflaphingelimit(90.f); m_currentBirdData->set_featheraoahingelimit(40.f); m_currentBirdData->set_featheraoamotormaximpulse(0.05f); m_currentBirdData->set_wingflapmotormaximpulse(1.0f); m_currentBirdData->set_randseed((unsigned int)time(NULL)); srand(m_currentBirdData->randseed()); int numPoints = kNumSamplesInWingbeat; if(m_numGeneration == 0) { fillWithRandomNumbers(m_currentBirdData); //fillWithRun(m_currentBirdData); } else if (m_numGeneration > 0 && (m_giveBirdThisId % kNumBirdsPerGeneration) == 0) { m_currentBirdData->CopyFrom(*m_currentBestInfo); } else if (m_numGeneration > 0) { perturbBestResult(*m_currentBestInfo, m_currentBirdData); } //std::cout << m_currentBirdData->wingbeatdata().DebugString() << std::endl; m_currentTrajectoryData = new proto::TrajectoryData(); m_bigbird = new BigBird(m_ownerWorld, *m_currentBirdLocalParam,*m_currentBirdData); }
void RagdollDemo::initPhysics() { // Setup the basic world setTexturing(true); setShadows(true); setCameraDistance(btScalar(5.)); m_collisionConfiguration = new btDefaultCollisionConfiguration(); m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); btVector3 worldAabbMin(-10000,-10000,-10000); btVector3 worldAabbMax(10000,10000,10000); m_broadphase = new btAxisSweep3 (worldAabbMin, worldAabbMax); m_solver = new btSequentialImpulseConstraintSolver; m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration); //m_dynamicsWorld->getDispatchInfo().m_useConvexConservativeDistanceUtil = true; //m_dynamicsWorld->getDispatchInfo().m_convexConservativeDistanceThreshold = 0.01f; // Setup a big ground box { btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(200.),btScalar(10.),btScalar(200.))); m_collisionShapes.push_back(groundShape); btTransform groundTransform; groundTransform.setIdentity(); groundTransform.setOrigin(btVector3(0,-10,0)); #define CREATE_GROUND_COLLISION_OBJECT 1 #ifdef CREATE_GROUND_COLLISION_OBJECT btCollisionObject* fixedGround = new btCollisionObject(); fixedGround->setCollisionShape(groundShape); fixedGround->setWorldTransform(groundTransform); m_dynamicsWorld->addCollisionObject(fixedGround); #else localCreateRigidBody(btScalar(0.),groundTransform,groundShape); #endif //CREATE_GROUND_COLLISION_OBJECT } // Spawn one ragdoll btVector3 startOffset(1,0.5,0); spawnRagdoll(startOffset); startOffset.setValue(-1,0.5,0); spawnRagdoll(startOffset); clientResetScene(); }
void MotorDemo::initPhysics() { setTexturing(true); setShadows(true); // Setup the basic world m_Time = 0; m_fCyclePeriod = 2000.f; // in milliseconds // m_fMuscleStrength = 0.05f; // new SIMD solver for joints clips accumulated impulse, so the new limits for the motor // should be (numberOfsolverIterations * oldLimits) // currently solver uses 10 iterations, so: m_fMuscleStrength = 0.5f; setCameraDistance(btScalar(5.)); m_collisionConfiguration = new btDefaultCollisionConfiguration(); m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); btVector3 worldAabbMin(-10000,-10000,-10000); btVector3 worldAabbMax(10000,10000,10000); m_broadphase = new btAxisSweep3 (worldAabbMin, worldAabbMax); m_solver = new btSequentialImpulseConstraintSolver; m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration); m_dynamicsWorld->setInternalTickCallback(motorPreTickCallback,this,true); // Setup a big ground box { btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(200.),btScalar(10.),btScalar(200.))); m_collisionShapes.push_back(groundShape); btTransform groundTransform; groundTransform.setIdentity(); groundTransform.setOrigin(btVector3(0,-10,0)); localCreateRigidBody(btScalar(0.),groundTransform,groundShape); } // Spawn one ragdoll btVector3 startOffset(1,0.5,0); spawnTestRig(startOffset, false); startOffset.setValue(-2,0.5,0); spawnTestRig(startOffset, true); clientResetScene(); }
void RagdollApp::initPhysics() { // Setup the basic world m_time = 0; m_CycPerKnee = 2000.f; // in milliseconds m_CycPerHip = 3000.f; // in milliseconds m_fMuscleStrength = 0.5f; setTexturing(true); setShadows(true); setCameraDistance(btScalar(5.)); m_collisionConfiguration = new btDefaultCollisionConfiguration(); m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); btVector3 worldAabbMin(-10000,-10000,-10000); btVector3 worldAabbMax(10000,10000,10000); m_broadphase = new btAxisSweep3 (worldAabbMin, worldAabbMax); m_solver = new btSequentialImpulseConstraintSolver; m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration); //m_dynamicsWorld->getDispatchInfo().m_useConvexConservativeDistanceUtil = true; //m_dynamicsWorld->getDispatchInfo().m_convexConservativeDistanceThreshold = 0.01f; m_dynamicsWorld->setInternalTickCallback( forcePreTickCB, this, true ); m_dynamicsWorld->setGravity( btVector3(0,-0,0) ); // create surface //createSurface(); //// Setup a big ground box btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(200.),btScalar(10.),btScalar(200.))); m_collisionShapes.push_back(groundShape); btTransform groundTransform; groundTransform.setIdentity(); groundTransform.setOrigin(btVector3(0,-10,0)); btCollisionObject* fixedGround = new btCollisionObject(); fixedGround->setCollisionShape(groundShape); fixedGround->setWorldTransform(groundTransform); m_dynamicsWorld->addCollisionObject(fixedGround); // Spawn one ragdoll btVector3 startOffset(1,0.5,0); spawnRagdoll(startOffset); startOffset.setValue(-1,0.1,0); spawnRagdoll(startOffset); clientResetScene(); }
bool EFXFixture::saveXML(QDomDocument* doc, QDomElement* efx_root) const { QDomElement subtag; QDomElement tag; QDomText text; Q_ASSERT(doc != NULL); Q_ASSERT(efx_root != NULL); /* EFXFixture */ tag = doc->createElement(KXMLQLCEFXFixture); efx_root->appendChild(tag); /* Fixture ID */ subtag = doc->createElement(KXMLQLCEFXFixtureID); tag.appendChild(subtag); text = doc->createTextNode(QString("%1").arg(head().fxi)); subtag.appendChild(text); /* Fixture Head */ subtag = doc->createElement(KXMLQLCEFXFixtureHead); tag.appendChild(subtag); text = doc->createTextNode(QString("%1").arg(head().head)); subtag.appendChild(text); /* Mode */ subtag = doc->createElement(KXMLQLCEFXFixtureMode); tag.appendChild(subtag); text = doc->createTextNode(QString::number(mode ())); subtag.appendChild(text); /* Direction */ subtag = doc->createElement(KXMLQLCEFXFixtureDirection); tag.appendChild(subtag); text = doc->createTextNode(Function::directionToString(m_direction)); subtag.appendChild(text); /* Start offset */ subtag = doc->createElement(KXMLQLCEFXFixtureStartOffset); tag.appendChild(subtag); text = doc->createTextNode(QString::number(startOffset())); subtag.appendChild(text); /* Intensity */ subtag = doc->createElement(KXMLQLCEFXFixtureIntensity); tag.appendChild(subtag); text = doc->createTextNode(QString::number(fadeIntensity())); subtag.appendChild(text); return true; }
void SimulationVisual::keyboardCallback(unsigned char key, int x, int y) { switch (key) { case 'e': { btVector3 startOffset(0,2,0); spawnRagdoll(startOffset); break; } default: GlutDemoApplication::keyboardCallback(key, x, y); } }
bool K3bAudioCdTrackSource::seek( const K3b::Msf& msf ) { // HACK: to reinitialize every time we restart the decoding if( msf == 0 && m_cdParanoiaLib ) closeParanoia(); m_position = msf; if( m_cdParanoiaLib ) m_cdParanoiaLib->initReading( m_toc[m_cdTrackNumber-1].firstSector().lba() + startOffset().lba() + m_position.lba(), m_toc[m_cdTrackNumber-1].firstSector().lba() + lastSector().lba() ); return true; }
void RagdollDemo::keyboardCallback(unsigned char key, int x, int y) { switch (key) { case 'e': { btVector3 startOffset(0,2,0); spawnRagdoll(startOffset); break; } default: DemoApplication::keyboardCallback(key, x, y); case 'p': { if(pause) pause = FALSE; else pause = TRUE; } case 'o': { if(oneStep) { oneStep = FALSE; } else { oneStep = TRUE; } } case 'z': { //cout << "SIZE: " << sizeof(collisionID)/sizeof(collisionID[0]) << endl; for(int i = 0; i < sizeof(collisionID)/sizeof(collisionID[0]); i++) { /* cout << i << ": " << collisionID[i]->id; cout << " | ADDRESS: " << collisionID[i]; cout << " | HIT: " << collisionID[i]->hit; cout << " | Colliosion Flags: " << collisionID[i]->body->getCollisionFlags() << endl; */ } } } }
void ChainBtDynamics::initPhysics() { // Setup the basic world m_collisionConfiguration = new btDefaultCollisionConfiguration(); m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); btVector3 worldAabbMin(-10000,-10000,-10000); btVector3 worldAabbMax(10000,10000,10000); m_broadphase = new btAxisSweep3 (worldAabbMin, worldAabbMax); m_solver = new btSequentialImpulseConstraintSolver; m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration); //m_dynamicsWorld->setGravity(btVector3(0.0f, -9.8f*GRAVITY_SCALE, 0.0f)); //m_dynamicsWorld->setGravity(btVector3(0.0f, 0.1f*GRAVITY_SCALE, 0.0f)); //m_dynamicsWorld->setGravity(btVector3(0.0f, -3.0f*GRAVITY_SCALE, 0.0f)); m_dynamicsWorld->setGravity(btVector3(0.0f, 0.00f*GRAVITY_SCALE, 0.0f)); //m_dynamicsWorld->getDispatchInfo().m_useConvexConservativeDistanceUtil = true; //m_dynamicsWorld->getDispatchInfo().m_convexConservativeDistanceThreshold = 0.01f; // Setup a big ground box //{ // //btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(1.5),btScalar(0.1),btScalar(1.5))); // // btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(3000.0f), // btScalar(600.0f), // btScalar(3000.0f))); // m_collisionShapes.push_back(groundShape); // btTransform groundTransform; // groundTransform.setIdentity(); // //groundTransform.setOrigin(btVector3(0,-10,0)); // groundTransform.setOrigin(btVector3(0,-600.0f,0)); // // btCollisionObject* fixedGround = new btCollisionObject(); // fixedGround->setCollisionShape(groundShape); // fixedGround->setWorldTransform(groundTransform); // m_groundInfo.isGround = true; // fixedGround->setUserPointer(&m_groundInfo); // // m_dynamicsWorld->addCollisionObject(fixedGround); //} btVector3 startOffset(0,100,0); clientResetScene(); }
void Simulation::initPhysics() { // setup the ANN ANN* neuralNet = new ANN(); neuralNet->loadXML(); // Setup the basic world m_collisionConfiguration = new btDefaultCollisionConfiguration(); m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); btVector3 worldAabbMin(-10000,-10000,-10000); btVector3 worldAabbMax(10000,10000,10000); m_broadphase = new btAxisSweep3 (worldAabbMin, worldAabbMax); m_solver = new btSequentialImpulseConstraintSolver; m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher, m_broadphase, m_solver,m_collisionConfiguration); //tick = 0; m_dynamicsWorld->setInternalTickCallback(robotPreTickCallback, this, true); // Setup a big ground box { btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(200.), btScalar(10.),btScalar(200.))); m_collisionShapes.push_back(groundShape); btTransform groundTransform; groundTransform.setIdentity(); groundTransform.setOrigin(btVector3(0,-10,0)); btCollisionObject* fixedGround = new btCollisionObject(); fixedGround->setCollisionShape(groundShape); fixedGround->setWorldTransform(groundTransform); m_dynamicsWorld->addCollisionObject(fixedGround); } // Spawn one ragdoll btVector3 startOffset(1,0.5,0); spawnRagdoll(startOffset); }
void RagdollDemo::keyboardCallback(unsigned char key, int x, int y) { switch (key) { case 'p': pause = !pause; break; case 'o': oneStep = true; break; case 'e': { btVector3 startOffset(0,2,0); spawnRagdoll(startOffset); break; } default: DemoApplication::keyboardCallback(key, x, y); } }
void Text3D::computeGlyphRepresentation() { if (_font.valid() == false) return; _textRenderInfo.clear(); _lineCount = 0; if (_text.empty()) { _textBB.set(0,0,0, 0,0,0);//no size text TextBase::computePositions(); //to reset the origin return; } // initialize bounding box, it will be expanded during glyph position calculation _textBB.init(); osg::Vec2 startOfLine_coords(0.0f,0.0f); osg::Vec2 cursor(startOfLine_coords); osg::Vec2 local(0.0f,0.0f); osg::Vec2 startOffset(0.0f,0.0f); unsigned int previous_charcode = 0; unsigned int linelength = 0; bool kerning = true; unsigned int lineNumber = 0; for(String::iterator itr=_text.begin(); itr!=_text.end(); ) { _textRenderInfo.resize(lineNumber + 1); LineRenderInfo & currentLineRenderInfo = _textRenderInfo.back(); // record the start of the current line String::iterator startOfLine_itr = itr; // find the end of the current line. osg::Vec2 endOfLine_coords(cursor); String::iterator endOfLine_itr = computeLastCharacterOnLine(endOfLine_coords, itr,_text.end()); // ** position the cursor function to the Layout and the alignement TextBase::positionCursor(endOfLine_coords, cursor, (unsigned int) (endOfLine_itr - startOfLine_itr)); if (itr!=endOfLine_itr) { for(;itr!=endOfLine_itr;++itr) { unsigned int charcode = *itr; Font3D::Glyph3D* glyph = _font->getGlyph(charcode); if (glyph) { const osg::BoundingBox & bb = glyph->getBoundingBox(); // adjust cursor position w.r.t any kerning. if (previous_charcode) { if (_layout == RIGHT_TO_LEFT) { cursor.x() -= glyph->getHorizontalAdvance(); } if (kerning) { switch (_layout) { case LEFT_TO_RIGHT: { cursor += _font->getKerning(previous_charcode, charcode, _kerningType); break; } case RIGHT_TO_LEFT: { cursor -= _font->getKerning(charcode, previous_charcode, _kerningType); break; } case VERTICAL: break; // no kerning when vertical. } } } else { switch (_layout) { case LEFT_TO_RIGHT: { cursor.x() -= glyph->getHorizontalBearing().x(); break; } case RIGHT_TO_LEFT: { cursor.x() -= bb.xMax(); break; } case VERTICAL: { // cursor.y() += glyph->getVerticalBearing().y(); break; } } } local = cursor; if (_layout==VERTICAL) { local.x() += -glyph->getVerticalBearing().x(); local.y() += -glyph->getVerticalBearing().y(); } // move the cursor onto the next character. // also expand bounding box switch (_layout) { case LEFT_TO_RIGHT: _textBB.expandBy(osg::Vec3(cursor.x() + bb.xMin(), cursor.y() + bb.yMin(), 0.0f)); //lower left corner _textBB.expandBy(osg::Vec3(cursor.x() + bb.xMax(), cursor.y() + bb.yMax(), 0.0f)); //upper right corner cursor.x() += glyph->getHorizontalAdvance(); break; case VERTICAL: _textBB.expandBy(osg::Vec3(cursor.x(), cursor.y(), 0.0f)); //upper left corner _textBB.expandBy(osg::Vec3(cursor.x() + glyph->getWidth(), cursor.y() - glyph->getHeight(), 0.0f)); //lower right corner cursor.y() -= glyph->getVerticalAdvance(); break; case RIGHT_TO_LEFT: _textBB.expandBy(osg::Vec3(cursor.x()+bb.xMax(), cursor.y() + bb.yMax(), 0.0f)); //upper right corner _textBB.expandBy(osg::Vec3(cursor.x()+bb.xMin(), cursor.y()+bb.yMin(), 0.0f)); //lower left corner break; } osg::Vec3 pos = osg::Vec3(local.x(), local.y(), 0.0f); currentLineRenderInfo.push_back(Text3D::GlyphRenderInfo(glyph, pos)); previous_charcode = charcode; } } } else { ++itr; } if (itr!=_text.end()) { // skip over return. if (*itr=='\n') ++itr; } // move to new line. switch(_layout) { case LEFT_TO_RIGHT: case RIGHT_TO_LEFT: { startOfLine_coords.y() -= (1.0 + _lineSpacing) / _font->getScale(); ++_lineCount; break; } case VERTICAL: { startOfLine_coords.x() += _characterHeight / _font->getScale() / _characterAspectRatio * (1.0 + _lineSpacing); // because _lineCount is the max vertical no. of characters.... _lineCount = (_lineCount >linelength)?_lineCount:linelength; break; } default: break; } cursor = startOfLine_coords; previous_charcode = 0; ++lineNumber; } _textBB.expandBy(0.0f,0.0f,-1); TextBase::computePositions(); }
int main(int argc, char **argv) { ros::init(argc, argv, "msf_eval"); ros::Time::init(); enum argIndices{ bagfile = 1, EVAL_topic = 2, GT_topic = 3, singleRunOnly = 4 }; //calibration of sensor to vicon Eigen::Matrix4d T_BaBg_mat; //this is the Vicon one - SLAM sensor V0 /////////////////////////////////////////////////////////////////////////////////////////// T_BaBg_mat << 0.999706627053000, -0.022330158354000, 0.005123243528000, -0.060614697387000, 0.022650462142000, 0.997389634278000, -0.068267398302000, 0.035557942651000, -0.003589706237000, 0.068397960288000, 0.997617159323000, -0.042589657349000, 0, 0, 0, 1.000000000000000; //////////////////////////////////////////////////////////////////////////////////////////// ros::Duration dt(0.0039); const double timeSyncThreshold = 0.005; const double timeDiscretization = 10.0; //discretization step for different starting points into the dataset const double trajectoryTimeDiscretization = 0.049; //discretization of evaluation points (vision framerate for fair comparison) const double startTimeOffset = 10.0; if (argc < 4) { MSF_ERROR_STREAM("usage: ./"<<argv[0]<<" bagfile EVAL_topic GT_topic [singleRunOnly]"); return -1; } bool singleRun = false; if (argc == 5) { singleRun = atoi(argv[singleRunOnly]); } if(singleRun){ MSF_WARN_STREAM("Doing only a single run."); }else{ MSF_WARN_STREAM("Will process the dataset from different starting points."); } typedef geometry_msgs::TransformStamped GT_TYPE; typedef geometry_msgs::PoseWithCovarianceStamped EVAL_TYPE; // output file std::stringstream matlab_fname; std::string path = ros::package::getPath("msf_eval"); matlab_fname << path << "/Matlab/matlab_data" << ros::Time::now().sec << ".m"; std::ofstream outfile(matlab_fname.str().c_str()); std::stringstream poses_EVAL; std::stringstream poses_GT; assert(outfile.good()); outfile << "data=[" << std::endl; ros::Duration startOffset(startTimeOffset); sm::kinematics::Transformation T_BaBg(T_BaBg_mat); //body aslam to body Ground Truth // open for reading rosbag::Bag bag(argv[bagfile], rosbag::bagmode::Read); // views on topics rosbag::View view_EVAL(bag, rosbag::TopicQuery(argv[EVAL_topic])); rosbag::View view_GT(bag, rosbag::TopicQuery(argv[GT_topic])); //check topics if (view_EVAL.size() == 0) { MSF_ERROR_STREAM("The bag you provided does not contain messages for topic "<<argv[EVAL_topic]); return -1; } if (view_GT.size() == 0) { MSF_ERROR_STREAM("The bag you provided does not contain messages for topic "<<argv[GT_topic]); return -1; } //litter console with number of messages MSF_INFO_STREAM("Reading from "<<argv[bagfile]); MSF_INFO_STREAM("Topic "<<argv[EVAL_topic]<<", size: "<<view_EVAL.size()); MSF_INFO_STREAM("Topic "<<argv[GT_topic]<<", size: "<<view_GT.size()); //get times of first messages GT_TYPE::ConstPtr GT_begin = view_GT.begin()->instantiate<GT_TYPE>(); assert(GT_begin); EVAL_TYPE::ConstPtr POSE_begin = view_EVAL.begin()->instantiate<EVAL_TYPE>(); assert(POSE_begin); MSF_INFO_STREAM("First GT data at "<<GT_begin->header.stamp); MSF_INFO_STREAM("First EVAL data at "<<POSE_begin->header.stamp); while (true) // start eval from different starting points { rosbag::View::const_iterator it_EVAL = view_EVAL.begin(); rosbag::View::const_iterator it_GT = view_GT.begin(); // read ground truth ros::Time start; // Find start time alignment: set the GT iterater to point to a time larger than the aslam time while (true) { GT_TYPE::ConstPtr trafo = it_GT->instantiate<GT_TYPE>(); assert(trafo); ros::Time time_GT; time_GT = trafo->header.stamp + dt; EVAL_TYPE::ConstPtr pose = it_EVAL->instantiate<EVAL_TYPE>(); assert(pose); ros::Time time_EKF; time_EKF = pose->header.stamp; if (time_EKF >= time_GT) { it_GT++; if (it_GT == view_GT.end()) { MSF_ERROR_STREAM("Time synchronization failed"); return false; } } else { start = time_GT; MSF_INFO_STREAM("Time synced! GT start: "<<start <<" EVAL start: "<<time_EKF); break; } } // world frame alignment sm::kinematics::Transformation T_WaBa; sm::kinematics::Transformation T_WgBg; sm::kinematics::Transformation T_WgBg_last; sm::kinematics::Transformation T_WaWg; // now find the GT/EKF pairings int ctr = 0; //how many meas did we add this run? double ds = 0.0; // distance travelled ros::Time lastTime(0.0); MSF_INFO_STREAM("Processing measurements... Current start point: "<<startOffset<<"s into the bag."); for (; it_GT != view_GT.end(); ++it_GT) { GT_TYPE::ConstPtr trafo = it_GT->instantiate<GT_TYPE>(); assert(trafo); // find closest timestamp ros::Time time_GT = trafo->header.stamp + dt; EVAL_TYPE::ConstPtr pose = it_EVAL->instantiate<EVAL_TYPE>(); assert(pose); ros::Time time_EKF = pose->header.stamp; bool terminate = false; //get the measurement close to this GT value while (time_GT > time_EKF) { it_EVAL++; if (it_EVAL == view_EVAL.end()) { terminate = true; MSF_INFO_STREAM("done. All EKF meas processed!"); break; } pose = it_EVAL->instantiate<EVAL_TYPE>(); assert(pose); time_EKF = pose->header.stamp; } if (terminate){ break; } // add comparison value if (time_GT - start >= startOffset) { T_WaBa = sm::kinematics::Transformation( Eigen::Vector4d(-pose->pose.pose.orientation.x, -pose->pose.pose.orientation.y, -pose->pose.pose.orientation.z, pose->pose.pose.orientation.w), Eigen::Vector3d(pose->pose.pose.position.x, pose->pose.pose.position.y, pose->pose.pose.position.z)); T_WgBg = sm::kinematics::Transformation( Eigen::Vector4d(-trafo->transform.rotation.x, -trafo->transform.rotation.y, -trafo->transform.rotation.z, trafo->transform.rotation.w), Eigen::Vector3d(trafo->transform.translation.x, trafo->transform.translation.y, trafo->transform.translation.z)); // initial alignment if (ctr == 0) { T_WaWg = (T_WaBa) * T_BaBg * T_WgBg.inverse(); T_WgBg_last = T_WgBg; } sm::kinematics::Transformation dT = T_WaBa * (T_WaWg * T_WgBg * T_BaBg.inverse()).inverse(); sm::kinematics::Transformation T_WaBa_gt = (T_WaWg * T_WgBg * T_BaBg.inverse()); T_WaBa_gt = sm::kinematics::Transformation(T_WaBa_gt.q().normalized(), T_WaBa_gt.t()); dT = sm::kinematics::Transformation(dT.q().normalized(), dT.t()); // update integral if (trafo) { ds += (T_WgBg.t() - T_WgBg_last.t()).norm(); // store last GT transformation T_WgBg_last = T_WgBg; } else { // too noisy if ((T_WgBg * T_WgBg_last.inverse()).t().norm() > .1) { ds += (T_WgBg.t() - T_WgBg_last.t()).norm(); //MSF_INFO_STREAM((T_WgBg*T_WgBg_last.inverse()).t().norm()); // store last GT transformation T_WgBg_last = T_WgBg; } } Eigen::Vector3d dalpha; if (dT.q().head<3>().norm() > 1e-12) { dalpha = (asin(dT.q().head<3>().norm()) * 2 * dT.q().head<3>().normalized()); } else { dalpha = 2 * dT.q().head<3>(); } // g-vector alignment Eigen::Vector3d e_z_Wg(0, 0, 1); Eigen::Vector3d e_z_Wa = dT.C() * e_z_Wg; double dalpha_e_z = acos(std::min(1.0, e_z_Wg.dot(e_z_Wa))); if (fabs((time_GT - time_EKF).toSec()) < timeSyncThreshold && (time_EKF - lastTime).toSec() > trajectoryTimeDiscretization) { if (startOffset.toSec() == startTimeOffset) { poses_EVAL << T_WaBa.t().transpose() << ";" << std::endl; poses_GT << T_WgBg.t().transpose() << ";" << std::endl; } Eigen::Matrix<double, 6, 6> cov = getCovariance(pose); outfile << (time_GT - start).toSec() << " " << ds << " " << (T_WaBa.t() - T_WaBa_gt.t()).norm() << " " //translation << 2 * acos(std::min(1.0, fabs(dT.q()[3]))) << " " << dalpha_e_z << " " //orientation <<cov(0, 0)<<" "<<cov(1, 1)<<" "<<cov(2, 2)<<" " //position covariances <<cov(3, 3)<<" "<<cov(4, 4)<<" "<<cov(5, 5)<<";" //orientation covariances << std::endl; lastTime = time_EKF; // remember } // count comparisons ctr++; } } MSF_INFO_STREAM("Added "<<ctr<<" measurement edges."); //where in the bag should the next eval start startOffset += ros::Duration(timeDiscretization); if (ctr == 0 || singleRun) //any new measurements this run? { break; } } // cleanup bag.close(); outfile << "];"; outfile << "poses = [" << poses_EVAL.str() << "];" << std::endl; outfile << "poses_GT = [" << poses_GT.str() << "];" << std::endl; outfile.close(); return 0; }
bool EFX::saveXML(QDomDocument* doc, QDomElement* wksp_root) { QDomElement root; QDomElement tag; QDomElement subtag; QDomText text; QString str; Q_ASSERT(doc != NULL); Q_ASSERT(wksp_root != NULL); /* Function tag */ root = doc->createElement(KXMLQLCFunction); wksp_root->appendChild(root); root.setAttribute(KXMLQLCFunctionID, id()); root.setAttribute(KXMLQLCFunctionType, Function::typeToString(type())); root.setAttribute(KXMLQLCFunctionName, name()); /* Fixtures */ QListIterator <EFXFixture*> it(m_fixtures); while (it.hasNext() == true) it.next()->saveXML(doc, &root); /* Propagation mode */ tag = doc->createElement(KXMLQLCEFXPropagationMode); root.appendChild(tag); text = doc->createTextNode(propagationModeToString(m_propagationMode)); tag.appendChild(text); /* Speeds */ saveXMLSpeed(doc, &root); /* Direction */ saveXMLDirection(doc, &root); /* Run order */ saveXMLRunOrder(doc, &root); /* Algorithm */ tag = doc->createElement(KXMLQLCEFXAlgorithm); root.appendChild(tag); text = doc->createTextNode(algorithmToString(algorithm())); tag.appendChild(text); /* Width */ tag = doc->createElement(KXMLQLCEFXWidth); root.appendChild(tag); str.setNum(width()); text = doc->createTextNode(str); tag.appendChild(text); /* Height */ tag = doc->createElement(KXMLQLCEFXHeight); root.appendChild(tag); str.setNum(height()); text = doc->createTextNode(str); tag.appendChild(text); /* Rotation */ tag = doc->createElement(KXMLQLCEFXRotation); root.appendChild(tag); str.setNum(rotation()); text = doc->createTextNode(str); tag.appendChild(text); /* StartOffset */ tag = doc->createElement(KXMLQLCEFXStartOffset); root.appendChild(tag); str.setNum(startOffset()); text = doc->createTextNode(str); tag.appendChild(text); /******************************************** * X-Axis ********************************************/ tag = doc->createElement(KXMLQLCEFXAxis); root.appendChild(tag); tag.setAttribute(KXMLQLCFunctionName, KXMLQLCEFXX); /* Offset */ subtag = doc->createElement(KXMLQLCEFXOffset); tag.appendChild(subtag); str.setNum(xOffset()); text = doc->createTextNode(str); subtag.appendChild(text); /* Frequency */ subtag = doc->createElement(KXMLQLCEFXFrequency); tag.appendChild(subtag); str.setNum(xFrequency()); text = doc->createTextNode(str); subtag.appendChild(text); /* Phase */ subtag = doc->createElement(KXMLQLCEFXPhase); tag.appendChild(subtag); str.setNum(xPhase()); text = doc->createTextNode(str); subtag.appendChild(text); /******************************************** * Y-Axis ********************************************/ tag = doc->createElement(KXMLQLCEFXAxis); root.appendChild(tag); tag.setAttribute(KXMLQLCFunctionName, KXMLQLCEFXY); /* Offset */ subtag = doc->createElement(KXMLQLCEFXOffset); tag.appendChild(subtag); str.setNum(yOffset()); text = doc->createTextNode(str); subtag.appendChild(text); /* Frequency */ subtag = doc->createElement(KXMLQLCEFXFrequency); tag.appendChild(subtag); str.setNum(yFrequency()); text = doc->createTextNode(str); subtag.appendChild(text); /* Phase */ subtag = doc->createElement(KXMLQLCEFXPhase); tag.appendChild(subtag); str.setNum(yPhase()); text = doc->createTextNode(str); subtag.appendChild(text); return true; }
void RagdollDemo::initPhysics() { // Setup the basic world setTexturing(true); setShadows(true); setCameraDistance(btScalar(5.)); m_collisionConfiguration = new btDefaultCollisionConfiguration(); m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); btVector3 worldAabbMin(-10000,-10000,-10000); btVector3 worldAabbMax(10000,10000,10000); m_broadphase = new btAxisSweep3 (worldAabbMin, worldAabbMax); m_solver = new btSequentialImpulseConstraintSolver; m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration); //m_dynamicsWorld->getDispatchInfo().m_useConvexConservativeDistanceUtil = true; //m_dynamicsWorld->getDispatchInfo().m_convexConservativeDistanceThreshold = 0.01f; // Setup a big ground box { btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(200.),btScalar(10.),btScalar(200.))); m_collisionShapes.push_back(groundShape); btTransform groundTransform; groundTransform.setIdentity(); groundTransform.setOrigin(btVector3(0,-10,0)); #define CREATE_GROUND_COLLISION_OBJECT 1 #ifdef CREATE_GROUND_COLLISION_OBJECT btCollisionObject* fixedGround = new btCollisionObject(); fixedGround->setCollisionShape(groundShape); fixedGround->setWorldTransform(groundTransform); m_dynamicsWorld->addCollisionObject(fixedGround); #else localCreateRigidBody(btScalar(0.),groundTransform,groundShape); #endif //CREATE_GROUND_COLLISION_OBJECT } // Spawn one ragdoll btVector3 startOffset(1,0.5,0); //spawnRagdoll(startOffset); startOffset.setValue(-1,0.5,0); //spawnRagdoll(startOffset); CreateBox(0, 0., 2., 0., 1., 0.2, 1.); // Create the box //leg components CreateCylinder(1, 2. , 2., 0., .2, 1., 0., 0., M_PI_2); //xleft horizontal CreateCylinder(2, -2., 2., 0., .2, 1., 0., 0., M_PI_2); //xright (negative) horizontal CreateCylinder(3, 0, 2., 2., .2, 1., M_PI_2, 0., 0.); //zpositive (into screen) CreateCylinder(4, 0, 2., -2., .2, 1., M_PI_2, 0., 0.); //znegative (out of screen) CreateCylinder(5, 3.0, 1., 0., .2, 1., 0., 0., 0.); //xleft vertical CreateCylinder(6, -3.0, 1., 0., .2, 1., 0., 0., 0.); //xright vertical CreateCylinder(7, 0., 1., 3.0, .2, 1., 0., 0., 0.); //zpositive vertical CreateCylinder(8, 0., 1., -3.0, .2, 1., 0., 0., 0.); //znegative vertical //The axisworldtolocal defines a vector perpendicular to the plane that you want the bodies to rotate in //hinge the legs together //xnegative -- right //two bodies should rotate in y-plane through x--give axisworldtolocal it a z vector btVector3 local2 = PointWorldToLocal(2, btVector3(-3., 2., 0)); btVector3 local6 = PointWorldToLocal(6, btVector3(-3., 2., 0)); btVector3 axis2 = AxisWorldToLocal(2, btVector3(0., 0., 1.)); btVector3 axis6 = AxisWorldToLocal(6, btVector3( 0., 0., 1.)); CreateHinge(0, *body[2], *body[6], local2, local6, axis2, axis6); joints[0]->setLimit(btScalar(0.), btScalar(M_PI_2+M_PI_4)); //positive -- left //give axisworldtolocal a z vector btVector3 local1 = PointWorldToLocal(1, btVector3(3., 2., 0)); btVector3 local5 = PointWorldToLocal(5, btVector3(3., 2., 0)); btVector3 axis1 = AxisWorldToLocal(1, btVector3( 0., 0., 1.)); btVector3 axis5 = AxisWorldToLocal(5, btVector3(0., 0., 1.)); CreateHinge(1, *body[1], *body[5], local1, local5, axis1, axis5); joints[1]->setLimit(btScalar(M_PI_4), btScalar(M_PI_4)); //zpositive -- back //rotates in y-plane through z--give it an x vector btVector3 local3 = PointWorldToLocal(3, btVector3(0, 2., 3.)); btVector3 local7 = PointWorldToLocal(7, btVector3(0, 2., 3.)); btVector3 axis3 = AxisWorldToLocal(3, btVector3(1., 0., 0.)); btVector3 axis7 = AxisWorldToLocal(7, btVector3(1., 0., 0.)); CreateHinge(2, *body[3], *body[7], local3, local7, axis3, axis7); joints[2]->setLimit(btScalar(0.), btScalar(M_PI_2+M_PI_4)); //znegative -- front btVector3 local4 = PointWorldToLocal(4, btVector3(0, 2., -3.)); btVector3 local8 = PointWorldToLocal(8, btVector3(0, 2., -3.)); btVector3 axis4 = AxisWorldToLocal(4, btVector3(1., 0., 0.)); btVector3 axis8 = AxisWorldToLocal(8, btVector3(1., 0., 0.)); CreateHinge(3, *body[4], *body[8], local4, local8, axis4, axis8); joints[3]->setLimit(btScalar(M_PI_4), btScalar(M_PI_4)); //hinge the legs to the body //xright to main btVector3 localHinge2 = PointWorldToLocal(2, btVector3(-1, 2., 0)); btVector3 mainHinge2 = PointWorldToLocal(0, btVector3(-1, 2., 0)); btVector3 localAxis2 = AxisWorldToLocal(2, btVector3(0., 0., 1.)); btVector3 mainAxis2 = AxisWorldToLocal(0, btVector3( 0., 0., 1.)); CreateHinge(4, *body[0], *body[2], mainHinge2, localHinge2, mainAxis2, localAxis2); //joints[4]->setLimit(btScalar(-M_PI_2-M_PI_4), btScalar(M_PI_4)); //xleft to main btVector3 localHinge1 = PointWorldToLocal(1, btVector3(1, 2., 0)); btVector3 mainHinge1 = PointWorldToLocal(0, btVector3(1, 2., 0)); btVector3 localAxis1 = AxisWorldToLocal(1, btVector3(0., 0., 1.)); btVector3 mainAxis1 = AxisWorldToLocal(0, btVector3( 0., 0., 1.)); CreateHinge(5, *body[0], *body[1], mainHinge1, localHinge1, mainAxis1, localAxis1); //joints[5]->setLimit(btScalar(-M_PI_2), btScalar(M_PI_2)); //zpositive (back) to main btVector3 localHinge3 = PointWorldToLocal(3, btVector3(0., 2., 1)); btVector3 mainHinge3 = PointWorldToLocal(0, btVector3(0., 2., 1)); btVector3 localAxis3 = AxisWorldToLocal(3, btVector3(1., 0., 0.)); btVector3 mainAxis3 = AxisWorldToLocal(0, btVector3( 1., 0., 0.)); CreateHinge(6, *body[0], *body[3], mainHinge3, localHinge3, mainAxis3, localAxis3); //joints[6]->setLimit(btScalar(-M_PI_2-M_PI_4), btScalar(M_PI_4)); btVector3 localHinge4 = PointWorldToLocal(4, btVector3(0., 2., -1)); btVector3 mainHinge4= PointWorldToLocal(0, btVector3(0., 2., -1)); btVector3 localAxis4 = AxisWorldToLocal(4, btVector3(1., 0., 0. )); btVector3 mainAxis4 = AxisWorldToLocal(0, btVector3( 1., 0., 0.)); CreateHinge(7, *body[0], *body[4], mainHinge4, localHinge4, mainAxis4, localAxis4); //joints[7]->setLimit(btScalar(-M_PI_2), btScalar(M_PI_2)); clientResetScene(); }
void RagdollDemo::initPhysics() { // Setup the basic world setTexturing(true); setShadows(true); setCameraDistance(btScalar(5.)); m_collisionConfiguration = new btDefaultCollisionConfiguration(); m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); btVector3 worldAabbMin(-10000,-10000,-10000); btVector3 worldAabbMax(10000,10000,10000); m_broadphase = new btAxisSweep3 (worldAabbMin, worldAabbMax); m_solver = new btSequentialImpulseConstraintSolver; m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration); //m_dynamicsWorld->getDispatchInfo().m_useConvexConservativeDistanceUtil = true; //m_dynamicsWorld->getDispatchInfo().m_convexConservativeDistanceThreshold = 0.01f; // Setup a big ground box { btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(200.),btScalar(10.),btScalar(200.))); m_collisionShapes.push_back(groundShape); btTransform groundTransform; groundTransform.setIdentity(); groundTransform.setOrigin(btVector3(0,-10,0)); #define CREATE_GROUND_COLLISION_OBJECT 1 #ifdef CREATE_GROUND_COLLISION_OBJECT btCollisionObject* fixedGround = new btCollisionObject(); fixedGround->setCollisionShape(groundShape); fixedGround->setWorldTransform(groundTransform); m_dynamicsWorld->addCollisionObject(fixedGround); #else localCreateRigidBody(btScalar(0.),groundTransform,groundShape); #endif //CREATE_GROUND_COLLISION_OBJECT } // Spawn one ragdoll btVector3 startOffset(1,0.5,0); //spawnRagdoll(startOffset); startOffset.setValue(-1,0.5,0); //spawnRagdoll(startOffset); CreateBox(0, 0., 0., 1., 1., 1., 0.2); // fore limbs CreateCylinder(1, 1., 0., 1., 0.1, 1., 1); CreateCylinder(2, -1., 0., 1., 0.1, 1., 1); CreateCylinder(3, 0., 1., 1., 0.1, 1., 2); CreateCylinder(4, 0., -1., 1., 0.1, 1., 2); CreateCylinder(5, 1.5, 0., .5, 0.1, 1., 3); CreateCylinder(6, -1.5, 0., .5, 0.1, 1., 3); CreateCylinder(7, 0., 1.5, .5, 0.1, 1., 3); CreateCylinder(8, 0., -1.5, .5, 0.1, 1., 3); btVector3 v = PointWorldToLocal(0, btVector3(0,1,0)); /* std::cerr << "v " << v[0] << " " << v[1] << " " << v[2] << std::endl; */ printf("(%f, %f, %f)\n", v[0], v[1], v[2]); CreateHinge(0, 0, 1, 0.5, 0., 1., 0., -1., 0.); CreateHinge(1, 0, 2, -.5, 0., 1., 0., 1., 0.); CreateHinge(2, 0, 3, 0., .5, 1., 1., 0., 0.); CreateHinge(3, 0, 4, 0., -.5, 1., -1., 0., 0.); CreateHinge(4, 1, 5, 1.5, 0., 1., 0., -1., 0.); CreateHinge(5, 2, 6, -1.5, 0., 1., 0., 1., 0.); CreateHinge(6, 3, 7, 0., 1.5, 1., 1., 0., 0.); CreateHinge(7, 4, 8, 0., -1.5, 1., -1., 0., 0.); clientResetScene(); }
void VisItSimStripChart::paintEvent( QPaintEvent * ) { int i =0; float h = height(); float w = width(); QPen penLimits; QPainter paint( this ); gridFont->setPointSize(pointSize); paint.scale(1.0,zoom); if ( center ) { paint.translate( 0,points.back().y()); center = false; } // start drawing the data n times step away from the right // hand edge of the window. timeShift = int(w - ( (delta/2.0) * points.size())); // do we have data to draw and are we enabled? if ( points.empty()) return; if ( !enabled ) return; // display the grid paintGrid( &paint); VisItPointD startOffset(points.front().x(),0); Points::iterator it; // connect all points together to make the graph for( it = points.begin(); it != points.end(); ) { // Set the pen width and color penLimits.setWidth(2); // set pen color to normal penLimits.setColor(Qt::darkGreen); VisItPointD startPoint(0,0); startPoint.setX( (*it).x() - startOffset.x()); startPoint.setY( (*it).y() - startOffset.y()); it++; if ( it == points.end()) break; VisItPointD endPoint(0,0); endPoint.setX((*it).x() - startOffset.x());; endPoint.setY((*it).y() - startOffset.y());; // check to see if it is out of limit if ( outOfBandLimitsEnabled ) { if ( startPoint.y() > maxYLimit || startPoint.y() < minYLimit || endPoint.y() > maxYLimit || endPoint.y() < minYLimit ) { // set pen color to out of limits penLimits.setColor(Qt::red); } } paint.setPen( penLimits ); QPoint startPoint_int; QPoint endPoint_int; // convert to screen space startPoint_int.setX ( int(startPoint.x()*delta +timeShift)); startPoint_int.setY ( int ((h-((startPoint.y()-minPoint)*vdelta)))); endPoint_int.setX ( int(endPoint.x()*delta + timeShift)); endPoint_int.setY ( int((h-((endPoint.y()-minPoint)*vdelta)) )); currentScaledY = ((h-((endPoint.y()-minPoint)*vdelta)) ); paint.drawLine( startPoint_int, endPoint_int ); // draw line i++; if ( i%10 == 0 ) { paint.drawText( startPoint_int.x(),int(h-10), QString::number((*it).x())); paint.drawText( startPoint_int.x(),int(middle*vdelta), QString::number((*it).x())); paint.drawText( startPoint_int.x(),int(10), QString::number((*it).x())); } // draw limit extents if ( outOfBandLimitsEnabled ) { penLimits.setColor(Qt::red); penLimits.setWidth(3); paint.setPen( penLimits ); paint.drawLine( QPoint(int(0),int(h-((maxYLimit)-minPoint)*vdelta)), QPoint(int(w),int(h-((maxYLimit-minPoint)*vdelta)))); // draw line paint.drawLine( QPoint(int(0),int(h-((minYLimit)-minPoint)*vdelta)), QPoint(int(w),int(h-((minYLimit)-minPoint)*vdelta))); // draw line } } }
bool SVGTextPathElement::selfHasRelativeLengths() const { return startOffset().isRelative() || SVGTextContentElement::selfHasRelativeLengths(); }
int main (int argc, char *argv[]){ char *x, *y, *z, *xbuf, *hbuf, *chrNames[MAXNBCHR]; int fd; off_t hsiz; struct stat st; MPI_File mpi_filed; MPI_File mpi_file_split_comm; MPI_Offset fileSize, unmapped_start, discordant_start; int num_proc, rank; int res, nbchr, i, paired, write_sam; int ierr, errorcode = MPI_ERR_OTHER; char *file_name, *output_dir; char *header; unsigned int headerSize; unsigned char threshold; size_t input_file_size; size_t unmappedSize = 0; size_t discordantSize = 0; size_t *readNumberByChr = NULL, *localReadNumberByChr = NULL; Read **reads; double time_count; double time_count1; int g_rank, g_size; MPI_Comm split_comm; //used to split communication when jobs have no reads to sort int split_rank, split_size; //after split communication we update the rank and the size double tic, toc; int compression_level; size_t fsiz, lsiz, loff; const char *sort_name; MPI_Info finfo; /* Set default values */ compression_level = 3; parse_mode = MODE_OFFSET; sort_name = "coordinate"; paired = 0; threshold = 0; write_sam = 0; /* Check command line */ while ((i = getopt(argc, argv, "c:hnpq:")) != -1) { switch(i) { case 'c': /* Compression level */ compression_level = atoi(optarg); break; case 'h': /* Usage display */ usage(basename(*argv)); return 0; case 'n': parse_mode = MODE_NAME; sort_name = "queryname"; break; case 'p': /* Paired reads */ paired = 1; break; case 'q': /* Quality threshold */ threshold = atoi(optarg); break; default: usage(basename(*argv)); return 1; } } if (argc - optind != 2) { usage(basename(*argv)); return 1; } file_name = argv[optind]; output_dir = argv[optind+1]; /* Check arguments */ res = access(file_name, F_OK|R_OK); if (res == -1) err(1, "%s", file_name); res = access(output_dir, F_OK|W_OK); if (res == -1) err(1, "%s", output_dir); /* MPI inits */ res = MPI_Init(&argc, &argv); assert(res == MPI_SUCCESS); res = MPI_Comm_rank(MPI_COMM_WORLD, &rank); assert(res == MPI_SUCCESS); res = MPI_Comm_size(MPI_COMM_WORLD, &num_proc); assert(res == MPI_SUCCESS); g_rank = rank; g_size = num_proc; /* Small summary */ if (rank == 0) { fprintf(stderr, "Number of processes : %d\n", num_proc); fprintf(stderr, "Reads' quality threshold : %d\n", threshold); fprintf(stderr, "Compression Level is : %d\n", compression_level); fprintf(stderr, "SAM file to read : %s\n", file_name); fprintf(stderr, "Output directory : %s\n", output_dir); } /* Process input file */ fd = open(file_name, O_RDONLY, 0666); assert(fd != -1); assert(fstat(fd, &st) != -1); xbuf = mmap(NULL, (size_t)st.st_size, PROT_READ, MAP_FILE|MAP_PRIVATE, fd, 0); assert(xbuf != MAP_FAILED); /* Parse SAM header */ memset(chrNames, 0, sizeof(chrNames)); x = xbuf; nbchr = 0; while (*x == '@') { y = strchr(x, '\n'); z = x; x = y + 1; if (strncmp(z, "@SQ", 3) != 0) continue; /* Save reference names */ y = strstr(z, "SN:"); assert(y != NULL); z = y + 3; while (*z && !isspace((unsigned char)*z)) z++; chrNames[nbchr++] = strndup(y + 3, z - y - 3); assert(nbchr < MAXNBCHR - 2); } chrNames[nbchr++] = strdup(UNMAPPED); chrNames[nbchr++] = strdup(DISCORDANT); hsiz = x - xbuf; hbuf = strndup(xbuf, hsiz); if (rank == 0) { fprintf(stderr, "The size of the file is %zu bytes\n", (size_t)st.st_size); fprintf(stderr, "Header has %d+2 references\n", nbchr - 2); } asprintf(&header, "@HD\tVN:1.0\tSO:%s\n%s", sort_name, hbuf); free(hbuf); assert(munmap(xbuf, (size_t)st.st_size) != -1); assert(close(fd) != -1); //task FIRST FINE TUNING FINFO FOR READING OPERATIONS MPI_Info_create(&finfo); /* * In this part you shall adjust the striping factor and unit according * to the underlying filesystem. * Harmless for other file system. * */ MPI_Info_set(finfo,"striping_factor", STRIPING_FACTOR); MPI_Info_set(finfo,"striping_unit", STRIPING_UNIT); //2G striping MPI_Info_set(finfo,"ind_rd_buffer_size", STRIPING_UNIT); //2gb buffer MPI_Info_set(finfo,"romio_ds_read",DATA_SIEVING_READ); /* * for collective reading and writing * should be adapted too and tested according to the file system * Harmless for other file system. */ MPI_Info_set(finfo,"nb_proc", NB_PROC); MPI_Info_set(finfo,"cb_nodes", CB_NODES); MPI_Info_set(finfo,"cb_block_size", CB_BLOCK_SIZE); MPI_Info_set(finfo,"cb_buffer_size", CB_BUFFER_SIZE); //we open the input file ierr = MPI_File_open(MPI_COMM_WORLD, file_name, MPI_MODE_RDONLY , finfo, &mpi_filed); //assert(in != -1); if (ierr){ if (rank == 0) fprintf(stderr, "%s: Failed to open file in process 0 %s\n", argv[0], argv[1]); MPI_Abort(MPI_COMM_WORLD, errorcode); exit(2); } ierr = MPI_File_get_size(mpi_filed, &fileSize); assert(ierr == MPI_SUCCESS); input_file_size = (long long)fileSize; /* Get chunk offset and size */ fsiz = input_file_size; lsiz = fsiz / num_proc; loff = rank * lsiz; tic = MPI_Wtime(); headerSize = unmappedSize = discordantSize = strlen(header); //We place file offset of each process to the begining of one read's line size_t *goff =(size_t*)calloc((size_t)(num_proc+1), sizeof(size_t)); init_goff(mpi_filed,hsiz,input_file_size,num_proc,rank,goff); //We calculate the size to read for each process lsiz = goff[rank+1]-goff[rank]; //NOW WE WILL PARSE size_t j=0; size_t poffset = goff[rank]; //Current offset in file sam //nbchr because we add the discordant reads in the structure reads = (Read**)malloc((nbchr)*sizeof(Read));//We allocate a linked list of struct for each Chromosome (last chr = unmapped reads) readNumberByChr = (size_t*)malloc((nbchr)*sizeof(size_t));//Array with the number of reads found in each chromosome localReadNumberByChr = (size_t*)malloc((nbchr)*sizeof(size_t));//Array with the number of reads found in each chromosome Read ** anchor = (Read**)malloc((nbchr)*sizeof(Read));//Pointer on the first read of each chromosome //Init first read for(i = 0; i < (nbchr); i++){ reads[i] = malloc(sizeof(Read)); reads[i]->coord = 0; anchor[i] = reads[i]; readNumberByChr[i]=0; } toc = MPI_Wtime(); char *local_data_tmp = malloc(1024*1024); char *local_data =(char*)malloc(((goff[rank+1]-poffset)+1)*sizeof(char)); size_t size_tmp= goff[rank+1]-poffset; local_data[goff[rank+1]-poffset] = 0; char *q=local_data; //We read the file sam and parse while(poffset < goff[rank+1]){ size_t size_to_read = 0; if( (goff[rank+1]-poffset) < DEFAULT_INBUF_SIZE ){ size_to_read = goff[rank+1]-poffset; } else{ size_to_read = DEFAULT_INBUF_SIZE; } // we load the buffer //hold temporary size of SAM //due to limitation in MPI_File_read_at local_data_tmp =(char*)realloc(local_data_tmp, (size_to_read+1)*sizeof(char)); local_data_tmp[size_to_read]=0; // Original reading part is before 18/09/2015 MPI_File_read_at(mpi_filed, (MPI_Offset)poffset, local_data_tmp, size_to_read, MPI_CHAR, MPI_STATUS_IGNORE); size_t local_offset=0; assert(strlen(local_data_tmp) == size_to_read); //we look where is the last line read for updating next poffset size_t offset_last_line = size_to_read-1; size_t extra_char=0; while(local_data_tmp[offset_last_line] != '\n'){ offset_last_line -- ; extra_char++; } local_data_tmp[size_to_read - extra_char]=0; size_t local_data_tmp_sz = strlen(local_data_tmp); //If it s the last line of file, we place a last '\n' for the function tokenizer if(rank == num_proc-1 && ((poffset+size_to_read) == goff[num_proc])){ local_data_tmp[offset_last_line]='\n'; } //Now we parse Read in local_data parser_paired(local_data_tmp, rank, poffset, threshold, nbchr, &readNumberByChr, chrNames, &reads); //now we copy local_data_tmp in local_data char *p = local_data_tmp; int pos =0; while (*p && (pos < local_data_tmp_sz)) {*q=*p;p++;q++;pos++;} //we go to the next line poffset+=(offset_last_line+1); local_offset+=(offset_last_line+1); } assert(size_tmp == strlen(local_data)); fprintf(stderr, "%d (%.2lf)::::: *** FINISH PARSING FILE ***\n", rank, MPI_Wtime()-toc); if (local_data_tmp) free(local_data_tmp); malloc_trim(0); MPI_Barrier(MPI_COMM_WORLD); //We set attribute next of the last read and go back to first read of each chromosome for(i = 0; i < nbchr; i++){ reads[i]->next = NULL; reads[i] = anchor[i]; } free(anchor); //We count how many reads we found size_t nb_reads_total =0,nb_reads_global =0; for(j=0;j<nbchr;j++){ nb_reads_total+=readNumberByChr[j]; } MPI_Allreduce(&nb_reads_total, &nb_reads_global, 1, MPI_UNSIGNED_LONG, MPI_SUM, MPI_COMM_WORLD); /* * We care for unmapped and discordants reads */ int s = 0; for (s = 1; s < 3; s++){ MPI_File mpi_file_split_comm2; double time_count; size_t total_reads = 0; MPI_Allreduce(&readNumberByChr[nbchr-s], &total_reads , 1, MPI_LONG_LONG_INT, MPI_SUM, MPI_COMM_WORLD); if ((rank == 0) && (s == 1)) fprintf(stderr, "rank %d :::: total read to sort for unmapped = %zu \n", rank, total_reads); if ((rank == 0) && (s == 2)) fprintf(stderr, "rank %d :::: total read to sort for discordant = %zu \n", rank, total_reads); MPI_Barrier(MPI_COMM_WORLD); if (total_reads == 0){ // nothing to sort for unmapped // maybe write an empty bam file } else{ int i1,i2; size_t *localReadsNum_rank0 = (size_t *)malloc(num_proc*sizeof(size_t)); localReadsNum_rank0[0] = 0; int file_pointer_to_free = 0; int split_comm_to_free = 0; //we build a vector with rank job int val_tmp1 = 0; int val_tmp2 = 0; int chosen_rank = 0; // the color tells in what communicator the rank pertain // color = 0 will be the new communicator color // otherwise the color is 1 int *color_vec_to_send = (int *)malloc(num_proc*sizeof(int)); // the key value tell the order in the new communicator int *key_vec_to_send = (int *)malloc(num_proc*sizeof(int)); //rank 0 gather the vector MPI_Allgather(&readNumberByChr[nbchr-s] , 1, MPI_LONG_LONG_INT, localReadsNum_rank0 , 1, MPI_LONG_LONG_INT, MPI_COMM_WORLD); MPI_Barrier(MPI_COMM_WORLD); if (rank == 0){ //we must chose the first rank with reads to sort i1=0; while (localReadsNum_rank0[i1] == 0){ chosen_rank++; i1++; } } //we broadcast the chosen rank //task: replace the broadcast with a sendrecieve MPI_Bcast( &chosen_rank, 1, MPI_INT, 0, MPI_COMM_WORLD); MPI_Barrier(MPI_COMM_WORLD); //we must chose which rank is going to split the communication if (((rank == chosen_rank) || rank == 0) && (chosen_rank != 0)){ //the rank 0 will recieve the key_vec_to_send and colorvec_to_send //first we exchange the size o if (rank == chosen_rank){ header=(char *)malloc((headerSize + 1)*sizeof(char)); MPI_Recv(header, headerSize + 1, MPI_CHAR, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); } if (rank == 0){ MPI_Send(header, headerSize + 1, MPI_CHAR, chosen_rank, 0, MPI_COMM_WORLD); } } else { //we do nothing here } if (rank == chosen_rank) { int counter = 0; //we compute the number of 0 in the localReadsNum_vec for(i1 = 0; i1 < num_proc; i1++){ if (localReadsNum_rank0[i1] == 0) { counter++; } } // if no jobs without reads we do nothing if ( counter == 0 ){ // nothing to do we associate split_comm with split_comm = MPI_COMM_WORLD; for (i2 = 0; i2 < num_proc; i2++) { if (localReadsNum_rank0[i2] == 0) { color_vec_to_send[i2] = 1; key_vec_to_send[i2] = val_tmp2; val_tmp2++; } else { color_vec_to_send[i2] = 0; key_vec_to_send[i2] = val_tmp1; val_tmp1++; } } } else{ // now we compute the color according to // the number of reads to sort for(i2 = 0; i2 < num_proc; i2++){ if (localReadsNum_rank0[i2] == 0){ color_vec_to_send[i2] = 1; key_vec_to_send[i2] = val_tmp2; val_tmp2++; } else{ color_vec_to_send[i2] = 0; key_vec_to_send[i2] = val_tmp1; val_tmp1++; } } // end for loop }// end if }// end if (rank == chosen_rank) MPI_Barrier(MPI_COMM_WORLD); // we scatter the key and color vector // we create key and color variable for each job int local_color = 0; int local_key = 0; // we scatter the color and key MPI_Scatter( color_vec_to_send, 1, MPI_INT, &local_color, 1, MPI_INT, chosen_rank, MPI_COMM_WORLD); MPI_Scatter( key_vec_to_send, 1, MPI_INT, &local_key, 1, MPI_INT, chosen_rank, MPI_COMM_WORLD); // we create a communicator // we group all communicator // with color of zero if (local_color == 0){ MPI_Comm_split( MPI_COMM_WORLD, local_color, local_key, &split_comm); ierr = MPI_File_open(split_comm, file_name, MPI_MODE_RDONLY , finfo, &mpi_file_split_comm2); //we ask to liberate file pointer file_pointer_to_free = 1; //we ask to liberate the split_comm split_comm_to_free = 1; } else{ MPI_Comm_split( MPI_COMM_WORLD, MPI_UNDEFINED, local_key, &split_comm); mpi_file_split_comm2 = mpi_filed; } //now we change the rank in the reads structure if (local_color == 0){ MPI_Comm_rank(split_comm, &split_rank); MPI_Comm_size(split_comm, &split_size); g_rank = split_rank; g_size = split_size; reads[nbchr-s] = reads[nbchr-s]->next; localReadNumberByChr[nbchr-s] = readNumberByChr[nbchr-s]; if (s == 2){ unmapped_start = startOffset(g_rank, g_size, unmappedSize, headerSize, nbchr-s, localReadNumberByChr[nbchr-s], split_comm ); if(!unmapped_start){ fprintf(stderr, "No header was defined for unmapped. \n Shutting down.\n"); MPI_Finalize(); return 0; } time_count = MPI_Wtime(); writeSam_discordant_and_unmapped( split_rank, output_dir, header, localReadNumberByChr[nbchr-s], chrNames[nbchr-s], reads[nbchr-s], split_size, split_comm, file_name, mpi_file_split_comm2, finfo, compression_level, local_data, goff[rank], write_sam); if (split_rank == chosen_rank){ fprintf(stderr, "rank %d :::::[MPISORT] Time to write chromosom %s , %f seconds \n\n\n", split_rank, chrNames[nbchr-s], MPI_Wtime() - time_count); } } else{ discordant_start = startOffset(g_rank, g_size, discordantSize, headerSize, nbchr-s, localReadNumberByChr[nbchr-s], split_comm); if(!discordant_start){ fprintf(stderr, "No header was defined for discordant.\n Shutting down.\n"); MPI_Finalize(); return 0; } time_count = MPI_Wtime(); writeSam_discordant_and_unmapped( g_rank, output_dir, header, localReadNumberByChr[nbchr-s], chrNames[nbchr-s], reads[nbchr-s], g_size, split_comm, file_name, mpi_file_split_comm2, finfo, compression_level, local_data, goff[rank], write_sam ); if (split_rank == chosen_rank){ fprintf(stderr, "rank %d :::::[MPISORT] Time to write chromosom %s , %f seconds \n\n\n", split_rank, chrNames[nbchr-s], MPI_Wtime() - time_count); } } while( reads[nbchr-s]->next != NULL){ Read *tmp_chr = reads[nbchr-s]; reads[nbchr-s] = reads[nbchr-s]->next; free(tmp_chr); } free(localReadsNum_rank0); } else{ // we do nothing } //we put a barrier before freeing pointers MPI_Barrier(MPI_COMM_WORLD); //we free the file pointer if (file_pointer_to_free) MPI_File_close(&mpi_file_split_comm2); //we free the split_comm if (split_comm_to_free) MPI_Comm_free(&split_comm); split_comm_to_free = 0; file_pointer_to_free = 0; free(color_vec_to_send); free(key_vec_to_send); } } //end for (s=1; s < 3; s++){ /* * We write the mapped reads in a file named chrX.bam * We loop by chromosoms. */ MPI_Barrier(MPI_COMM_WORLD); for(i = 0; i < (nbchr-2); i++){ /* * First Part of the algorithm * * In this part we elected a rank which is the first rank * to have reads to sort. * * Once elected a rank, we plit the communicator according to * wether the rank has reads to sort for this chromosom. * * The new communicator is COMM_WORLD. * * If all jobs have reads to sort no need to split the communicator and then * COMM_WORLD = MPI_COMM_WORLD * */ int i1,i2; size_t localReadsNum_rank0[num_proc]; localReadsNum_rank0[0]=0; int file_pointer_to_free = 0; int split_comm_to_free = 0; //we build a vector with rank job int val_tmp1 = 0; int val_tmp2 = 0; int chosen_rank = 0; //needed to tell what rank is going to compute the color and key int chosen_split_rank= 0; //the rank that collect data once the communication splitted normally this rank is 0 // the color tells in what communicator the rank pertain // color = 0 will be the new communicator color // otherwise the color is 1 // the key value tell the order in the new communicator int *color_vec_to_send = malloc(num_proc * sizeof(int)); int *key_vec_to_send = malloc(num_proc * sizeof(int)); // first we test if the there's reads to sort // rank 0 recieve the sum of all the reads count size_t total_reads_by_chr = 0; MPI_Allreduce(&readNumberByChr[i], &total_reads_by_chr, 1, MPI_LONG_LONG_INT, MPI_SUM, MPI_COMM_WORLD); //fprintf(stderr, "rank %d :::: readNumberByChr[i] = %zu \n", rank, readNumberByChr[i]); //fprintf(stderr, "rank %d :::: total_reads_by_chr = %zu \n", rank, total_reads_by_chr); if (total_reads_by_chr == 0) continue; //pass to next chromosome //rank 0 gather the vector MPI_Allgather(&readNumberByChr[i] , 1, MPI_LONG_LONG_INT, localReadsNum_rank0 , 1, MPI_LONG_LONG_INT, MPI_COMM_WORLD); if (rank == 0){ //the rank 0 chose the first rank with reads to sort i1=0; while ((localReadsNum_rank0[i1] == 0) && (i1 < num_proc)){ chosen_rank++; i1++; } fprintf(stderr, "rank %d :::: Elected rank = %d \n", rank, chosen_rank); } //we broadcast the chosen rank //task: replace the broadcast with a sendrecieve MPI_Bcast( &chosen_rank, 1, MPI_INT, 0, MPI_COMM_WORLD); MPI_Barrier(MPI_COMM_WORLD); if (((rank == chosen_rank) || rank == 0) && (chosen_rank != 0)){ //first we exchange the size o if (rank == chosen_rank){ header = malloc((headerSize + 1)*sizeof(char)); header[headerSize] = '\0'; MPI_Recv(header, headerSize + 1, MPI_CHAR, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); } if (rank == 0){ MPI_Send(header, headerSize + 1, MPI_CHAR, chosen_rank, 0, MPI_COMM_WORLD); } } else { //we do nothing here } MPI_Barrier(MPI_COMM_WORLD); if (rank == chosen_rank) { int counter = 0; //we compute the number of 0 in the localReadsNum_vec for(i1 = 0; i1 < num_proc; i1++){ if (localReadsNum_rank0[i1] == 0) { counter++; } } // if no jobs without reads we do nothing if ( counter == 0 ){ // nothing to do we associate split_comm with fprintf(stderr, "rank %d ::::[MPISORT] we don't split the rank \n", rank); split_comm = MPI_COMM_WORLD; for (i2 = 0; i2 < num_proc; i2++) { if (localReadsNum_rank0[i2] == 0) { color_vec_to_send[i2] = 1; key_vec_to_send[i2] = val_tmp2; val_tmp2++; } else { color_vec_to_send[i2] = 0; key_vec_to_send[i2] = val_tmp1; val_tmp1++; } } } else{ // now we compute the color according to // the number of reads to sort fprintf(stderr, "rank %d ::::[MPISORT] we split the rank \n", rank); for(i2 = 0; i2 < num_proc; i2++){ if (localReadsNum_rank0[i2] == 0){ color_vec_to_send[i2] = 1; key_vec_to_send[i2] = val_tmp2; val_tmp2++; } else{ color_vec_to_send[i2] = 0; key_vec_to_send[i2] = val_tmp1; val_tmp1++; } } // end for loop }// end if }// end if (rank == plit_rank) MPI_Barrier(MPI_COMM_WORLD); //we create key and color variable for each job int local_color = 0; int local_key = 0; // rank 0 scatter the color and the key vector MPI_Scatter( color_vec_to_send, 1, MPI_INT, &local_color, 1, MPI_INT, chosen_rank, MPI_COMM_WORLD); MPI_Scatter( key_vec_to_send, 1, MPI_INT, &local_key, 1, MPI_INT, chosen_rank, MPI_COMM_WORLD); MPI_Barrier(MPI_COMM_WORLD); // now we create a communicator // we group all communicator // with color of zero if (local_color == 0){ MPI_Comm_split( MPI_COMM_WORLD, local_color, local_key, &split_comm); ierr = MPI_File_open(split_comm, file_name, MPI_MODE_RDONLY, finfo, &mpi_file_split_comm); //we ask to liberate file pointer file_pointer_to_free = 1; //we ask to liberate the split_comm split_comm_to_free = 1; } else{ MPI_Comm_split( MPI_COMM_WORLD, MPI_UNDEFINED, local_key, &split_comm); mpi_file_split_comm = mpi_filed; } //now we change the rank in the reads structure if (local_color == 0){ MPI_Comm_rank(split_comm, &split_rank); MPI_Comm_size(split_comm, &split_size); //we update g_rank g_rank = split_rank; g_size = split_size; } else{ g_rank = split_rank; g_size = split_size = num_proc; } localReadNumberByChr[i] = readNumberByChr[i]; MPI_Barrier(MPI_COMM_WORLD); if ((local_color == 0) && (i < (nbchr - 2))) { /* * Second part of the algorithm * * First we load coordinates, offset sources, and read size in vector * * Then we sort the coordinates of the reads * with a bitonic sorter * * Then according to the reads coordinates we reoder the offset sources, and size * this is done thanks to the index of the sorting. * * Afterward we compute the offsets of the reads in * the destination file. * * Finally we dispatch the information to all ranks * in the communicator for the next step. */ //we do a local merge sort if(reads[i] && reads[i]->next && reads[i]->next->next){ mergeSort(reads[i], readNumberByChr[i]); } size_t local_readNum = localReadNumberByChr[i]; reads[i] = reads[i]->next; //first we compute the dimension of the parabitonic sort // dimension is the number of processors where we // perform the bitonic sort // int dimensions = (int)(log2(num_processes)); // find next ( must be greater) power, and go one back int dimensions = 1; while (dimensions <= split_size) dimensions <<= 1; dimensions >>= 1; // we get the maximum number of reads among // all the workers /* * Here we split the programm in 2 cases * * 1) The first case de split_size is a power of 2 (the best case) * this case is the simpliest we don't have extra communication to dispatch the read * envenly between the jobs * * 2) The split_size is not a power of 2 (the worst case) * well in this case we shall dispatch the jobs between jobs evenly. * */ if (split_rank == chosen_split_rank){ fprintf(stderr, "Rank %d :::::[MPISORT] Dimensions for bitonic = %d \n", split_rank, dimensions); fprintf(stderr, "Rank %d :::::[MPISORT] Split size = %d \n", split_rank, split_size); } //we test the computed dimension if (dimensions == split_size ){ size_t max_num_read = 0; MPI_Allreduce(&localReadNumberByChr[i], &max_num_read, 1, MPI_LONG_LONG_INT, MPI_MAX, split_comm); // if the dimension == split_size MPI_Barrier(split_comm); size_t first_local_readNum = local_readNum; /* * Vector creation and allocation fprintf(stderr, "split rank %d :::::[MPISORT] max_num_read = %zu \n", split_rank, max_num_read); */ local_readNum = max_num_read; time_count = MPI_Wtime(); size_t *local_reads_coordinates_unsorted = calloc(local_readNum, sizeof(size_t)); size_t *local_reads_coordinates_sorted = calloc(local_readNum, sizeof(size_t)); size_t *local_offset_source_unsorted = calloc(local_readNum, sizeof(size_t)); size_t *local_offset_source_sorted = calloc(local_readNum, sizeof(size_t)); int *local_dest_rank_sorted = calloc(local_readNum, sizeof(int)); int *local_reads_sizes_unsorted = calloc(local_readNum, sizeof(int)); int *local_reads_sizes_sorted = calloc(local_readNum, sizeof(int)); int *local_source_rank_unsorted = calloc(local_readNum, sizeof(int)); int *local_source_rank_sorted = calloc(local_readNum, sizeof(int)); if (split_rank == chosen_split_rank) fprintf(stderr, "rank %d :::::[MPISORT][MALLOC 1] time spent = %f s\n", split_rank, MPI_Wtime() - time_count); local_reads_coordinates_unsorted[0] = 0; local_reads_coordinates_sorted[0] = 0; local_dest_rank_sorted[0] = 0; local_reads_sizes_unsorted[0] = 0; local_reads_sizes_sorted[0] = 0; local_source_rank_unsorted[0] = 0; local_source_rank_sorted[0] = 0; local_offset_source_unsorted[0] = 0; local_offset_source_sorted[0] = 0; //those vectors are the same that local_..._sorted but without zero padding size_t *local_reads_coordinates_sorted_trimmed = NULL; int *local_dest_rank_sorted_trimmed = NULL; int *local_reads_sizes_sorted_trimmed = NULL; size_t *local_offset_source_sorted_trimmed = NULL; size_t *local_offset_dest_sorted_trimmed = NULL; int *local_source_rank_sorted_trimmed = NULL; //vectors used in the bruck just after the parabitonic sort size_t *local_reads_coordinates_sorted_trimmed_for_bruck = NULL; int *local_dest_rank_sorted_trimmed_for_bruck = NULL; int *local_reads_sizes_sorted_trimmed_for_bruck = NULL; size_t *local_offset_source_sorted_trimmed_for_bruck = NULL; size_t *local_offset_dest_sorted_trimmed_for_bruck = NULL; int *local_source_rank_sorted_trimmed_for_bruck = NULL; //task Init offset and size for source - free chr // from mpiSort_utils.c get_coordinates_and_offset_source_and_size_and_free_reads( split_rank, local_source_rank_unsorted, local_reads_coordinates_unsorted, local_offset_source_unsorted, local_reads_sizes_unsorted, reads[i], first_local_readNum ); //init indices for qksort size_t *coord_index = (size_t*)malloc(local_readNum*sizeof(size_t)); for(j = 0; j < local_readNum; j++){ coord_index[j] = j; } //To start we sort locally the reads coordinates. //this is to facilitate the bitonic sorting //if the local coordinates to sort are to big we could get rid of //this step. time_count = MPI_Wtime(); base_arr2 = local_reads_coordinates_unsorted; qksort(coord_index, local_readNum, sizeof(size_t), 0, local_readNum - 1, compare_size_t); if (split_rank == chosen_split_rank) fprintf(stderr, "rank %d :::::[MPISORT][LOCAL SORT] time spent = %f s\n", split_rank, MPI_Wtime() - time_count); //We index data for(j = 0; j < local_readNum; j++){ local_reads_coordinates_sorted[j] = local_reads_coordinates_unsorted[coord_index[j]]; local_source_rank_sorted[j] = local_source_rank_unsorted[coord_index[j]]; local_reads_sizes_sorted[j] = local_reads_sizes_unsorted[coord_index[j]]; local_offset_source_sorted[j] = local_offset_source_unsorted[coord_index[j]]; local_dest_rank_sorted[j] = rank; //will be updated after sorting the coordinates } /* * FOR DEBUG * for(j = 0; j < local_readNum - 1; j++){ assert( local_reads_coordinates_sorted[j] < local_reads_coordinates_sorted[j+1]); } */ free(coord_index); //ok free(local_source_rank_unsorted); //ok free(local_reads_coordinates_unsorted); //ok free(local_reads_sizes_unsorted); //ok free(local_offset_source_unsorted); //ok // we need the total number of reads. size_t total_num_read = 0; MPI_Allreduce(&localReadNumberByChr[i], &total_num_read, 1, MPI_LONG_LONG_INT, MPI_SUM, split_comm); /* * * In this section the number of bitonic dimension * is equal to the split size. * * In this case there are less communication in preparation * of the sorting. * * We use the parabitonic version 2. */ //we calll the bitonic time_count = MPI_Wtime(); ParallelBitonicSort2( split_comm, split_rank, dimensions, local_reads_coordinates_sorted, local_reads_sizes_sorted, local_source_rank_sorted, local_offset_source_sorted, local_dest_rank_sorted, max_num_read ); if (split_rank == chosen_split_rank) fprintf(stderr, "rank %d :::::[MPISORT][BITONIC 2] time spent = %f s\n", split_rank, MPI_Wtime() - time_count); size_t k1; size_t tmp2 = 0; for (k1 = 1; k1 < max_num_read; k1++){ assert(local_reads_coordinates_sorted[k1-1] <= local_reads_coordinates_sorted[k1]); local_dest_rank_sorted[k1]= split_rank; } /* for (k1 = 0; k1 < max_num_read; k1++){ fprintf(stderr, "rank %d :::::[MPISORT][BITONIC 2] local_reads_coordinates_sorted[%zu]= %zu s\n", split_rank, k1, local_reads_coordinates_sorted[k1]); fprintf(stderr, "rank %d :::::[MPISORT][BITONIC 2] local_source_rank_sorted[%zu]= %d s\n", split_rank, k1, local_source_rank_sorted[k1]); } */ size_t *local_offset_dest_sorted = malloc(max_num_read*sizeof(size_t)); size_t last_local_offset = 0; // We compute the local_dest_offsets_sorted size_t local_total_offset = 0; for (k1 = 0; k1 < max_num_read; k1++){ local_offset_dest_sorted[k1] = local_reads_sizes_sorted[k1]; local_total_offset += local_reads_sizes_sorted[k1]; } //we make the cumulative sum of all offsets for (k1 = 1; k1 < max_num_read; k1++){ local_offset_dest_sorted[k1] = local_offset_dest_sorted[k1 - 1] + local_offset_dest_sorted[k1]; } //we exchange the last destination offset last_local_offset = local_offset_dest_sorted[max_num_read-1]; //number of block to send int blocksize = 1; MPI_Offset *y = calloc(split_size, sizeof(MPI_Offset)); MPI_Offset *y2 = calloc(split_size + 1, sizeof(MPI_Offset)); //we wait all processors MPI_Gather(&last_local_offset, 1, MPI_LONG_LONG_INT, y, 1, MPI_LONG_LONG_INT, 0, split_comm); if (split_rank ==0){ for (k1 = 1; k1 < (split_size + 1); k1++) { y2[k1] = y[k1-1]; } } if (split_rank ==0){ for (k1 = 1; k1 < (split_size +1); k1++) { y2[k1] = y2[k1-1] + y2[k1]; } } size_t offset_to_add = 0; MPI_Scatter(y2, 1, MPI_LONG_LONG_INT, &offset_to_add, 1, MPI_LONG_LONG_INT, 0, split_comm); free(y); free(y2); //we add offset of the previous rank for (k1 = 0; k1 < max_num_read; k1++){ if (local_reads_sizes_sorted[k1] != 0) local_offset_dest_sorted[k1] += offset_to_add; else local_offset_dest_sorted[k1] = 0; } /* for (k1 = 0; k1 < max_num_read; k1++){ fprintf(stderr, "\n"); fprintf(stderr, "rank %d :::::[MPISORT][BITONIC 2] local_reads_coordinates_sorted[%zu]= %zu s\n", split_rank, k1, local_reads_coordinates_sorted[k1]); fprintf(stderr, "rank %d :::::[MPISORT][BITONIC 2] local_source_rank_sorted[%zu]= %d s\n", split_rank, k1, local_source_rank_sorted[k1]); fprintf(stderr, "rank %d :::::[MPISORT][BITONIC 2] local_offset_dest_sorted[%zu]= %d s\n", split_rank, k1, local_offset_dest_sorted[k1]); fprintf(stderr, "\n"); } */ /* * we update destination rank according to * original number of reads read. * */ //we compute the new rank dest according to max_num_read size_t previous_num_reads_per_job[dimensions]; //we create a vector of size split_size with previous reads per job MPI_Allgather(&first_local_readNum , 1, MPI_LONG_LONG_INT, previous_num_reads_per_job , 1, MPI_LONG_LONG_INT, split_comm); // we compute the position of of the read in the first // reference without the zero padding of bitonic size_t pos_ref0 = 0; //we need the number of zeros we add for the padding size_t N0 = max_num_read*dimensions - total_num_read; int new_rank = 0; int previous_rank = 0; // we compute the new rank for // the reads sorted by offset destination size_t h = 0; pos_ref0 = max_num_read*split_rank - N0; for(j = 0; j < max_num_read; j++) { if ( local_reads_sizes_sorted[j] != 0){ int new_rank = chosen_split_rank; pos_ref0 = (max_num_read*split_rank +j) - N0; if (pos_ref0 >= 0) { size_t tmp2 = 0; for (h = 0; h < dimensions; h++){ tmp2 += previous_num_reads_per_job[h]; if ( pos_ref0 < tmp2) { new_rank = h; break; } } previous_rank = local_dest_rank_sorted[j]; local_dest_rank_sorted[j] = new_rank; } } } MPI_Barrier(split_comm); size_t offset = 0; size_t numItems = 0; size_t num_read_for_bruck = 0; int *p = local_reads_sizes_sorted; if (p[0] != 0) {offset = 0;}; if (p[max_num_read -1] == 0){offset = max_num_read;} else {while ((*p == 0) && (offset < max_num_read )){ offset++; p++;}} /* * REMOVE ZERO PADDING BEFORE BRUCK * */ time_count = MPI_Wtime(); if (offset > 0){ // we remove zeros in the vector we have 2 cases // the first offset < max_num_read // and the entire vector is null if ( offset < max_num_read ){ numItems = max_num_read - offset; local_reads_coordinates_sorted_trimmed_for_bruck = malloc(numItems * sizeof(size_t)); local_offset_source_sorted_trimmed_for_bruck = malloc(numItems * sizeof(size_t)); local_offset_dest_sorted_trimmed_for_bruck = malloc(numItems * sizeof(size_t)); local_reads_sizes_sorted_trimmed_for_bruck = malloc(numItems * sizeof(int)); local_dest_rank_sorted_trimmed_for_bruck = malloc(numItems * sizeof(int)); local_source_rank_sorted_trimmed_for_bruck = malloc(numItems * sizeof(int)); size_t y=0; for (y = 0; y < numItems; y++){ local_reads_coordinates_sorted_trimmed_for_bruck[y] = local_reads_coordinates_sorted[y+offset]; local_offset_source_sorted_trimmed_for_bruck[y] = local_offset_source_sorted[y+offset]; local_offset_dest_sorted_trimmed_for_bruck[y] = local_offset_dest_sorted[y+offset]; local_reads_sizes_sorted_trimmed_for_bruck[y] = local_reads_sizes_sorted[y+offset]; local_dest_rank_sorted_trimmed_for_bruck[y] = local_dest_rank_sorted[y+offset]; local_source_rank_sorted_trimmed_for_bruck[y] = local_source_rank_sorted[y+offset]; } num_read_for_bruck = numItems; /* * * FOR DEBUG * for(y = 0; y < num_read_for_bruck; y++){ assert( local_reads_sizes_sorted_trimmed_for_bruck[y] != 0 ); assert( local_source_rank_sorted_trimmed_for_bruck[y] < dimensions); assert( local_dest_rank_sorted_trimmed_for_bruck[y] < dimensions); assert( local_offset_source_sorted_trimmed_for_bruck[y] != 0); assert( local_offset_dest_sorted_trimmed_for_bruck[y] != 0); assert( local_reads_coordinates_sorted_trimmed_for_bruck[y] != 0); } */ } else{ numItems = 0; local_reads_coordinates_sorted_trimmed_for_bruck = malloc(numItems * sizeof(size_t)); local_offset_source_sorted_trimmed_for_bruck = malloc(numItems * sizeof(size_t)); local_offset_dest_sorted_trimmed_for_bruck = malloc(numItems * sizeof(size_t)); local_reads_sizes_sorted_trimmed_for_bruck = malloc(numItems * sizeof(int)); local_dest_rank_sorted_trimmed_for_bruck = malloc(numItems * sizeof(int)); local_source_rank_sorted_trimmed_for_bruck = malloc(numItems * sizeof(int)); num_read_for_bruck = 0; } } else { numItems = local_readNum; local_reads_coordinates_sorted_trimmed_for_bruck = malloc(local_readNum * sizeof(size_t)); local_offset_source_sorted_trimmed_for_bruck = malloc(local_readNum * sizeof(size_t)); local_offset_dest_sorted_trimmed_for_bruck = malloc(local_readNum * sizeof(size_t)); local_reads_sizes_sorted_trimmed_for_bruck = malloc(local_readNum * sizeof(int)); local_dest_rank_sorted_trimmed_for_bruck = malloc(local_readNum * sizeof(int)); local_source_rank_sorted_trimmed_for_bruck = malloc(local_readNum * sizeof(int)); size_t y=0; for (y = 0; y < local_readNum; y++){ local_reads_coordinates_sorted_trimmed_for_bruck[y] = local_reads_coordinates_sorted[y]; local_offset_source_sorted_trimmed_for_bruck[y] = local_offset_source_sorted[y]; local_offset_dest_sorted_trimmed_for_bruck[y] = local_offset_dest_sorted[y]; local_reads_sizes_sorted_trimmed_for_bruck[y] = local_reads_sizes_sorted[y]; local_dest_rank_sorted_trimmed_for_bruck[y] = local_dest_rank_sorted[y]; local_source_rank_sorted_trimmed_for_bruck[y] = local_source_rank_sorted[y]; } num_read_for_bruck = numItems; /* * * FOR DEBUG * for(y = 0; y < num_read_for_bruck; y++){ assert( local_reads_sizes_sorted_trimmed_for_bruck[y] != 0 ); assert( local_source_rank_sorted_trimmed_for_bruck[y] < dimensions); assert( local_dest_rank_sorted_trimmed_for_bruck[y] < dimensions); assert( local_offset_source_sorted_trimmed_for_bruck[y] != 0); assert( local_offset_dest_sorted_trimmed_for_bruck[y] != 0); assert( local_reads_coordinates_sorted_trimmed_for_bruck[y] != 0); } */ } free(local_reads_coordinates_sorted); free(local_offset_source_sorted); free(local_offset_dest_sorted); free(local_reads_sizes_sorted); free(local_dest_rank_sorted); free(local_source_rank_sorted); if (split_rank == chosen_split_rank) fprintf(stderr, "rank %d :::::[MPISORT][TRIMMING] time spent = %f s\n", split_rank, MPI_Wtime() - time_count); /* * We do a Bruck on rank of origin reading */ size_t m=0; int num_proc = dimensions; size_t *number_of_reads_by_procs = calloc( dimensions, sizeof(size_t)); //fprintf(stderr, "rank %d :::::[MPISORT] num_read_for_bruck = %zu \n", split_rank, num_read_for_bruck); for(m = 0; m < num_read_for_bruck; m++){ //assert(new_pbs_orig_rank_off_phase1[m] < dimensions); //assert(new_pbs_dest_rank_phase1[m] < dimensions); number_of_reads_by_procs[local_source_rank_sorted_trimmed_for_bruck[m]]++; } int *local_source_rank_sorted_trimmed_for_bruckv2 = malloc( num_read_for_bruck * sizeof(int)); for(m = 0; m < num_read_for_bruck; m++){ local_source_rank_sorted_trimmed_for_bruckv2[m] = local_source_rank_sorted_trimmed_for_bruck[m]; } size_t count6 = 0; for(m = 0; m < dimensions; m++){ count6 += number_of_reads_by_procs[m]; } assert( count6 == num_read_for_bruck ); MPI_Barrier(split_comm); size_t **reads_coordinates = malloc(sizeof(size_t *) * dimensions); size_t **local_source_offsets = malloc(sizeof(size_t *) * dimensions); size_t **dest_offsets = malloc(sizeof(size_t *) * dimensions); int **read_size = malloc(sizeof(int *) * dimensions); int **dest_rank = malloc(sizeof(int *) * dimensions); int **source_rank = malloc(sizeof(int *) * dimensions); /* * We send in order * * local_offset_source_sorted_trimmed_for_bruck * local_dest_rank_sorted_trimmed_for_bruck * local_reads_coordinates_sorted_trimmed_for_bruck * local_reads_sizes_sorted_trimmed_for_bruck * */ COMM_WORLD = split_comm; time_count = MPI_Wtime(); bruckWrite3(split_rank, dimensions, count6, number_of_reads_by_procs, local_source_rank_sorted_trimmed_for_bruckv2, local_offset_source_sorted_trimmed_for_bruck, //offset sources &local_source_offsets, local_dest_rank_sorted_trimmed_for_bruck, //destination rank &dest_rank, local_reads_coordinates_sorted_trimmed_for_bruck, //reads coordinates &reads_coordinates, local_reads_sizes_sorted_trimmed_for_bruck, //read size &read_size, local_source_rank_sorted_trimmed_for_bruck, //source rank &source_rank, local_offset_dest_sorted_trimmed_for_bruck, &dest_offsets ); if (split_rank == chosen_split_rank) fprintf(stderr, "rank %d :::::[MPISORT][BRUCK 3] time spent = %f s\n", split_rank, MPI_Wtime() - time_count); time_count = MPI_Wtime(); free(local_reads_coordinates_sorted_trimmed_for_bruck); free(local_dest_rank_sorted_trimmed_for_bruck); free(local_reads_sizes_sorted_trimmed_for_bruck); free(local_offset_source_sorted_trimmed_for_bruck); free(local_offset_dest_sorted_trimmed_for_bruck); free(local_source_rank_sorted_trimmed_for_bruck); free(local_source_rank_sorted_trimmed_for_bruckv2); local_reads_coordinates_sorted_trimmed = malloc(first_local_readNum * sizeof(size_t)); local_offset_source_sorted_trimmed = malloc(first_local_readNum * sizeof(size_t)); local_offset_dest_sorted_trimmed = malloc(first_local_readNum * sizeof(size_t)); local_dest_rank_sorted_trimmed = malloc(first_local_readNum * sizeof(int)); local_source_rank_sorted_trimmed = malloc(first_local_readNum * sizeof(int)); local_reads_sizes_sorted_trimmed = malloc(first_local_readNum * sizeof(int)); if (split_rank == chosen_split_rank) fprintf(stderr, "rank %d :::::[MPISORT][FREE + MALLOC] time spent = %f s\n", split_rank, MPI_Wtime() - time_count); /* * GET DATA AFTER BRUCK * */ j=0; size_t k = 0; for(m = 0; m < num_proc; m++) { for(k = 0; k < number_of_reads_by_procs[m]; k++) { local_offset_dest_sorted_trimmed[k + j] = dest_offsets[m][k]; local_dest_rank_sorted_trimmed[k + j] = dest_rank[m][k]; local_reads_sizes_sorted_trimmed[k + j] = read_size[m][k]; local_offset_source_sorted_trimmed[k + j] = local_source_offsets[m][k]; local_reads_coordinates_sorted_trimmed[k + j] = reads_coordinates[m][k]; local_source_rank_sorted_trimmed[k + j] = source_rank[m][k]; } free(dest_offsets[m]); free(dest_rank[m]); free(read_size[m]); free(local_source_offsets[m]); free(reads_coordinates[m]); free(source_rank[m]); j += number_of_reads_by_procs[m]; } free(number_of_reads_by_procs); if (dest_rank != NULL) free(dest_rank); if (read_size != NULL) free(read_size); if (local_source_offsets != NULL) free(local_source_offsets); if (reads_coordinates != NULL) free(reads_coordinates); if (source_rank != NULL) free(source_rank); if (dest_offsets != NULL) free(dest_offsets); local_readNum = first_local_readNum; /* * * FOR DEBUG * for ( j = 0; j < local_readNum; j++){ assert ( local_reads_coordinates_sorted_trimmed[j] != 0 ); assert ( local_offset_source_sorted_trimmed[j] != 0 ); assert ( local_offset_dest_sorted_trimmed[j] != 0 ); assert ( local_reads_sizes_sorted_trimmed != 0 ); assert ( local_dest_rank_sorted_trimmed[j] < split_size ); assert ( local_source_rank_sorted_trimmed[j] < split_size ); } */ free(local_reads_coordinates_sorted_trimmed); if (split_rank == chosen_split_rank) fprintf(stderr, "rank %d :::::[MPISORT] we call write SAM \n", split_rank); malloc_trim(0); time_count = MPI_Wtime(); writeSam( split_rank, output_dir, header, local_readNum, total_reads_by_chr, chrNames[i], reads[i], split_size, split_comm, chosen_split_rank, file_name, mpi_file_split_comm, finfo, compression_level, local_offset_dest_sorted_trimmed, local_offset_source_sorted_trimmed, local_reads_sizes_sorted_trimmed, local_dest_rank_sorted_trimmed, local_source_rank_sorted_trimmed, local_data, goff[rank], first_local_readNum ); if (split_rank == chosen_split_rank){ fprintf(stderr, "rank %d :::::[MPISORT][WRITESAM] chromosom %s ::: %f seconds\n\n\n", split_rank, chrNames[i], MPI_Wtime() - time_count); } } else{ /* * We are in the case the number of cpu is * not a power of 2 * * */ parallel_sort_any_dim( dimensions, //dimension for parabitonic local_readNum, split_rank, split_size, reads, i, //chromosom number chosen_split_rank, split_comm, localReadNumberByChr, local_data, file_name, output_dir, finfo, compression_level, total_reads_by_chr, goff[rank], headerSize, header, chrNames[i], mpi_file_split_comm ); } //end if dimensions < split_rank } //if ((local_color == 0) && (i < (nbchr - 2))) //in the splitted dimension else{ //we do nothing here } //we put a barrier before freeing pointers MPI_Barrier(MPI_COMM_WORLD); //we free the file pointer if (file_pointer_to_free) MPI_File_close(&mpi_file_split_comm); //we free the split_comm if (split_comm_to_free){ MPI_Comm_free(&split_comm); } free(color_vec_to_send); free(key_vec_to_send); }// end loop upon chromosoms (line 665)
bool EFX::saveXML(QXmlStreamWriter *doc) { Q_ASSERT(doc != NULL); /* Function tag */ doc->writeStartElement(KXMLQLCFunction); /* Common attributes */ saveXMLCommon(doc); /* Fixtures */ QListIterator <EFXFixture*> it(m_fixtures); while (it.hasNext() == true) it.next()->saveXML(doc); /* Propagation mode */ doc->writeTextElement(KXMLQLCEFXPropagationMode, propagationModeToString(m_propagationMode)); /* Speeds */ saveXMLSpeed(doc); /* Direction */ saveXMLDirection(doc); /* Run order */ saveXMLRunOrder(doc); /* Algorithm */ doc->writeTextElement(KXMLQLCEFXAlgorithm, algorithmToString(algorithm())); /* Width */ doc->writeTextElement(KXMLQLCEFXWidth, QString::number(width())); /* Height */ doc->writeTextElement(KXMLQLCEFXHeight, QString::number(height())); /* Rotation */ doc->writeTextElement(KXMLQLCEFXRotation, QString::number(rotation())); /* StartOffset */ doc->writeTextElement(KXMLQLCEFXStartOffset, QString::number(startOffset())); /* IsRelative */ doc->writeTextElement(KXMLQLCEFXIsRelative, QString::number(isRelative() ? 1 : 0)); /******************************************** * X-Axis ********************************************/ doc->writeStartElement(KXMLQLCEFXAxis); doc->writeAttribute(KXMLQLCFunctionName, KXMLQLCEFXX); /* Offset */ doc->writeTextElement(KXMLQLCEFXOffset, QString::number(xOffset())); /* Frequency */ doc->writeTextElement(KXMLQLCEFXFrequency, QString::number(xFrequency())); /* Phase */ doc->writeTextElement(KXMLQLCEFXPhase, QString::number(xPhase())); /* End the (X) <Axis> tag */ doc->writeEndElement(); /******************************************** * Y-Axis ********************************************/ doc->writeStartElement(KXMLQLCEFXAxis); doc->writeAttribute(KXMLQLCFunctionName, KXMLQLCEFXY); /* Offset */ doc->writeTextElement(KXMLQLCEFXOffset, QString::number(yOffset())); /* Frequency */ doc->writeTextElement(KXMLQLCEFXFrequency, QString::number(yFrequency())); /* Phase */ doc->writeTextElement(KXMLQLCEFXPhase, QString::number(yPhase())); /* End the (Y) <Axis> tag */ doc->writeEndElement(); /* End the <Function> tag */ doc->writeEndElement(); return true; }