Beispiel #1
0
void PlotWidget::drawData( const ChartDataIndex &index, const ChartAxisIndex &axisSet ) 
{
    kDebug()<<index.number()<<index.userData;
    QVariantList data;
    int axisCount = model.axisCount( axisSet );
    for ( int j = 0; j < axisCount; ++j ) {
        ChartAxisIndex axis = model.axisIndex( j, axisSet );
        if ( model.hasAxisChildren( axis ) ) {
            kDebug()<<"multiple axis";
        } else {
            data << model.data( index, axis );
        }
    }
    kDebug()<<data;
    Q_ASSERT( data.count() == 2 );
    QVariantList x = data[0].toList();
    QVariantList y = data[1].toList();
    QVariant color = model.data( index, Qt::ForegroundRole );
    KPlotObject *kpo = new KPlotObject( color.value<QColor>(), KPlotObject::Lines );
    for (int i = 0; i < y.count(); ++i ) {
        kDebug()<<"Add point:"<<x[i].toInt() << y[i].toDouble();
        kpo->addPoint( x[i].toInt(), y[i].toDouble() );
        kpo->setShowLines(true);
    }
    addPlotObject( kpo );
}
Beispiel #2
0
void JMoonTool::initPlotObjects() {
    KPlotObject *orbit[4];
    KPlotObject *jpath;
    long double jd0 = ksw->data()->ut().djd();
    KSSun *ksun = (KSSun*)ksw->data()->skyComposite()->findByName( "Sun" );
    KSPlanet *jup = (KSPlanet*)ksw->data()->skyComposite()->findByName( i18n("Jupiter") );
    JupiterMoons jm;

    pw->removeAllPlotObjects();

    orbit[0] = new KPlotObject( colIo, KPlotObject::Lines, 1.0 );
    orbit[1] = new KPlotObject( colEu, KPlotObject::Lines, 1.0 );
    orbit[2] = new KPlotObject( colGn, KPlotObject::Lines, 1.0 );
    orbit[3] = new KPlotObject( colCa, KPlotObject::Lines, 1.0 );
    jpath    = new KPlotObject( colJp, KPlotObject::Lines, 1.0 );

    QRectF dataRect = pw->dataRect();
    double dy = 0.01*dataRect.height();

    //t is the offset from jd0, in days.
    for ( double t=dataRect.y(); t<=dataRect.bottom(); t+=dy ) {
        KSNumbers num( jd0 + t );
        jm.findPosition( &num, jup, ksun );

        //jm.x(i) tells the offset from Jupiter, in units of Jupiter's angular radius.
        //multiply by 0.5*jup->angSize() to get arcminutes
        for ( unsigned int i=0; i<4; ++i )
            orbit[i]->addPoint( 0.5*jup->angSize()*jm.x(i), t );

        jpath->addPoint( 0.0, t );
    }

    for ( unsigned int i=0; i<4; ++i )
        pw->addPlotObject( orbit[i] );

    pw->addPlotObject( jpath );
}
Beispiel #3
0
void JMoonTool::initPlotObjects() {
	KPlotObject *orbit[4];
	KPlotObject *jpath;
	long double jd0 = ksw->data()->ut().djd();
	KSSun *ksun = (KSSun*)ksw->data()->PCat->findByName( "Sun" );
	KSPlanet *jup = (KSPlanet*)ksw->data()->PCat->findByName( "Jupiter" );
	JupiterMoons jm;
	
	if ( pw->objectCount() ) pw->clearObjectList();
	
	orbit[0] = new KPlotObject( "io", colIo, KPlotObject::CURVE, 1, KPlotObject::SOLID );
	orbit[1] = new KPlotObject( "europa", colEu, KPlotObject::CURVE, 1, KPlotObject::SOLID );
	orbit[2] = new KPlotObject( "ganymede", colGn, KPlotObject::CURVE, 1, KPlotObject::SOLID );
	orbit[3] = new KPlotObject( "callisto", colCa, KPlotObject::CURVE, 1, KPlotObject::SOLID );
	jpath    = new KPlotObject( "jupiter", colJp, KPlotObject::CURVE, 1, KPlotObject::SOLID );
	
	double dy = 0.01*pw->dataHeight();
	
	//t is the offset from jd0, in hours.
	for ( double t=pw->y(); t<=pw->y2(); t+=dy ) {
		KSNumbers num( jd0 + t/24.0 );
		jm.findPosition( &num, jup, ksun );
		
		//jm.x(i) tells the offset from Jupiter, in units of Jupiter's angular radius.
		//multiply by 0.5*jup->angSize() to get arcminutes
		for ( unsigned int i=0; i<4; ++i ) 
			orbit[i]->addPoint( new DPoint( 0.5*jup->angSize()*jm.x(i), t ) );
		
		jpath->addPoint( new DPoint( 0.0, t ) );
	}

	for ( unsigned int i=0; i<4; ++i ) 
		pw->addObject( orbit[i] );

	pw->addObject( jpath );
}
Beispiel #4
0
void KTouchStatistics::updateChartTab() {
	// remove all current chart objects
	chartWidget->clearObjectList();
	// if no lecture data is available, return
	if (m_allStats.m_lectureStats.count()==0 || m_lectureIndex >= m_allStats.m_lectureStats.count())  return;
	// what kind of chart is required?
	if (levelsRadio->isChecked()) {
		// TODO : nothing yet
	}
	else {
		// find correct lecture index
		QMapConstIterator<KURL, KTouchLectureStats> it = m_allStats.m_lectureStats.begin();	
		int index = m_lectureIndex;
		while (index-- > 0) ++it;
		std::vector< std::pair<double, double> > data;
		QString caption = "Session data";
		switch (buttonGroup2->selectedId()) {
			case 0 : // words per minute
				// loop over all session data entries in *it and store words per minute data
				for (QValueVector<KTouchSessionStats>::const_iterator session_it = (*it).m_sessionStats.begin();
					session_it != (*it).m_sessionStats.end(); ++session_it)
				{
					double t = (*session_it).m_elapsedTime;
					double wpm = (t == 0) ? 0 : (*session_it).m_words/t*60.0;
					double tp = (*session_it).m_timeRecorded.toTime_t()/(3600.0*24);
					data.push_back(std::make_pair(tp, wpm) );
				}
				// add current session if selected lecture matches
				if (m_currentIndex == m_lectureIndex && 
					m_currSessionStats.m_elapsedTime != 0) 
				{
					double t = m_currSessionStats.m_elapsedTime;
					double wpm = m_currSessionStats.m_words/t*60.0;
					double tp = QDateTime::currentDateTime().toTime_t()/(3600.0*24);
					data.push_back(std::make_pair(tp, wpm) );
				}
				chartWidget->LeftAxis.setLabel( i18n("Words per minute") );
				chartWidget->LeftAxis.setLabelFormat(0, 'f', 0);
				break;


			case 1 : // chars per minute
				// loop over all session data entries in *it and store chars per minute data
				for (QValueVector<KTouchSessionStats>::const_iterator session_it = (*it).m_sessionStats.begin();
					session_it != (*it).m_sessionStats.end(); ++session_it)
				{
					double t = (*session_it).m_elapsedTime;
					double cpm = (t == 0) ? 0 : (*session_it).m_correctChars/t*60.0;
					double tp = (*session_it).m_timeRecorded.toTime_t()/(3600.0*24);
					data.push_back(std::make_pair(tp, cpm) );
				}
				// add current session
				if (m_currentIndex == m_lectureIndex && 
					m_currSessionStats.m_elapsedTime != 0) 
				{
					double t = m_currSessionStats.m_elapsedTime;
					double cpm = m_currSessionStats.m_correctChars/t*60.0;
					double tp = QDateTime::currentDateTime().toTime_t()/(3600.0*24);
					data.push_back(std::make_pair(tp, cpm) );
				}
				chartWidget->LeftAxis.setLabel( i18n("Characters per minute") );
				chartWidget->LeftAxis.setLabelFormat(0, 'f', 0);
				break;


			case 2 : // correctness
				// loop over all session data entries in *it and store correctness data
				for (QValueVector<KTouchSessionStats>::const_iterator session_it = (*it).m_sessionStats.begin();
					session_it != (*it).m_sessionStats.end(); ++session_it)
				{
					double tc = (*session_it).m_totalChars;
					double corr = (tc == 0) ? 0 : (*session_it).m_correctChars/tc;
					double tp = (*session_it).m_timeRecorded.toTime_t()/(3600.0*24);
					data.push_back(std::make_pair(tp, corr) );
				}
				// add current session
				if (m_currentIndex == m_lectureIndex && 
					m_currSessionStats.m_totalChars != 0) 
				{
					double tc = m_currSessionStats.m_totalChars;
					double corr = m_currSessionStats.m_correctChars/tc;
					double tp = QDateTime::currentDateTime().toTime_t()/(3600.0*24);
					data.push_back(std::make_pair(tp, corr) );
				}
				chartWidget->LeftAxis.setLabel( i18n("Correctness") );
				chartWidget->LeftAxis.setLabelFormat(0, 'g', 1);
				break;


			case 3 : // skill
				// loop over all session data entries in *it and store correctness data
				for (QValueVector<KTouchSessionStats>::const_iterator session_it = (*it).m_sessionStats.begin();
					session_it != (*it).m_sessionStats.end(); ++session_it)
				{
					double tc = (*session_it).m_totalChars;
					double corr = (tc == 0) ? 0 : (*session_it).m_correctChars/tc;
					double t = (*session_it).m_elapsedTime;
					double cpm = (t == 0) ? 0 : (*session_it).m_correctChars/t*60.0;
					double skill = corr*cpm;
					double tp = (*session_it).m_timeRecorded.toTime_t()/(3600.0*24);
					data.push_back(std::make_pair(tp, skill) );
				}
				// add current session
				if (m_currentIndex == m_lectureIndex && 
					m_currSessionStats.m_totalChars != 0 && 
					m_currSessionStats.m_elapsedTime != 0)
				{
					double tc = m_currSessionStats.m_totalChars;
					double corr = m_currSessionStats.m_correctChars/tc;
					double t = m_currSessionStats.m_elapsedTime;
					double cpm = m_currSessionStats.m_correctChars/t*60.0;
					double skill = corr*cpm;
					double tp = QDateTime::currentDateTime().toTime_t()/(3600.0*24);
					data.push_back(std::make_pair(tp, skill) );
				}
				chartWidget->LeftAxis.setLabel( i18n("Skill") );
				chartWidget->LeftAxis.setLabelFormat(0, 'f', 0);
				break;
				
			default : return;
		}
		// Create plot object for session statistics
		KPlotObject * ob;
		if (data.size() <= 1) return;
		ob = new KPlotObject(caption, "red", KPlotObject::CURVE, 2, KPlotObject::SOLID);
		
		// Add some random points to the plot object
		double min_x = 1e20;
		double max_x = -1;
		double max_y = -1;
		for (unsigned int i=0; i<data.size(); ++i) {
			double x;
			if (timeRadio->isChecked()) {
				x = data[i].first - data[0].first;
				chartWidget->BottomAxis.setLabel( i18n( "Time since first practice session in days" ));
			}
			else {	
				x = i+1;
				chartWidget->BottomAxis.setLabel( i18n( "Sessions" ));
			}
			ob->addPoint( DPoint(x, data[i].second) );
			min_x = std::min(x, min_x);
			max_x = std::max(x, max_x);
			max_y = std::max(data[i].second, max_y);
		}
		if (max_y == 0)  max_y = 1;
		max_y *= 1.1;
		chartWidget->setLimits( min_x, max_x, -0.1*max_y, max_y );
//		kdDebug() << min_x << " " << max_x << "    " << max_y << endl;
		// Add plot object to chart
		chartWidget->addObject(ob);
	}
}
//Add custom top/bottom axes with tickmarks for each month
void modCalcEquinox::addDateAxes() {
    KPlotObject *poTopAxis = new KPlotObject( Qt::white, KPlotObject::Lines, 1 );
    poTopAxis->addPoint( 0.0, Plot->dataRect().bottom() ); //y-axis is reversed!
    poTopAxis->addPoint( 366.0, Plot->dataRect().bottom() );
    Plot->addPlotObject( poTopAxis );

    KPlotObject *poBottomAxis = new KPlotObject( Qt::white, KPlotObject::Lines, 1 );
    poBottomAxis->addPoint( 0.0, Plot->dataRect().top() + 0.02 );
    poBottomAxis->addPoint( 366.0, Plot->dataRect().top() + 0.02 );
    Plot->addPlotObject( poBottomAxis );

    //Tick mark for each month
    for ( int imonth=0; imonth<12; imonth++ ) {
        KPlotObject *poMonth = new KPlotObject( Qt::white, KPlotObject::Lines, 1 );
        poMonth->addPoint( dmonth(imonth), Plot->dataRect().top() );
        poMonth->addPoint( dmonth(imonth), Plot->dataRect().top() + 1.4 );
        Plot->addPlotObject( poMonth );
        poMonth = new KPlotObject( Qt::white, KPlotObject::Lines, 1 );
        poMonth->addPoint( dmonth(imonth), Plot->dataRect().bottom() );
        poMonth->addPoint( dmonth(imonth), Plot->dataRect().bottom() - 1.4 );
        Plot->addPlotObject( poMonth );
    }
}
void modCalcEquinox::slotCompute()
{
    KStarsData* data = KStarsData::Instance();
    KSSun Sun;
    int year0 = Year->value();

    KStarsDateTime dt( QDate(year0, 1, 1), QTime(0,0,0) );
    long double jd0 = dt.djd(); //save JD on Jan 1st
    for ( int imonth=0; imonth < 12; imonth++ ) {
        KStarsDateTime kdt( QDate(year0, imonth+1, 1), QTime(0,0,0) );
        DMonth[imonth] = kdt.djd() - jd0;
    }

    Plot->removeAllPlotObjects();

    //Add the celestial equator, just a single line bisecting the plot horizontally
    KPlotObject *ce = new KPlotObject( data->colorScheme()->colorNamed( "EqColor" ), KPlotObject::Lines, 2.0 );
    ce->addPoint( 0.0, 0.0 );
    ce->addPoint( 366.0, 0.0 );
    Plot->addPlotObject( ce );

    //Add Ecliptic.  This is more complicated than simply incrementing the
    //ecliptic longitude, because we want the x-axis to be time, not RA.
    //For each day in the year, compute the Sun's position.
    KPlotObject *ecl = new KPlotObject( data->colorScheme()->colorNamed( "EclColor" ), KPlotObject::Lines, 2 );
    ecl->setLinePen( QPen( ecl->pen().color(), 4 ) );

    Plot->setLimits( 1.0, double(dt.date().daysInYear()), -30.0, 30.0 );

    //Add top and bottom axis lines, and custom tickmarks at each month
    addDateAxes();

    for ( int i=1; i<=dt.date().daysInYear(); i++ ) {
        KSNumbers num( dt.djd() );
        Sun.findPosition( &num );
        ecl->addPoint( double(i), Sun.dec().Degrees() );

        dt = dt.addDays( 1 );
    }
    Plot->addPlotObject( ecl );

    dSpring = findEquinox( Year->value(), true, ecl );
    dSummer = findSolstice( Year->value(), true );
    dAutumn = findEquinox( Year->value(), false, ecl );
    dWinter = findSolstice( Year->value(), false );

    //Display the Date/Time of each event in the text fields
    VEquinox->setText( KGlobal::locale()->formatDateTime( dSpring, KLocale::LongDate ) );
    SSolstice->setText( KGlobal::locale()->formatDateTime( dSummer, KLocale::LongDate ) );
    AEquinox->setText( KGlobal::locale()->formatDateTime( dAutumn, KLocale::LongDate ) );
    WSolstice->setText( KGlobal::locale()->formatDateTime( dWinter, KLocale::LongDate ) );

    //Add vertical dotted lines at times of the equinoxes and solstices
    KPlotObject *poSpring = new KPlotObject( Qt::white, KPlotObject::Lines, 1 );
    poSpring->setLinePen( QPen( Qt::white, 1.0, Qt::DotLine ) );
    poSpring->addPoint( dSpring.djd()-jd0, Plot->dataRect().top() );
    poSpring->addPoint( dSpring.djd()-jd0, Plot->dataRect().bottom() );
    Plot->addPlotObject( poSpring );
    KPlotObject *poSummer = new KPlotObject( Qt::white, KPlotObject::Lines, 1 );
    poSummer->setLinePen( QPen( Qt::white, 1.0, Qt::DotLine ) );
    poSummer->addPoint( dSummer.djd()-jd0, Plot->dataRect().top() );
    poSummer->addPoint( dSummer.djd()-jd0, Plot->dataRect().bottom() );
    Plot->addPlotObject( poSummer );
    KPlotObject *poAutumn = new KPlotObject( Qt::white, KPlotObject::Lines, 1 );
    poAutumn->setLinePen( QPen( Qt::white, 1.0, Qt::DotLine ) );
    poAutumn->addPoint( dAutumn.djd()-jd0, Plot->dataRect().top() );
    poAutumn->addPoint( dAutumn.djd()-jd0, Plot->dataRect().bottom() );
    Plot->addPlotObject( poAutumn );
    KPlotObject *poWinter = new KPlotObject( Qt::white, KPlotObject::Lines, 1 );
    poWinter->setLinePen( QPen( Qt::white, 1.0, Qt::DotLine ) );
    poWinter->addPoint( dWinter.djd()-jd0, Plot->dataRect().top() );
    poWinter->addPoint( dWinter.djd()-jd0, Plot->dataRect().bottom() );
    Plot->addPlotObject( poWinter );
}
/*
    <name>Lines</name>
    <description>Lines from top to bottom</description>
    <author>Marco Gittler</author>
    <properties tag="lines" id="lines" />
    <parameter default="5" type="constant" value="5" min="0" name="num" max="255" >
      <name>Num</name>
    </parameter>
    <parameter default="4" type="constant" value="4" min="0" name="width" max="255" >
      <name>Width</name>
    </parameter>
  </effect>

*/
void ParameterPlotter::setPointLists(const QDomElement& d, const QString& paramName, int startframe, int endframe)
{

    //QListIterator <QPair <QString, QMap< int , QVariant > > > nameit(params);
    m_paramName = paramName;
    m_itemParameter = d;
    QDomNodeList namenode = d.elementsByTagName("parameter");

    m_max_y = 0;
    m_min_y = 0;
    removeAllPlotObjects();
    m_stretchFactors.clear();
    m_parameterNameList.clear();
    m_plotobjects.clear();

    QString dat;
    QTextStream stre(&dat);
    d.save(stre, 2);
    //qDebug() << dat;
    int i = 0;
    while (!namenode.item(i).isNull() && namenode.item(i).toElement().attribute("name") != m_paramName)
        ++i;

    if (namenode.count()) {
        QDomElement pa = namenode.item(i).toElement();
        //QDomNode na = pa.firstChildElement("name");

        m_parameterNameList << pa.attribute("namedesc").split(';');
        emit parameterList(m_parameterNameList);

        //max_y=pa.attributes().namedItem("max").nodeValue().toInt();
        //int val=pa.attributes().namedItem("value").nodeValue().toInt();
        QStringList defaults;
        if (pa.attribute("start").contains(';'))
            defaults = pa.attribute("start").split(';');
        else if (pa.attribute("value").contains(';'))
            defaults = pa.attribute("value").split(';');
        else if (pa.attribute("default").contains(';'))
            defaults = pa.attribute("default").split(';');
        QStringList maxv = pa.attribute("max").split(';');
        QStringList minv = pa.attribute("min").split(';');
        for (int i = 0; i < maxv.size() && i < minv.size(); ++i) {
            if (m_max_y < maxv[i].toInt()) m_max_y = maxv[i].toInt();
            if (m_min_y > minv[i].toInt()) m_min_y = minv[i].toInt();
        }
        for (int i = 0; i < m_parameterNameList.count(); ++i) {
            KPlotObject *plot = new KPlotObject(m_colors[m_plotobjects.size()%m_colors.size()]);
            plot->setShowLines(true);
            if (!m_stretchFactors.contains(i) && i < maxv.size()) {
                if (maxv[i].toInt() != 0)
                    m_stretchFactors[i] = m_max_y / maxv[i].toInt();
                else
                    m_stretchFactors[i] = 1.0;
            }
            if (i < defaults.size() && defaults[i].toDouble() > m_max_y)
                defaults[i] = m_max_y;
            int def = 0;
            if (i < defaults.size())
                def = (int)(defaults[i].toInt() * m_stretchFactors[i]);
            QString name = "";
            if (i < m_parameterNameList.size())
                name = m_parameterNameList[i];
            plot->addPoint(startframe, def, name);
            //add keyframes here
            plot->addPoint(endframe, def);

            m_plotobjects.append(plot);
        }

        /*TODO keyframes
        while (pointit.hasNext()){
         pointit.next();
         plot->addPoint(QPointF(pointit.key(),pointit.value().toDouble()),item.first,1);
         if (pointit.value().toInt() >maxy)
          max_y=pointit.value().toInt();
        }*/

    }
    setLimits(-1, endframe + 1, m_min_y - 10, m_max_y + 10);

    addPlotObjects(m_plotobjects);

}
Beispiel #8
0
void titrationCalculator::plot()
{
    width = int(xmax - xmin);
    //now I'm preparing the kplot widget
    uid.kplotwidget->removeAllPlotObjects();
    uid.kplotwidget->setLimits(xmin, xmax, ymin, ymax); //now I need to set the limits of the plot

    KPlotObject *kpor = new KPlotObject(Qt::red,KPlotObject::Lines);
    KPlotObject *kpog = new KPlotObject(Qt::green, KPlotObject::Lines);
    KPlotObject *kpob = new KPlotObject(Qt::blue, KPlotObject::Lines);
    redplot = "<polyline points=\"";
    greenplot = "<polyline points=\"";
    blueplot = "<polyline points=\"";

    if (!uid.tableWidget->item(0,0) || uid.tableWidget->item(0,0)->text().isEmpty()) {
        //go on
    } else {
        char yvalue[80];
        int tmpy = 0;
        for (int i = 0; i < uid.tableWidget->rowCount(); ++i) {
            if (!uid.tableWidget->item(i,0) || uid.tableWidget->item(i,0)->text().isEmpty()) {
                break;
            } else {
                if (uid.tableWidget->item(i,0)->data(Qt::DisplayRole).toString() == uid.yaxis->text()) {
                    QString yvalueq = uid.tableWidget->item(i,1)->data(Qt::DisplayRole).toString();
                    QByteArray ba = yvalueq.toLatin1();
                    char *yvaluen = ba.data();
                    strcpy(yvalue,yvaluen);
                    tmpy = 1;
                }
            }
        }
        QString mreporto;
        int iter = 0;
        if (uid.xaxis->text() == "" or uid.xaxis->text() == " ") {
            uid.xaxis->setText(i18n("nothing"));
        }
        if (tmpy == 0) {
            QMessageBox::critical(this,i18n("Error"),i18n("Unable to find an equation for Y-axis variable."));
        } else {
            //now we have to solve the system of equations NOTE:yvalue contains the equation of Y-axis variable
            //we iterates the process until you have an equation in one only unknown variable or a numeric expression
            mreporto = solve(yvalue);
            while (end == 0 or lettere == 1) {
                QByteArray ba = mreporto.toLatin1();
                char *tmreport = ba.data();
                ++iter;
                if (end == 1 or lettere == 0) {
                    break;
                }
                if (iter > 100) {
                    break; //preventing from an endless iteration
                }
                mreporto = solve(tmreport);
            }
        }
        //if (mreporto!="") uid.note->setText("Theoretical Curve: "+mreporto);
        if (!mreporto.isEmpty()) {
            uid.note->setText(i18n("Theoretical curve") + ": " + mreporto);
            for (int i = int(xmin); i < int(xmax); ++i) {
                double id = i;
                QScriptEngine myEngine;
                QByteArray ban = mreporto.toLatin1();
                char *tmreporto = ban.data();

                QString istr;
                istr.append(QString("%1").arg((id)));
                //now i'm using QScript language to solve the expression
                //in a future we can consider to change it supporting some backends, but it's really complex
                QString myscript = solvex(tmreporto,istr);
                QScriptValue three = myEngine.evaluate(myscript);

                double tvalue = three.toNumber();
                kpor->addPoint(id, tvalue);
                redplot = redplot
                          + ' '
                          + QString::number((id * 10) + 5).replace(QChar(','), QChar('.'))
                          + ','
                          + QString::number((ymax - tvalue) * 10).replace(QChar(','), QChar('.'));
            }
        }
        temponu = 0;
    } //here ends the equations mode

    //uid.tableWidget_2->sortItems(1, Qt::AscendingOrder); //seems that the sorting doesn't work correctly
    if (!uid.tableWidget_2->item(0, 0) || uid.tableWidget_2->item(0, 0)->text().isEmpty()) {
        //go on
    } else {
        //now we can plot the values
        double a, b, c, d, xval;
        QVarLengthArray<double, 64> px(uid.tableWidget_2->rowCount());
        QVarLengthArray<double, 64> py(uid.tableWidget_2->rowCount());
        int totaldata = 0;
        for (int i = 0; i < uid.tableWidget_2->rowCount(); ++i) {
            if (!uid.tableWidget_2->item(i,0) || uid.tableWidget_2->item(i, 0)->text().isEmpty()) {
                break;
            } else {
                ++totaldata;
                kpob->addPoint(uid.tableWidget_2->item(i,1)->data(Qt::DisplayRole).toDouble(), uid.tableWidget_2->item(i,0)->data(Qt::DisplayRole).toDouble());
                py[i] = uid.tableWidget_2->item(i,0)->data(Qt::DisplayRole).toDouble();
                px[i] = uid.tableWidget_2->item(i,1)->data(Qt::DisplayRole).toDouble();
                blueplot = blueplot
                           + ' '
                           + QString::number((uid.tableWidget_2->item(i,1)->data(Qt::DisplayRole).toDouble() * 10) + 5).replace(QChar(','), QChar('.'))
                           + ','
                           + QString::number((ymax-uid.tableWidget_2->item(i, 0)->data(Qt::DisplayRole).toDouble()) * 10).replace(QChar(','), QChar('.'));
            }
        }
        a = py[totaldata - 1] - py[0];
        b = 4 / (px[totaldata - 1] - px[0]);
        d = 0;
        if (a > 0) {
            d = py[0] + (a / 2);
        } else if (a < 0) {
            d = py[totaldata - 1] - (a / 2);
        }
        double cn = 0.0;
        int th = 0;
        for (int i = 1; i < (totaldata - 1); ++i) {
            //now i'm using the value of the points to fit the curve
            double ci = ((setttanh((py[i] - d) / a)) / b) - px[i];
            if ((ci * 0) == 0) {
                cn = cn + ci;
                ++th;
            }
        }
        //c = cn/(th); it doesn't wok, but i found out this little hack. The strange thing is that in the standalone application it works fine.
        c = cn / (th * 2);
        //THIS IS THE PLOT OF APPROXIMATED CURVE
        for (int i = int(xmin); i < (int(xmax)); ++i) {
            double id = i;
            xval = (a * tanh(b * (id + c))) + d;
            kpog->addPoint(id, xval);
            greenplot = greenplot
                        + ' '
                        + QString::number((id * 10) + 5).replace(QChar(','), QChar('.'))
                        + ','
                        + QString::number((ymax-xval) * 10).replace(QChar(','), QChar('.'));
        }
        //THIS IS THE EQUIVALENCE POINT (THE INFLECTION OF THE CURVE)
        QString es = QString::number(-c);
        QString as = QString::number(a);
        QString bs = QString::number(b);
        QString cs = QString::number(c);
        QString ds = QString::number(d);
        QString tempon = uid.note->toPlainText()+QChar('\n');
        if (temponu != 0) {
            tempon = "";
        }
        uid.note->setText(tempon
                          + '\n'
                          + i18n("Approximated curve")
                          + ": "
                          + as
                          + "*tanh("
                          + bs
                          + "*(x+"+cs+"))+"
                          + ds
                          +'\n'
                          + i18n("Equivalence point")
                          + ": "
                          + es);
    } //here ends the experimental values mode

    uid.kplotwidget->addPlotObject(kpor);
    uid.kplotwidget->addPlotObject(kpog);
    uid.kplotwidget->addPlotObject(kpob);

    redplot = redplot + "\" style=\"stroke:red;fill:none\"/> ";
    blueplot = blueplot + "\" style=\"stroke:blue;fill:none\"/> ";
    greenplot = greenplot + "\" style=\"stroke:green;fill:none\"/> ";

}
Beispiel #9
0
void Focus::autoFocusAbs(double currentHFR)
{
    static int initHFRPos=0, lastHFRPos=0, minHFRPos=0, initSlopePos=0, initPulseDuration=0, focusOutLimit=0, focusInLimit=0, minPos=1e6, maxPos=0;
    static double initHFR=0, minHFR=0, maxHFR=1,initSlopeHFR=0;
    double targetPulse=0, delta=0;

    QString deltaTxt = QString("%1").arg(fabs(currentHFR-minHFR)*100.0, 0,'g', 2);
    QString HFRText = QString("%1").arg(currentHFR, 0,'g', 3);

    //qDebug() << "Current HFR: " << currentHFR << " Current Position: " << pulseStep << endl;
    //qDebug() << "minHFR: " << minHFR << " MinHFR Pos: " << minHFRPos << endl;
    //qDebug() << "Delta: " << deltaTxt << endl;

    if (minHFR)
         appendLogText(i18n("FITS received. HFR %1 @ %2. Delta (%3%)", HFRText, pulseStep, deltaTxt));
    else
        appendLogText(i18n("FITS received. HFR %1 @ %2.", HFRText, pulseStep));

    if (++absIterations > MAXIMUM_ABS_ITERATIONS)
    {
        appendLogText(i18n("Autofocus failed to reach proper focus. Try increasing tolerance value."));
        stopFocus();
        return;
    }

    // No stars detected, try to capture again
    if (currentHFR == -1)
    {
        appendLogText(i18n("No stars detected, capturing again..."));
        capture();
        return;
    }

    if (currentHFR > maxHFR || HFRPoints.empty())
    {
        maxHFR = currentHFR;

        if (HFRPoints.empty())
        {
            maxPos=1;
            minPos=1e6;
        }
    }

    if (pulseStep > maxPos)
        maxPos = pulseStep;
    if (pulseStep < minPos)
        minPos = pulseStep;

    HFRPoint *p = new HFRPoint();

    p->HFR = currentHFR;
    p->pos = pulseStep;

    HFRPoints.append(p);

    HFRPlot->removeAllPlotObjects();

    //HFRPlot->setLimits(pulseStep-pulseDuration*5, pulseStep+pulseDuration*5, currentHFR/1.5, currentHFR*1.5 );
    HFRPlot->setLimits(minPos-pulseDuration, maxPos+pulseDuration, currentHFR/1.5, maxHFR );

    KPlotObject *hfrObj = new KPlotObject( Qt::red, KPlotObject::Points, 2 );

    foreach(HFRPoint *p, HFRPoints)
        hfrObj->addPoint(p->pos, p->HFR);

    HFRPlot->addPlotObject(hfrObj);

    HFRPlot->update();

    switch (lastFocusDirection)
    {
        case FOCUS_NONE:
            HFR = currentHFR;
            initHFRPos = pulseStep;
            initHFR=HFR;
            minHFR=currentHFR;
            minHFRPos=pulseStep;
            HFRDec=0;
            HFRInc=0;
            focusOutLimit=0;
            focusInLimit=0;
            initPulseDuration=pulseDuration;
            FocusIn(pulseDuration);
            break;

        case FOCUS_IN:
        case FOCUS_OUT:
        if (reverseDir && focusInLimit && focusOutLimit && fabs(currentHFR - minHFR) < (toleranceIN->value()/100.0) && HFRInc == 0 )
            {
                if (absIterations <= 2)
                    appendLogText(i18n("Change in HFR is too small. Try increasing the step size or decreasing the tolerance."));
                else
                    appendLogText(i18n("Autofocus complete."));
                stopFocus();
                break;
            }
            else if (currentHFR < HFR)
            {
                double slope=0;

                // Let's try to calculate slope of the V curve.
                if (initSlopeHFR == 0 && HFRInc == 0 && HFRDec >= 1)
                {
                    initSlopeHFR = HFR;
                    initSlopePos = lastHFRPos;
                }

                // Let's now limit the travel distance of the focuser
                if (lastFocusDirection == FOCUS_OUT && lastHFRPos < focusInLimit)
                    focusInLimit = lastHFRPos;
                else if (lastFocusDirection == FOCUS_IN && lastHFRPos > focusOutLimit)
                    focusOutLimit = lastHFRPos;

                // If we have slope, get next target position
                if (initSlopeHFR)
                {
                    slope = (currentHFR - initSlopeHFR) / (pulseStep - initSlopePos);
                    targetPulse = pulseStep + (currentHFR*0.5 - currentHFR)/slope;
                }
                // Otherwise proceed iteratively
                else
                {
                     if (lastFocusDirection == FOCUS_IN)
                         targetPulse = pulseStep + pulseDuration;
                     else
                         targetPulse = pulseStep - pulseDuration;

                }

                HFR = currentHFR;

                // Let's keep track of the minimum HFR
                if (HFR < minHFR)
                {
                    minHFR = HFR;
                    minHFRPos = pulseStep;
                }

                lastHFRPos = pulseStep;

                // HFR is decreasing, we are on the right direction
                HFRDec++;
                HFRInc=0;
            }
            else

            {
                // HFR increased, let's deal with it.
                HFRInc++;
                HFRDec=0;
                reverseDir = true;

                // Reality Check: If it's first time, let's capture again and see if it changes.
                if (HFRInc <= 1)
                {
                    capture();
                    return;
                }
                // Looks like we're going away from optimal HFR
                else
                {

                    HFR = currentHFR;
                    lastHFRPos = pulseStep;
                    initSlopeHFR=0;
                    HFRInc=0;

                    // Let's set new limits
                    if (lastFocusDirection == FOCUS_IN)
                        focusInLimit = pulseStep;
                    else
                        focusOutLimit = pulseStep;

                    // Decrease pulse
                    pulseDuration = pulseDuration * 0.75;

                    // Let's get close to the minimum HFR position so far detected
                    if (lastFocusDirection == FOCUS_OUT)
                          targetPulse = minHFRPos+pulseDuration/2;
                     else
                          targetPulse = minHFRPos-pulseDuration/2;

                }
            }

        // Limit target Pulse to algorithm limits
        if (focusInLimit != 0 && lastFocusDirection == FOCUS_IN && targetPulse > focusInLimit)
            targetPulse = focusInLimit;
        else if (focusOutLimit != 0 && lastFocusDirection == FOCUS_OUT && targetPulse < focusOutLimit)
            targetPulse = focusOutLimit;

        // Limit target pulse to focuser limits
        if (targetPulse < absMotionMin)
            targetPulse = absMotionMin;
        else if (targetPulse > absMotionMax)
            targetPulse = absMotionMax;

        // Ops, we can't go any further, we're done.
        if (targetPulse == pulseStep)
        {
            appendLogText(i18n("Autofocus complete."));
            stopFocus();
            return;
        }

        // Ops, deadlock
        if (focusOutLimit && focusOutLimit == focusInLimit)
        {
            appendLogText(i18n("Deadlock reached. Please try again with different settings."));
            stopFocus();
            return;
        }

        // Get delta for next move
        delta = (targetPulse - pulseStep);

        // Now cross your fingers and wait
       if (delta > 0)
            FocusIn(delta);
        else
          FocusOut(fabs(delta));

        break;

    }

}