void quadratic_fit(void) { int i, n; double xi, yi, ei, chisq; gsl_matrix *X, *cov; gsl_vector *y, *w, *c; n = 7; double x_vec[] = { 0, 100, 200, 300, 400, 500, 600 }; double y_vec[] = { 0, 12.5, 50.0, 112.5, 200.0, 312.5, 450.0 }; double e_vec[] = { 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1 }; X = gsl_matrix_alloc(n, 3); y = gsl_vector_alloc(n); w = gsl_vector_alloc(n); c = gsl_vector_alloc(3); cov = gsl_matrix_alloc(3, 3); for (i = 0; i < n; i++) { xi = x_vec[i]; yi = y_vec[i]; ei = e_vec[i]; printf("%g %g +/- %g\n", xi, yi, ei); gsl_matrix_set(X, i, 0, 1.0); gsl_matrix_set(X, i, 1, xi); gsl_matrix_set(X, i, 2, xi * xi); gsl_vector_set(y, i, yi); gsl_vector_set(w, i, 1.0 / (ei * ei)); } { gsl_multifit_linear_workspace * work = gsl_multifit_linear_alloc(n, 3); gsl_multifit_wlinear(X, w, y, c, cov, &chisq, work); gsl_multifit_linear_free(work); } #define C(i) (gsl_vector_get(c,(i))) #define COV(i,j) (gsl_matrix_get(cov,(i),(j))) { printf("# best fit: Y = %g + %g X + %g X^2\n", C(0), C(1), C(2)); printf("# covariance matrix:\n"); printf("[ %+.5e, %+.5e, %+.5e \n", COV(0,0), COV(0,1), COV(0,2)); printf(" %+.5e, %+.5e, %+.5e \n", COV(1,0), COV(1,1), COV(1,2)); printf(" %+.5e, %+.5e, %+.5e ]\n", COV(2,0), COV(2,1), COV(2,2)); printf("# chisq = %g\n", chisq); } gsl_matrix_free(X); gsl_vector_free(y); gsl_vector_free(w); gsl_vector_free(c); gsl_matrix_free(cov); }
TGraphErrors *getUnc(TMatrixDSym COV, TF1 *fit, TH1F *h) { int N = COV.GetNrows(); float vx[200],vy[200],vex[200],vey[200]; float dx = (h->GetBinLowEdge(h->GetNbinsX())+h->GetBinWidth(1)-h->GetBinLowEdge(1))/200; for(int b=0;b<200;b++) { vx[b] = h->GetBinLowEdge(1)+b*dx; vy[b] = fit->Eval(vx[b]); vex[b] = 0.0; float sum(0.0); for(int i=0;i<N;i++) { for(int j=0;j<N;j++) { sum += pow(vx[b],i)*pow(vx[b],j)*COV(i,j); } } vey[b] = sqrt(sum); } TGraphErrors *g = new TGraphErrors(200,vx,vy,vex,vey); return g; }
int main (int argc, char **argv) { int i, n; double xi, yi, ei, chisq; gsl_matrix *X, *cov; gsl_vector *y, *w, *c; if (argc != 2) { fprintf (stderr,"usage: fit n < data\n"); exit (-1); } n = atoi (argv[1]); X = gsl_matrix_alloc (n, 3); y = gsl_vector_alloc (n); w = gsl_vector_alloc (n); c = gsl_vector_alloc (3); cov = gsl_matrix_alloc (3, 3); for (i = 0; i < n; i++) { int count = fscanf (stdin, "%lg %lg %lg", &xi, &yi, &ei); if (count != 3) { fprintf (stderr, "error reading file\n"); exit (-1); } printf ("%g %g +/- %g\n", xi, yi, ei); gsl_matrix_set (X, i, 0, 1.0); gsl_matrix_set (X, i, 1, xi); gsl_matrix_set (X, i, 2, xi*xi); gsl_vector_set (y, i, yi); gsl_vector_set (w, i, 1.0/(ei*ei)); } { gsl_multifit_linear_workspace * work = gsl_multifit_linear_alloc (n, 3); gsl_multifit_wlinear (X, w, y, c, cov, &chisq, work); gsl_multifit_linear_free (work); } #define C(i) (gsl_vector_get(c,(i))) #define COV(i,j) (gsl_matrix_get(cov,(i),(j))) { printf ("# best fit: Y = %g + %g X + %g X^2\n", C(0), C(1), C(2)); printf ("# covariance matrix:\n"); printf ("[ %+.5e, %+.5e, %+.5e \n", COV(0,0), COV(0,1), COV(0,2)); printf (" %+.5e, %+.5e, %+.5e \n", COV(1,0), COV(1,1), COV(1,2)); printf (" %+.5e, %+.5e, %+.5e ]\n", COV(2,0), COV(2,1), COV(2,2)); printf ("# chisq = %g\n", chisq); } gsl_matrix_free (X); gsl_vector_free (y); gsl_vector_free (w); gsl_vector_free (c); gsl_matrix_free (cov); return 0; }
int main(int argc, char **argv) { int i; size_t n; const size_t p = 2; /* linear fit */ gsl_matrix *X, *cov; gsl_vector *x, *y, *c, *c_ols; const double a = 1.48; /* slope */ const double b = 3.88; /* intercept */ gsl_rng *r; if (argc != 2) { fprintf(stderr, "usage: robfit n\n"); exit(-1); } n = atoi(argv[1]); X = gsl_matrix_alloc(n, p); x = gsl_vector_alloc(n); y = gsl_vector_alloc(n); c = gsl_vector_alloc(p); c_ols = gsl_vector_alloc(p); cov = gsl_matrix_alloc(p, p); r = gsl_rng_alloc(gsl_rng_default); /* generate linear dataset */ for (i = 0; i < n - 3; i++) { double dx = 10.0 / (n - 1.0); double ei = gsl_rng_uniform(r); double xi = -5.0 + i * dx; double yi = a * xi + b; gsl_vector_set(x, i, xi); gsl_vector_set(y, i, yi + ei); } /* add a few outliers */ gsl_vector_set(x, n - 3, 4.7); gsl_vector_set(y, n - 3, -8.3); gsl_vector_set(x, n - 2, 3.5); gsl_vector_set(y, n - 2, -6.7); gsl_vector_set(x, n - 1, 4.1); gsl_vector_set(y, n - 1, -6.0); /* construct design matrix X for linear fit */ for (i = 0; i < n; ++i) { double xi = gsl_vector_get(x, i); gsl_matrix_set(X, i, 0, 1.0); gsl_matrix_set(X, i, 1, xi); } /* perform robust and OLS fit */ dofit(gsl_multifit_robust_ols, X, y, c_ols, cov); dofit(gsl_multifit_robust_bisquare, X, y, c, cov); /* output data and model */ for (i = 0; i < n; ++i) { double xi = gsl_vector_get(x, i); double yi = gsl_vector_get(y, i); gsl_vector_view v = gsl_matrix_row(X, i); double y_ols, y_rob, y_err; gsl_multifit_robust_est(&v.vector, c, cov, &y_rob, &y_err); gsl_multifit_robust_est(&v.vector, c_ols, cov, &y_ols, &y_err); printf("%g %g %g %g\n", xi, yi, y_rob, y_ols); } #define C(i) (gsl_vector_get(c,(i))) #define COV(i,j) (gsl_matrix_get(cov,(i),(j))) { printf("# best fit: Y = %g + %g X\n", C(0), C(1)); printf("# covariance matrix:\n"); printf("# [ %+.5e, %+.5e\n", COV(0, 0), COV(0, 1)); printf("#%+.5e, %+.5e\n", COV(1, 0), COV(1, 1)); } gsl_matrix_free(X); gsl_vector_free(x); gsl_vector_free(y); gsl_vector_free(c); gsl_vector_free(c_ols); gsl_matrix_free(cov); gsl_rng_free(r); return 0; }
QFFitAlgorithm::FitResult QFFitAlgorithmLMFit::intFit(double* paramsOut, double* paramErrorsOut, const double* initialParams, QFFitAlgorithm::Functor* model, const double* paramsMin, const double* paramsMax) { QFFitAlgorithm::FitResult result; qDebug()<<"QFFitAlgorithmLMFit::intFit 1"; int paramCount=model->get_paramcount(); // number of parameters memcpy(paramsOut, initialParams, paramCount*sizeof(double)); qDebug()<<"QFFitAlgorithmLMFit::intFit 2"; //double param=getParameter("param_name").toDouble(); lm_status_struct status; lm_control_struct control = lm_control_double; control.verbosity = 0; // monitor status (+1) and parameters (+2) control.ftol=getParameter("ftol").toDouble(); control.xtol=getParameter("xtol").toDouble(); control.gtol=getParameter("gtol").toDouble(); control.epsilon=getParameter("epsilon").toDouble(); control.stepbound=getParameter("stepbound").toDouble(); control.patience=getParameter("max_iterations").toInt(); qDebug()<<"QFFitAlgorithmLMFit::intFit 3"; QFFItAlgorithmGSL_evalData d; d.model=model; d.paramsMin=paramsMin; d.paramsMax=paramsMax; d.pcount=paramCount; d.p=(double*)qfMalloc(paramCount*sizeof(double)); qDebug()<<"QFFitAlgorithmLMFit::intFit 4"; lmmin( paramCount, paramsOut, model->get_evalout(), &d, lmfit_eval, &control, &status ); qDebug()<<"QFFitAlgorithmLMFit::intFit 5"; if ( paramsMin && paramsMax) { for (int i=0; i<paramCount; i++) { const double& par=paramsOut[i]; if (par>paramsMax[i]) paramsOut[i]=paramsMax[i]; if (par<paramsMin[i]) paramsOut[i]=paramsMin[i]; } } result.addNumber("error_sum", status.fnorm); result.addNumber("iterations", status.nfev); qDebug()<<"QFFitAlgorithmLMFit::intFit 6"; QVector<double> J(model->get_evalout()*model->get_paramcount()); QVector<double> COV(model->get_paramcount()*model->get_paramcount()); qDebug()<<"QFFitAlgorithmLMFit::intFit 7"; model->evaluateJacobian(J.data(), paramsOut); qDebug()<<"QFFitAlgorithmLMFit::intFit 8"; double chi2=status.fnorm; qDebug()<<"QFFitAlgorithmLMFit::intFit 9"; if (QFFitAlgorithm::functorHasWeights(model) && !QFFitAlgorithm::functorAllWeightsOne(model)) statisticsGetFitProblemCovMatrix(COV.data(), J.data(), model->get_evalout(), model->get_paramcount()); else statisticsGetFitProblemVarCovMatrix(COV.data(), J.data(), model->get_evalout(), model->get_paramcount(), chi2); qDebug()<<"QFFitAlgorithmLMFit::intFit 10"; result.addNumberMatrix("covariance_matrix", COV.data(), model->get_paramcount(), model->get_paramcount()); qDebug()<<"QFFitAlgorithmLMFit::intFit 11"; for (int i=0; i<model->get_paramcount(); i++) { qDebug()<<"QFFitAlgorithmLMFit::intFit 12: "<<i; paramErrorsOut[i]=statisticsGetFitProblemParamErrors(i, COV.data(), model->get_paramcount()); } qDebug()<<"QFFitAlgorithmLMFit::intFit 13"; if (status.outcome>=0) { result.fitOK=QString(lm_infmsg[status.outcome]).contains("success") || QString(lm_infmsg[status.outcome]).contains("converged"); result.message=QString(lm_infmsg[status.outcome]); result.messageSimple=QString(lm_infmsg[status.outcome]); } else { result.fitOK=true; result.message=""; result.messageSimple=""; } qDebug()<<"QFFitAlgorithmLMFit::intFit 14"; if (d.p) qfFree(d.p); qDebug()<<"QFFitAlgorithmLMFit::intFit 15 ... DONE"; return result; }
QFFitAlgorithm::FitResult QFFitAlgorithmGSLSimplex::intFit(double* paramsOut, double* paramErrorsOut, const double* initialParams, QFFitAlgorithm::Functor* model, const double* paramsMin, const double* paramsMax) { QFFitAlgorithm::FitResult result; int paramCount=model->get_paramcount(); // number of parameters if (paramCount<=0) { result.fitOK=false; result.message=QObject::tr("no parameters to optimize"); result.messageSimple=result.message; return result; } QFFItAlgorithmGSL_evalData d; d.model=model; d.paramsMin=paramsMin; d.paramsMax=paramsMax; d.pcount=paramCount; d.out=gsl_vector_alloc(model->get_evalout()); d.out_ast=gsl_vector_alloc(model->get_evalout()); d.params=gsl_vector_alloc(paramCount); d.params_ast=gsl_vector_alloc(paramCount); int iter = 0; int maxIter = getParameter("max_iterations").toInt(); int status; //const gsl_multimin_fdfminimizer_type *T; //gsl_multimin_fdfminimizer *s; gsl_multimin_fminimizer *s; // set starting value to initial parameters gsl_vector *x=QFFitAlgorithmGSL_transformParams(initialParams, paramCount, paramsMin, paramsMax); //gsl_multimin_function_fdf my_func; gsl_multimin_function my_func; my_func.n = paramCount; my_func.f = QFFitAlgorithmGSL_f; //my_func.df = QFFitAlgorithmGSL_df; //my_func.fdf = QFFitAlgorithmGSL_fdf; my_func.params = &d; // initialize minimizer //s = gsl_multimin_fdfminimizer_alloc (T, paramCount); s = gsl_multimin_fminimizer_alloc (T, paramCount); /* Set initial step sizes to 1 */ gsl_vector *ss = gsl_vector_alloc(paramCount); gsl_vector_set_all (ss, getParameter("stepsize").toDouble()); //gsl_multimin_fdfminimizer_set(s, &my_func, x, getParameter("stepsize").toDouble(), getParameter("tol").toDouble()); gsl_multimin_fminimizer_set(s, &my_func, x, ss); do { iter++; //status = gsl_multimin_fdfminimizer_iterate (s); status = gsl_multimin_fminimizer_iterate (s); //qDebug()<<"it "<<iter<<": "<<arrayToString(gsl_vector_ptr(s->x, 0), paramCount); //qDebug()<<" f = "<<s->fval; //qDebug()<<" status = "<<status; if (status) break; //status = gsl_multimin_test_gradient (s->gradient, 1e-3); double size = gsl_multimin_fminimizer_size (s); status = gsl_multimin_test_size (size, 1e-2); //if (status == GSL_SUCCESS) qDebug()<<" Minimum found !!!"; } while (status == GSL_CONTINUE && iter < maxIter); /*for (int i=0; i<paramCount; i++) { const double par=gsl_vector_get(s->x, i); paramsOut[i]=par; if (par>paramsMax[i]) paramsOut[i]=paramsMax[i]; if (par<paramsMin[i]) paramsOut[i]=paramsMin[i]; }*/ QFFitAlgorithmGSL_backTransformParams(paramsOut, paramCount, s->x, paramsMin, paramsMax); QVector<double> J(model->get_evalout()*model->get_paramcount()); QVector<double> COV(model->get_paramcount()*model->get_paramcount()); model->evaluateJacobian(J.data(), paramsOut); double chi2=s->fval; if (QFFitAlgorithm::functorHasWeights(model) && !QFFitAlgorithm::functorAllWeightsOne(model)) statisticsGetFitProblemCovMatrix(COV.data(), J.data(), model->get_evalout(), model->get_paramcount()); else statisticsGetFitProblemVarCovMatrix(COV.data(), J.data(), model->get_evalout(), model->get_paramcount(), chi2); result.addNumberMatrix("covariance_matrix", COV.data(), model->get_paramcount(), model->get_paramcount()); for (int i=0; i<model->get_paramcount(); i++) { paramErrorsOut[i]=statisticsGetFitProblemParamErrors(i, COV.data(), model->get_paramcount()); } result.addNumber("error_sum", s->fval); result.addNumber("iterations", iter); result.fitOK=false; result.message=QObject::tr("error during optimization"); result.messageSimple=result.message; if (status == GSL_SUCCESS) { result.fitOK=true; result.message=QObject::tr("success after %1 iterations").arg(iter); result.messageSimple=result.message; } else if (status == GSL_ENOPROG) { result.fitOK=true; result.message=QObject::tr("no more optimization progress after %1 iterations").arg(iter); result.messageSimple=result.message; } //gsl_multimin_fdfminimizer_free (s); gsl_multimin_fminimizer_free (s); gsl_vector_free (x); gsl_vector_free(d.params); gsl_vector_free(d.params_ast); gsl_vector_free(d.out); gsl_vector_free(d.out_ast); return result; }
std::vector<float> compute_ec_features( USImageType::Pointer input_image, USImageType::Pointer inp_labeled, int number_of_rois, unsigned short thresh, int surr_dist, int inside_dist ){ std::vector< float > qfied_num; std::vector< USImageType::PixelType > labelsList; std::vector< double > quantified_numbers_cell; typedef itk::ExtractImageFilter< USImageType, UShortImageType > LabelExtractType; typedef itk::ImageRegionConstIterator< UShortImageType > ConstIteratorType; typedef itk::ImageRegionIteratorWithIndex< USImageType > IteratorType; typedef itk::SignedDanielssonDistanceMapImageFilter<FloatImageType, FloatImageType > DTFilter; typedef itk::ImageRegionIteratorWithIndex< FloatImageType > IteratorTypeFloat; typedef itk::LabelGeometryImageFilter< USImageType > GeometryFilterType; typedef GeometryFilterType::LabelIndicesType labelindicestype; itk::SizeValueType sz_x, sz_y, sz_z; sz_x = input_image->GetLargestPossibleRegion().GetSize()[0]; sz_y = input_image->GetLargestPossibleRegion().GetSize()[1]; sz_z = input_image->GetLargestPossibleRegion().GetSize()[2]; if( sz_x==1 || sz_y==1 || sz_z==1 ){ LabelExtractType::Pointer deFilter = LabelExtractType::New(); USImageType::RegionType dRegion = inp_labeled->GetLargestPossibleRegion(); dRegion.SetSize(2,0); deFilter->SetExtractionRegion(dRegion); deFilter->SetInput( inp_labeled ); deFilter->SetDirectionCollapseToIdentity(); try{ deFilter->Update(); } catch( itk::ExceptionObject & excep ){ std::cerr << "Exception caught !" << std::endl; std::cerr << excep << std::endl; } //Dialate input first WholeCellSeg *dialate_filter = new WholeCellSeg; dialate_filter->set_nuc_img( deFilter->GetOutput() ); dialate_filter->set_radius( surr_dist ); dialate_filter->RunSegmentation(); UShortImageType::Pointer input_lab = dialate_filter->getSegPointer(); USImageType::Pointer input_labeled = USImageType::New(); USImageType::PointType origint; origint[0] = 0; origint[1] = 0; origint[2] = 0; input_labeled->SetOrigin( origint ); USImageType::IndexType startt; startt[0] = 0; // first index on X startt[1] = 0; // first index on Y startt[2] = 0; // first index on Z USImageType::SizeType sizet; sizet[0] = inp_labeled->GetLargestPossibleRegion().GetSize()[0]; // size along X sizet[1] = inp_labeled->GetLargestPossibleRegion().GetSize()[1]; // size along Y sizet[2] = inp_labeled->GetLargestPossibleRegion().GetSize()[2]; // size along Z USImageType::RegionType regiont; regiont.SetSize( sizet ); regiont.SetIndex( startt ); input_labeled->SetRegions( regiont ); input_labeled->Allocate(); input_labeled->FillBuffer(0); input_labeled->Update(); ConstIteratorType pix_buf1( input_lab, input_lab->GetRequestedRegion() ); IteratorType iterator2 ( input_labeled, input_labeled->GetRequestedRegion() ); iterator2.GoToBegin(); for ( pix_buf1.GoToBegin(); !pix_buf1.IsAtEnd(); ++pix_buf1 ){ iterator2.Set( pix_buf1.Get() ); ++iterator2; } std::vector< float > quantified_numbers; typedef itk::LabelGeometryImageFilter< USImageType > GeometryFilterType; typedef GeometryFilterType::LabelIndicesType labelindicestype; GeometryFilterType::Pointer geomfilt1 = GeometryFilterType::New(); geomfilt1->SetInput( input_labeled ); geomfilt1->SetCalculatePixelIndices( true ); geomfilt1->Update(); labelsList = geomfilt1->GetLabels(); bool zp=false; for( USImageType::PixelType i=0; i < labelsList.size(); ++i ){ if( labelsList[i] == 0 ){ zp=true; continue; } std::vector<float> quantified_numbers_cell; for( unsigned j=0; j<number_of_rois; ++j ) quantified_numbers_cell.push_back((float)0.0); double centroid_x = geomfilt1->GetCentroid(labelsList[i])[0]; double centroid_y = geomfilt1->GetCentroid(labelsList[i])[1]; labelindicestype indices1; indices1 = geomfilt1->GetPixelIndices(labelsList[i]); for( labelindicestype::iterator itPixind = indices1.begin(); itPixind!=indices1.end(); ++itPixind ){ IteratorType iterator1 ( input_image, input_image->GetRequestedRegion() ); iterator1.SetIndex( *itPixind ); if( iterator1.Get() < thresh ) continue; double x = iterator1.GetIndex()[0]; double y = iterator1.GetIndex()[1]; double angle = atan2((centroid_y-y),fabs(centroid_x-x)); if( (centroid_x-x)>0 ) angle += M_PI_2; else angle = M_PI+M_PI-(angle+M_PI_2); angle = ((number_of_rois-1)*angle)/(2*M_PI); double angle_fraction[1]; unsigned angular_index; if( modf( angle, angle_fraction ) > 0.5 ) angular_index = ceil( angle ); else angular_index = floor( angle ); quantified_numbers_cell[angular_index] += iterator1.Get(); } for( unsigned j=0; j<number_of_rois; ++j ) quantified_numbers.push_back(quantified_numbers_cell[j]); } unsigned qnum_sz = zp? (labelsList.size()-1) : (labelsList.size()); for( unsigned i=0; i<qnum_sz; ++i ){ unsigned counter=0; for( unsigned j=0; j<number_of_rois; ++j ){ if( quantified_numbers[(i*number_of_rois+j)] > (255.0*surr_dist) ) ++counter; } qfied_num.push_back(counter); } } else{ GeometryFilterType::Pointer geomfilt1 = GeometryFilterType::New(); geomfilt1->SetInput( inp_labeled ); geomfilt1->SetCalculatePixelIndices( true ); geomfilt1->Update(); labelsList = geomfilt1->GetLabels(); std::cout<<std::endl<<"The size is: "<<labelsList.size(); if( labelsList.size() == 1 ) { qfied_num.clear(); return qfied_num; } bool zp=false; USPixelType zero; //Check if the background is also included for( USPixelType i=0; i<labelsList.size(); ++i ) if( labelsList[i] == 0 ){ zp=true; zero = i; } USImageType::SizeType sizee; sizee[0] = inp_labeled->GetLargestPossibleRegion().GetSize()[0]; // size along X sizee[1] = inp_labeled->GetLargestPossibleRegion().GetSize()[1]; // size along Y sizee[2] = inp_labeled->GetLargestPossibleRegion().GetSize()[2]; // size along Z itk::SizeValueType roi_list_size = zp ? ((itk::SizeValueType)number_of_rois*(labelsList.size()-1)*2) : ((itk::SizeValueType)number_of_rois*labelsList.size()*2); std::vector<double> quantified_numbers_cell((roi_list_size),0.0 ); std::cout<<"Bounding boxes computed"<<std::endl; #ifdef _OPENMP itk::MultiThreader::SetGlobalDefaultNumberOfThreads(1); #pragma omp parallel for #if _OPENMP < 200805L for( int i=0; i<labelsList.size(); ++i ) #else for( USImageType::PixelType i=0; i<labelsList.size(); ++i ) #endif #else for( USImageType::PixelType i=0; i<labelsList.size(); ++i ) #endif { itk::SizeValueType ind; if( zp && (zero==i) ) continue; if( zp && (i>zero) ) ind = i-1; else ind = i; //Get label indices labelindicestype indices1; double centroid_x,centroid_y,centroid_z; GeometryFilterType::BoundingBoxType boundbox; #pragma omp critical { indices1 = geomfilt1->GetPixelIndices(labelsList[i]); //Get Centroid centroid_x = geomfilt1->GetCentroid(labelsList[i])[0]; centroid_y = geomfilt1->GetCentroid(labelsList[i])[1]; centroid_z = geomfilt1->GetCentroid(labelsList[i])[2]; //Create an image with bounding box + 2 * outside distance + 2 //and get distance map for the label boundbox = geomfilt1->GetBoundingBox(labelsList[i]); } //Create vnl array 3xN( label indicies ) vnl_matrix<double> B(3,indices1.size()); FloatImageType::Pointer inp_lab = FloatImageType::New(); FloatImageType::PointType origint; origint[0] = 0; origint[1] = 0; origint[2] = 0; inp_lab->SetOrigin( origint ); FloatImageType::IndexType startt; startt[0] = 0; // first index on X startt[1] = 0; // first index on Y startt[2] = 0; // first index on Z FloatImageType::SizeType sizet; sizet[0] = boundbox[1]-boundbox[0]+2*surr_dist+2; // size along X sizet[1] = boundbox[3]-boundbox[2]+2*surr_dist+2; // size along Y sizet[2] = boundbox[5]-boundbox[4]+2*surr_dist+2; // size along Z FloatImageType::RegionType regiont; regiont.SetSize( sizet ); regiont.SetIndex( startt ); inp_lab->SetRegions( regiont ); inp_lab->Allocate(); inp_lab->FillBuffer(0.0); inp_lab->Update(); IteratorTypeFloat iterator444 ( inp_lab, inp_lab->GetRequestedRegion() ); //Populate matrix with deviations from the centroid for principal axes and //at the same time set up distance-transform computation itk::SizeValueType ind1=0; for( labelindicestype::iterator itPixind = indices1.begin(); itPixind!=indices1.end(); ++itPixind ){ IteratorType iterator3( input_image, input_image->GetRequestedRegion() ); iterator3.SetIndex( *itPixind ); B(0,(ind1)) = iterator3.GetIndex()[0]-centroid_x; B(1,(ind1)) = iterator3.GetIndex()[1]-centroid_y; B(2,(ind1)) = iterator3.GetIndex()[2]-centroid_z; FloatImageType::IndexType cur_in; cur_in[0] = iterator3.GetIndex()[0]-boundbox[0]+1+surr_dist; cur_in[1] = iterator3.GetIndex()[1]-boundbox[2]+1+surr_dist; cur_in[2] = iterator3.GetIndex()[2]-boundbox[4]+1+surr_dist; iterator444.SetIndex( cur_in ); iterator444.Set( 255.0 ); ++ind1; } //Compute distance transform for the current object DTFilter::Pointer dt_obj= DTFilter::New() ; dt_obj->SetInput( inp_lab ); dt_obj->SquaredDistanceOff(); dt_obj->InsideIsPositiveOff(); try{ dt_obj->Update() ; } catch( itk::ExceptionObject & err ){ std::cerr << "Error in Distance Transform: " << err << std::endl; } FloatImageType::Pointer dist_im = dt_obj->GetOutput(); //Use KLT to compute pricipal axes vnl_matrix<double> B_transp((int)indices1.size(),3); B_transp = B.transpose(); vnl_matrix<double> COV(3,3); COV = B * B_transp; double norm = 1.0/(double)indices1.size(); COV = COV * norm; //Eigen decomposition vnl_real_eigensystem Eyegun( COV ); vnl_matrix<vcl_complex<double> > EVals = Eyegun.D; double Eval1 = vnl_real(EVals)(0,0); double Eval2 = vnl_real(EVals)(1,1); double Eval3 = vnl_real(EVals)(2,2); vnl_double_3x3 EVectMat = Eyegun.Vreal; double V1[3],V2[3],EP_norm[3]; if( Eval1 >= Eval3 && Eval2 >= Eval3 ){ if( Eval1 >= Eval2 ){ V1[0] = EVectMat(0,0); V1[1] = EVectMat(1,0); V1[2] = EVectMat(2,0); V2[0] = EVectMat(0,1); V2[1] = EVectMat(1,1); V2[2] = EVectMat(2,1); } else { V2[0] = EVectMat(0,0); V2[1] = EVectMat(1,0); V2[2] = EVectMat(2,0); V1[0] = EVectMat(0,1); V1[1] = EVectMat(1,1); V1[2] = EVectMat(2,1); } } else if( Eval1 >= Eval2 && Eval3 >= Eval2 ) { if( Eval1 >= Eval3 ){ V1[0] = EVectMat(0,0); V1[1] = EVectMat(1,0); V1[2] = EVectMat(2,0); V2[0] = EVectMat(0,2); V2[1] = EVectMat(1,2); V2[2] = EVectMat(2,2); } else { V2[0] = EVectMat(0,0); V2[1] = EVectMat(1,0); V2[2] = EVectMat(2,0); V1[0] = EVectMat(0,2); V1[1] = EVectMat(1,2); V1[2] = EVectMat(2,2); } } else { if( Eval2 >= Eval3 ){ V1[0] = EVectMat(0,1); V1[1] = EVectMat(1,1); V1[2] = EVectMat(2,1); V2[0] = EVectMat(0,2); V2[1] = EVectMat(1,2); V2[2] = EVectMat(2,2); } else { V2[0] = EVectMat(0,1); V2[1] = EVectMat(1,1); V2[2] = EVectMat(2,1); V1[0] = EVectMat(0,2); V1[1] = EVectMat(1,2); V1[2] = EVectMat(2,2); } } double n_sum = sqrt( V1[0]*V1[0]+V1[1]*V1[1]+V1[2]*V1[2] ); V1[0] /= n_sum; V1[1] /= n_sum; V1[2] /= n_sum; n_sum = sqrt( V2[0]*V2[0]+V2[1]*V2[1]+V2[2]*V2[2] ); V2[0] /= n_sum; V2[1] /= n_sum; V2[2] /= n_sum; //Get the normal to the plane formed by the biggest two EVs EP_norm[0] = V1[1]*V2[2]-V1[2]*V2[1]; EP_norm[1] = V1[2]*V2[0]-V1[0]*V2[2]; EP_norm[2] = V1[0]*V2[1]-V1[1]*V2[0]; //Reassign V2 so that it is orthogonal to both EP_norm and V1 V2[0] = V1[1]*EP_norm[2]-V1[2]*EP_norm[1]; V2[1] = V1[2]*EP_norm[0]-V1[0]*EP_norm[2]; V2[2] = V1[0]*EP_norm[1]-V1[1]*EP_norm[0]; //Now we have the point normal form; EP_norm is the normal and //centroid_x, centroid_y, centroid_z is the point //The equation to the plane is EP_norm[0](x-centroid_x)+EP_norm[1](y-centroid_y)+EP_norm[2](z-centroid_z)=0 double dee = (centroid_x*EP_norm[0]+centroid_y*EP_norm[1]+centroid_z*EP_norm[2])*(-1.00); //Iterate through and assign values to each region typedef itk::ImageRegionConstIterator< FloatImageType > ConstIteratorTypeFloat; ConstIteratorTypeFloat pix_buf2( dist_im, dist_im->GetRequestedRegion() ); IteratorType iterator44( input_image, input_image->GetRequestedRegion() ); for ( pix_buf2.GoToBegin(); !pix_buf2.IsAtEnd(); ++pix_buf2 ){ //Use pixels that are only within the defined radius from the nucleus double current_distance = pix_buf2.Get(); if( (current_distance <= (double)surr_dist) && (current_distance>=(-1*inside_dist)) ){ USImageType::IndexType cur_in;//,cur_in_cpy; double n_vec[3]; cur_in[0] = pix_buf2.GetIndex()[0]+boundbox[0]-1-surr_dist; cur_in[1] = pix_buf2.GetIndex()[1]+boundbox[2]-1-surr_dist; cur_in[2] = pix_buf2.GetIndex()[2]+boundbox[4]-1-surr_dist; //cur_in_cpy[0] = cur_in[0]; cur_in_cpy[1] = cur_in[1]; cur_in_cpy[2] = cur_in[2]; if( cur_in[0] < 0 || cur_in[1] < 0 || cur_in[2] < 0 ) continue; if( cur_in[0] >= sizee[0] || cur_in[1] >= sizee[1] || cur_in[2] >= sizee[2] ) continue; iterator44.SetIndex( cur_in ); USImageType::PixelType pixel_intensity; pixel_intensity = iterator44.Get(); if( pixel_intensity < thresh ) continue; //The projection of the point on the plane formed by the fist two major axes double xxx, yyy, zzz; xxx = cur_in[0] - EP_norm[0]*((EP_norm[0]*cur_in[0]+EP_norm[1]*cur_in[1]+EP_norm[2]*cur_in[2]+dee) /(EP_norm[0]*EP_norm[0]+EP_norm[1]*EP_norm[1]+EP_norm[2]*EP_norm[2])); yyy = cur_in[1] - EP_norm[1]*((EP_norm[0]*cur_in[0]+EP_norm[1]*cur_in[1]+EP_norm[2]*cur_in[2]+dee) /(EP_norm[0]*EP_norm[0]+EP_norm[1]*EP_norm[1]+EP_norm[2]*EP_norm[2])); zzz = cur_in[2] - EP_norm[2]*((EP_norm[0]*cur_in[0]+EP_norm[1]*cur_in[1]+EP_norm[2]*cur_in[2]+dee) /(EP_norm[0]*EP_norm[0]+EP_norm[1]*EP_norm[1]+EP_norm[2]*EP_norm[2])); //The vector from the centroid to the projected point n_vec[0] = centroid_x-xxx; n_vec[1] = centroid_y-yyy; n_vec[2] = centroid_z-zzz; n_sum = sqrt( n_vec[0]*n_vec[0] + n_vec[1]*n_vec[1] + n_vec[2]*n_vec[2] ); n_vec[0] /= n_sum; n_vec[1] /= n_sum; n_vec[2] /= n_sum; //n_vec is the normalized vect in the direction of the projected point //V1 is the largest eigenvector //Get the dot and cross product between the two double doooot, crooos,fin_est_angle; doooot = n_vec[0]*V1[0]+n_vec[1]*V1[1]+n_vec[2]*V1[2]; crooos = n_vec[0]*V2[0]+n_vec[1]*V2[1]+n_vec[2]*V2[2]; fin_est_angle = atan2( crooos, doooot ); USPixelType bin_num; //Compute bin num if( fin_est_angle<0 ) fin_est_angle += (2*M_PI); bin_num = floor(fin_est_angle*number_of_rois/(2*M_PI)); //Check which side of the plane the point lies on double v_norm = (cur_in[0]-centroid_x)*(cur_in[0]-centroid_x) +(cur_in[1]-centroid_y)*(cur_in[1]-centroid_y) +(cur_in[2]-centroid_z)*(cur_in[2]-centroid_z); v_norm = sqrt( v_norm ); double doot = (cur_in[0]-centroid_x)*EP_norm[0]/v_norm + (cur_in[1]-centroid_y)*EP_norm[1]/v_norm + (cur_in[2]-centroid_z)*EP_norm[2]/v_norm; if( doot<0 ) bin_num += number_of_rois; quantified_numbers_cell.at((ind*(2*number_of_rois)+bin_num)) += pixel_intensity; } } } number_of_rois = number_of_rois*2; if( labelsList.size() == 1 ) { qfied_num.clear(); return qfied_num; } std::vector<double> quantified_numbers_cell_cpy(roi_list_size); std::copy(quantified_numbers_cell.begin(), quantified_numbers_cell.end(), quantified_numbers_cell_cpy.begin() ); //Run k-means //Most of the code is adapted from mul/mbl/mbl_k_means.cxx std::sort(quantified_numbers_cell.begin(), quantified_numbers_cell.end()); bool skipKmeans; double Positive_thresh; if( quantified_numbers_cell.at(0) == quantified_numbers_cell.at(quantified_numbers_cell.size()-1) ) skipKmeans = true; if( !skipKmeans ){ std::cout<<"Starting k-means\n"; std::cout<<"First:"<<quantified_numbers_cell.at(0)<<" Last:"<<quantified_numbers_cell.at(quantified_numbers_cell.size()-1)<<std::endl; unsigned k = 2; //Vectors and matrices for k-means std::vector< USImageType::PixelType > partition( roi_list_size, 0 ); std::vector< double > sums ( k, 0.0 ); std::vector< double > centers( k, 0.0 ); std::vector< USImageType::PixelType > nNearest( k, 0 ); //Use the elements that are evenly spaced to get the intial centers for( unsigned i=0; i<k; ++i ){ double index = ((double)(i)*roi_list_size)/(k+1); centers.at(i) = quantified_numbers_cell.at((itk::SizeValueType)index); bool duplicated; std::cout<<"Initializing centers\n"<<std::flush; if(i){ if( centers.at((i-1)) == centers.at(i) ){ duplicated = true; itk::SizeValueType ind=i+1; while( centers.at((i-1))==quantified_numbers_cell.at(ind) ) ++ind; centers.at(i) = quantified_numbers_cell.at(ind); sums.at(i) = quantified_numbers_cell.at(ind); } } if(!duplicated) sums.at(i) = quantified_numbers_cell.at((i+1)/(k+1)); ++nNearest[i]; } bool changed = true; std::cout<<"Waiting for kmeans to converge\n"<<std::flush; while(changed){ changed = false; for(itk::SizeValueType i=0; i<roi_list_size; ++i){ unsigned bestCentre = 0; double bestDist = fabs((centers.at(0)-quantified_numbers_cell.at(i))); for(unsigned j=1; j<k; ++j){ double dist = fabs((centers.at(j)-quantified_numbers_cell.at(i))); if( dist < bestDist ){ bestDist = dist; bestCentre = j; } } sums[bestCentre] += quantified_numbers_cell.at(i); ++ nNearest[bestCentre]; if( bestCentre != partition.at(i) ){ changed = true; partition.at(i) = bestCentre; } } for( unsigned j=0; j<k; ++j) centers.at(j) = sums.at(j)/nNearest.at(j); for( unsigned j=0; j<k; ++j) sums.at(j) = 0; for( unsigned j=0; j<k; ++j) nNearest.at(j) = 0; } for( unsigned i=0; i<k; ++i ) std::cout<<"Center "<<i<<" "<<centers.at(i)<<"\n"; Positive_thresh = ((centers.at(0)+centers.at(1))/2) < (255.0*thresh)? ((centers.at(0)+centers.at(1))/2) : (255.0*thresh); //Arbitrary upper thresh } else Positive_thresh = 255.0*thresh; std::cout<<"Positive_thresh "<<Positive_thresh<<"\n"; std::cout<<"Done k-means\n"; itk::SizeValueType ind = 0; for( USPixelType i=0; i<labelsList.size(); ++i ){ if( zp && (zero==i) ) continue; int num_positive_rois = 0; for( unsigned j=0; j<number_of_rois; ++j ){ itk::SizeValueType index_of_roi = ind*number_of_rois+j; if( quantified_numbers_cell_cpy.at(index_of_roi)>Positive_thresh ) ++num_positive_rois; } qfied_num.push_back(num_positive_rois); ++ind; } } std::cout<<"Done surroundedness\n"<<std::flush; return qfied_num; }