void
 CDFBasis<d,dt>::evaluate
 (const unsigned int derivative,
  const RIndex& lambda,
  const Array1D<double>& points, Array1D<double>& values)
 {
   values.resize(points.size());
   for (unsigned int i(0); i < values.size(); i++) {
     values[i] = evaluate(derivative, lambda, points[i]);
   }
 }
/*!
 * Name		  : rayTraceFiller
 * Description: Used to generate rachis segmentation
 * Arguments  : PROTO_INPUT  : protobuf input containing segmented germline
 * 				IMAGE_OUTPUT : float image containing intermediate rachis segmentation.  This
 * 				               image needs to be post-processed (thresholding, throw out
 * 				               unconnected components).
 * Syntax	  : ./segpipeline_FREEBSD 0 0 0 0 0 PROTO_INPUT 0 0 rayTraceFiller 32 IMAGE_OUTPUT 0 0 0 0 0 0 0 0
 * Notes	  : This function has a random component, so you won't get the exact same result every time.
 */
void rayTraceFiller(TextIO* inputText, ImageIO* outputImage,
		CallbackFunctions *cb) {
	log(cb, 4, "Calculating rachis segmentation through ray tracing");

	// generate full segmentation
	Protobuf proto(cb);
	proto.readProto(inputText);
	Image3D<float> *I = new Image3D<float> (cb);
	Array1D<float> color(cb);
	proto.getList("protobuf_index", &color);
	color + 1;
	proto.drawSegmentationImage("full", I, &color);

	// generate points spaced uniformly on a sphere
	double Jiggle = 0.03 / sqrt(double(NUM_UNIFORM_POINTS_ON_SPHERE));
	unsigned int Rounds = 5000;
	points P("default", NUM_UNIFORM_POINTS_ON_SPHERE, Jiggle, Rounds);
	Array1D<float> *xUniformP = new Array1D<float> (cb);
	Array1D<float> *yUniformP = new Array1D<float> (cb);
	Array1D<float> *zUniformP = new Array1D<float> (cb);
	P.report(xUniformP, yUniformP, zUniformP);

	// allocate rayScore.   0 if not yet checked, 1 if collision, 2 if no collision
	int dimx, dimy, dimz;
	I->getDimensions(dimx, dimy, dimz);
	boost::multi_array<unsigned char, 4> *rayScore = new boost::multi_array<
			unsigned char, 4>(
			boost::extents[dimx][dimy][dimz][NUM_UNIFORM_POINTS_ON_SPHERE]);

	// allocate array for progress bar
	Array1D<float> *progress = new Array1D<float> (cb);
	progress->resize(NUM_UNIFORM_POINTS_ON_SPHERE);

	// do ray tracing
	log(cb, 4, "Starting ray tracing");
#if defined USELIBDISPATCH
	dispatch_apply(NUM_UNIFORM_POINTS_ON_SPHERE, dispatch_get_global_queue(0,0), ^(size_t ii) {
#else
	for (int ii = 0; ii < NUM_UNIFORM_POINTS_ON_SPHERE; ii++) {
#endif
		int i = (int) ii;

		// get a discrete line
		int xP = iround(LENGTH_BRESENHAM_LINE * (*xUniformP)(i));
		int yP = iround(LENGTH_BRESENHAM_LINE * (*yUniformP)(i));
		int zP = iround(LENGTH_BRESENHAM_LINE * (*zUniformP)(i));
		Array1D<int> xLine(cb), yLine(cb), zLine(cb);
		bresenhamLine(&xLine, &yLine, &zLine, xP, yP, zP);

		// check if ray hits image boundary for every pixel in the image
		for (int xc = 0; xc < dimx; xc++) {
			for (int yc = 0; yc < dimy; yc++) {
				for (int zc = 0; zc < dimz; zc++) {

					// only do ray tracing if ray has not passed through point previously.
					if ((*rayScore)[xc][yc][zc][i] == 0) {
						// iterate over length of ray
						for (int r = 0; r < yLine.size(); r++) {
							int x = xc + xLine(r), y = yc + yLine(r), z = zc
									+ zLine(r);
							if (x >= 0 & x < dimx & y >= 0 & y < dimy & z >= 0
									& z < dimz) { // check if ray in image boundary
								if ((*I)(x, y, z) > float(BWTHRESH)) { // if collision detected, update collision information for all points on ray
									for (int rr = 0; rr <= r; rr++) {
										int xx = xc + xLine(rr), yy = yc
												+ yLine(rr), zz = zc
												+ zLine(rr);
										(*rayScore)[xx][yy][zz][i] = 1;
									}
									break;
								}
								// else ray has reach image boundary
							} else {
								// update non-collision information on all points on the ray
								for (int rr = 0; rr < r; rr++) {
									int xx = xc + xLine(rr), yy = yc
											+ yLine(rr), zz = zc + zLine(rr);
									(*rayScore)[xx][yy][zz][i] = 2;
								}
								break; // break out of iteration over length of the ray
							}
						} // end iterate over length of ray
					}
				}
			}
		}

		// update progress
		(*progress)(i) = 1;
		int progressOutOf100 = (int) (progress->sum()
				/ NUM_UNIFORM_POINTS_ON_SPHERE * 100);
		cb->progressReport(progressOutOf100);
#if defined USELIBDISPATCH
	});
#else
	}
  Array1D<SampledMapping<2> >
  evaluate(const LDomainJLBasis& basis,
	   const Index& lambda,
	   const int N)
  {
    Array1D<SampledMapping<2> > r(3);

    // supp(psi_{j,e,c,k}) = 2^{-j}[k1-1,k1+1]x[k2-1,k2+1] cap Omega

    FixedArray1D<Array1D<double>,2> values;
    values[0].resize(N+1); // values in x-direction
    values[1].resize(N+1); // values in y-direction
    Array1D<double> knots;
    knots.resize(N+1);
    const double h = 1./N;
    
    // patch Omega_0 = [-1,0]x[0,1]
    for (int i = 0; i <= N; i++) {
      values[0][i] = 0.;
      values[1][i] = 0.;
    }
    if (lambda.k()[0] <= 0 && lambda.k()[1] >= 0) {
      for (int i = 0; i <= N; i++)
	knots[i] = -1.0+i*h;
      evaluate(0, lambda.j(), lambda.e()[0], lambda.c()[0], lambda.k()[0], knots, values[0]);
      for (int i = 0; i <= N; i++)
	knots[i] = i*h;
      evaluate(0, lambda.j(), lambda.e()[1], lambda.c()[1], lambda.k()[1], knots, values[1]);
    }
    r[0] = SampledMapping<2>(Point<2>(-1, 0), Point<2>(0,1), values);
    
    // patch Omega_1 = [-1,0]x[-1,0]
    for (int i = 0; i <= N; i++) {
      values[0][i] = 0.;
      values[1][i] = 0.;
    }
    if (lambda.k()[0] <= 0 && lambda.k()[1] <= 0) {
      for (int i = 0; i <= N; i++)
	knots[i] = -1.0+i*h;
      evaluate(0, lambda.j(), lambda.e()[0], lambda.c()[0], lambda.k()[0], knots, values[0]);
      evaluate(0, lambda.j(), lambda.e()[1], lambda.c()[1], lambda.k()[1], knots, values[1]);
    }
    r[1] = SampledMapping<2>(Point<2>(-1,-1), Point<2>(0,0), values);
    
    // patch Omega_2 = [0,1]x[-1,0]
    for (int i = 0; i <= N; i++) {
      values[0][i] = 0.;
      values[1][i] = 0.;
    }
    if (lambda.k()[0] >= 0 && lambda.k()[1] <= 0) {
      for (int i = 0; i <= N; i++)
	knots[i] = i*h;
      evaluate(0, lambda.j(), lambda.e()[0], lambda.c()[0], lambda.k()[0], knots, values[0]);
      for (int i = 0; i <= N; i++)
	knots[i] = -1.0+i*h;
      evaluate(0, lambda.j(), lambda.e()[1], lambda.c()[1], lambda.k()[1], knots, values[1]);
    }
    r[2] = SampledMapping<2>(Point<2>( 0,-1), Point<2>(1,0), values);
    
    return r;
  }
Exemple #4
0
/*!
 * Print simulation results to standard output
 */
void printSimulationResultsForTed_pedigreeDepth(PedigreeDepthStorage *pdStorage, bool cellProductionConstraintsMet, bool fecundityScheduleConstraintsMet, bool allConstraintsMet, ProgramOptionParser *opt) {

	// print pedigree depth (i.e., value that Ted's optimizer is minimizing)
	float valueBeingOptimized = 0;
	string option_str(opt->fitnessMetric.c_str());
	if      (option_str.find("meanPedigreeDepthMeioticCells:")!=string::npos) {valueBeingOptimized = pdStorage->pd_AllCellsEnterMeioticRegion->mean();}
	else if (strcmp(option_str.c_str(),"spermOocyteMean")==0) {valueBeingOptimized = pdStorage->pd_spermOocyte->mean();}
	else if (strcmp(option_str.c_str(),"spermOocyteSum")==0) {valueBeingOptimized = pdStorage->pd_spermOocyteSum->mean();}
	else if (strcmp(option_str.c_str(),"generationRate")==0) {float r = calculateGenerationFitness(pdStorage->simulatedFecunditySchedule,pdStorage->fecundityConstraints,pdStorage->pd_spermOocyte->mean(),opt->deleteriousMutationRate,opt->maximalGenerationRate,opt->maximalPedigreeDepth);valueBeingOptimized = -r;}
        else if (strcmp(option_str.c_str(),"generationRate2")==0) {float r = calculateGenerationFitness_selectionCoefficient(pdStorage->simulatedFecunditySchedule,pdStorage->fecundityConstraints,pdStorage->pd_spermOocyte->mean(),opt->deleteriousMutationRate,opt->maximalGenerationRate,opt->maximalPedigreeDepth);valueBeingOptimized = -r;}

	else {std::cerr << "Invalid choice of fitnessScoringMethod" << endl;exit(1);}
	printf("%f\n",valueBeingOptimized);

	// print whether cell production constraints (cpc) met
	printf("%d\n", cellProductionConstraintsMet);

	// print whether fecundity constraints (fc) met
	printf("%d\n", fecundityScheduleConstraintsMet);

	// print whether all constraints met
	printf("%d\n", allConstraintsMet);

	// print pedigree depth of individual simulations runs
	if      (option_str.find("meanPedigreeDepthMeioticCells:")!=string::npos) {pdStorage->pd_AllCellsEnterMeioticRegion->display();}
	else if (strcmp(option_str.c_str(),"spermOocyteMean")==0) {pdStorage->pd_spermOocyte->display();}
	else if (strcmp(option_str.c_str(),"spermOocyteSum")==0) {pdStorage->pd_spermOocyteSum->display();}
	else if (strcmp(option_str.c_str(),"generationRate")==0) {
		Array1D<float> output;
		output.resize(pdStorage->pd_spermOocyte->size());
        float r = calculateGenerationFitness(pdStorage->simulatedFecunditySchedule,pdStorage->fecundityConstraints,pdStorage->pd_spermOocyte->mean(),opt->deleteriousMutationRate,opt->maximalGenerationRate,opt->maximalPedigreeDepth);
		for (int i=0;i<pdStorage->pd_spermOocyte->size();i++) {
			output(i) = -r;
		}
		output.display();
	}
        else if (strcmp(option_str.c_str(),"generationRate2")==0) {
                Array1D<float> output;
                output.resize(pdStorage->pd_spermOocyte->size());
        float r = calculateGenerationFitness_selectionCoefficient(pdStorage->simulatedFecunditySchedule,pdStorage->fecundityConstraints,pdStorage->pd_spermOocyte->mean(),opt->deleteriousMutationRate,opt->maximalGenerationRate,opt->maximalPedigreeDepth);
                for (int i=0;i<pdStorage->pd_spermOocyte->size();i++) {
                        output(i) = -r;
                }
                output.display();
        }

	else {std::cerr << "Invalid choice of fitnessScoringMethod" << endl;exit(1);}

	// print whether cell production constraint is met for individual simulation runs
	Array2D<float>::array_index dimx_cellProduction,dimy_cellProduction;
	pdStorage->simulatedCellProductionSchedule->getDimensions(dimx_cellProduction,dimy_cellProduction);
	for (int x=0;x<dimx_cellProduction;x++) {
		bool constraintsSatisfied=true;
		for (int y=0;y<dimy_cellProduction;y++) {
			if ((*pdStorage->simulatedCellProductionSchedule)(x,y)>(*pdStorage->cellProductionConstraints)(0,y)) {
				constraintsSatisfied=false;
				break;
			}
		}
		if (opt->constraintMethod.compare("none")==0){
			constraintsSatisfied=true;
		}
		printf("%d",constraintsSatisfied);
		if (x!=dimx_cellProduction-1) {
			printf(",");
		}
	}
	printf("\n");

	// print whether fecundity constraint is met for individual simulation runs
	Array2D<float>::array_index dimx_simulatedFecundity, dimy_simulatedFecundity;
	pdStorage->simulatedFecunditySchedule->getDimensions(dimx_simulatedFecundity,dimy_simulatedFecundity);
	for (Array2D<float>::array_index x=0;x<dimx_simulatedFecundity;x++) {
		bool constraintsSatisfied=true;
		int sum_sim = 0;
		int sum_sched = 0;
		for (int y=0;y<dimy_simulatedFecundity;y++) {
			if (y==0) {  			// check sperm constraint
				int numSperm_sim = boost::math::iround((*pdStorage->simulatedFecunditySchedule)(x,y));
				int numSperm_sched = opt->numSperm; // boost::math::iround((*pdStorage->fecundityConstraints)(0,y));
				if (numSperm_sim!=numSperm_sched) {
					constraintsSatisfied=false;
					break;
				}
			} else {				// check oocyte constraint
				sum_sim+=ceil((*pdStorage->simulatedFecunditySchedule)(x,y));
				sum_sched+=boost::math::iround((*pdStorage->fecundityConstraints)(y));
				if (sum_sim<sum_sched) {
					constraintsSatisfied=false;
					break;
				}
			}
		}
		if (opt->constraintMethod.compare("none")==0){
			constraintsSatisfied=true;
		}
		printf("%d",constraintsSatisfied);
		if (x!=dimx_simulatedFecundity-1) {
			printf(",");
		}
	}
	printf("\n");

	// print cell production time constraints for individual runs
	for (int i=0;i<dimy_cellProduction;i++) {
		printf("%f",(*pdStorage->cellProductionConstraints)(0,i));
		if (i!=dimy_cellProduction-1) {
			printf(",");
		}
	}
	printf("\n");

	// print cell production times for individual runs
	for (int i=0;i<dimy_cellProduction;i++) {
		for (int j=0;j<dimx_cellProduction;j++) {
			printf("%f",(*pdStorage->simulatedCellProductionSchedule)(j,i));
			if (j!=dimx_cellProduction-1) {
				printf(",");
			}
		}
		printf("\n");
	}

	// print fecundity constraints for individual runs
	int sumConstraint=0;
	for (int i=0;i<dimy_simulatedFecundity;i++) {
		int constraint;
		if (i==0) {
			constraint = opt->numSperm;
		} else {
			constraint = boost::math::iround((*pdStorage->fecundityConstraints)(i));
		}
		sumConstraint+=constraint;
		printf("%d",sumConstraint);
		if (i!=dimy_simulatedFecundity-1) {
			printf(",");
		}
	}
	printf("\n");

	// print fecundity for individual runs
	Array1D<float> sumGamete;
	sumGamete.resize(dimx_cellProduction);
	for (int i=0;i<dimy_simulatedFecundity;i++) {
		for (int j=0;j<dimx_cellProduction;j++) {
			sumGamete(j)+=(*pdStorage->simulatedFecunditySchedule)(j,i);
			printf("%d",boost::math::iround(sumGamete(j)));
			if (j!=dimx_cellProduction-1) {
				printf(",");
			}
		}
		printf("\n");
	}
}
Exemple #5
0
/*!
 * Print simulation results to standard output when MR constraints are not satisfied.
 * These results fixed to very high pedigree depths / non-satisfied constraints
 */
void printSimulationResultsForTed_pedigreeDepth_badMR(PedigreeDepthStorage *pdStorage, ProgramOptionParser *opt) {

	// print pedigree depth (i.e., value that Ted's optimizer is minimizing)
	printf("999\n");

	// print whether cell production constraints (cpc) met
	printf("0\n");

	// print whether fecundity constraints (fc) met
	printf("0\n");

	// print whether all constraints met
	printf("0\n");

	// print pedigree depth of individual simulations runs
	Array1D<float> temp;
	Array1D<float>::array_index numRuns = pdStorage->pd_AllCellsEnterMeioticRegion->size();
	temp.resize(numRuns);
	temp.fill(999);
	temp.display();

	// print whether cell production constraint is met for individual simulation runs
	Array2D<float>::array_index dimx_cellProduction,dimy_cellProduction;
	pdStorage->simulatedCellProductionSchedule->getDimensions(dimx_cellProduction,dimy_cellProduction);
	for (int x=0;x<dimx_cellProduction;x++) {
		printf("0");
		if (x!=dimx_cellProduction-1) {
			printf(",");
		}
	}
	printf("\n");

	// print whether fecundity constraint is met for individual simulation runs
	Array2D<float>::array_index dimx_simulatedFecundity, dimy_simulatedFecundity;
	pdStorage->simulatedFecunditySchedule->getDimensions(dimx_simulatedFecundity,dimy_simulatedFecundity);
	for (Array2D<float>::array_index x=0;x<dimx_simulatedFecundity;x++) {
		printf("%d",false);
		if (x!=dimx_simulatedFecundity-1) {
			printf(",");
		}
	}
	printf("\n");

	// print cell production time constraints for individual runs
	for (int i=0;i<dimy_cellProduction;i++) {
		printf("%f",(*pdStorage->cellProductionConstraints)(0,i));
		if (i!=dimy_cellProduction-1) {
			printf(",");
		}
	}
	printf("\n");

	// print cell production times for individual runs
	for (int i=0;i<dimy_cellProduction;i++) {
		for (int j=0;j<dimx_cellProduction;j++) {
			printf("999");
			if (j!=dimx_cellProduction-1) {
				printf(",");
			}
		}
		printf("\n");
	}

	// print fecundity constraints for individual runs
	int sumConstraint=0;
	for (int i=0;i<dimy_simulatedFecundity;i++) {
		int constraint;
		if (i==0) {
			constraint = opt->numSperm;
		} else {
			constraint = boost::math::iround((*pdStorage->fecundityConstraints)(i));
		}
		sumConstraint+=constraint;
		printf("%d",sumConstraint);
		if (i!=dimy_simulatedFecundity-1) {
			printf(",");
		}
	}
	printf("\n");

	// print fecundity for individual runs
	Array1D<float> sumGamete;
	sumGamete.resize(dimx_cellProduction);
	for (int i=0;i<dimy_simulatedFecundity;i++) {
		for (int j=0;j<dimx_cellProduction;j++) {
			sumGamete(j)+=(*pdStorage->simulatedFecunditySchedule)(j,i);
			printf("%d",boost::math::iround(sumGamete(j)));
			if (j!=dimx_cellProduction-1) {
				printf(",");
			}
		}
		printf("\n");
	}
}
Exemple #6
0
/*!
 * Print simulation results to standard output
 */
void printSimulationResults(PedigreeDepthStorage *pdStorage, int numSperm, bool cellProductionConstraintsMet, bool fecundityScheduleConstraintsMet, bool allConstraintsMet, ProgramOptionParser *opt) {
	// print fitness metric values
	printf("\n******************************\n");
	printf("Fitness metrics:\n");
	printf("pedigree depth sperm (mean) = %f\n",pdStorage->pd_sperm->mean());
	printf("pedigree depth oocyte (mean) = %f\n",pdStorage->pd_oocyte->mean());
	printf("pedigree depth sperm and oocyte (mean) = %f\n",pdStorage->pd_spermOocyte->mean());
	printf("pedigree depth mitotic region (mean) = %f\n",pdStorage->pd_mitoticRegion->mean());
	printf("pedigree depth meiotic region (mean) = %f\n",pdStorage->pd_meioticRegion->mean());
	printf("pedigree depth whole germline (mean) = %f\n",pdStorage->pd_wholeGermline->mean());
	printf("pedigree depth sperm (median) = %f\n",pdStorage->pd_sperm->perctile(0.5));
	printf("pedigree depth oocyte (median) = %f\n",pdStorage->pd_oocyte->perctile(0.5));
	printf("pedigree depth sperm and oocyte (median) = %f\n",pdStorage->pd_spermOocyte->perctile(0.5));
	printf("pedigree depth mitotic region (median) = %f\n",pdStorage->pd_mitoticRegion->perctile(0.5));
	printf("pedigree depth meiotic region (median) = %f\n",pdStorage->pd_meioticRegion->perctile(0.5));
	printf("pedigree depth whole germline (median) = %f\n",pdStorage->pd_wholeGermline->perctile(0.5));
	printf("pedigree depth sperm and oocyte (sum/numGametes) = %f\n",pdStorage->pd_spermOocyteSum->mean());
	printf("pedigree depth of germline at egg laying = %f\n",pdStorage->pd_GermlineAtEggLaying->mean());
	printf("pedigree depth of first N cells that entered meiotic region = %f\n",pdStorage->pd_AllCellsEnterMeioticRegion->mean());
	// print generation rates
	float r = calculateGenerationRate(pdStorage->simulatedFecunditySchedule,pdStorage->fecundityConstraints);
	float rFitness = calculateGenerationFitness(pdStorage->simulatedFecunditySchedule,pdStorage->fecundityConstraints,pdStorage->pd_spermOocyte->mean(),opt->deleteriousMutationRate,opt->maximalGenerationRate,opt->maximalPedigreeDepth);
	printf("generation rate without pedigree depth contribution (hours^-1) = %f\n",r);
	printf("negative generation rate with pedigree depth contribution (hours^-1, negative so minimization will optimize fitness) = %f\n",-rFitness); // negative so that minimization will optimize fitness
	printf("\n");

	// print timers
	printf("Timers:\n");
	printf("Number of cell divisions = %f\n",pdStorage->num_cellDivisions->mean());
	printf("Number of cells that enter meiotic region = %f\n",pdStorage->num_meioticCellsProduced->mean());
	printf("Time of first cell exiting meiotic region = %f\n",pdStorage->time_firstMeioticExit->mean());
	printf("\n");

	// print simulated fecundity schedule
	Array2D<float>::array_index dummy,dimy_fecundity;
	pdStorage->fecundityConstraints->getDimensions(dummy,dimy_fecundity);
	printf("Simulated fecundity schedule:\n");
	for (int i=0;i<dimy_fecundity;i++) {
		float meanGametesProduced = pdStorage->simulatedFecunditySchedule->mean(i);
		if (i==0) {
			printf("%f sperm produced at %f hours (%d expected)\n",meanGametesProduced,(*pdStorage->fecundityConstraints)(0,i),numSperm);
		} else {
			printf("%f oocytes produced at %f hours (%d expected)\n",meanGametesProduced,(*pdStorage->fecundityConstraints)(0,i),(int)(*pdStorage->fecundityConstraints)(i));
		}
	}
	printf("\n");

	// print simulated cell exiting meiotic region schedule
	printf("Simulated cells that hit end of meiotic region (and undergo apoptosis/oogenesis):\n");
	for (int i=0;i<dimy_fecundity;i++) {
		float meanCellDivisions = pdStorage->simulatedCellProductionSchedule_atFecundityBins->mean(i);
		float meanNumCellsHitMeioticRegion = pdStorage->simulatedMeioticExitSchedule->mean(i);
		printf("%f cell divisions, %f cells hit end of meiotic region at at %f hours\n",meanCellDivisions,meanNumCellsHitMeioticRegion,(*pdStorage->fecundityConstraints)(0,i));
	}
	printf("\n");

	printf("theoretical oocyte probability = step*0:");
	float total_numCellsHitMeioticRegion=0;
	for (int i=1;i<dimy_fecundity;i++) {
		float numCellsHitMeioticRegion       =  pdStorage->simulatedMeioticExitSchedule->mean(i);
		float expectedNumberOocytes = (*pdStorage->fecundityConstraints)(i);
		printf("%.3f",expectedNumberOocytes/numCellsHitMeioticRegion);
		if (i!=dimy_fecundity-1) {
			total_numCellsHitMeioticRegion += numCellsHitMeioticRegion;
			printf("/%.2f:",total_numCellsHitMeioticRegion);
		}
	}
	printf("\n\n");

	// print simulated cell production schedule
	printf("cell production schedule:\n");
	Array2D<float>::array_index dimx_cellProduction,dimy_cellProduction;
	pdStorage->simulatedCellProductionSchedule->getDimensions(dimx_cellProduction,dimy_cellProduction);
	for (int i=0;i<dimy_cellProduction;i++) {
		float time = pdStorage->simulatedCellProductionSchedule->mean(i);
		float constraint = (*pdStorage->cellProductionConstraints)(0,i);
		int cellDivisions = (int)(*pdStorage->cellProductionConstraints)(i);
		printf("%d cell divisions at %f hours (constraint=%f)\n",cellDivisions,time,constraint);
	}
	printf("\n");

	// print whether constraints were met
	printf("cell production constraints met: %d\n", cellProductionConstraintsMet);
	printf("fecundity constraints met: %d\n", fecundityScheduleConstraintsMet);
	printf("all constraints met: %d\n", allConstraintsMet);

	// pedigree depth for individual runs
	printf("\n****** Individual Output ******\n");
	printf("sperm/oocyte mean pedigree depth = ");
	pdStorage->pd_spermOocyte->display();

	// print whether cell production constraint is met for individual runs
	printf("cell production constraint = ");
	for (int x=0;x<dimx_cellProduction;x++) {
		bool constraintsSatisfied=true;
		for (int y=0;y<dimy_cellProduction;y++) {
			if ((*pdStorage->simulatedCellProductionSchedule)(x,y)>(*pdStorage->cellProductionConstraints)(0,y)) {
				constraintsSatisfied=false;
				break;
			}
		}
		if (opt->constraintMethod.compare("none")==0){
			constraintsSatisfied=true;
		}
		printf("%d",constraintsSatisfied);
		if (x!=dimx_cellProduction-1) {
			printf(",");
		}
	}
	printf("\n");

	// print whether fecundity constraint is met for individual runs
	Array2D<float>::array_index dimx_simulatedFecundity, dimy_simulatedFecundity;
	printf("fecundity constraint = ");
	pdStorage->simulatedFecunditySchedule->getDimensions(dimx_simulatedFecundity,dimy_simulatedFecundity);
	for (Array2D<float>::array_index x=0;x<dimx_simulatedFecundity;x++) {
		bool constraintsSatisfied=true;
		int sum_sim = 0;
		int sum_sched = 0;
		for (int y=0;y<dimy_simulatedFecundity;y++) {
			if (y==0) {  			// check sperm constraint
				int numSperm_sim = boost::math::iround((*pdStorage->simulatedFecunditySchedule)(x,y));
				int numSperm_sched = opt->numSperm; // boost::math::iround((*pdStorage->fecundityConstraints)(0,y));
				if (numSperm_sim!=numSperm_sched) {
					constraintsSatisfied=false;
					break;
				}
			} else {				// check oocyte constraint
				sum_sim+=ceil((*pdStorage->simulatedFecunditySchedule)(x,y));
				sum_sched+=boost::math::iround((*pdStorage->fecundityConstraints)(y));
				if (sum_sim<sum_sched) {
					constraintsSatisfied=false;
					break;
				}
			}
		}
		if (opt->constraintMethod.compare("none")==0){
			constraintsSatisfied=true;
		}
		printf("%d",constraintsSatisfied);
		if (x!=dimx_simulatedFecundity-1) {
			printf(",");
		}
	}
	printf("\n");

	for (int i=0;i<dimy_cellProduction;i++) {
		printf("cell production time by simulation (constraint=%f) = ",(*pdStorage->cellProductionConstraints)(0,i));
		for (int j=0;j<dimx_cellProduction;j++) {
			printf("%f",(*pdStorage->simulatedCellProductionSchedule)(j,i));
			if (j!=dimx_cellProduction-1) {
				printf(",");
			}
		}
		printf("\n");
	}

	int sumConstraint=0;
	Array1D<float> sumGamete;
	sumGamete.resize(dimx_cellProduction);
	for (int i=0;i<dimy_simulatedFecundity;i++) {
		int constraint;
		if (i==0) {
			constraint = opt->numSperm;
		} else {
			constraint = boost::math::iround((*pdStorage->fecundityConstraints)(i));
		}
		sumConstraint+=constraint;
		printf("fecundity time by simulation (constraint=%d) = ",sumConstraint);
		for (int j=0;j<dimx_cellProduction;j++) {
			sumGamete(j)+=(*pdStorage->simulatedFecunditySchedule)(j,i);
			printf("%d",boost::math::iround(sumGamete(j)));
			if (j!=dimx_cellProduction-1) {
				printf(",");
			}
		}
		printf("\n");
	}
}