void LeastSquaresFitHistory::execute() { if (_x_values.size() != _y_values.size()) mooseError("In LeastSquresFitTimeHistory size of data in x_values and y_values must be equal"); if (_x_values.size() == 0) mooseError("In LeastSquresFitTimeHistory size of data in x_values and y_values must be > 0"); // Create a copy of _x_values that we can modify. std::vector<Real> x_values(_x_values.begin(), _x_values.end()); std::vector<Real> y_values(_y_values.begin(), _y_values.end()); for (MooseIndex(_x_values) i = 0; i < _x_values.size(); ++i) { x_values[i] = (x_values[i] + _x_shift) * _x_scale; y_values[i] = (y_values[i] + _y_shift) * _y_scale; } PolynomialFit pf(x_values, y_values, _order, true); pf.generate(); std::vector<Real> coeffs = pf.getCoefficients(); mooseAssert(coeffs.size() == _coeffs.size(), "Sizes of current coefficients and vector of coefficient vectors must match"); for (MooseIndex(coeffs) i = 0; i < coeffs.size(); ++i) _coeffs[i]->push_back(coeffs[i]); _times->push_back(_t); }
HypreSolver3D::HypreSolver3D(ptrdiff_t N0_, double Lz_, ptrdiff_t N1_, double Ly_, ptrdiff_t N2_, double Lx_): N0(N0_), Lz(Lz_), N1(N1_), Ly(Ly_), N2(N2_), Lx(Lx_) { MPI_Comm_rank(MPI_COMM_WORLD, &myid); MPI_Comm_size(MPI_COMM_WORLD, &num_procs); N = N0*N1*N2; dz = Lz/(N0+1); dy = Ly/(N1+1); dx = Lx/(N2+1); h2 = dy*dy; nx = N2; ny = N1; int zp = (int)(N0/num_procs); int extra = N0-zp*num_procs; if(myid<extra) { z0 = myid*zp + myid; nz = zp+1; } else { z0 = myid*zp + extra; nz = zp; } local_size = ny*nx*nz; ilower = z0*nx*ny; iupper = ilower+local_size-1; // Build rhs and init x HYPRE_IJVectorCreate(MPI_COMM_WORLD, ilower, iupper, &hv_b); HYPRE_IJVectorSetObjectType(hv_b, HYPRE_PARCSR); HYPRE_IJVectorCreate(MPI_COMM_WORLD, ilower, iupper, &hv_x); HYPRE_IJVectorSetObjectType(hv_x, HYPRE_PARCSR); std::vector<double> rhs_values(local_size, 1.); std::vector<double> x_values(local_size, 0.); rows.resize(local_size); for (int i=0; i<local_size; i++) rows[i] = ilower + i; set_x0(&x_values[0]); set_rhs(&rhs_values[0]); build_A(); build_solver(); }
/** Calculation of a derivate with order h. @param h: order of the derivative. @param x: coordinate to interpolate to. */ double Interpolator1D::operator()(unsigned int h, double x) const { // This will be the returned value. // Initialize it to zero. double y = 0.0; if (x < x_values(0)) { if (h == 0) y = extrap_values(0); else y = 0; } else if (x > x_values(x_values.size() - 1)) { if (h == 0) y = extrap_values(1); else y = 0; } else { // if it is within the bounds, interpolate with the polynomial. unsigned int index; if (x == x_values(0)) index = 0; else if (x == x_values.last_v()) index = x_values.size() - 2; else { const double* itx = lower_bound(x_values.begin(), x_values.end(), x); itx--; index = itx - x_values.begin(); } y = calcSplineValue(index, h, x); } return y; }
/** * Interpolates the spline value for the a given abscissas "x" */ double Interpolator1D::operator()(double x) const { // This will be the returned value. // Initialize it to zero. double y = 0.0; if (x < x_values(0)) y = extrap_values(0); else if (x == x_values(0)) y = y_values(0); else if (x > x_values(x_values.size() - 1)) y = extrap_values(1); else { // if it is within the bounds, interpolate with the polynomial. const double* itx = lower_bound(x_values.begin(), x_values.end(), x); itx--; const unsigned int index = itx - x_values.begin(); //Important note!: spline values could be different from //node values because of discontinuity of the spline at the nodes. //When the spline is discontinuous, the function value is one half //the value from the left and the value from the right. if (x == x_values(index)) y = y_values(index); else if (x == x_values(index + 1)) y = y_values(index + 1); else y = calcSplineValue(index, 0, x); } return y; }
double Interpolator1D::calcSplineValue(unsigned int interval, unsigned int h, double x) const { double dx = x - x_values(interval); double t = 1.0; double y = 0.0; for (size_t j = h; j < spline_coeffs.numrows(); ++j) { double m = 1.0; for (size_t k = j; k > j - h; --k) m *= double(k); y += spline_coeffs(j, interval) * m * t; t *= dx; } return y; }
Vector<double> Interpolator1D::getInterpolationRange() const { Vector<double> x(2); x(0) = x_values(0); x(1) = x_values.last_v(); return x; }
// Processes the point cloud with OpenCV using the PCL cluster indices void processClusters( const std::vector<pcl::PointIndices> cluster_indices, // const sensor_msgs::PointCloud2ConstPtr& pointcloud_msg, const pcl::PointCloud<pcl::PointXYZRGB>::ConstPtr cloud_transformed, const pcl::PointCloud<pcl::PointXYZRGB>::ConstPtr& cloud_filtered, const pcl::PointCloud<pcl::PointXYZRGB>& cloud ) { // ------------------------------------------------------------------------------------------------------- // Convert image ROS_INFO_STREAM_NAMED("perception","Converting image to OpenCV format"); try { sensor_msgs::ImagePtr image_msg(new sensor_msgs::Image); // pcl::toROSMsg (*pointcloud_msg, *image_msg); pcl::toROSMsg (*cloud_transformed, *image_msg); cv_bridge::CvImagePtr input_bridge = cv_bridge::toCvCopy(image_msg, "rgb8"); full_input_image = input_bridge->image; } catch (cv_bridge::Exception& ex) { ROS_ERROR_STREAM_NAMED("perception","[calibrate] Failed to convert image"); return; } // ------------------------------------------------------------------------------------------------------- // Process Image // Convert image to gray cv::cvtColor( full_input_image, full_input_image_gray, CV_BGR2GRAY ); //cv::adaptiveThreshold( full_input_image, full_input_image_gray, 255, CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY,5,10); // Blur image - reduce noise with a 3x3 kernel cv::blur( full_input_image_gray, full_input_image_gray, cv::Size(3,3) ); ROS_INFO_STREAM_NAMED("perception","Finished coverting"); // ------------------------------------------------------------------------------------------------------- // Check OpenCV and PCL image height for errors int image_width = cloud.width; int image_height = cloud.height; ROS_DEBUG_STREAM( "PCL Image height " << image_height << " -- width " << image_width << "\n"); int image_width_cv = full_input_image.size.p[1]; int image_height_cv = full_input_image.size.p[0]; ROS_DEBUG_STREAM( "OpenCV Image height " << image_height_cv << " -- width " << image_width_cv << "\n"); if( image_width != image_width_cv || image_height != image_height_cv ) { ROS_ERROR_STREAM_NAMED("perception","PCL and OpenCV image heights/widths do not match!"); return; } // ------------------------------------------------------------------------------------------------------- // GUI Stuff // First window const char* opencv_window = "Source"; /* cv::namedWindow( opencv_window, CV_WINDOW_AUTOSIZE ); cv::imshow( opencv_window, full_input_image_gray ); */ // while(true) // use this when we want to tweak the image { output_image = full_input_image.clone(); // ------------------------------------------------------------------------------------------------------- // Start processing clusters ROS_INFO_STREAM_NAMED("perception","Finding min/max in x/y axis"); int top_image_overlay_x = 0; // tracks were to copyTo the mini images // for each cluster, see if it is a block for(size_t c = 0; c < cluster_indices.size(); ++c) { ROS_INFO_STREAM_NAMED("perception","\n\n"); ROS_INFO_STREAM_NAMED("perception","On cluster " << c); // find the outer dimensions of the cluster double xmin = 0; double xmax = 0; double ymin = 0; double ymax = 0; // also remember each min & max's correponding other coordinate (not needed for z) double xminy = 0; double xmaxy = 0; double yminx = 0; double ymaxx = 0; // also remember their corresponding indice int xmini = 0; int xmaxi = 0; int ymini = 0; int ymaxi = 0; // loop through and find all min/max of x/y for(size_t i = 0; i < cluster_indices[c].indices.size(); i++) { int j = cluster_indices[c].indices[i]; // Get RGB from point cloud pcl::PointXYZRGB p = cloud_transformed->points[j]; double x = p.x; double y = p.y; if(i == 0) // initial values { xmin = xmax = x; ymin = ymax = y; xminy = xmaxy = y; yminx = ymaxx = x; xmini = xmaxi = ymini = ymaxi = j; // record the indice corresponding to the min/max } else { if( x < xmin ) { xmin = x; xminy = y; xmini = j; } if( x > xmax ) { xmax = x; xmaxy = y; xmaxi = j; } if( y < ymin ) { ymin = y; yminx = x; ymini = j; } if( y > ymax ) { ymax = y; ymaxx = x; ymaxi = j; } } } ROS_DEBUG_STREAM_NAMED("perception","Cluster size - xmin: " << xmin << " xmax: " << xmax << " ymin: " << ymin << " ymax: " << ymax); ROS_DEBUG_STREAM_NAMED("perception","Cluster size - xmini: " << xmini << " xmaxi: " << xmaxi << " ymini: " << ymini << " ymaxi: " << ymaxi); // --------------------------------------------------------------------------------------------- // Check if these dimensions make sense for the block size specified double xside = xmax-xmin; double yside = ymax-ymin; const double tol = 0.01; // 1 cm error tolerance // In order to be part of the block, xside and yside must be between // blocksize and blocksize*sqrt(2) if(xside > block_size-tol && xside < block_size*sqrt(2)+tol && yside > block_size-tol && yside < block_size*sqrt(2)+tol ) { // ------------------------------------------------------------------------------------------------------- // Get the four farthest corners of the block - use OpenCV only on the region identified by PCL // Get the pixel coordinates of the xmax and ymax indicies int px_xmax = 0; int py_xmax = 0; int px_ymax = 0; int py_ymax = 0; getXYCoordinates( xmaxi, image_height, image_width, px_xmax, py_xmax); getXYCoordinates( ymaxi, image_height, image_width, px_ymax, py_ymax); // Get the pixel coordinates of the xmin and ymin indicies int px_xmin = 0; int py_xmin = 0; int px_ymin = 0; int py_ymin = 0; getXYCoordinates( xmini, image_height, image_width, px_xmin, py_xmin); getXYCoordinates( ymini, image_height, image_width, px_ymin, py_ymin); ROS_DEBUG_STREAM_NAMED("perception","px_xmin " << px_xmin << " px_xmax: " << px_xmax << " py_ymin: " << py_ymin << " py_ymax: " << py_ymax ); // ------------------------------------------------------------------------------------------------------- // Change the frame of reference from the robot to the camera // Create an array of all the x value options const int x_values_a[] = {px_xmax, px_ymax, px_xmin, px_ymin}; const int y_values_a[] = {py_xmax, py_ymax, py_xmin, py_ymin}; // Turn it into a vector std::vector<int> x_values (x_values_a, x_values_a + sizeof(x_values_a) / sizeof(x_values_a[0])); std::vector<int> y_values (y_values_a, y_values_a + sizeof(y_values_a) / sizeof(y_values_a[0])); // Find the min int x1 = *std::min_element(x_values.begin(), x_values.end()); int y1 = *std::min_element(y_values.begin(), y_values.end()); // Find the max int x2 = *std::max_element(x_values.begin(), x_values.end()); int y2 = *std::max_element(y_values.begin(), y_values.end()); ROS_DEBUG_STREAM_NAMED("perception","x1: " << x1 << " y1: " << y1 << " x2: " << x2 << " y2: " << y2); // ------------------------------------------------------------------------------------------------------- // Expand the ROI by a fudge factor, if possible const int FUDGE_FACTOR = 5; // pixels if( x1 > FUDGE_FACTOR) x1 -= FUDGE_FACTOR; if( y1 > FUDGE_FACTOR ) y1 -= FUDGE_FACTOR; if( x2 < image_width - FUDGE_FACTOR ) x2 += FUDGE_FACTOR; if( y2 < image_height - FUDGE_FACTOR ) y2 += FUDGE_FACTOR; ROS_DEBUG_STREAM_NAMED("perception","After Fudge Factor - x1: " << x1 << " y1: " << y1 << " x2: " << x2 << " y2: " << y2); // ------------------------------------------------------------------------------------------------------- // Create ROI parameters // (x1,y1)---------------------- // | | // | ROI | // | | // |_____________________(x2,y2)| // Create Region of Interest int roi_width = x2 - x1; int roi_height = y2 - y1; cv::Rect region_of_interest = cv::Rect( x1, y1, roi_width, roi_height ); ROS_DEBUG_STREAM_NAMED("perception","ROI: x " << x1 << " -- y " << y1 << " -- height " << roi_height << " -- width " << roi_width ); // ------------------------------------------------------------------------------------------------------- // Find paramters of the block in pixel coordiantes int block_center_x = x1 + 0.5*roi_width; int block_center_y = y1 + 0.5*roi_height; int block_center_z = block_size / 2; // TODO: make this better const cv::Point block_center = cv::Point( block_center_x, block_center_y ); // ------------------------------------------------------------------------------------------------------- // Create a sub image of just the block cv::Point a1 = cv::Point(x1, y1); cv::Point a2 = cv::Point(x2, y2); cv::rectangle( output_image, a1, a2, cv::Scalar(0, 255, 255), 1, 8); // Crop image (doesn't actually copy the data) cropped_image = full_input_image_gray(region_of_interest); // ------------------------------------------------------------------------------------------------------- // Detect edges using canny ROS_INFO_STREAM_NAMED("perception","Detecting edges using canny"); // Find edges cv::Mat canny_output; cv::Canny( cropped_image, canny_output, canny_threshold, canny_threshold*2, 3 ); // Get mini window stats const int mini_width = canny_output.size.p[1]; const int mini_height = canny_output.size.p[0]; const cv::Size mini_size = canny_output.size(); const cv::Point mini_center = cv::Point( mini_width/2, mini_height/2 ); // Find contours vector<vector<cv::Point> > contours; vector<cv::Vec4i> hierarchy; cv::findContours( canny_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, cv::Point(0, 0) ); ROS_INFO_STREAM_NAMED("perception","Contours"); // Draw contours cv::Mat drawing = cv::Mat::zeros( mini_size, CV_8UC3 ); ROS_INFO_STREAM_NAMED("perception","Drawing contours"); // Find the largest contour for getting the angle double max_contour_length = 0; int max_contour_length_i; for( size_t i = 0; i< contours.size(); i++ ) { double contour_length = cv::arcLength( contours[i], false ); if( contour_length > max_contour_length ) { max_contour_length = contour_length; max_contour_length_i = i; } //ROS_DEBUG_STREAM_NAMED("perception","Contour length = " << contour_length << " of index " << max_contour_length_i); cv::Scalar color = cv::Scalar( (30 + i*10) % 255, (30 + i*10) % 255, (30 + i*10) % 255); cv::drawContours( drawing, contours, (int)i, color, 1, 8, hierarchy, 0, cv::Point() ); //drawContours( image, contours, contourIdx, color, thickness, lineType, hierarchy, maxLevel, offset ) } // ------------------------------------------------------------------------------------------------------- // Copy largest contour to main image cv::Scalar color = cv::Scalar( 0, 255, 0 ); cv::drawContours( output_image, contours, (int)max_contour_length_i, color, 1, 8, hierarchy, 0, a1 ); //drawContours( image, contours, contourIdx, color, thickness, lineType, hierarchy, maxLevel, offset ) // ------------------------------------------------------------------------------------------------------- // Copy largest contour to seperate image cv::Mat hough_input = cv::Mat::zeros( mini_size, CV_8UC1 ); cv::Mat hough_input_color; cv::Scalar hough_color = cv::Scalar( 200 ); cv::drawContours( hough_input, contours, (int)max_contour_length_i, hough_color, 1, 8, hierarchy, 0 ); cv::cvtColor(hough_input, hough_input_color, CV_GRAY2BGR); // ------------------------------------------------------------------------------------------------------- // Hough Transform cv::Mat hough_drawing = cv::Mat::zeros( mini_size, CV_8UC3 ); std::vector<cv::Vec4i> lines; ROS_DEBUG_STREAM_NAMED("perception","hough_rho " << hough_rho << " hough_theta " << hough_theta << " theta_converted " << (1/hough_theta)*CV_PI/180 << " hough_threshold " << hough_threshold << " hough_minLineLength " << hough_minLineLength << " hough_maxLineGap " << hough_maxLineGap ); cv::HoughLinesP(hough_input, lines, hough_rho, (1/hough_theta)*CV_PI/180, hough_threshold, hough_minLineLength, hough_maxLineGap); ROS_WARN_STREAM_NAMED("perception","Found " << lines.size() << " lines"); std::vector<double> line_angles; // Copy detected lines to the drawing image for( size_t i = 0; i < lines.size(); i++ ) { cv::Vec4i line = lines[i]; cv::line( hough_drawing, cv::Point(line[0], line[1]), cv::Point(line[2], line[3]), cv::Scalar(255,255,255), 1, CV_AA); // Error check if(line[3] - line[1] == 0 && line[2] - line[0] == 0) { ROS_ERROR_STREAM_NAMED("perception","Line is actually two points at the origin, unable to calculate. TODO: handle better?"); continue; } // Find angle double line_angle = atan2(line[3] - line[1], line[2] - line[0]); //in radian, degrees: * 180.0 / CV_PI; // Reverse angle direction if negative if( line_angle < 0 ) { line_angle += CV_PI; } line_angles.push_back(line_angle); ROS_DEBUG_STREAM_NAMED("perception","Hough Line angle: " << line_angle * 180.0 / CV_PI;); } double block_angle = 0; // the overall result of the block's angle // Everything is based on the first angle if( line_angles.size() == 0 ) // make sure we have at least 1 angle { ROS_ERROR_STREAM_NAMED("perception","No lines were found for this cluster, unable to calculate block angle"); } else { calculateBlockAngle( line_angles, block_angle ); } // ------------------------------------------------------------------------------------------------------- // Draw chosen angle ROS_INFO_STREAM_NAMED("perception","Using block angle " << block_angle*180.0/CV_PI); // Draw chosen angle on mini image cv::Mat angle_drawing = cv::Mat::zeros( mini_size, CV_8UC3 ); int line_length = 0.5*double(mini_width); // have the line go 1/4 across the screen int new_x = mini_center.x + line_length*cos( block_angle ); int new_y = mini_center.y + line_length*sin( block_angle ); ROS_INFO_STREAM("Origin (" << mini_center.x << "," << mini_center.y << ") New (" << new_x << "," << new_y << ") length " << line_length << " angle " << block_angle << " mini width " << mini_width << " mini height " << mini_height); cv::Point angle_point = cv::Point(new_x, new_y); cv::line( angle_drawing, mini_center, angle_point, cv::Scalar(255,255,255), 1, CV_AA); // Draw chosen angle on contours image cv::line( hough_drawing, mini_center, angle_point, cv::Scalar(255,0, 255), 1, CV_AA); // Draw chosen angle on main image line_length = 0.75 * double(mini_width); // have the line go 1/2 across the box new_x = block_center_x + line_length*cos( block_angle ); new_y = block_center_y + line_length*sin( block_angle ); ROS_INFO_STREAM_NAMED("perception",block_center_x << ", " << block_center_y << ", " << new_x << ", " << new_y); angle_point = cv::Point(new_x, new_y); cv::line( output_image, block_center, angle_point, cv::Scalar(255,0,255), 2, CV_AA); // ------------------------------------------------------------------------------------------------------- // Get world coordinates // Find the block's center point double world_x1 = xmin+(xside)/2.0; double world_y1 = ymin+(yside)/2.0; double world_z1 = table_height + block_size / 2; // Convert pixel coordiantes back to world coordinates double world_x2 = cloud_transformed->at(new_x, new_y).x; double world_y2 = cloud_transformed->at(new_x, new_y).y; double world_z2 = world_z1; // is this even necessary? // Get angle from two world coordinates... double world_theta = abs( atan2(world_y2 - world_y1, world_x2 - world_x1) ); // Attempt to make all angles point in same direction makeAnglesUniform( world_theta ); // ------------------------------------------------------------------------------------------------------- // GUI Stuff // Copy the cluster image to the main image in the top left corner if( top_image_overlay_x + mini_width < image_width ) { const int common_height = 42; cv::Rect small_roi_row0 = cv::Rect(top_image_overlay_x, common_height*0, mini_width, mini_height); cv::Rect small_roi_row1 = cv::Rect(top_image_overlay_x, common_height*1, mini_width, mini_height); cv::Rect small_roi_row2 = cv::Rect(top_image_overlay_x, common_height*2, mini_width, mini_height); cv::Rect small_roi_row3 = cv::Rect(top_image_overlay_x, common_height*3, mini_width, mini_height); drawing.copyTo( output_image(small_roi_row0) ); hough_input_color.copyTo( output_image(small_roi_row1) ); hough_drawing.copyTo( output_image(small_roi_row2) ); angle_drawing.copyTo( output_image(small_roi_row3) ); top_image_overlay_x += mini_width; } // figure out the position and the orientation of the block //double angle = atan(block_size/((xside+yside)/2)); //double angle = atan( (xmaxy - xminy) / (xmax - xmin ) ); // Then add it to our set //addBlock( xmin+(xside)/2.0, ymin+(yside)/2.0, zmax - block_size/2.0, angle); //ROS_INFO_STREAM_NAMED("perception","FOUND -> xside: " << xside << " yside: " << yside << " angle: " << block_angle); addBlock( world_x1, world_y1, world_z1, world_theta ); //addBlock( block_center_x, block_center_y, block_center_z, block_angle); } else {
RcppExport SEXP treePhaser(SEXP Rsignal, SEXP RkeyFlow, SEXP RflowCycle, SEXP Rcf, SEXP Rie, SEXP Rdr, SEXP Rbasecaller, SEXP RdiagonalStates, SEXP RmodelFile, SEXP RmodelThreshold, SEXP Rxval, SEXP Ryval) { SEXP ret = R_NilValue; char *exceptionMesg = NULL; try { Rcpp::NumericMatrix signal(Rsignal); Rcpp::IntegerVector keyFlow(RkeyFlow); string flowCycle = Rcpp::as<string>(RflowCycle); Rcpp::NumericVector cf_vec(Rcf); Rcpp::NumericVector ie_vec(Rie); Rcpp::NumericVector dr_vec(Rdr); string basecaller = Rcpp::as<string>(Rbasecaller); unsigned int diagonalStates = Rcpp::as<int>(RdiagonalStates); // Recalibration Variables string model_file = Rcpp::as<string>(RmodelFile); int model_threshold = Rcpp::as<int>(RmodelThreshold); Rcpp::IntegerVector x_values(Rxval); Rcpp::IntegerVector y_values(Ryval); RecalibrationModel recalModel; if (model_file.length() > 0) { recalModel.InitializeModel(model_file, model_threshold); } ion::FlowOrder flow_order(flowCycle, flowCycle.length()); unsigned int nFlow = signal.cols(); unsigned int nRead = signal.rows(); if(basecaller != "treephaser-swan" && basecaller != "treephaser-solve" && basecaller != "dp-treephaser" && basecaller != "treephaser-adaptive") { std::string exception = "base value for basecaller supplied: " + basecaller; exceptionMesg = strdup(exception.c_str()); } else if (flowCycle.length() < nFlow) { std::string exception = "Flow cycle is shorter than number of flows to solve"; exceptionMesg = strdup(exception.c_str()); } else { // Prepare objects for holding and passing back results Rcpp::NumericMatrix predicted_out(nRead,nFlow); Rcpp::NumericMatrix residual_out(nRead,nFlow); Rcpp::NumericMatrix norm_additive_out(nRead,nFlow); Rcpp::NumericMatrix norm_multipl_out(nRead,nFlow); std::vector< std::string> seq_out(nRead); // Set up key flow vector int nKeyFlow = keyFlow.size(); vector <int> keyVec(nKeyFlow); for(int iFlow=0; iFlow < nKeyFlow; iFlow++) keyVec[iFlow] = keyFlow(iFlow); // Iterate over all reads vector <float> sigVec(nFlow); BasecallerRead read; DPTreephaser dpTreephaser(flow_order); dpTreephaser.SetStateProgression((diagonalStates>0)); // In contrast to pipeline, we always use droop here. // To have the same behavior of treephaser-swan as in the pipeline, supply dr=0 bool per_read_phasing = true; if (cf_vec.size() == 1) { per_read_phasing = false; dpTreephaser.SetModelParameters((double)cf_vec(0), (double)ie_vec(0), (double)dr_vec(0)); } // Main loop iterating over reads and solving them for(unsigned int iRead=0; iRead < nRead; iRead++) { // Set phasing parameters for this read if (per_read_phasing) dpTreephaser.SetModelParameters((double)cf_vec(iRead), (double)ie_vec(iRead), (double)dr_vec(iRead)); // And load recalibration model if (recalModel.is_enabled()) { int my_x = (int)x_values(iRead); int my_y = (int)y_values(iRead); const vector<vector<vector<float> > > * aPtr = 0; const vector<vector<vector<float> > > * bPtr = 0; aPtr = recalModel.getAs(my_x, my_y); bPtr = recalModel.getBs(my_x, my_y); if (aPtr == 0 or bPtr == 0) { cout << "Error finding a recalibration model for x: " << x_values(iRead) << " y: " << y_values(iRead); cout << endl; } dpTreephaser.SetAsBs(aPtr, bPtr); } for(unsigned int iFlow=0; iFlow < nFlow; iFlow++) sigVec[iFlow] = (float) signal(iRead,iFlow); // Interface to just solve without any normalization if (basecaller == "treephaser-solve") { // Interface to just solve without any normalization read.SetData(sigVec, (int)nFlow); } else { read.SetDataAndKeyNormalize(&(sigVec[0]), (int)nFlow, &(keyVec[0]), nKeyFlow-1); } // Execute the iterative solving-normalization routine if (basecaller == "dp-treephaser") { dpTreephaser.NormalizeAndSolve_GainNorm(read, nFlow); } else if (basecaller == "treephaser-solve") { dpTreephaser.Solve(read, nFlow); } else if (basecaller == "treephaser-adaptive") { dpTreephaser.NormalizeAndSolve_Adaptive(read, nFlow); // Adaptive normalization } else { dpTreephaser.NormalizeAndSolve_SWnorm(read, nFlow); // sliding window adaptive normalization } seq_out[iRead].assign(read.sequence.begin(), read.sequence.end()); for(unsigned int iFlow=0; iFlow < nFlow; iFlow++) { predicted_out(iRead,iFlow) = (double) read.prediction[iFlow]; residual_out(iRead,iFlow) = (double) read.normalized_measurements[iFlow] - read.prediction[iFlow]; norm_multipl_out(iRead,iFlow) = (double) read.multiplicative_correction.at(iFlow); norm_additive_out(iRead,iFlow) = (double) read.additive_correction.at(iFlow); } } // Store results ret = Rcpp::List::create(Rcpp::Named("seq") = seq_out, Rcpp::Named("predicted") = predicted_out, Rcpp::Named("residual") = residual_out, Rcpp::Named("norm_additive") = norm_additive_out, Rcpp::Named("norm_multipl") = norm_multipl_out); } } catch(std::exception& ex) { forward_exception_to_r(ex); } catch(...) { ::Rf_error("c++ exception (unknown reason)"); } if(exceptionMesg != NULL) Rf_error(exceptionMesg); return ret; }
RcppExport SEXP treePhaserSim(SEXP Rsequence, SEXP RflowCycle, SEXP Rcf, SEXP Rie, SEXP Rdr, SEXP Rmaxflows, SEXP RgetStates, SEXP RdiagonalStates, SEXP RmodelFile, SEXP RmodelThreshold, SEXP Rxval, SEXP Ryval) { SEXP ret = R_NilValue; char *exceptionMesg = NULL; try { Rcpp::StringVector sequences(Rsequence); string flowCycle = Rcpp::as<string>(RflowCycle); Rcpp::NumericMatrix cf_vec(Rcf); Rcpp::NumericMatrix ie_vec(Rie); Rcpp::NumericMatrix dr_vec(Rdr); unsigned int max_flows = Rcpp::as<int>(Rmaxflows); unsigned int get_states = Rcpp::as<int>(RgetStates); unsigned int diagonalStates = Rcpp::as<int>(RdiagonalStates); // Recalibration Variables string model_file = Rcpp::as<string>(RmodelFile); int model_threshold = Rcpp::as<int>(RmodelThreshold); Rcpp::IntegerVector x_values(Rxval); Rcpp::IntegerVector y_values(Ryval); RecalibrationModel recalModel; if (model_file.length() > 0) { recalModel.InitializeModel(model_file, model_threshold); } ion::FlowOrder flow_order(flowCycle, flowCycle.length()); unsigned int nFlow = flow_order.num_flows(); unsigned int nRead = sequences.size(); max_flows = min(max_flows, nFlow); // Prepare objects for holding and passing back results Rcpp::NumericMatrix predicted_out(nRead,nFlow); vector<vector<float> > query_states; vector<int> hp_lengths; // Iterate over all sequences BasecallerRead read; DPTreephaser dpTreephaser(flow_order); bool per_read_phasing = true; if (cf_vec.ncol() == 1) { per_read_phasing = false; dpTreephaser.SetModelParameters((double)cf_vec(0,0), (double)ie_vec(0,0), (double)dr_vec(0,0)); } dpTreephaser.SetStateProgression((diagonalStates>0)); unsigned int max_length = (2*flow_order.num_flows()); for(unsigned int iRead=0; iRead<nRead; iRead++) { string mySequence = Rcpp::as<std::string>(sequences(iRead)); read.sequence.clear(); read.sequence.reserve(2*flow_order.num_flows()); for(unsigned int iBase=0; iBase<mySequence.length() and iBase<max_length; ++iBase){ read.sequence.push_back(mySequence.at(iBase)); } // Set phasing parameters for this read if (per_read_phasing) dpTreephaser.SetModelParameters((double)cf_vec(0,iRead), (double)ie_vec(0,iRead), (double)dr_vec(0,iRead)); // If you bothered specifying a recalibration model you probably want its effect on the predictions... if (recalModel.is_enabled()) { int my_x = (int)x_values(iRead); int my_y = (int)y_values(iRead); const vector<vector<vector<float> > > * aPtr = 0; const vector<vector<vector<float> > > * bPtr = 0; aPtr = recalModel.getAs(my_x, my_y); bPtr = recalModel.getBs(my_x, my_y); if (aPtr == 0 or bPtr == 0) { cout << "Error finding a recalibration model for x: " << x_values(iRead) << " y: " << y_values(iRead); cout << endl; } dpTreephaser.SetAsBs(aPtr, bPtr); } if (nRead == 1 and get_states > 0) dpTreephaser.QueryAllStates(read, query_states, hp_lengths, max_flows); else dpTreephaser.Simulate(read, max_flows); for(unsigned int iFlow=0; iFlow<nFlow and iFlow<max_flows; ++iFlow){ predicted_out(iRead,iFlow) = (double) read.prediction.at(iFlow); } } // Store results if (nRead == 1 and get_states > 0) { Rcpp::NumericMatrix states(hp_lengths.size(), nFlow); Rcpp::NumericVector HPlengths(hp_lengths.size()); for (unsigned int iHP=0; iHP<hp_lengths.size(); iHP++){ HPlengths(iHP) = (double)hp_lengths[iHP]; for (unsigned int iFlow=0; iFlow<nFlow; iFlow++) states(iHP, iFlow) = (double)query_states.at(iHP).at(iFlow); } ret = Rcpp::List::create(Rcpp::Named("sig") = predicted_out, Rcpp::Named("states") = states, Rcpp::Named("HPlengths") = HPlengths); } else { ret = Rcpp::List::create(Rcpp::Named("sig") = predicted_out); } } catch(std::exception& ex) { forward_exception_to_r(ex); } catch(...) { ::Rf_error("c++ exception (unknown reason)"); } if(exceptionMesg != NULL) Rf_error(exceptionMesg); return ret; }