示例#1
0
std::pair<double,double>
HcalPulseContainmentAlgo::calcpair(double truefc)
{
    double timeslew_ns = HcalTimeSlew::delay(std::max(0.0,(double)truefc),
                         HcalTimeSlew::Medium);
    double shift_ns  = fixedphasens_ - time0shiftns_ + timeslew_ns;
    //std::cout << "SHIFT " << fixedphasens_ << " " << time0shiftns_ << " " << timeslew_ns << std::endl;
    double tmin      = -shift_ns;
    double tmax      = tmin+integrationwindowns_;

    //double integral  = shape_.integrate( tmin, tmax );
    double integral = integrator_(tmin, tmax);
    //std::cout << "INTEGRAL " << integral << " " << truefc << " " << tmin << " "  << tmax << std::endl;
    double corfactor = 1.0/integral;
    double recofc    = (double)truefc * integral;

#if 0
    char s[80];
    sprintf (s, "%8.2f %8.4f %8.4f %8.5f %8.5f %8.5f ",
             truefc, tmin, tmax, integral, corfactor, recofc);
    cout << s;
#endif

    std::pair<double,double> thepair(recofc,corfactor);
    return thepair;
}
bool AlternateStoichiometries::deeperAltStoichSearch(std::size_t slowRxnIndex, dense_vec& currentRealizableFastPopulation) {
//	std::cout << "in AlternateStoichiometries::deeperAltStoichSearch...searching for alt stoich for reaction index "<<slowRxnIndex<<"\n";
//	std::cout << "currentRealizableFastPopulation is:\n";
//	for (std::size_t i=0; i!=currentRealizableFastPopulation.size(); ++i) {
//		std::cout << currentRealizableFastPopulation(i) << "\t";
//	}
//	std::cout << "\n";
//
//	std::cout << "maxSearchDepth="<<maxSearchDepth<<"\n";
	
	//verify that current population does not satisfy level 0 dependency
//	std::cout << "does current population satisfy level 0 dependency: "<<level0[slowRxnIndex].dependencyIsSatisfied(currentRealizableFastPopulation)<<"\n";

	typedef std::pair<AlternateStoichiometry,dense_vec> altStoichRealizablePopPair;

	std::vector<altStoichRealizablePopPair> reachablePaths;

	//level 1 is easy, just see which reactions can fire, given current realizable population
	for (std::size_t rxnIndex=0; rxnIndex!=fastReactions.size(); ++rxnIndex) {
//		std::cout << "checking fast reaction "<<rxnIndex<<", propensity="<<fastReactions[rxnIndex].propensity(currentRealizableFastPopulation)<<"\n";
		if (fastReactions[rxnIndex].propensity(currentRealizableFastPopulation)>0) {
			sparse_vec rxnIndexStoich=fastReactions[rxnIndex].getStoichiometry();
			dense_vec dense_rxnIndexStoich(rxnIndexStoich.size());
			for (std::size_t i=0; i!=rxnIndexStoich.size(); ++i) {
				dense_rxnIndexStoich(i)=rxnIndexStoich(i);
			}
			//create a new alt stoich and realizable pop pair corresponding to the "path" of firing this rxn
			AlternateStoichiometry tmpAltStoich;
			tmpAltStoich.setStoich(dense_rxnIndexStoich);
			//update the dependencies in the alt stoich
			//by looking at reactants (for future steps, will also look at the alt stoich stoichiometry)
			std::vector<Reactant> reactants=fastReactions[rxnIndex].getReactants().get();
			for (std::size_t r=0; r!=reactants.size(); ++r) {
				tmpAltStoich.addDependency(reactants[r].getSpeciesIndex(),reactants[r].getMoleculeCount());
			}
			//insert new alt stoich and realizable pop into reachable paths
			dense_vec tmpRealizablePop=currentRealizableFastPopulation;
			tmpAltStoich.applyStoichiometry(tmpRealizablePop);
			reachablePaths.push_back(std::make_pair(tmpAltStoich,tmpRealizablePop));
			
			if (level0[slowRxnIndex].dependencyIsSatisfied(tmpRealizablePop)) {
				std::cout << "StochKit ERROR (AlternateStoichiometries::deeperAltStoichSearch): unexpectedly satisfied alternate stoichiometry dependency at level 1 (bug). Terminating.\n";
				exit(1);
			}
		}
	}

	if (reachablePaths.size()==0) {
		//don't need to print this warning message because a message is displayed in IVFP.fire
//		if (!seenFailedAltStoichSearchWarning) {
//			std::cout << "StochKit WARNING (AlternateStoichiometries::deeperAltStoichSearch): Unable to find an alternate stoichiometry. (Fast process has propensity 0?) (This message will only be displayed once per thread.)\n";
//			seenFailedAltStoichSearchWarning=true;
//		}
		return false;
//		std::cout << "StochKit ERROR (AlternateStoichiometries::deeperAltStoichSearch): Unable to find an alternate stoichiometry. (fast process has propensity 0?)\n";
//		std::cout << "slowRxnIndex="<<slowRxnIndex<<", currentRealizableFastPopulation=[";
//		for (std::size_t i=0; i!=currentRealizableFastPopulation.size(); ++i) {
//			std::cout << currentRealizableFastPopulation(i) << " ";
//		}
//		std::cout << "]\n";
//		exit(1);
	}
//	std::cout << "detected "<<reachablePaths.size()<<" reachable paths from level 1...\n";

	//level 2
	//for each "reachable path" we have so far, loop over fast reactions...
	std::vector<altStoichRealizablePopPair> previousLevelPaths=reachablePaths;
	reachablePaths.clear();
	for (std::size_t path=0; path!=previousLevelPaths.size(); ++path) {
		for (std::size_t rxnIndex=0; rxnIndex!=fastReactions.size(); ++rxnIndex) {
//			std::cout << "checking fast reaction "<<rxnIndex<<", propensity="<<fastReactions[rxnIndex].propensity(previousLevelPaths[path].second)<<"\n";
			
			if (fastReactions[rxnIndex].propensity(previousLevelPaths[path].second)>0) {
				sparse_vec rxnIndexStoich=fastReactions[rxnIndex].getStoichiometry();
				dense_vec dense_rxnIndexStoich(rxnIndexStoich.size());
				for (std::size_t i=0; i!=rxnIndexStoich.size(); ++i) {
					dense_rxnIndexStoich(i)=rxnIndexStoich(i);
				}				
				//create a new alt stoich and realizable pop pair corresponding to the "path" of firing this rxn
				AlternateStoichiometry tmpAltStoich=previousLevelPaths[path].first;

				//update the dependencies
				//loop over reactants, if alt stoich for that species is less than molecule count, add to dependency
				std::vector<Reactant> reactants=fastReactions[rxnIndex].getReactants().get();
				for (std::size_t r=0; r!=reactants.size(); ++r) {
					if (reactants[r].getMoleculeCount() - tmpAltStoich.getStoich()(reactants[r].getSpeciesIndex()) > 0) {
						//add reactants[r].getSpeciesIndex() to dependency (add function handles whether it already exists or not)
						tmpAltStoich.addDependency(reactants[r].getSpeciesIndex(), (reactants[r].getMoleculeCount() - tmpAltStoich.getStoich()(reactants[r].getSpeciesIndex())) );
					}
				
				}
				tmpAltStoich.incrementStoich(dense_rxnIndexStoich);
				bool altStoichIsZero=true;
				dense_vec newStoich=tmpAltStoich.getStoich();
				for (std::size_t i=0; i!=newStoich.size(); ++i) {
					if (newStoich(i)!=0) {
						altStoichIsZero=false;
						break;
					}
				}
				
				if (!altStoichIsZero) {
					//insert new alt stoich and realizable pop into reachable paths
					dense_vec tmpRealizablePop=currentRealizableFastPopulation;
					tmpAltStoich.applyStoichiometry(tmpRealizablePop);
					reachablePaths.push_back(std::make_pair(tmpAltStoich,tmpRealizablePop));
					
					if (level0[slowRxnIndex].dependencyIsSatisfied(tmpRealizablePop)) {
						std::cout << "StochKit ERROR (AlternateStoichiometries::deeperAltStoichSearch): unexpectedly satisfied alternate stoichiometry dependency at level 2 (bug). Terminating.\n";
						exit(1);
					}
				}//if (!altStoichIsZero)
			}//if
		}//rxnIndex
	}//path


	//level N
	for (std::size_t level=2; level<=maxSearchDepth; ++level) {
		//for each "reachable path" we have so far, loop over fast reactions...
		previousLevelPaths=reachablePaths;
		reachablePaths.clear();
		for (std::size_t path=0; path!=previousLevelPaths.size(); ++path) {
			for (std::size_t rxnIndex=0; rxnIndex!=fastReactions.size(); ++rxnIndex) {
//				std::cout << "checking fast reaction "<<rxnIndex<<", propensity="<<fastReactions[rxnIndex].propensity(previousLevelPaths[path].second)<<"\n";
				
				if (fastReactions[rxnIndex].propensity(previousLevelPaths[path].second)>0) {
					sparse_vec rxnIndexStoich=fastReactions[rxnIndex].getStoichiometry();
					dense_vec dense_rxnIndexStoich(rxnIndexStoich.size());
					for (std::size_t i=0; i!=rxnIndexStoich.size(); ++i) {
						dense_rxnIndexStoich(i)=rxnIndexStoich(i);
					}				
					//create a new alt stoich and realizable pop pair corresponding to the "path" of firing this rxn
					AlternateStoichiometry tmpAltStoich=previousLevelPaths[path].first;

					//update the dependencies
					//loop over reactants, if alt stoich for that species is less than molecule count, add to dependency
					std::vector<Reactant> reactants=fastReactions[rxnIndex].getReactants().get();
					for (std::size_t r=0; r!=reactants.size(); ++r) {
						if (reactants[r].getMoleculeCount() - tmpAltStoich.getStoich()(reactants[r].getSpeciesIndex()) > 0) {
							//add reactants[r].getSpeciesIndex() to dependency (add function handles whether it already exists or not)
							tmpAltStoich.addDependency(reactants[r].getSpeciesIndex(), (reactants[r].getMoleculeCount() - tmpAltStoich.getStoich()(reactants[r].getSpeciesIndex())) );
						}
					
					}
					tmpAltStoich.incrementStoich(dense_rxnIndexStoich);

					bool altStoichIsZero=true;
					dense_vec newStoich=tmpAltStoich.getStoich();
					for (std::size_t i=0; i!=newStoich.size(); ++i) {
						if (newStoich(i)!=0) {
							altStoichIsZero=false;
							break;
						}
					}
					
					if (!altStoichIsZero) {
						//insert new alt stoich and realizable pop into reachable paths
						dense_vec tmpRealizablePop=currentRealizableFastPopulation;
						tmpAltStoich.applyStoichiometry(tmpRealizablePop);
						reachablePaths.push_back(std::make_pair(tmpAltStoich,tmpRealizablePop));
												
						if (level0[slowRxnIndex].dependencyIsSatisfied(tmpRealizablePop)) {
//							std::cout << "success, satisfied dependency at level "<<level<<". now we can stop looking. terminating.\n";
							
							//add original reaction fast stoich to our alt stoich
							dense_vec slowRxnFastStoich=slowRxnStoich[slowRxnIndex];
							tmpAltStoich.incrementStoich( slowRxnStoich[slowRxnIndex] );

//							std::cout << "new alternate stoichiometry is:\n";
//							dense_vec newStoich=tmpAltStoich.getStoich();
//							for (std::size_t i=0; i!=newStoich.size(); ++i) {
//								std::cout << newStoich(i) <<"\t";
//							}
//							std::cout << "\ndisplay:";
//							tmpAltStoich.display();
//							std::cout << "\n";
							
							//add our new alt stoich ....
							//...figure out if it should be in oneReactantZero, or twoReactantWhatever...
							
							
							if (level0[slowRxnIndex].numberOfMoleculesInDependency()==1) {
//								std::cout << "add it to oneReactantZero\n";
								oneReactantZero[slowRxnIndex].push_back(tmpAltStoich);
							}
							else if (level0[slowRxnIndex].numberOfMoleculesInDependency()==2) {
								if (slowRxnFastReactants[slowRxnIndex][0].getMoleculeCount()!=2) {
									//we know it is not an A+A-> type reaction
									//how to quickly tell if first, second or both reactants are short?
									std::pair<std::size_t,std::size_t> thepair(slowRxnFastReactants[slowRxnIndex][0].getSpeciesIndex(),slowRxnFastReactants[slowRxnIndex][1].getSpeciesIndex());
									std::vector<bool>(2,false);
									if (slowRxnFastReactants[slowRxnIndex][0].getMoleculeCount()>currentRealizableFastPopulation(slowRxnFastReactants[slowRxnIndex][0].getSpeciesIndex())) {
										if (slowRxnFastReactants[slowRxnIndex][1].getMoleculeCount()>currentRealizableFastPopulation(slowRxnFastReactants[slowRxnIndex][1].getSpeciesIndex())) {
											//both are zero
//											std::cout << "add to twoReactantBothZero\n";
											twoReactantBothZero[slowRxnIndex].push_back(tmpAltStoich);
										}
										else {
											//only the first is zero
//											std::cout << "add to twoReactantFirstZero\n";
											twoReactantFirstZero[slowRxnIndex].push_back(tmpAltStoich);											
										}
									}
									//since dependency was not satisfied, must be 2nd reactant that is zero
//									std::cout << "add to twoReactantSecondZero\n";
									twoReactantSecondZero[slowRxnIndex].push_back(tmpAltStoich);
								}
								//here handle A+A-> type reactions
								else {
									std::cout << "StochKit ERROR (AlternateStoichiometries::deeperAltStoichSearch): handler for this reaction type not yet implemented (beta). Terminating\n";
									exit(1);
								}
							}
//							std::cout << "returning true in deeperAltStoichSearch...\n";
							return true;
						}
					}//if (!altStoichIsZero)
				}//if
			}//rxnIndex
		}//path
	}//level

//	std::cout << "StochKit WARNING (AlternateStoichiometries::deeperAltStoichSearch) unable to find an alternate stoichiometry (increasing max search depth might prevent this message).\n";
	return false;
}
bool AlternateStoichiometries::applyAlternateStoichiometry(std::size_t slowRxnIndex, dense_vec& currentRealizableFastPopulation) {
//	std::cout << "in applyAlternateStoichiometry...\n";	

	//could probably speed this up on average if cached most recently used one or two alternate stoichiometries for each slow reaction

//		std::cout << "applying alt stoich for slow rxn "<<slowRxnIndex<<"\n";
//		std::cout << "realizable fast pop before:\n";
//		print_dense_vec(currentRealizableFastPopulation);

	//first, check level 0
	if (level0[slowRxnIndex].dependencyIsSatisfied(currentRealizableFastPopulation)) {
		level0[slowRxnIndex].applyStoichiometry(currentRealizableFastPopulation);
//			std::cout << "applied level 0 stoichiometry\n";
//			std::cout << "realizable fast pop after:\n";
//			print_dense_vec(currentRealizableFastPopulation);

		return true;
	}
	else {
		if (level0[slowRxnIndex].numberOfMoleculesInDependency()==1) {
			for (std::size_t i=0; i!=oneReactantZero[slowRxnIndex].size(); ++i) {
				//within each level, iterate over the vector of possible alternate stoichiometries
				if (oneReactantZero[slowRxnIndex][i].dependencyIsSatisfied(currentRealizableFastPopulation)) {
					oneReactantZero[slowRxnIndex][i].applyStoichiometry(currentRealizableFastPopulation);
					return true;
				}
			}
		}
		else if (level0[slowRxnIndex].numberOfMoleculesInDependency()==2) {
			if (slowRxnFastReactants[slowRxnIndex][0].getMoleculeCount()!=2) {
				//we know it is not an A+A-> type reaction
				//how to quickly tell if first, second or both reactants are short?
				std::pair<std::size_t,std::size_t> thepair(slowRxnFastReactants[slowRxnIndex][0].getSpeciesIndex(),slowRxnFastReactants[slowRxnIndex][1].getSpeciesIndex());
				std::vector<bool>(2,false);
				if (slowRxnFastReactants[slowRxnIndex][0].getMoleculeCount()>currentRealizableFastPopulation(slowRxnFastReactants[slowRxnIndex][0].getSpeciesIndex())) {
					if (slowRxnFastReactants[slowRxnIndex][1].getMoleculeCount()>currentRealizableFastPopulation(slowRxnFastReactants[slowRxnIndex][1].getSpeciesIndex())) {
						//both are zero
						for (std::size_t i=0; i!=twoReactantBothZero[slowRxnIndex].size(); ++i) {
							//within each level, iterate over the vector of possible alternate stoichiometries
							if (twoReactantBothZero[slowRxnIndex][i].dependencyIsSatisfied(currentRealizableFastPopulation)) {
								twoReactantBothZero[slowRxnIndex][i].applyStoichiometry(currentRealizableFastPopulation);
								return true;
							}
						}							
					}
					else {
						//only the first is zero
						for (std::size_t i=0; i!=twoReactantFirstZero[slowRxnIndex].size(); ++i) {
							//within each level, iterate over the vector of possible alternate stoichiometries
							if (twoReactantFirstZero[slowRxnIndex][i].dependencyIsSatisfied(currentRealizableFastPopulation)) {
								twoReactantFirstZero[slowRxnIndex][i].applyStoichiometry(currentRealizableFastPopulation);
								return true;
							}
						}							
						
					}
				}
				//since dependency was not satisfied, must be 2nd reactant that is zero
				for (std::size_t i=0; i!=twoReactantSecondZero[slowRxnIndex].size(); ++i) {
					//within each level, iterate over the vector of possible alternate stoichiometries
					if (twoReactantSecondZero[slowRxnIndex][i].dependencyIsSatisfied(currentRealizableFastPopulation)) {
						twoReactantSecondZero[slowRxnIndex][i].applyStoichiometry(currentRealizableFastPopulation);
						return true;
					}
				}							
				
			}
			//here handle A+A-> type reactions
			else {
//				std::cout << "not yet able to handle A+A-> slow reaction when A is a fast species. terminating\n";
				if (currentRealizableFastPopulation(slowRxnFastReactants[slowRxnIndex][0].getSpeciesIndex())==0) {
//					std::cout << "twoSameReactantZero["<<slowRxnIndex<<"].size="<<twoSameReactantZero[slowRxnIndex].size()<<"\n";
					for (std::size_t i=0; i!=twoSameReactantZero[slowRxnIndex].size(); ++i) {
//						std::cout << "checking if dependency for entry "<<i<<" is satisfied...\n";
						if (twoSameReactantZero[slowRxnIndex][i].dependencyIsSatisfied(currentRealizableFastPopulation)) {
//							std::cout << i << ": dependency IS satisfied, attempting to apply stoichiometry...\n";
							twoSameReactantZero[slowRxnIndex][i].applyStoichiometry(currentRealizableFastPopulation);
//							std::cout << "successfully applied alt stoich from TwoSameReactantZero.\n";
							return true;
						}
						else {
//							std::cout << i << ": dependency is NOT satisfied...\n";
						}
					}
				}
				else if (currentRealizableFastPopulation(slowRxnFastReactants[slowRxnIndex][0].getSpeciesIndex())==1) {
//					std::cout << "twoSameReactantOne.size="<<twoSameReactantOne.size()<<"\n";
					for (std::size_t i=0; i!=twoSameReactantOne[slowRxnIndex].size(); ++i) {
						if (twoSameReactantOne[slowRxnIndex][i].dependencyIsSatisfied(currentRealizableFastPopulation)) {
							twoSameReactantOne[slowRxnIndex][i].applyStoichiometry(currentRealizableFastPopulation);
//							std::cout << "successfully applied alt stoich from TwoSameReactantOne.\n";
							return true;
						}
					}				
				}
				else {
					std::cout << "StochKit ERROR (AlternateStoichiometries::applyAlternateStoichiometry): reached unexpected internal state for A+A type reaction (bug). Terminating.\n";
					exit(1);
				}
			}
		}
		else {
			//should never reach here, it is a bug if it does
			std::cout << "StochKit ERROR (AlternateStoichiometry::applyAlternateStoichiometry): unable to fire slow reaction (debug: slow rxn index="<<slowRxnIndex<<", numberOfMoleculesInDependency="<<level0[slowRxnIndex].numberOfMoleculesInDependency()<<"\n";
			exit(1);
		}
	}
	
//	std::cout << "StochKit MESSAGE (AlternateStoichiometries::applyAlternateStoichiometry): unable to apply exact alternate stoichiometry (perhaps due to numerical error in equilibrium solution of virtual fast process or perhaps due to a complex virtual fast process)\n";
//	
//	std::cout << "more info: reindexed fast stoichiometry is:\n";
//	for (std::size_t i=0; i!=slowRxnStoich[slowRxnIndex].size(); ++i) {
//		std::cout << slowRxnStoich[slowRxnIndex](i) << "  ";
//	}
//	std::cout << "\n";

	if (maxSearchDepth>2) {
//		std::cout << "attempting a deeper search for an alternate stoichiometry...\n";
		return deeperAltStoichSearch(slowRxnIndex, currentRealizableFastPopulation);
	}

	return false;
}//applyAlternateStoichiometry dense_vec version
void AlternateStoichiometries::buildAltStoichVectors(std::vector<dense_vec> slowRxnFastStoich) {

//	std::cout << "in buildAltStoichVectors, size of slowRxnFastStoich is "<<slowRxnFastStoich.size()<<"\n";//size should be number of reactions in full model

	oneReactantZero.clear();
	twoSameReactantZero.clear();
	twoSameReactantOne.clear();
	twoReactantBothZero.clear();
	twoReactantFirstZero.clear();
	twoReactantSecondZero.clear();
	oneReactantZero.resize(slowRxnFastStoich.size());
	twoSameReactantZero.resize(slowRxnFastStoich.size());
	twoSameReactantOne.resize(slowRxnFastStoich.size());
	twoReactantBothZero.resize(slowRxnFastStoich.size());
	twoReactantFirstZero.resize(slowRxnFastStoich.size());
	twoReactantSecondZero.resize(slowRxnFastStoich.size());


	//use the alternate stoichiometries created, apply slowRxnFastStoich to create the actual alternate stoichiometry vectors
	for (std::size_t i=0; i!=slowRxnFastReactants.size(); ++i) {
		
		//see how many fast species are in reactants
//		std::cout << "slowRxnFastReactants[i].size="<<slowRxnFastReactants[i].size()<<"...\n";
		if (slowRxnFastReactants[i].size()==0) continue;
		else if (slowRxnFastReactants[i].size()==1) {
			//includes A->  and A+A->  reactions
			if (slowRxnFastReactants[i][0].getMoleculeCount()==1) {

				//iterate over the "levels" that create the consumed species				
				if (oneReactantMoleculeLevels.find(slowRxnFastReactants[i][0].getSpeciesIndex())==oneReactantMoleculeLevels.end()) {

					//decided this warning does not offer much info. only matters if "unable to apply alt stoich", in which case we have a message for that
//					if (!seenFailedBuiltAltStoichWarning) {
//						std::cout << "StochKit WARNING (AlternateStoichiometries::buildAltStoichVectors): at least one build of alternate stoichiometry failed (fast species may be consumed by slow reaction but is not produced by any fast reaction; likely to lead to \"unable to apply alternate stoichiometry\" warning. This message will be displayed at most once per IVFP.).\n";
//						seenFailedBuiltAltStoichWarning=true;
//					}
					continue;
					//std::cout << "StochKit ERROR (AlternateStoichiometries::buildAltStoichVectors): build of alternate stoichiometry vector failed (unstable fast species in stable subset?). Terminating.\n";
//					std::cout << "slowRxnFastReactants[i][0].getSpeciesIndex()="<<slowRxnFastReactants[i][0].getSpeciesIndex()<<"\n";
//					std::cout << "not found in oneReactantMoleculeLevels...\n"; 
//					exit(1);
				}

				std::vector<AlternateStoichiometry > thing;
				if (oneReactantMoleculeLevels.find(slowRxnFastReactants[i][0].getSpeciesIndex())!=oneReactantMoleculeLevels.end()) {
				 thing=oneReactantMoleculeLevels.find(slowRxnFastReactants[i][0].getSpeciesIndex())->second;
				}

				for (std::vector<AlternateStoichiometry >::iterator it=thing.begin(); it!=thing.end(); ++it) {
					oneReactantZero[i].push_back(*it);
					//update the stoichiometry to include affect of "real" stoichiometry
					oneReactantZero[i].back().incrementStoich(slowRxnFastStoich[i]);
				}
			 }
			 else {
				//A+A-> type reaction
//				std::cout << "StochKit ERROR (AlternateStoichiometries::buildAltStoichVectors): reaction consumes two molecules of one fast species--ssSSA does not yet support this. Terminating.\n";
//				exit(1);
				//first handle situation where we are short one
				//iterate over the "levels" that create the consumed species
				if (oneReactantMoleculeLevels.find(slowRxnFastReactants[i][0].getSpeciesIndex())!=oneReactantMoleculeLevels.end()) {
					for (std::vector<AlternateStoichiometry >::iterator it=oneReactantMoleculeLevels.find(slowRxnFastReactants[i][0].getSpeciesIndex())->second.begin();
						it!=oneReactantMoleculeLevels.find(slowRxnFastReactants[i][0].getSpeciesIndex())->second.end(); ++it)
					{
						twoSameReactantOne[i].push_back(*it);
						//update the stoichiometry to include affect of "real" stoichiometry
						twoSameReactantOne[i].back().incrementStoich(slowRxnFastStoich[i]);
					}
				}
				
				//now handle when we are short both
				std::pair<std::size_t,std::size_t> thepair(slowRxnFastReactants[i][0].getSpeciesIndex(),slowRxnFastReactants[i][0].getSpeciesIndex());
//				std::cout << "processing pair "<<thepair.first<<", "<<thepair.second<<" for reaction "<<i<<"\n";
//				std::cout<<" that pair has "<<twoReactantMoleculeLevels.find(thepair)->second.size()<<" alternate stoichs...\n";
				if (twoReactantMoleculeLevels.find(thepair)!=twoReactantMoleculeLevels.end()) {
					for (std::vector<AlternateStoichiometry >::iterator it=twoReactantMoleculeLevels.find(thepair)->second.begin();
						it!=twoReactantMoleculeLevels.find(thepair)->second.end(); ++it)
					{
						twoSameReactantZero[i].push_back(*it);
						//update the stoichiometry to include affect of "real" stoichiometry
						twoSameReactantZero[i].back().incrementStoich(slowRxnFastStoich[i]);
					}
				}
			 }
		}
		else {
			std::vector<AlternateStoichiometry> tmpVec;

			//A+B-> type reaction
			//first handle situation where only one of the two species is zero
			//iterate over the "levels" that create the consumed species
			//reactant 0 first
			if (oneReactantMoleculeLevels.find(slowRxnFastReactants[i][0].getSpeciesIndex())!=oneReactantMoleculeLevels.end()) {
				tmpVec=oneReactantMoleculeLevels.find(slowRxnFastReactants[i][0].getSpeciesIndex())->second;
			}
			for (std::size_t j=0; j!=tmpVec.size(); ++j) {
				twoReactantFirstZero[i].push_back(tmpVec[j]);
				//update the stoichiometry to include affect of "real" stoichiometry
				twoReactantFirstZero[i].back().incrementStoich(slowRxnFastStoich[i]);
				//also have to add the dependency on reactant 1? probably don't have to, but just in case
				twoReactantFirstZero[i].back().addDependency(slowRxnFastReactants[i][1].getSpeciesIndex(),1);
			}

			//now reactant 1
			tmpVec.clear();
			if (oneReactantMoleculeLevels.find(slowRxnFastReactants[i][1].getSpeciesIndex())!=oneReactantMoleculeLevels.end()) {
				tmpVec=oneReactantMoleculeLevels.find(slowRxnFastReactants[i][1].getSpeciesIndex())->second;
			}
			for (std::size_t j=0; j!=tmpVec.size(); ++j) {
				twoReactantSecondZero[i].push_back(tmpVec[j]);
				//update the stoichiometry to include affect of "real" stoichiometry
				twoReactantSecondZero[i].back().incrementStoich(slowRxnFastStoich[i]);
				//also have to add the dependency on reactant 0? probably don't have to, but just in case
				twoReactantSecondZero[i].back().addDependency(slowRxnFastReactants[i][0].getSpeciesIndex(),1);
			}

			//now handle when both reactants are zero
			std::pair<std::size_t,std::size_t> thepair(slowRxnFastReactants[i][0].getSpeciesIndex(),slowRxnFastReactants[i][1].getSpeciesIndex());
			tmpVec.clear();
			if (twoReactantMoleculeLevels.find(thepair)!=twoReactantMoleculeLevels.end()) {
				tmpVec=twoReactantMoleculeLevels.find(thepair)->second;
			}
			for (std::size_t j=0; j!=tmpVec.size(); ++j) {
				twoReactantBothZero[i].push_back(tmpVec[j]);
				//update the stoichiometry to include affect of "real" stoichiometry
				twoReactantBothZero[i].back().incrementStoich(slowRxnFastStoich[i]);
			}
			
		}
	}
	
//		std::cout << "alternate stoichiometries...one reactant only:\n";
//		for (std::size_t i=0; i!=oneReactantZero.size(); ++i) {
//			std::cout << "rxn "<<i<<": \n";
//			for (std::size_t j=0; j!=oneReactantZero[i].size(); ++j) {
//				oneReactantZero[i][j].display();
//			}
//		}
//		std::cout << "alternate stoichiometries...two reactant first zero:\n";
//		for (std::size_t i=0; i!=twoReactantFirstZero.size(); ++i) {
//			std::cout << "rxn "<<i<<": \n";
//			for (std::size_t j=0; j!=twoReactantFirstZero[i].size(); ++j) {
//				twoReactantFirstZero[i][j].display();
//			}
//		}
//		std::cout << "alternate stoichiometries...two reactant second zero:\n";
//		for (std::size_t i=0; i!=twoReactantSecondZero.size(); ++i) {
//			std::cout << "rxn "<<i<<": \n";
//			for (std::size_t j=0; j!=twoReactantSecondZero[i].size(); ++j) {
//				twoReactantSecondZero[i][j].display();
//			}
//		}
//		std::cout << "alternate stoichiometries...two reactant both zero:\n";
//		for (std::size_t i=0; i!=twoReactantBothZero.size(); ++i) {
//			std::cout << "rxn "<<i<<": \n";
//			for (std::size_t j=0; j!=twoReactantBothZero[i].size(); ++j) {
//				twoReactantBothZero[i][j].display();
//			}
//		}
//		std::cout << "alternate stoichiometries...two same reactant, one:\n";
//		for (std::size_t i=0; i!=twoSameReactantOne.size(); ++i) {
//			std::cout << "rxn "<<i<<": \n";
//			for (std::size_t j=0; j!=twoSameReactantOne[i].size(); ++j) {
//				twoSameReactantOne[i][j].display();
//			}
//		}
//		std::cout << "alternate stoichiometries...two same reactant, zero:\n";
//		for (std::size_t i=0; i!=twoSameReactantZero.size(); ++i) {
//			std::cout << "rxn "<<i<<": \n";
//			for (std::size_t j=0; j!=twoSameReactantZero[i].size(); ++j) {
//				twoSameReactantZero[i][j].display();
//			}
//		}

//	std::cout << "terminating here.\n";
//	exit(1);
	
}