3 changes: 0 additions & 3 deletions src/datasources/its/its.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,9 +166,6 @@ int ITSreadimage(ITSfile *its, int frame, int i_img, ITSimage *I) {
return 0;
}

// FIXME: INDEX is wrong! (?)
//index-=3;

// Second: read the header in the data file
offset = lseek(its->fp_data, index, SEEK_SET);
if (offset != index) {
Expand Down
4 changes: 3 additions & 1 deletion src/datasources/its/itsdatasource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,7 @@ void ITSSource::reset() {
if (_itsfile) {
ITSclose(_itsfile);
}
_nframes = 0;
_valid = false;
if (init()) {
_valid = true;
Expand All @@ -329,6 +330,7 @@ bool ITSSource::init() {
_itsfile = ITSopen(_filename.toAscii().data());
if (_itsfile->status != ITS_OK) {
ITSclose(_itsfile);
_nframes = 0;
_itsfile = 0;
return false;
}
Expand All @@ -351,7 +353,7 @@ bool ITSSource::init() {
}


// Check if the data in the from the source has updated. Typically done by checking the frame count of the datasource for
// Check if the data in the source has updated. Typically done by checking the frame count of the datasource for
// changes.
Kst::Object::UpdateType ITSSource::internalDataSourceUpdate() {

Expand Down
7 changes: 7 additions & 0 deletions src/datasources/its/kstdata_itssource.desktop
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,12 @@ X-KDE-ModuleType=Plugin
X-KDE-Library=itssource
X-Kst-Plugin-Author=C. Barth Netterfield
Name=Indexed Thumbnail Stream Reader
Name[ca]=Lector de fluxos de miniatures indexades
Name[ca@valencia]=Lector de fluxos de miniatures indexades
Name[en_GB]=Indexed Thumbnail Stream Reader
Name[nl]=Streamleesprogramma van geïndexeerde miniaturen
Name[pt]=Leitor de Sequências de Miniaturas Indexadas
Name[sv]=Strömläsare av indexerade miniatyrbilder
Name[uk]=Засіб читання Indexed Thumbnail Stream
Name[x-test]=xxIndexed Thumbnail Stream Readerxx

2 changes: 1 addition & 1 deletion src/libkst/datamatrix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,7 @@ LabelInfo DataMatrix::titleInfo() const {
label_info.units.clear();
}

label_info.name = _field;
label_info.name = descriptiveName();

return label_info;
}
Expand Down
7 changes: 3 additions & 4 deletions src/libkst/object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,12 +108,11 @@ Object::UpdateType Object::objectUpdate(qint64 newSerial) {
_serialOfLastChange = newSerial;
_serial = newSerial;
return Updated;
} else {
_serial = newSerial;
return NoChange;
}
// else
_serial = newSerial;
return NoChange;
}

}

// vim: ts=2 sw=2 et
8 changes: 8 additions & 0 deletions src/libkstapp/matrixdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ MatrixTab::MatrixTab(ObjectStore *store, QWidget *parent)
connect(_gradientX, SIGNAL(clicked()), this, SIGNAL(modified()));
connect(_gradientY, SIGNAL(clicked()), this, SIGNAL(modified()));

connect(_frame, SIGNAL(valueChanged(int)), this, SIGNAL(modified()));
connect(_lastFrame, SIGNAL(toggled(bool)), this, SIGNAL(modified()));
connect(_field, SIGNAL(activated(int)), this, SIGNAL(modified()));
}


Expand Down Expand Up @@ -955,6 +958,11 @@ ObjectPtr MatrixDialog::editExistingDataObject() const {

dataMatrix->writeLock();
dataMatrix->change(dataSource, field, xStart, yStart, xNumSteps, yNumSteps, doAverage, doSkip, skip, frame, minX, minY, stepX, stepY);
if (DataDialog::tagStringAuto()) {
dataMatrix->setDescriptiveName(QString());
} else {
dataMatrix->setDescriptiveName(DataDialog::tagString());
}
dataMatrix->registerChange();
dataMatrix->unlock();
setDataMatrixDefaults(dataMatrix);
Expand Down
9 changes: 8 additions & 1 deletion src/libkstmath/curve.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,14 @@ LabelInfo Curve::yLabelInfo() const {


LabelInfo Curve::titleInfo() const {
return yVector()->titleInfo();

LabelInfo label_info = yVector()->titleInfo();

if (!_manualDescriptiveName.isEmpty()) {
label_info.name = _manualDescriptiveName;
}

return label_info;
}


Expand Down
11 changes: 9 additions & 2 deletions src/libkstmath/image.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -403,11 +403,18 @@ LabelInfo Image::yLabelInfo() const {


LabelInfo Image::titleInfo() const {
LabelInfo label_info;
if (_inputMatrices.contains(THEMATRIX)) {
return (_inputMatrices[THEMATRIX]->titleInfo());
label_info = _inputMatrices[THEMATRIX]->titleInfo();
} else {
return LabelInfo();
label_info.name = descriptiveName();
}
if (!_manualDescriptiveName.isEmpty()) {
label_info.name = _manualDescriptiveName;
}

return label_info;

}

double Image::distanceToPoint(double xpos, double dx, double ypos) const {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,9 @@ void function_initial_estimate( const double x[], const double y[], int npts, do
fflush(stdout);
}


// It would be nice to fit exp(B*(x-_X0)) + C, and not have A,
// but A is required to at least hold the sign. We we just fix
// _X0 to the first X value in the data set, and fit for A.
double function_calculate( double x, double* P ) {
double A = P[0];
double B = P[1];
Expand Down
180 changes: 147 additions & 33 deletions src/plugins/fits/exponential_weighted/fitexponential_weighted.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
#include "objectstore.h"
#include "ui_fitexponential_weightedconfig.h"

#define NUM_PARAMS 3
#define NUM_PARAMS 4
#define MAX_NUM_ITERATIONS 500

#include <gsl/gsl_fit.h>
Expand Down Expand Up @@ -174,49 +174,149 @@ void FitExponentialWeightedSource::setupOutputs() {
setOutputScalar(SCALAR_OUT, "");
}

double _X0 = 0; // this use of a global is a hack to inject the first sample into the function.

void function_initial_estimate( const double* pdX, const double* pdY, int iLength, double* pdParameterEstimates ) {
Q_UNUSED( pdX )
Q_UNUSED( pdY )
Q_UNUSED( iLength )
void swapDouble(double *A, double *B) {
double C;

pdParameterEstimates[0] = 1.0;
pdParameterEstimates[1] = 0.0;
pdParameterEstimates[2] = 0.0;
C = *A;
*A = *B;
*B = C;
}


double function_calculate( double dX, double* pdParameters ) {
double dScale = pdParameters[0];
double dLambda = pdParameters[1];
double dOffset = pdParameters[2];
double dY;
void function_initial_estimate( const double x[], const double y[], int npts, double P0[] ) {
Q_UNUSED( x )
Q_UNUSED( y )
Q_UNUSED( npts )

_X0 = x[0];

// determine the signs of the terms.
// get the average of the first 5%, last 5% and middle 5% of points
int n_ave = npts/20;
if (n_ave < 1) n_ave = 1;
if (n_ave > 100) n_ave = 100;

double y0 = 0;
double x0 = 0;
double x1 = 0;
double y1 = 0;
double x2 = 0;
double y2 = 0;
int d1 = npts/2 - n_ave/2;
int d2 = npts-n_ave;

if ((d1 + n_ave > npts) || (d2 + n_ave > npts)) { // bail if not enough points.
P0[0] = 1.0;
P0[1] = 0.0;
P0[2] = 0.0;
return;
}

for (int i=0; i<n_ave; i++) {
x0+=x[i];
y0+=y[i];
x1+=x[i+d1];
y1+=y[i+d1];
x2+=x[i+d2];
y2+=y[i+d2];
}
x0 /= (double)n_ave;
y0 /= (double)n_ave;
x1 /= (double)n_ave;
y1 /= (double)n_ave;
x2 /= (double)n_ave;
y2 /= (double)n_ave;

// Make sure x0, x1, x2 are monotonic.
if (x2 > x0) {
if (x1 > x2) {
swapDouble(&x1, &x2);
swapDouble(&y1, &y2);
}
if (x1 < x0) {
swapDouble(&x1, &x0);
swapDouble(&y1, &y0);
}
} else {
if (x1 < x2) {
swapDouble(&x1, &x2);
swapDouble(&y1, &y2);
}
if (x1 > x0) {
swapDouble(&x1, &x0);
swapDouble(&y1, &y0);
}
}

dY = ( dScale * exp( -dLambda * dX ) ) + dOffset;
if ((x1 == x0) || (x2 == x0) || (x1 == x2)) { // bail if no x range
P0[0] = 1.0;
P0[1] = 0.0;
P0[2] = 0.0;
return;
}

return dY;
P0[0] = fabs(y2 - y0)/M_E;
P0[1] = M_E/fabs(x2 - x0);
P0[2] = y0;

double m = (y2 - y0)/(x2 - x0);
if (m > 0) { // rising
if ((x1-x0)*m + y0 > y1) { // neg curvature +A, +B
//P0[0] *= -1;
//P0[1] *= -1.0;
} else { // -A, -B
P0[0] *= -1;
P0[1] *= -1.0;
}
} else { // falling
if ((x1-x0)*m + y0 > y1) { // Curving down +A, -B
//P0[0] *= -1;
P0[1] *= -1.0;
} else { // -A, +B
P0[0] *= -1;
//P0[1] *= -1.0;
}
}

fflush(stdout);
}

// It would be nice to fit exp(B*(x-_X0)) + C, and not have A,
// but A is required to at least hold the sign. We we just fix
// _X0 to the first X value in the data set, and fit for A.
double function_calculate( double x, double* P ) {
double A = P[0];
double B = P[1];
double C = P[2];
double y;

void function_derivative( double dX, double* pdParameters, double* pdDerivatives ) {
double dScale = pdParameters[0];
double dLambda = pdParameters[1];
double dExp;
double ddScale;
double ddLambda;
double ddOffset;
y = ( A*exp( B*(x - _X0) ) ) + C;

dExp = exp( -dLambda * dX );
ddScale = dExp;
ddLambda = -dX * dScale * dExp;
ddOffset = 1.0;
return y;
}


void function_derivative( double x, double* P, double* dFdP ) {
double A = P[0];
double B = P[1];
double exp_BxXo;

// dFdA = exp(b*(x-_X0)
// dFdB = A*(x-_X0)*exp(b*(x-_X0))

exp_BxXo = exp( B * (x-_X0) );

dFdP[0] = exp_BxXo;
dFdP[1] = (x-_X0) * A * exp_BxXo;
dFdP[2] = 1.0;

pdDerivatives[0] = ddScale;
pdDerivatives[1] = ddLambda;
pdDerivatives[2] = ddOffset;
}




bool FitExponentialWeightedSource::algorithm() {
Kst::VectorPtr inputVectorX = _inputVectors[VECTOR_IN_X];
Kst::VectorPtr inputVectorY = _inputVectors[VECTOR_IN_Y];
Expand All @@ -229,7 +329,11 @@ bool FitExponentialWeightedSource::algorithm() {
Kst::ScalarPtr outputScalar = _outputScalars[SCALAR_OUT];

Kst::LabelInfo label_info = inputVectorY->labelInfo();
label_info.name = tr("Exponential Fit to %1").arg(label_info.name);

_X0 = inputVectorX->noNanValue()[0];
n_params = 3;

label_info.name = tr("A\\Cdotexp((x-x_o)/\\tau) + C fit to %1").arg(label_info.name);
outputVectorYFitted->setLabelInfo(label_info);

label_info.name = tr("Exponential Fit Residuals");
Expand All @@ -241,6 +345,10 @@ bool FitExponentialWeightedSource::algorithm() {
bReturn = kstfit_nonlinear_weighted( inputVectorX, inputVectorY, inputVectorWeights,
outputVectorYFitted, outputVectorYResiduals, outputVectorYParameters,
outputVectorYCovariance, outputScalar );

outputVectorYParameters->raw_V_ptr()[1] = 1.0/outputVectorYParameters->raw_V_ptr()[1];
outputVectorYParameters->raw_V_ptr()[3] = _X0;

return bReturn;
}

Expand Down Expand Up @@ -308,13 +416,19 @@ QString FitExponentialWeightedSource::parameterName(int index) const {
QString parameter;
switch (index) {
case 0:
parameter = "Scale";
parameter = "A";
break;
case 1:
parameter = "Lambda";
parameter = "\\tau";
break;
case 2:
parameter = "Offset";
parameter = "C";
break;
case 3:
parameter = "X_o";
break;
default:
parameter = "";
break;
}

Expand Down
Loading