///
/// DrawingCanvas::useWhiteInk()
///
///
///
bool DrawingCanvas::useWhiteInk(Individual *pIndividual){
	//
	// How many sections are there?
	//
	unsigned sections = pIndividual->getDataTable()->getIconColumnCount();
	if(!sections){
		return false;
	}else{
		const DataTable  * pDT = pIndividual->getDataTable();
		//
		// Well, we are only going to look at the first section of the pie
		// even if there are multiple sections ...
		//
		DataColumn * pDC = pDT->getColumn( pDT->getIconColumnIndex(0) );
		const UniqueList * pUL = pDC->getUniqueList();
		//
		// Only process if there are some non-missing levels present:
		//
		if(!pUL->getLevels()){
			
			return false;
			
		}else{
			//
			// What is the level and label in the UniqueList corresponding to the data value
			// for this individual?
			//
			unsigned level;
			std::string label;
			pUL->getOrdinalAndLabelForKey( pDC->getDataAtIndex( pIndividual->getRowIndex() ),label,level );
			//
			// UniqueList ordinals are 1-offset, so we should only get zero back
			// if the key was not found, which should never happen:
			//
			if(level==0) throw Exception("DrawingCanvas::useWhiteInk()","UniqueList returned ordinal 0.");
			//
			// Level is 1-offset, so subtract:
			//
			level--;
			//
			// Get the color series corresponding to this icon column:
			//
			ColorSeries *pCS;
			if(DrawingMetrics::getColor()){
				pCS = pDT->getColorSeriesFromStack(0);
			}else{
				pCS = pDT->getBlackAndWhiteSeriesFromStack(0);
			}
			if(pCS->useBlackInkAtLevel(level)){
				return false;
			}else{
				return true;
			}
		}
	}
}
Beispiel #2
0
///
/// toggleColumnsForPedigree(): User can specify any number of columns to be displayed on the pedigree.
/// Mark all such columns for output display, if they exist.
///
void DataTable::toggleColumnsForPedigree(const std::vector<std::string> &columns){
	
	// Since the labels are specified by the user clear the vector  that contains
	// the default label 'Individual Id'
	_labelColumns.clear();
	for(unsigned i=0;i<columns.size();i++){
		if(columnExists(columns[i])){
			DataColumn* dc = getColumn(stringToUpper(columns[i]).c_str());
			dc->setShowOnPedigree(true);
			_labelColumns.push_back(dc->getOrdinal());
		}else Warning("DataTable::toggleColumnsForPedigree","Could not find column %s to show on the pedigree.",columns[i].c_str());
	}
	
}
void DataChart::Load(Simulator *lpSim, CStdXml &oXml)
{
	short iColumn, iTotalColumns;

	ActivatedItem::Load(lpSim, oXml);

	oXml.IntoElem();  //Into DataChart Element

	if(m_aryDataBuffer) delete[] m_aryDataBuffer;
	m_aryDataBuffer = NULL;
	m_aryDataColumns.RemoveAll();

	float fltCollectInterval = oXml.GetChildFloat("CollectInterval");
	Std_IsAboveMin((float) 0, fltCollectInterval, TRUE, "CollectInterval");

	//Lets calculate the number of slices for the collect interval.
	m_iCollectInterval = (int) (fltCollectInterval/lpSim->TimeStep());
	if(m_iCollectInterval<=0) m_iCollectInterval = 1;

	if(!oXml.FindChildElement("SetStartEndTime", FALSE))
	{
		m_bSetStartEndTime = oXml.GetChildBool("SetStartEndTime", TRUE);
		m_fltCollectTimeWindow = oXml.GetChildFloat("CollectTimeWindow", -1);
	}
	else
	{
		m_bSetStartEndTime = TRUE;
		m_fltCollectTimeWindow = -1;
	}

	//*** Begin Loading DataColumns. *****
	oXml.IntoChildElement("DataColumns");

	iTotalColumns = oXml.NumberOfChildren();
	DataColumn *lpColumn = NULL;
	for(iColumn=0; iColumn<iTotalColumns; iColumn++)
	{
		oXml.FindChildByIndex(iColumn);
		lpColumn = LoadDataColumn(lpSim, oXml);

		if(lpColumn->Index() < 0)
			lpColumn->Index(iColumn);
	}

	oXml.OutOfElem();
	//*** End Loading DataColumns. *****

	oXml.OutOfElem(); //OutOf DataChart Element
}
Beispiel #4
0
Attribute::Attribute(const DataColumn& col)
{
    totalUnique = 0;
    name = col.Name();
    PopulateMaps(col);
    totalEntities = col.size;
}
DataColumn *DataChart::FindColumn(string strID, int &iIndex, BOOL bThrowError)
{
	int iCount = m_aryDataColumns.GetSize();
	DataColumn *lpColumn = NULL;
	strID = Std_CheckString(strID);
	for(iIndex=0; iIndex<iCount; iIndex++)
	{
		lpColumn = m_aryDataColumns[iIndex];

		if(lpColumn->ID() >= strID)
			return lpColumn;
	}

	if(bThrowError)
		THROW_TEXT_ERROR(Al_Err_lDataColumnIDNotFound, Al_Err_strDataColumnIDNotFound, " DataColumn ID: " + strID);

	return NULL;
}
//
// addPedigreesFromDataTable():
//
void PedigreeSet::addPedigreesFromDataTable(const DataTable * p_pedigreeTable, unsigned tableIndex,const std::string& sortField){
	
	//
	// Use const reference for convenience:
	// (so I don't have to change the code
	//  since the parameter has changed from a
	//  const DataTable & to a const DataTable * )
	//
	const DataTable & pedigreeTable = (*p_pedigreeTable);
	
	std::cout << "Start of addPedigreesFromDataTable" << std::endl;
	
	//
	// Get all the core columns from the datatable:
	//
	DataColumn *familyIdColumn = pedigreeTable.getColumn( pedigreeTable.labels.FamilyIdField );
	//familyIdColumn->printData();
	DataColumn *individualIdColumn = pedigreeTable.getColumn( pedigreeTable.labels.IndividualIdField );
	//individualIdColumn->printData();
	DataColumn *motherIdColumn = pedigreeTable.getColumn( pedigreeTable.labels.MotherIdField );
	DataColumn *fatherIdColumn = pedigreeTable.getColumn( pedigreeTable.labels.FatherIdField );
	DataColumn *genderColumn   = pedigreeTable.getColumn( pedigreeTable.labels.GenderField );
	//
	// Insert the Pedigrees in a set:
	//
	std::string currentFamily;
	int numberOfRows = familyIdColumn->getNumberOfRows();
	int index=0;
	while(index < numberOfRows){
		
		currentFamily = familyIdColumn->get(index);
		if(currentFamily == "."){
			Warning("PedigreeSet::addPedigreesFromDataTable()",
			        "Family Id is missing for individual %s and will be ignored.",
			        individualIdColumn->get(index).c_str()
			);
			index++;
			continue;
		}
		std::pair<std::set<Pedigree*,comparePedigrees>::iterator,bool> pp;
		pp = _pedigrees.insert(new Pedigree(currentFamily,tableIndex));
		if(pp.second){
			for(int i=0;i<familyIdColumn->getNumberOfRows();i++) { 
				if(currentFamily.compare(familyIdColumn->get(i)) == 0){
					(*pp.first)->addIndividual(individualIdColumn->get(i),motherIdColumn->get(i),fatherIdColumn->get(i),genderColumn->get(i),i,tableIndex,pedigreeTable);
				}
			}
		}
		index++;
	}
	
	// Set the core optional fields on the individuals
	_setCoreOptionalFields(p_pedigreeTable);
	
	_establishConnections();
	
	bool dobPresent = false;
	if(pedigreeTable.getDOBColumnIndex() != DataTable::COLUMN_IS_MISSING){
		_checkParentChildDOB();
		dobPresent = true;
	}
	_determineFoundingGroups();
	
	bool sortFieldPresent = false;
	if(sortField != std::string("") && sortField != pedigreeTable.labels.DOBField){
		// Check to see if the field actually exists in the data table
		if(pedigreeTable.columnExists(sortField)){
			_computeWidths(sortField);
			sortFieldPresent = true;
		}else{
			Warning("PedigreeSet::addPedigreesFromDataTable()",
			        "Field '%s' specified for sorting the siblings does not exist in the Pedigree Table. Default ordering will be used.",
			        sortField.c_str()
			);
		}
	}
	if(!sortFieldPresent){
		if(dobPresent){
			std::cout << "Siblings are ordered by DOB." << std::endl;
			_computeWidths(pedigreeTable.labels.DOBField,true);
			DrawingMetrics::setDisplayBirthOrder(true);
		}else{    
			std::cout << "Default ordering of siblings." << std::endl;
			_computeWidths(std::string(""));
			
		}
	}
	std::cout << "End of addPedigreesFromDataTable" << std::endl;
	
}
///
/// iconPie(): Draws a pie with a given color on the individual icon. Each pie corresponds to one 
/// categorical variable. The color corresponds to the level in that variable. 
///
void DrawingCanvas::iconPie( double x, double y, Individual *pIndividual ){
	
	//
	// Handle virtual individuals:
	//
	if(pIndividual->isVirtual()){
		
		//_body << "<circle cx=\"" << x << "\" cy=\"" << y << "\" r=\"" << 0.5*DrawingMetrics::getScalingFactor() << "\"";
		//_body << " class=\"thinLine\"";
		//_body << "/>\n";
		return;
		
	}
	//
	// Get here if non-virtual:
	//
	
	//
	// How many sections are there?
	//
	unsigned sections = pIndividual->getDataTable()->getIconColumnCount();
	if(!sections){
		//
		// No affected fields : Draw a small circle in the middle:
		// (Nice for debugging -- otherwise comment out )
		//
		//_body << "<circle cx=\"" << x << "\" cy=\"" << y << "\" r=\"" << 0.5*DrawingMetrics::getScalingFactor() << "\"";
		//_body << " class=\"thinLine\"";
		//_body << "/>\n";
		return;
	}
	
	//
	// Setup clipping Id, if needed:
	//
	std::string clipId = pIndividual->getId().get() + "_clipPath";
	double radius=DrawingMetrics::getIconRadius();
	bool isMale = false;
	if( pIndividual->getGender().getEnum()==Gender::MALE ){
		
		setClipPath(x,y,clipId);
		//
		// Increase radius for clipping:
		//
		radius*=Number::SQRT_TWO;
		isMale = true;
		_body << "<g clip-path=\"url(#" << clipId << ")\">\n";
		
	}else{
		//
		// Empty g with no clipping for female:
		//
		_body << "<g>\n";
		
	}
	
	//
	// Iterate over _iconColumns:
	//
	const DataTable *pDT = pIndividual->getDataTable();
	double arcAngle = 2.0*Number::PI/sections;
	double startAngle = 0.5*Number::PI - arcAngle;
	double endAngle   = startAngle+arcAngle;
	for(unsigned i=0;i<sections;i++){
		//
		// Get the data column of the ith icon column:
		//
		DataColumn * pDC = pDT->getColumn( pDT->getIconColumnIndex(i) );
		//
		// Get the UniqueList for this column:
		//
		const UniqueList * pUL = pDC->getUniqueList();
		
		//
		// Only process if there are some non-missing levels
		// present:
		//
		if(!pUL->getLevels()) continue;
		
		//
		// What is the level and label in the UniqueList corresponding to the data value
		// for this individual?
		//
		unsigned level;
		std::string label;
		pUL->getOrdinalAndLabelForKey( pDC->getDataAtIndex( pIndividual->getRowIndex() ),label,level );
		//
		// UniqueList ordinals are 1-offset, so we should only get zero back
		// if the key was not found, which should never happen:
		//
		if(level==0) throw Exception("DrawingCanvas::iconPie()","UniqueList returned ordinal 0.");
		//
		// Level is 1-offset, so subtract:
		//
		level--;
		
		//
		// Get the color series corresponding to this icon column:
		//
		// NOTA BENE: (1) IF there is only one section, we use the 
		//                blackAndWhite series
		//                UNLESS there is a color override.
		//
		//            (2) OTHERWISE if there are more than one section, 
		//                we use the color series
		//                UNLESS there is a black-and-white override.
		//
		ColorSeries *pCS;
		if(sections==1){
			if(DrawingMetrics::getColor()) pCS = pDT->getColorSeriesFromStack(i);
			else                           pCS = pDT->getBlackAndWhiteSeriesFromStack(i);
		}else{
			if(DrawingMetrics::getBlackAndWhite()) pCS = pDT->getBlackAndWhiteSeriesFromStack(i);
			else                                   pCS = pDT->getColorSeriesFromStack(i);
		}
		//
		// Assume reversed for now:
		//
		bool reversed=true;
		std::string arcClass="blackInkLetter";
		if(!pCS->reversedSeriesUseBlackInkAtLevel(level)) arcClass="whiteInkLetter";
		
		//
		// If the number of sections is small, use a larger font size
		//
		
		if(sections == 1)      arcClass += "_1";
		else if(sections == 2) arcClass += "_2";
		else if(sections == 3) arcClass += "_3";
		arc(x,y,radius,startAngle,endAngle,(reversed?pCS->reversedSeriesGetColorAtLevel(level):pCS->getColorAtLevel(level)),label,arcClass,isMale);
		startAngle+=arcAngle;
		endAngle+=arcAngle;
		
		// For the first time draw the icon legend too:
		if(!_iconLegendFlag){
			_iconLegendFlag = true;
			_iconLegend.setPedigreeTable(pDT);
		}
		
	}
	_body << "</g>\n";
	return;
	
}
///
/// iconQuadrantFill(): Shade quadrants of the icon to indicate specific levels.
///                     This method has a limit of 16 distinct levels.
///
void DrawingCanvas::iconQuadrantFill( double x, double y, Individual *pIndividual ){
	
	//
	// Handle virtual individuals:
	//
	if(pIndividual->isVirtual()){
		
		return;
		
	}
	//
	// Get here if non-virtual:
	//
	
	//
	// How many sections are there?
	//
	unsigned sections = pIndividual->getDataTable()->getIconColumnCount();
	if(!sections){
		//
		// No affected fields : Draw a small circle in the middle:
		// (Nice for debugging -- otherwise comment out )
		//
		//_body << "<circle cx=\"" << x << "\" cy=\"" << y << "\" r=\"" << 0.5*DrawingMetrics::getScalingFactor() << "\"";
		//_body << " class=\"thinLine\"";
		//_body << "/>\n";
		return;
	}
	
	//
	// Setup clipping Id, if needed:
	//
	double radius=DrawingMetrics::getIconRadius();
	bool isMale = false;
	if( pIndividual->getGender().getEnum()==Gender::MALE ){
		
		std::string clipId = pIndividual->getId().get() + "_clipPath";
		setClipPath(x,y,clipId);
		//
		// Increase radius for clipping:
		//
		radius*=Number::SQRT_TWO;
		isMale = true;
		_body << "<g clip-path=\"url(#" << clipId << ")\">\n";
		
	}else{
		//
		// Empty g with no clipping for female:
		//
		_body << "<g>\n";
		
	}
	
	//
	// NOTA BENE: The quadrant fill method looks only at the 
	// FIRST iconColumn and ignores any additional icon columns:
	//
	const DataTable *pDT = pIndividual->getDataTable();
	//
	// Get the data column of the first icon column:
	//
	DataColumn * pDC = pDT->getColumn( pDT->getIconColumnIndex(0) );
	
	//
	// Get the UniqueList for this column:
	//
	const UniqueList * pUL = pDC->getUniqueList();
	//
	// Only process if there are some non-missing levels
	// present:
	//
	if(!pUL->getLevels()){
		_body << "</g>\n";
		return;
	}
	
	//
	// What is the level and label in the UniqueList corresponding to the data value
	// for this individual?
	//
	//unsigned level;
	//std::string label;
	//pUL->getOrdinalAndLabelForKey( pDC->getDataAtIndex( pIndividual->getRowIndex() ),label,level );
	//
	
	Data* data = pDC->getDataAtIndex( pIndividual->getRowIndex());
	//
	// Draw a dot for missing values:
	//
	if(data->isMissing()){
		drawText(x,y,".","blackInkLetter_1");
		_body << "</g>\n";
		return;
	}
	std::string label;
	std::string svalue = data->get();
	std::istringstream i(svalue);
	int level;
	bool converted = (i>>level);
	if(!converted || level<0 || level>15 ){
		//
		// (1) Unable to convert data string to integer, or
		// (2) integer value is out of range
		//
		double lineSpacing,xAdvance,yMinimum,yMaximum;
		_lasiWrapper.getDimensions(svalue,&lineSpacing,&xAdvance,&yMinimum,&yMaximum);
		y+= 0.5*(yMaximum-yMinimum);
		drawIconText(x,y,svalue,"blackInkLetter_1");
		_body << "</g>\n";
		return;
	}
	
	//
	// Fill arc for each quadrant based on level:
	// Note: Madeline's "arc()" method doesn't use the standard counter-clockwise quadrants
	// starting at 0, so the order of the 4 "if" statements below may appear mixed up but 
	// this actually results in shading of the quadrants according to standard notation:
	//
	if(level & 0x02 ){
		arc(x,y,radius,0,0.5*Number::PI,"#000",label,"whiteInkLetter",isMale);
	}
	if(level & 0x01 ){
		arc(x,y,radius,0.5*Number::PI,Number::PI,"#000",label,"whiteInkLetter",isMale);
	}
	if(level & 0x08 ){
		arc(x,y,radius,Number::PI,1.5*Number::PI,"#000",label,"whiteInkLetter",isMale);
	}
	if(level & 0x04 ){
		arc(x,y,radius,1.5*Number::PI,2.0*Number::PI,"#000",label,"whiteInkLetter",isMale);
	}
	
	//
	// For the first time draw the icon legend too:
	//
	//if(!_iconLegendFlag){
	//	_iconLegendFlag = true;
	//	_iconLegend.setPedigreeTable(pDT);
	//}
	
	_body << "</g>\n";
	return;
	
}
Beispiel #9
0
	int SqliteClient::executeSqlQuery(const string& sql, DataTable& table)
	{
		Locker locker(&_sqliteDbMutex);

#if DEBUG
		Stopwatch sw("executeSqlQuery", 100);
#endif
		sqlite3_stmt *stmt;
		int result = sqlite3_prepare_v2(_sqliteDb, sql.c_str(),  sql.length(), &stmt, 0);  
		if(result != SQLITE_OK)
		{
			printErrorInfo("sqlite3_prepare_v2", sql);
			return result;
		}

		//const char* name = sqlite3_column_table_name(stmt, 0);
		//table.setName(name != NULL ? name : "temp");
        // todo: linke error for sqlite3_column_table_name.
        table.setName("temp");

#if DEBUG
		sw.setInfo(Convert::convertStr("executeSqlQuery, the table name is '%s'", table.getName().c_str()));
#endif

		int columnCount = sqlite3_column_count(stmt);
		for (int i = 0; i < columnCount; i++)
		{
			char* nameStr = (char*)sqlite3_column_name(stmt, i);
			string name;
			if(nameStr != NULL)
			{
				name = nameStr;
			}
			else
			{
				char temp[32];
				sprintf(temp, "tempCol%d", i);
				name = temp;
			}
			const char* typeStr = sqlite3_column_decltype(stmt, i);
			string type = typeStr != NULL ? typeStr : "int";
			DataColumn* column = new DataColumn(name, type);
			table.addColumn(column);
		}

		while(sqlite3_step(stmt) == SQLITE_ROW)
		{
			DataRow* row = new DataRow();
			for (int i = 0; i < columnCount; i++)
			{
				DataColumn* column = table.getColumns()->at(i);
				DataCell* cell = NULL;
				Value value;
				memset(&value, 0, sizeof(value));
				ValueTypes type = column->getType();
				switch (type)
				{
				case Null:
					break;
				case Integer:
					value.nValue = sqlite3_column_int(stmt, i);
					break;
				case String:
				case DateTime:
					{
						char* str = (char*)sqlite3_column_text(stmt, i);
						DataCell::setStringValue(value, str);
					}
					break;
				case Float:
					value.dValue = sqlite3_column_double(stmt, i);
					break;
				default:
					assert(false);
					break;
				}

				cell = new DataCell(column, value);
				row->addCell(cell);
			}
			table.addRow(row);
		}
		result = sqlite3_finalize(stmt);
		if(result != SQLITE_OK)
		{
			printErrorInfo("sqlite3_finalize", sql);
			return result;
		}

		return SQLITE_OK;
	}
Beispiel #10
0
//
// addPedigreesFromDataTable():
//
void PedigreeSet::addPedigreesFromDataTable(const DataTable * p_pedigreeTable, unsigned tableIndex,const std::string& sortField){
	
	//
	// Use const reference for convenience:
	// (so I don't have to change the code
	//  since the parameter has changed from a
	//  const DataTable & to a const DataTable * )
	//
	const DataTable & pedigreeTable = (*p_pedigreeTable);
	
	//std::cout << vt100::startBlue << "┏ Start of    addPedigreesFromDataTable ┓" << vt100::stopColor << std::endl;
	
	//
	// Get all the core columns from the datatable:
	//
	DataColumn *familyIdColumn = pedigreeTable.getColumn( pedigreeTable.labels.FamilyIdField );
	//familyIdColumn->printData();
	DataColumn *individualIdColumn = pedigreeTable.getColumn( pedigreeTable.labels.IndividualIdField );
	//individualIdColumn->printData();
	DataColumn *motherIdColumn = pedigreeTable.getColumn( pedigreeTable.labels.MotherIdField );
	DataColumn *fatherIdColumn = pedigreeTable.getColumn( pedigreeTable.labels.FatherIdField );
	DataColumn *genderColumn   = pedigreeTable.getColumn( pedigreeTable.labels.GenderField );
	
	DataColumn *collapsedColumn= 0;
	if(pedigreeTable.columnExists(pedigreeTable.labels.CollapsedField)){
		// 2015.11.30.ET ADDENDA:
		collapsedColumn=pedigreeTable.getColumn( pedigreeTable.labels.CollapsedField );
	}
	//
	// Insert the Pedigrees in a set:
	//
	std::string currentFamily;
	int numberOfRows = familyIdColumn->getNumberOfRows();
	int index=0;
	
	std::map<std::string,Individual *> collapsedIndicatorSet;
	Individual * collapsedIndividual=0;
	
	while(index < numberOfRows){
		
		currentFamily = familyIdColumn->get(index);
		if(currentFamily == "."){
			Warning("PedigreeSet::addPedigreesFromDataTable()",
			        "Family Id is missing for individual %s and will be ignored.",
			        individualIdColumn->get(index).c_str()
			);
			index++;
			continue;
		}
		std::pair<std::set<Pedigree*,comparePedigrees>::iterator,bool> pp;
		pp = _pedigrees.insert(new Pedigree(currentFamily,tableIndex));
		if(pp.second){
			for(int i=0;i<familyIdColumn->getNumberOfRows();i++) { 
				if(currentFamily.compare(familyIdColumn->get(i)) == 0){
					///////////////////////////////////
					//
					// Handle "collapsing":
					//
					///////////////////////////////////
					if(DrawingMetrics::getCollapsible() && collapsedColumn){
						std::string indicator=collapsedColumn->get(i);
						if(indicator=="."){
							// Add normal, non-collapsed individual, as usual:
							(*pp.first)->addIndividual(individualIdColumn->get(i),motherIdColumn->get(i),fatherIdColumn->get(i),genderColumn->get(i),i,tableIndex,pedigreeTable);
						}else{
							//
							// Handling collapsed individuals:
							//
							std::map<std::string,Individual *>::iterator it=collapsedIndicatorSet.find(indicator);
							if(it==collapsedIndicatorSet.end()){
								//
								// Indicator not yet present in set, so add the first marked individual
								// as the token individual:
								//
								collapsedIndividual = (*pp.first)->addIndividual(individualIdColumn->get(i),motherIdColumn->get(i),fatherIdColumn->get(i),genderColumn->get(i),i,tableIndex,pedigreeTable);
								collapsedIndividual->incrementCollapsedCount();
								collapsedIndicatorSet.insert(std::pair<std::string,Individual *>(indicator,collapsedIndividual));
								// 2015.12.01.ET DEBUG
								std::cout << "*** Individual " << individualIdColumn->get(i) << " used for collapsed group " << indicator << std::endl;
							}else{
								//////////////////////////////////////////////////
								//
								// Is gender of new person consistent?
								// 
								// Note: using Gender.getEnum() guarantees 
								// symbolic equivalency across different
								// string representations, e.g. "M"=="male", 
								// "♀"=="female", etc.
								//
								//////////////////////////////////////////////////
								if( it->second->getGender().getEnum() != Gender(genderColumn->get(i)).getEnum() ){
									// Change to missing on token individual:
									it->second->setGender(".");
								}
								//////////////////////////////////////////////////
								//
								// Is affection status of new person consistent?
								//
								//////////////////////////////////////////////////
								
								//////////////////////////////////////////////////
								//
								// increment collapsed count:
								//
								//////////////////////////////////////////////////
								it->second->incrementCollapsedCount();
								// 2015.12.01.ET DEBUG
								// std::cout << "*** Individual " << it->second->getId() << " with indicator " << indicator << " incremented to " << it->second->getCollapsedCount() << std::endl;
							}
						}
					}else{
						// CollapsedState OFF or Collapsed column not present, so just add everybody:
						(*pp.first)->addIndividual(individualIdColumn->get(i),motherIdColumn->get(i),fatherIdColumn->get(i),genderColumn->get(i),i,tableIndex,pedigreeTable);
					}
				}
			}
		}
		index++;
	}
	
	// Set the core optional fields on the individuals
	_setCoreOptionalFields(p_pedigreeTable);
	
	_establishConnections();
	
	bool dobPresent = false;
	if(pedigreeTable.getDOBColumnIndex() != DataTable::COLUMN_IS_MISSING){
		_checkParentChildDOB();
		dobPresent = true;
	}
	
	if(pedigreeTable.getPregnancyColumnIndex() != DataTable::COLUMN_IS_MISSING){
		_checkPregnancyStateValidity();
	}
	
	_determineFoundingGroups();
	
	bool sortFieldPresent = false;
	if(sortField != std::string("") && sortField != pedigreeTable.labels.DOBField){
		// Check to see if the field actually exists in the data table
		if(pedigreeTable.columnExists(sortField)){
			_computeWidths(sortField);
			sortFieldPresent = true;
		}else{
			Warning("PedigreeSet::addPedigreesFromDataTable()",
			        "Field '%s' specified for sorting the siblings does not exist in the Pedigree Table. Default ordering will be used.",
			        sortField.c_str()
			);
		}
	}
	if(!sortFieldPresent){
		if(dobPresent){
			//std::cout << "Siblings are ordered by DOB." << std::endl;
			_computeWidths(pedigreeTable.labels.DOBField,true);
			DrawingMetrics::setDisplayBirthOrder(true);
		}else{    
			//std::cout << "Default ordering of siblings." << std::endl;
			_computeWidths(std::string(""));
			
		}
	}
	//std::cout << vt100::startBlue << "┗ End of      addPedigreesFromDataTable ┛" << vt100::stopColor << std::endl;
	
}