<commit_before>/*
 * CityRegionImplementation.cpp
 *
 *  Created on: Feb 9, 2012
 *      Author: xyborn
 */

#include "CityRegion.h"
#include "events/CityUpdateEvent.h"
#include "server/chat/StringIdChatParameter.h"
#include "server/ServerCore.h"
#include "server/zone/managers/city/CityManager.h"
#include "server/zone/managers/planet/PlanetManager.h"
#include "server/zone/managers/planet/PlanetTravelPoint.h"
#include "server/zone/managers/stringid/StringIdManager.h"
#include "server/zone/managers/structure/StructureManager.h"
#include "server/zone/objects/area/ActiveArea.h"
#include "server/zone/objects/building/BuildingObject.h"
#include "server/zone/objects/creature/commands/BoardShuttleCommand.h"
#include "server/zone/objects/creature/commands/QueueCommand.h"
#include "server/zone/objects/creature/CreatureObject.h"
#include "server/zone/objects/player/PlayerObject.h"
#include "server/zone/objects/region/Region.h"
#include "server/zone/objects/scene/SceneObject.h"
#include "server/zone/objects/structure/StructureObject.h"
#include "server/zone/objects/tangible/components/vendor/AuctionTerminalDataComponent.h"
#include "server/zone/templates/tangible/SharedStructureObjectTemplate.h"
#include "server/zone/Zone.h"

int BoardShuttleCommand::MAXIMUM_PLAYER_COUNT = 3000;

void CityRegionImplementation::initializeTransientMembers() {
	ManagedObjectImplementation::initializeTransientMembers();

	loaded = false;
}

void CityRegionImplementation::notifyLoadFromDatabase() {
	ManagedObjectImplementation::notifyLoadFromDatabase();

	if (cityRank == CityManager::CLIENT)
		return;

	//if (zone !=)

	Zone* zone = getZone();

	if (zone == NULL)
		return;

	zone->addCityRegionToUpdate(_this.get());

	if (isRegistered())
		zone->getPlanetManager()->addRegion(_this.get());

	//Add taxes if they dont exist.
	if (taxes.size() <= 0) {
		info("Adding taxes for existing city that had no taxes.", true);
		taxes.add(0);
		taxes.add(0);
		taxes.add(0);
		taxes.add(0);
		taxes.add(0);
	}

	/*
	int seconds = -1 * round(nextUpdateTime.miliDifference() / 1000.f);

	if (seconds < 0) //If the update occurred in the past, force an immediate update.
		seconds = 0;

	rescheduleUpdateEvent(seconds);
	 */

	if (hasShuttle){
		CreatureObject* shuttle = cast<CreatureObject*>( zone->getZoneServer()->getObject(shuttleID, false));

		if (shuttle == NULL) {
			hasShuttle = false;
			shuttleID = 0;
			return;
		}

		float x = shuttle->getWorldPositionX();
		float y = shuttle->getWorldPositionY();
		float z = shuttle->getWorldPositionZ();

		Vector3 arrivalVector(x, y, z);
		PlanetTravelPoint* planetTravelPoint = new PlanetTravelPoint(zone->getZoneName(), getRegionName(), arrivalVector, arrivalVector, shuttle);
		zone->getPlanetManager()->addPlayerCityTravelPoint(planetTravelPoint);

		if (shuttle != NULL)
			zone->getPlanetManager()->scheduleShuttle(shuttle);
	}

}

void CityRegionImplementation::initialize() {
	zoningEnabled = true;

	registered = false;

	cityTreasury = 0;

	cityRank = RANK_CLIENT; //Default to client city

	cityHall = NULL;

	mayorID = 0;

	shuttleID = 0;

	hasShuttle = false;

	zone = NULL;

	cityUpdateEvent = NULL;

	zoningRights.setAllowOverwriteInsertPlan();
	zoningRights.setNullValue(0);

	cityMissionTerminals.setNoDuplicateInsertPlan();
	cityDecorations.setNoDuplicateInsertPlan();
	citySkillTrainers.setNoDuplicateInsertPlan();

	bazaars.setNoDuplicateInsertPlan();
	bazaars.setNullValue(NULL);

	setLoggingName("CityRegion");
	setLogging(true);

}

Region* CityRegionImplementation::addRegion(float x, float y, float radius, bool persistent) {
	if (zone == NULL) {
		return NULL;
	}

	String temp = "object/region_area.iff";
	ManagedReference<SceneObject*> obj = zone->getZoneServer()->createObject(temp.hashCode(), persistent ? 1 : 0);

	if (obj == NULL || !obj->isRegion()) {
		return NULL;
	}

	ManagedReference<Region*> region = cast<Region*>(obj.get());
	region->setCityRegion(_this.get());
	region->setRadius(radius);
	region->initializePosition(x, 0, y);
	region->setObjectName(regionName);

	if (isClientRegion())
		region->setNoBuildArea(true);

	zone->transferObject(region, -1, false);

	regions.put(region);

	return region;
}

void CityRegionImplementation::rescheduleUpdateEvent(uint32 seconds) {
	if (cityRank == CityManager::CLIENT)
		return;

	if (cityUpdateEvent == NULL) {
		cityUpdateEvent = new CityUpdateEvent(_this.get(), ServerCore::getZoneServer());
	} else if (cityUpdateEvent->isScheduled()) {
		cityUpdateEvent->cancel();
	}

	cityUpdateEvent->schedule(seconds * 1000);
	Core::getTaskManager()->getNextExecutionTime(cityUpdateEvent, nextUpdateTime);
}

int CityRegionImplementation::getTimeToUpdate() {
	return round(nextUpdateTime.miliDifference() / -1000.f);
}

void CityRegionImplementation::notifyEnter(SceneObject* object) {

	object->setCityRegion(_this.get());

	if (object->isBazaarTerminal() || object->isVendor()) {

		if (object->isBazaarTerminal())
			bazaars.put(object->getObjectID(), cast<TangibleObject*>(object));

		AuctionTerminalDataComponent* terminalData = NULL;
		DataObjectComponentReference* data = object->getDataObjectComponent();
		if(data != NULL && data->get() != NULL && data->get()->isAuctionTerminalData())
			terminalData = cast<AuctionTerminalDataComponent*>(data->get());

		if(terminalData != NULL)
			terminalData->updateUID();
	}

	if (object->isPlayerCreature())
		currentPlayers.increment();

	if (isClientRegion())
		return;

	if (object->isCreatureObject()){
		CreatureObject* creature = cast<CreatureObject*>(object);

		StringIdChatParameter params("city/city", "city_enter_city"); //You have entered %TT (%TO).
		params.setTT(getRegionName());

		UnicodeString strRank = StringIdManager::instance()->getStringId(String("@city/city:rank" + String::valueOf(cityRank)).hashCode());

		if (citySpecialization.isEmpty()) {
			params.setTO(strRank);
		}
		else {
			UnicodeString citySpec = StringIdManager::instance()->getStringId(citySpecialization.hashCode());
			params.setTO(strRank + ", " + citySpec);
		}

		creature->sendSystemMessage(params);

		applySpecializationModifiers(creature);
	}

	if (object->isStructureObject()){
		StructureObject* structure = cast<StructureObject*>(object);

		/*uint64 creatureID = structure->getOwnerObjectID();

		if (structure->isBuildingObject() && !citizenList.contains(creatureID)) {
			BuildingObject* building = cast<BuildingObject*>(object);
			CreatureObject* owner = building->getOwnerCreatureObject();

			if (owner != NULL) {
				PlayerObject* playerObject = owner->getPlayerObject();

				if (playerObject != NULL && playerObject->getDeclaredResidence() == building) {
					addCitizen(creatureID);
				}
			}
		}*/

		if (structure->isCivicStructure())
			addStructure(structure);
	}
}

void CityRegionImplementation::notifyExit(SceneObject* object) {
	//pre: no 2 different city regions should ever overlap, only 2 Regions of the same city region
	ManagedReference<Region*> activeRegion = cast<Region*>(object->getActiveRegion());

	if (activeRegion != NULL) {
		ManagedReference<CityRegion*> city = activeRegion->getCityRegion();

		object->setCityRegion(city);

		if (city == _this.get()) // if its the same city we wait till the object exits the last region
			return;
	} else {
		object->setCityRegion(NULL);
	}

	if (object->isBazaarTerminal() || object->isVendor()) {
		if (object->isBazaarTerminal())
			bazaars.drop(object->getObjectID());

		AuctionTerminalDataComponent* terminalData = NULL;
		DataObjectComponentReference* data = object->getDataObjectComponent();
		if(data != NULL && data->get() != NULL && data->get()->isAuctionTerminalData())
			terminalData = cast<AuctionTerminalDataComponent*>(data->get());

		if(terminalData != NULL)
			terminalData->updateUID();
	}

	if (object->isPlayerCreature())
		currentPlayers.decrement();

	if (isClientRegion())
		return;

	if (object->isCreatureObject()){

		CreatureObject* creature = cast<CreatureObject*>(object);

		StringIdChatParameter params("city/city", "city_leave_city"); //You have left %TO.
		params.setTO(getRegionName());

		creature->sendSystemMessage(params);

		removeSpecializationModifiers(creature);
	}

	if (object->isStructureObject()) {
		float x = object->getWorldPositionX();
		float y = object->getWorldPositionY();

		//StructureObject* structure = cast<StructureObject*>(object);

		StructureObject* structure = cast<StructureObject*>(object);

		/*uint64 creatureID = structure->getOwnerObjectID();

		if (structure->isBuildingObject() && citizenList.contains(creatureID)) {
			BuildingObject* building = cast<BuildingObject*>(object);

			CreatureObject* owner = building->getOwnerCreatureObject();

			if (owner != NULL) {
				PlayerObject* playerObject = owner->getPlayerObject();

				if (playerObject != NULL && playerObject->getDeclaredResidence() == building){
					removeCitizen(creatureID);
				}
			}
		}*/

		if (structure->isCivicStructure())
			removeStructure(structure);
	}
}

void CityRegionImplementation::setRegionName(const StringId& name) {
	regionName = name;
}

Vector<ManagedReference<TangibleObject*> >* CityRegionImplementation::getVendorsInCity() {
	Vector<ManagedReference<TangibleObject*> >* vendors = new Vector<ManagedReference<TangibleObject*> >();

	return vendors;
}

void CityRegionImplementation::addZoningRights(uint64 objectid, uint32 duration) {
	Time now;

	zoningRights.put(objectid, duration + now.getTime());
}

bool CityRegionImplementation::hasZoningRights(uint64 objectid) {
	if (isMilitiaMember(objectid))
		return true;

	uint32 timestamp = zoningRights.get(objectid);

	if (timestamp == 0)
		return false;

	Time now;
	return (now.getTime() <= timestamp);
}

void CityRegionImplementation::setZone(Zone* zne) {
	zone = zne;
}

void CityRegionImplementation::setRadius(float rad) {
	if (regions.size() <= 0)
		return;

	ManagedReference<ActiveArea*> aa = regions.get(0).get();
	aa->setRadius(rad);

	zone->removeObject(aa, NULL, false);
	zone->transferObject(aa, -1, false);
}

void CityRegionImplementation::destroyActiveAreas() {
	for (int i = 0; i < regions.size(); ++i) {
		ManagedReference<Region*> aa = regions.get(i);

		if (aa != NULL) {
			aa->destroyObjectFromWorld(false);
			aa->destroyObjectFromDatabase(true);

			regions.drop(aa);
		}
	}
}

String CityRegionImplementation::getRegionName() {
	if(!customRegionName.isEmpty())
		return customRegionName;

	return regionName.getFullPath();
}

bool CityRegionImplementation::hasUniqueStructure(uint32 crc){
	Locker locker(_this.get());

	for (int i = 0; i < structures.size(); ++i) {
		ManagedReference<StructureObject*> structure = structures.get(i);

		if (structure->getObjectTemplate()->getServerObjectCRC() == crc)
			return true;
	}

	return false;
}

void CityRegionImplementation::destroyAllStructuresForRank(uint8 rank){
	Locker locker(_this.get());

	if (zone == NULL)
		return;

	StructureManager* structureManager = StructureManager::instance();

	for (int i = structures.size(); i >= 0; --i) {
		ManagedReference<StructureObject*> structure = structures.get(i);

		SharedStructureObjectTemplate* ssot = dynamic_cast<SharedStructureObjectTemplate*>(structure->getObjectTemplate());

		//We only want to destroy civic structures.
		if (ssot == NULL || ssot->getCityRankRequired() < rank || !ssot->isCivicStructure())
			continue;

		Locker _clocker(structure, _this.get());

		structureManager->destroyStructure(structure);

		structures.drop(structure);
	}
}

void CityRegionImplementation::updateMilitia(){

	Locker locker (_this.get());

	uint64 objectID;

	for (int i = militiaMembers.size() - 1;i >= 0; --i){

		objectID = militiaMembers.get(i);

		if (!isCitizen(objectID))
			removeMilitiaMember(objectID);
	}
}

void CityRegionImplementation::removeAllTerminals(){
	for (int i = 0; i < cityMissionTerminals.size(); i++){
		cityMissionTerminals.get(i)->destroyObjectFromWorld(false);
		cityMissionTerminals.get(i)->destroyObjectFromDatabase(false);
	}

	cityMissionTerminals.removeAll();
}

void CityRegionImplementation::removeAllSkillTrainers(){

	for (int i = 0; i < citySkillTrainers.size(); i++){
		citySkillTrainers.get(i)->destroyObjectFromWorld(false);
		citySkillTrainers.get(i)->destroyObjectFromDatabase(false);
	}

	citySkillTrainers.removeAll();
}

void CityRegionImplementation::resetVotingPeriod() {
	nextInauguration.updateToCurrentTime();
	nextInauguration.addMiliTime(CityManagerImplementation::cityVotingDuration * 60000);
}

void CityRegionImplementation::applySpecializationModifiers(CreatureObject* creature) {
	if (getZone() == NULL)
		return;

	CityManager* cityManager = getZone()->getZoneServer()->getCityManager();
	CitySpecialization* cityspec = cityManager->getCitySpecialization(citySpecialization);

	if (cityspec == NULL)
		return;

	//Remove all current city skillmods
	creature->removeAllSkillModsOfType(SkillModManager::CITY);

	VectorMap<String, int>* mods = cityspec->getSkillMods();

	for (int i = 0; i < mods->size(); ++i) {
		VectorMapEntry<String, int> entry = mods->elementAt(i);

		creature->addSkillMod(SkillModManager::CITY, entry.getKey(), entry.getValue());
	}
}

void CityRegionImplementation::removeSpecializationModifiers(CreatureObject* creature) {
	creature->removeAllSkillModsOfType(SkillModManager::CITY);
}
<commit_msg>(unstable) [fixed] issue destroying city hall and city<commit_after>/*
 * CityRegionImplementation.cpp
 *
 *  Created on: Feb 9, 2012
 *      Author: xyborn
 */

#include "CityRegion.h"
#include "events/CityUpdateEvent.h"
#include "server/chat/StringIdChatParameter.h"
#include "server/ServerCore.h"
#include "server/zone/managers/city/CityManager.h"
#include "server/zone/managers/planet/PlanetManager.h"
#include "server/zone/managers/planet/PlanetTravelPoint.h"
#include "server/zone/managers/stringid/StringIdManager.h"
#include "server/zone/managers/structure/StructureManager.h"
#include "server/zone/objects/area/ActiveArea.h"
#include "server/zone/objects/building/BuildingObject.h"
#include "server/zone/objects/creature/commands/BoardShuttleCommand.h"
#include "server/zone/objects/creature/commands/QueueCommand.h"
#include "server/zone/objects/creature/CreatureObject.h"
#include "server/zone/objects/player/PlayerObject.h"
#include "server/zone/objects/region/Region.h"
#include "server/zone/objects/scene/SceneObject.h"
#include "server/zone/objects/structure/StructureObject.h"
#include "server/zone/objects/tangible/components/vendor/AuctionTerminalDataComponent.h"
#include "server/zone/templates/tangible/SharedStructureObjectTemplate.h"
#include "server/zone/Zone.h"

int BoardShuttleCommand::MAXIMUM_PLAYER_COUNT = 3000;

void CityRegionImplementation::initializeTransientMembers() {
	ManagedObjectImplementation::initializeTransientMembers();

	loaded = false;
}

void CityRegionImplementation::notifyLoadFromDatabase() {
	ManagedObjectImplementation::notifyLoadFromDatabase();

	if (cityRank == CityManager::CLIENT)
		return;

	//if (zone !=)

	Zone* zone = getZone();

	if (zone == NULL)
		return;

	zone->addCityRegionToUpdate(_this.get());

	if (isRegistered())
		zone->getPlanetManager()->addRegion(_this.get());

	//Add taxes if they dont exist.
	if (taxes.size() <= 0) {
		info("Adding taxes for existing city that had no taxes.", true);
		taxes.add(0);
		taxes.add(0);
		taxes.add(0);
		taxes.add(0);
		taxes.add(0);
	}

	/*
	int seconds = -1 * round(nextUpdateTime.miliDifference() / 1000.f);

	if (seconds < 0) //If the update occurred in the past, force an immediate update.
		seconds = 0;

	rescheduleUpdateEvent(seconds);
	 */

	if (hasShuttle){
		CreatureObject* shuttle = cast<CreatureObject*>( zone->getZoneServer()->getObject(shuttleID, false));

		if (shuttle == NULL) {
			hasShuttle = false;
			shuttleID = 0;
			return;
		}

		float x = shuttle->getWorldPositionX();
		float y = shuttle->getWorldPositionY();
		float z = shuttle->getWorldPositionZ();

		Vector3 arrivalVector(x, y, z);
		PlanetTravelPoint* planetTravelPoint = new PlanetTravelPoint(zone->getZoneName(), getRegionName(), arrivalVector, arrivalVector, shuttle);
		zone->getPlanetManager()->addPlayerCityTravelPoint(planetTravelPoint);

		if (shuttle != NULL)
			zone->getPlanetManager()->scheduleShuttle(shuttle);
	}

}

void CityRegionImplementation::initialize() {
	zoningEnabled = true;

	registered = false;

	cityTreasury = 0;

	cityRank = RANK_CLIENT; //Default to client city

	cityHall = NULL;

	mayorID = 0;

	shuttleID = 0;

	hasShuttle = false;

	zone = NULL;

	cityUpdateEvent = NULL;

	zoningRights.setAllowOverwriteInsertPlan();
	zoningRights.setNullValue(0);

	cityMissionTerminals.setNoDuplicateInsertPlan();
	cityDecorations.setNoDuplicateInsertPlan();
	citySkillTrainers.setNoDuplicateInsertPlan();

	bazaars.setNoDuplicateInsertPlan();
	bazaars.setNullValue(NULL);

	setLoggingName("CityRegion");
	setLogging(true);

}

Region* CityRegionImplementation::addRegion(float x, float y, float radius, bool persistent) {
	if (zone == NULL) {
		return NULL;
	}

	String temp = "object/region_area.iff";
	ManagedReference<SceneObject*> obj = zone->getZoneServer()->createObject(temp.hashCode(), persistent ? 1 : 0);

	if (obj == NULL || !obj->isRegion()) {
		return NULL;
	}

	ManagedReference<Region*> region = cast<Region*>(obj.get());
	region->setCityRegion(_this.get());
	region->setRadius(radius);
	region->initializePosition(x, 0, y);
	region->setObjectName(regionName);

	if (isClientRegion())
		region->setNoBuildArea(true);

	zone->transferObject(region, -1, false);

	regions.put(region);

	return region;
}

void CityRegionImplementation::rescheduleUpdateEvent(uint32 seconds) {
	if (cityRank == CityManager::CLIENT)
		return;

	if (cityUpdateEvent == NULL) {
		cityUpdateEvent = new CityUpdateEvent(_this.get(), ServerCore::getZoneServer());
	} else if (cityUpdateEvent->isScheduled()) {
		cityUpdateEvent->cancel();
	}

	cityUpdateEvent->schedule(seconds * 1000);
	Core::getTaskManager()->getNextExecutionTime(cityUpdateEvent, nextUpdateTime);
}

int CityRegionImplementation::getTimeToUpdate() {
	return round(nextUpdateTime.miliDifference() / -1000.f);
}

void CityRegionImplementation::notifyEnter(SceneObject* object) {

	object->setCityRegion(_this.get());

	if (object->isBazaarTerminal() || object->isVendor()) {

		if (object->isBazaarTerminal())
			bazaars.put(object->getObjectID(), cast<TangibleObject*>(object));

		AuctionTerminalDataComponent* terminalData = NULL;
		DataObjectComponentReference* data = object->getDataObjectComponent();
		if(data != NULL && data->get() != NULL && data->get()->isAuctionTerminalData())
			terminalData = cast<AuctionTerminalDataComponent*>(data->get());

		if(terminalData != NULL)
			terminalData->updateUID();
	}

	if (object->isPlayerCreature())
		currentPlayers.increment();

	if (isClientRegion())
		return;

	if (object->isCreatureObject()){
		CreatureObject* creature = cast<CreatureObject*>(object);

		StringIdChatParameter params("city/city", "city_enter_city"); //You have entered %TT (%TO).
		params.setTT(getRegionName());

		UnicodeString strRank = StringIdManager::instance()->getStringId(String("@city/city:rank" + String::valueOf(cityRank)).hashCode());

		if (citySpecialization.isEmpty()) {
			params.setTO(strRank);
		}
		else {
			UnicodeString citySpec = StringIdManager::instance()->getStringId(citySpecialization.hashCode());
			params.setTO(strRank + ", " + citySpec);
		}

		creature->sendSystemMessage(params);

		applySpecializationModifiers(creature);
	}

	if (object->isStructureObject()){
		StructureObject* structure = cast<StructureObject*>(object);

		/*uint64 creatureID = structure->getOwnerObjectID();

		if (structure->isBuildingObject() && !citizenList.contains(creatureID)) {
			BuildingObject* building = cast<BuildingObject*>(object);
			CreatureObject* owner = building->getOwnerCreatureObject();

			if (owner != NULL) {
				PlayerObject* playerObject = owner->getPlayerObject();

				if (playerObject != NULL && playerObject->getDeclaredResidence() == building) {
					addCitizen(creatureID);
				}
			}
		}*/

		if (structure->isCivicStructure())
			addStructure(structure);
	}
}

void CityRegionImplementation::notifyExit(SceneObject* object) {
	//pre: no 2 different city regions should ever overlap, only 2 Regions of the same city region
	ManagedReference<Region*> activeRegion = cast<Region*>(object->getActiveRegion());

	if (activeRegion != NULL) {
		ManagedReference<CityRegion*> city = activeRegion->getCityRegion();

		object->setCityRegion(city);

		if (city == _this.get()) // if its the same city we wait till the object exits the last region
			return;
	} else {
		object->setCityRegion(NULL);
	}

	if (object->isBazaarTerminal() || object->isVendor()) {
		if (object->isBazaarTerminal())
			bazaars.drop(object->getObjectID());

		AuctionTerminalDataComponent* terminalData = NULL;
		DataObjectComponentReference* data = object->getDataObjectComponent();
		if(data != NULL && data->get() != NULL && data->get()->isAuctionTerminalData())
			terminalData = cast<AuctionTerminalDataComponent*>(data->get());

		if(terminalData != NULL)
			terminalData->updateUID();
	}

	if (object->isPlayerCreature())
		currentPlayers.decrement();

	if (isClientRegion())
		return;

	if (object->isCreatureObject()){

		CreatureObject* creature = cast<CreatureObject*>(object);

		StringIdChatParameter params("city/city", "city_leave_city"); //You have left %TO.
		params.setTO(getRegionName());

		creature->sendSystemMessage(params);

		removeSpecializationModifiers(creature);
	}

	if (object->isStructureObject()) {
		float x = object->getWorldPositionX();
		float y = object->getWorldPositionY();

		//StructureObject* structure = cast<StructureObject*>(object);

		StructureObject* structure = cast<StructureObject*>(object);

		/*uint64 creatureID = structure->getOwnerObjectID();

		if (structure->isBuildingObject() && citizenList.contains(creatureID)) {
			BuildingObject* building = cast<BuildingObject*>(object);

			CreatureObject* owner = building->getOwnerCreatureObject();

			if (owner != NULL) {
				PlayerObject* playerObject = owner->getPlayerObject();

				if (playerObject != NULL && playerObject->getDeclaredResidence() == building){
					removeCitizen(creatureID);
				}
			}
		}*/

		if (structure->isCivicStructure())
			removeStructure(structure);
	}
}

void CityRegionImplementation::setRegionName(const StringId& name) {
	regionName = name;
}

Vector<ManagedReference<TangibleObject*> >* CityRegionImplementation::getVendorsInCity() {
	Vector<ManagedReference<TangibleObject*> >* vendors = new Vector<ManagedReference<TangibleObject*> >();

	return vendors;
}

void CityRegionImplementation::addZoningRights(uint64 objectid, uint32 duration) {
	Time now;

	zoningRights.put(objectid, duration + now.getTime());
}

bool CityRegionImplementation::hasZoningRights(uint64 objectid) {
	if (isMilitiaMember(objectid))
		return true;

	uint32 timestamp = zoningRights.get(objectid);

	if (timestamp == 0)
		return false;

	Time now;
	return (now.getTime() <= timestamp);
}

void CityRegionImplementation::setZone(Zone* zne) {
	zone = zne;
}

void CityRegionImplementation::setRadius(float rad) {
	if (regions.size() <= 0)
		return;

	ManagedReference<ActiveArea*> aa = regions.get(0).get();
	aa->setRadius(rad);

	zone->removeObject(aa, NULL, false);
	zone->transferObject(aa, -1, false);
}

void CityRegionImplementation::destroyActiveAreas() {
	for (int i = 0; i < regions.size(); ++i) {
		ManagedReference<Region*> aa = regions.get(i);

		if (aa != NULL) {
			aa->destroyObjectFromWorld(false);
			aa->destroyObjectFromDatabase(true);

			regions.drop(aa);
		}
	}
}

String CityRegionImplementation::getRegionName() {
	if(!customRegionName.isEmpty())
		return customRegionName;

	return regionName.getFullPath();
}

bool CityRegionImplementation::hasUniqueStructure(uint32 crc){
	Locker locker(_this.get());

	for (int i = 0; i < structures.size(); ++i) {
		ManagedReference<StructureObject*> structure = structures.get(i);

		if (structure->getObjectTemplate()->getServerObjectCRC() == crc)
			return true;
	}

	return false;
}

void CityRegionImplementation::destroyAllStructuresForRank(uint8 rank){
	Locker locker(_this.get());

	if (zone == NULL)
		return;

	StructureManager* structureManager = StructureManager::instance();

	for (int i = structures.size() - 1; i >= 0; --i) {
		ManagedReference<StructureObject*> structure = structures.get(i);

		SharedStructureObjectTemplate* ssot = dynamic_cast<SharedStructureObjectTemplate*>(structure->getObjectTemplate());

		//We only want to destroy civic structures.
		if (ssot == NULL || ssot->getCityRankRequired() < rank || !ssot->isCivicStructure())
			continue;

		Locker _clocker(structure, _this.get());

		structureManager->destroyStructure(structure);

		structures.drop(structure);
	}
}

void CityRegionImplementation::updateMilitia(){

	Locker locker (_this.get());

	uint64 objectID;

	for (int i = militiaMembers.size() - 1;i >= 0; --i){

		objectID = militiaMembers.get(i);

		if (!isCitizen(objectID))
			removeMilitiaMember(objectID);
	}
}

void CityRegionImplementation::removeAllTerminals(){
	for (int i = 0; i < cityMissionTerminals.size(); i++){
		cityMissionTerminals.get(i)->destroyObjectFromWorld(false);
		cityMissionTerminals.get(i)->destroyObjectFromDatabase(false);
	}

	cityMissionTerminals.removeAll();
}

void CityRegionImplementation::removeAllSkillTrainers(){

	for (int i = 0; i < citySkillTrainers.size(); i++){
		citySkillTrainers.get(i)->destroyObjectFromWorld(false);
		citySkillTrainers.get(i)->destroyObjectFromDatabase(false);
	}

	citySkillTrainers.removeAll();
}

void CityRegionImplementation::resetVotingPeriod() {
	nextInauguration.updateToCurrentTime();
	nextInauguration.addMiliTime(CityManagerImplementation::cityVotingDuration * 60000);
}

void CityRegionImplementation::applySpecializationModifiers(CreatureObject* creature) {
	if (getZone() == NULL)
		return;

	CityManager* cityManager = getZone()->getZoneServer()->getCityManager();
	CitySpecialization* cityspec = cityManager->getCitySpecialization(citySpecialization);

	if (cityspec == NULL)
		return;

	//Remove all current city skillmods
	creature->removeAllSkillModsOfType(SkillModManager::CITY);

	VectorMap<String, int>* mods = cityspec->getSkillMods();

	for (int i = 0; i < mods->size(); ++i) {
		VectorMapEntry<String, int> entry = mods->elementAt(i);

		creature->addSkillMod(SkillModManager::CITY, entry.getKey(), entry.getValue());
	}
}

void CityRegionImplementation::removeSpecializationModifiers(CreatureObject* creature) {
	creature->removeAllSkillModsOfType(SkillModManager::CITY);
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES)
 *
 * This file is part of Orfeo Toolbox
 *
 *     https://www.orfeo-toolbox.org/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "otbClassKMeansBase.h"

namespace otb
{
namespace Wrapper
{

class KMeansClassification: public ClassKMeansBase
{
public:
  /** Standard class typedefs. */
  typedef KMeansClassification Self;
  typedef ClassKMeansBase Superclass;
  typedef itk::SmartPointer<Self> Pointer;
  typedef itk::SmartPointer<const Self> ConstPointer;

  /** Standard macro */
  itkNewMacro(Self);

  itkTypeMacro(Self, Superclass);

private:
  void DoInit() ITK_OVERRIDE
  {
    SetName("KMeansClassification");
    SetDescription("Unsupervised KMeans image classification");

    SetDocName("Unsupervised KMeans image classification");
    SetDocLongDescription("Performs unsupervised KMeans image classification."
      "KMeansClassification is a composite application, "
      "using an existing training and classification application."
      "The SharkKMeans model is used.\n"
      "The steps of this composite application :\n"
        "1) ImageEnveloppe : create a shapefile (1 polygon),\n"
        "2) PolygonClassStatistics : compute the statistics,\n"
        "3) SampleSelection : select the samples by constant strategy in the shapefile "
            "(1000000 samples max),\n"
        "4) SamplesExtraction : extract the samples descriptors (update of SampleSelection output file),\n"
        "5) ComputeImagesStatistics : compute images second order statistics,\n"
        "6) TrainVectorClassifier : train the SharkKMeans model,\n"
        "7) ImageClassifier : performs the classification of the input image "
            "according to a model file.\n\n"
        "It's possible to choice random/periodic modes of the SampleSelection application.\n"
        "If you want keep the temporary files (sample selected, model file, ...), "
        "initialize cleanup parameter.\n"
        "For more information on shark KMeans algorithm [1].");

    SetDocLimitations("None");
    SetDocAuthors("OTB-Team");
    SetDocSeeAlso("ImageEnveloppe PolygonClassStatistics SampleSelection SamplesExtraction "
      "PolygonClassStatistics TrainVectorClassifier ImageClassifier\n"
      "[1] http://image.diku.dk/shark/sphinx_pages/build/html/rest_sources/tutorials/algorithms/kmeans.html");

    AddDocTag(Tags::Learning);
    AddDocTag(Tags::Segmentation);

    // Perform initialization
    ClearApplications();

    // initialisation parameters and synchronizes parameters
    initKMParams();

    AddRANDParameter();

    // Doc example parameter settings
    SetDocExampleParameterValue("in", "QB_1_ortho.tif");
    SetDocExampleParameterValue("ts", "1000");
    SetDocExampleParameterValue("nc", "5");
    SetDocExampleParameterValue("maxit", "1000");
    SetDocExampleParameterValue("out", "ClassificationFilterOutput.tif uint8");

    SetOfficialDocLink();
  }

  void DoUpdateParameters() ITK_OVERRIDE
  {
  }

  void DoExecute() ITK_OVERRIDE
  {
    if (IsParameterEnabled("vm") && HasValue("vm")) ConnectKMClassificationMask();

    KMeansFileNamesHandler fileNames;

    std::string fieldName = "field";

    fileNames.CreateTemporaryFileNames(GetParameterString( "out" ));

    // Create an image envelope
    ComputeImageEnvelope(fileNames.tmpVectorFile);
    // Add a new field at the ImageEnvelope output file
    ComputeAddField(fileNames.tmpVectorFile, fieldName);

    // Compute PolygonStatistics app
    UpdateKMPolygonClassStatisticsParameters(fileNames.tmpVectorFile);
    ComputePolygonStatistics(fileNames.polyStatOutput, fieldName);

    // Compute number of sample max for KMeans
    const int theoricNBSamplesForKMeans = GetParameterInt("ts");
    const int upperThresholdNBSamplesForKMeans = 1000 * 1000;
    const int actualNBSamplesForKMeans = std::min(theoricNBSamplesForKMeans,
                                                  upperThresholdNBSamplesForKMeans);
    otbAppLogINFO(<< actualNBSamplesForKMeans << " is the maximum sample size that will be used." \
                  << std::endl);

    // Compute SampleSelection and SampleExtraction app
    SelectAndExtractSamples(fileNames.polyStatOutput, fieldName,
                            fileNames.sampleOutput,
                            actualNBSamplesForKMeans);

    // Compute Images second order statistics
    ComputeImageStatistics(GetParameterString("in"), fileNames.imgStatOutput);

    // Compute a train model with TrainVectorClassifier app
    TrainKMModel(GetParameterImage("in"), fileNames.sampleOutput,
                 fileNames.modelFile);

    // Compute a classification of the input image according to a model file
    KMeansClassif();

    // Create the output text file containing centroids positions
    CreateOutMeansFile(GetParameterImage("in"), fileNames.modelFile, GetParameterInt("nc"));

    // Remove all tempory files
    if( IsParameterEnabled( "cleanup" ) )
      {
      otbAppLogINFO( <<"Final clean-up ..." );
      fileNames.clear();
      }
  }

private :
  void UpdateKMPolygonClassStatisticsParameters(const std::string &vectorFileName)
  {
    GetInternalApplication( "polystats" )->SetParameterString( "vec", vectorFileName, false );
    UpdateInternalParameters( "polystats" );
  }

};

}
}

OTB_APPLICATION_EXPORT(otb::Wrapper::KMeansClassification)

<commit_msg>ENH: add const at the param in KMeansClassification<commit_after>/*
 * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES)
 *
 * This file is part of Orfeo Toolbox
 *
 *     https://www.orfeo-toolbox.org/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "otbClassKMeansBase.h"

namespace otb
{
namespace Wrapper
{

class KMeansClassification: public ClassKMeansBase
{
public:
  /** Standard class typedefs. */
  typedef KMeansClassification Self;
  typedef ClassKMeansBase Superclass;
  typedef itk::SmartPointer<Self> Pointer;
  typedef itk::SmartPointer<const Self> ConstPointer;

  /** Standard macro */
  itkNewMacro(Self);

  itkTypeMacro(Self, Superclass);

private:
  void DoInit() ITK_OVERRIDE
  {
    SetName("KMeansClassification");
    SetDescription("Unsupervised KMeans image classification");

    SetDocName("Unsupervised KMeans image classification");
    SetDocLongDescription("Performs unsupervised KMeans image classification."
      "KMeansClassification is a composite application, "
      "using an existing training and classification application."
      "The SharkKMeans model is used.\n"
      "The steps of this composite application :\n"
        "1) ImageEnveloppe : create a shapefile (1 polygon),\n"
        "2) PolygonClassStatistics : compute the statistics,\n"
        "3) SampleSelection : select the samples by constant strategy in the shapefile "
            "(1000000 samples max),\n"
        "4) SamplesExtraction : extract the samples descriptors (update of SampleSelection output file),\n"
        "5) ComputeImagesStatistics : compute images second order statistics,\n"
        "6) TrainVectorClassifier : train the SharkKMeans model,\n"
        "7) ImageClassifier : performs the classification of the input image "
            "according to a model file.\n\n"
        "It's possible to choice random/periodic modes of the SampleSelection application.\n"
        "If you want keep the temporary files (sample selected, model file, ...), "
        "initialize cleanup parameter.\n"
        "For more information on shark KMeans algorithm [1].");

    SetDocLimitations("None");
    SetDocAuthors("OTB-Team");
    SetDocSeeAlso("ImageEnveloppe PolygonClassStatistics SampleSelection SamplesExtraction "
      "PolygonClassStatistics TrainVectorClassifier ImageClassifier\n"
      "[1] http://image.diku.dk/shark/sphinx_pages/build/html/rest_sources/tutorials/algorithms/kmeans.html");

    AddDocTag(Tags::Learning);
    AddDocTag(Tags::Segmentation);

    // Perform initialization
    ClearApplications();

    // initialisation parameters and synchronizes parameters
    initKMParams();

    AddRANDParameter();

    // Doc example parameter settings
    SetDocExampleParameterValue("in", "QB_1_ortho.tif");
    SetDocExampleParameterValue("ts", "1000");
    SetDocExampleParameterValue("nc", "5");
    SetDocExampleParameterValue("maxit", "1000");
    SetDocExampleParameterValue("out", "ClassificationFilterOutput.tif uint8");

    SetOfficialDocLink();
  }

  void DoUpdateParameters() ITK_OVERRIDE
  {
  }

  void DoExecute() ITK_OVERRIDE
  {
    if (IsParameterEnabled("vm") && HasValue("vm")) ConnectKMClassificationMask();

    KMeansFileNamesHandler fileNames;

    const std::string fieldName = "field";

    fileNames.CreateTemporaryFileNames(GetParameterString( "out" ));

    // Create an image envelope
    ComputeImageEnvelope(fileNames.tmpVectorFile);
    // Add a new field at the ImageEnvelope output file
    ComputeAddField(fileNames.tmpVectorFile, fieldName);

    // Compute PolygonStatistics app
    UpdateKMPolygonClassStatisticsParameters(fileNames.tmpVectorFile);
    ComputePolygonStatistics(fileNames.polyStatOutput, fieldName);

    // Compute number of sample max for KMeans
    const int theoricNBSamplesForKMeans = GetParameterInt("ts");
    const int upperThresholdNBSamplesForKMeans = 1000 * 1000;
    const int actualNBSamplesForKMeans = std::min(theoricNBSamplesForKMeans,
                                                  upperThresholdNBSamplesForKMeans);
    otbAppLogINFO(<< actualNBSamplesForKMeans << " is the maximum sample size that will be used." \
                  << std::endl);

    // Compute SampleSelection and SampleExtraction app
    SelectAndExtractSamples(fileNames.polyStatOutput, fieldName,
                            fileNames.sampleOutput,
                            actualNBSamplesForKMeans);

    // Compute Images second order statistics
    ComputeImageStatistics(GetParameterString("in"), fileNames.imgStatOutput);

    // Compute a train model with TrainVectorClassifier app
    TrainKMModel(GetParameterImage("in"), fileNames.sampleOutput,
                 fileNames.modelFile);

    // Compute a classification of the input image according to a model file
    KMeansClassif();

    // Create the output text file containing centroids positions
    CreateOutMeansFile(GetParameterImage("in"), fileNames.modelFile, GetParameterInt("nc"));

    // Remove all tempory files
    if( IsParameterEnabled( "cleanup" ) )
      {
      otbAppLogINFO( <<"Final clean-up ..." );
      fileNames.clear();
      }
  }

private :
  void UpdateKMPolygonClassStatisticsParameters(const std::string &vectorFileName)
  {
    GetInternalApplication( "polystats" )->SetParameterString( "vec", vectorFileName, false );
    UpdateInternalParameters( "polystats" );
  }

};

}
}

OTB_APPLICATION_EXPORT(otb::Wrapper::KMeansClassification)

<|endoftext|>


<commit_before>void runTTreeFilter() {
    // author: Redmer Alexander Bertens, Utrecht University
    // rbertens@cern.ch , rbertens@nikhef.nl , r.a.bertens@uu.nl
    //
    // example which converts input data (in this case local aod's put into a chain)
    // to a tree which holds
    // - AliFlowTTreeEvent : event object
    // - AliFlowTTreeTrack : track objects
    // see source of these classes for more details

    // load libraries
    gSystem->Load("libCore.so");
    gSystem->Load("libGeom.so");
    gSystem->Load("libVMC.so");
    gSystem->Load("libPhysics.so");
    gSystem->Load("libTree.so");
    gSystem->Load("libSTEERBase.so");
    gSystem->Load("libESD.so");
    gSystem->Load("libAOD.so");
    gSystem->Load("libANALYSIS.so");
    gSystem->Load("libANALYSISalice.so");

    // create the analysis manager
    AliAnalysisManager* mgr = new AliAnalysisManager("MyManager");

    // create a tchain which will point to an aod tree
    TChain* chain = new TChain("aodTree");
    // add a few files to the chain (change this so that your local files are added)
    chain->Add("/home/rbertens/Documents/CERN/ALICE_DATA/data/2010/LHC10h/000139510/ESDs/pass2/AOD086/0003/AliAOD.root");
    chain->Add("/home/rbertens/Documents/CERN/ALICE_DATA/data/2010/LHC10h/000139510/ESDs/pass2/AOD086/0003/AliAOD.root");
    chain->Add("/home/rbertens/Documents/CERN/ALICE_DATA/data/2010/LHC10h/000139510/ESDs/pass2/AOD086/0004/AliAOD.root");
    chain->Add("/home/rbertens/Documents/CERN/ALICE_DATA/data/2010/LHC10h/000139510/ESDs/pass2/AOD086/0005/AliAOD.root");
    chain->Add("/home/rbertens/Documents/CERN/ALICE_DATA/data/2010/LHC10h/000139510/ESDs/pass2/AOD086/0006/AliAOD.root");
    chain->Add("/home/rbertens/Documents/CERN/ALICE_DATA/data/2010/LHC10h/000139510/ESDs/pass2/AOD086/0007/AliAOD.root");
    chain->Add("/home/rbertens/Documents/CERN/ALICE_DATA/data/2010/LHC10h/000139510/ESDs/pass2/AOD086/0008/AliAOD.root");
    chain->Add("/home/rbertens/Documents/CERN/ALICE_DATA/data/2010/LHC10h/000139510/ESDs/pass2/AOD086/0009/AliAOD.root");
    chain->Add("/home/rbertens/Documents/CERN/ALICE_DATA/data/2010/LHC10h/000139510/ESDs/pass2/AOD086/0010/AliAOD.root");
    // create an input handler
    AliVEventHandler* inputH = new AliAODInputHandler();
    // and connect it to the manager
    mgr->SetInputEventHandler(inputH);

     // the manager is static, so get the existing manager via the static method
    AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
    if (!mgr) {
        printf("No analysis manager to connect to!\n");
        return NULL;
    }

    // just to see if all went well, check if the input event handler has been connected
    if (!mgr->GetInputEventHandler()) {
        printf("This task requires an input event handler!\n");
        return NULL;
      }

    // compile the relevant classes
      // include paths, necessary for compilation
    gSystem->AddIncludePath("-Wno-deprecated");
    gSystem->AddIncludePath("-I$ALICE_ROOT -I$ALICE_ROOT/include -I$ALICE_ROOT/EMCAL");
    gSystem->AddIncludePath("-I$ALICE_ROOT/PWGDQ/dielectron -I$ALICE_ROOT/PWGHF/hfe");
    gSystem->AddIncludePath("-I$ALICE_ROOT/JETAN -I$ALICE_ROOT/JETAN/fastjet");

    gROOT->LoadMacro("../objects/AliFlowTTreeEvent.cxx+");
    gROOT->LoadMacro("../objects/AliFlowTTreeTrack.cxx+");
    gROOT->LoadMacro("../objects/AliAnalysisTaskTTreeFilter.cxx+");

    // load the addtask
    gROOT->LoadMacro("AddTaskTTreeFilter.C");

    // launch the task
    AddTaskTTreeFilter();

    // check if we can initialize the manager
    if(!mgr->InitAnalysis()) return;
    // print the status of the manager to screen
    mgr->PrintStatus();
    // print to screen how the analysis is progressing
    mgr->SetUseProgressBar(1, 25);
    // start the analysis locally, reading the events from the tchain
    mgr->StartAnalysis("local", chain);
}
<commit_msg> remove redundant check from run macro<commit_after>void runTTreeFilter() {
    // author: Redmer Alexander Bertens, Utrecht University
    // rbertens@cern.ch , rbertens@nikhef.nl , r.a.bertens@uu.nl
    //
    // example which converts input data (in this case local aod's put into a chain)
    // to a tree which holds
    // - AliFlowTTreeEvent : event object
    // - AliFlowTTreeTrack : track objects
    // see source of these classes for more details

    // load libraries
    gSystem->Load("libCore.so");
    gSystem->Load("libGeom.so");
    gSystem->Load("libVMC.so");
    gSystem->Load("libPhysics.so");
    gSystem->Load("libTree.so");
    gSystem->Load("libSTEERBase.so");
    gSystem->Load("libESD.so");
    gSystem->Load("libAOD.so");
    gSystem->Load("libANALYSIS.so");
    gSystem->Load("libANALYSISalice.so");

    // create the analysis manager
    AliAnalysisManager* mgr = new AliAnalysisManager("MyManager");

    // create a tchain which will point to an aod tree
    TChain* chain = new TChain("aodTree");
    // add a few files to the chain (change this so that your local files are added)
    chain->Add("/home/rbertens/Documents/CERN/ALICE_DATA/data/2010/LHC10h/000139510/ESDs/pass2/AOD086/0003/AliAOD.root");
    chain->Add("/home/rbertens/Documents/CERN/ALICE_DATA/data/2010/LHC10h/000139510/ESDs/pass2/AOD086/0003/AliAOD.root");
    chain->Add("/home/rbertens/Documents/CERN/ALICE_DATA/data/2010/LHC10h/000139510/ESDs/pass2/AOD086/0004/AliAOD.root");
    chain->Add("/home/rbertens/Documents/CERN/ALICE_DATA/data/2010/LHC10h/000139510/ESDs/pass2/AOD086/0005/AliAOD.root");
    chain->Add("/home/rbertens/Documents/CERN/ALICE_DATA/data/2010/LHC10h/000139510/ESDs/pass2/AOD086/0006/AliAOD.root");
    chain->Add("/home/rbertens/Documents/CERN/ALICE_DATA/data/2010/LHC10h/000139510/ESDs/pass2/AOD086/0007/AliAOD.root");
    chain->Add("/home/rbertens/Documents/CERN/ALICE_DATA/data/2010/LHC10h/000139510/ESDs/pass2/AOD086/0008/AliAOD.root");
    chain->Add("/home/rbertens/Documents/CERN/ALICE_DATA/data/2010/LHC10h/000139510/ESDs/pass2/AOD086/0009/AliAOD.root");
    chain->Add("/home/rbertens/Documents/CERN/ALICE_DATA/data/2010/LHC10h/000139510/ESDs/pass2/AOD086/0010/AliAOD.root");
    // create an input handler
    AliVEventHandler* inputH = new AliAODInputHandler();
    // and connect it to the manager
    mgr->SetInputEventHandler(inputH);

    // compile the relevant classes

    // include paths, necessary for compilation
    gSystem->AddIncludePath("-Wno-deprecated");
    gSystem->AddIncludePath("-I$ALICE_ROOT -I$ALICE_ROOT/include -I$ALICE_ROOT/EMCAL");
    gSystem->AddIncludePath("-I$ALICE_ROOT/PWGDQ/dielectron -I$ALICE_ROOT/PWGHF/hfe");
    gSystem->AddIncludePath("-I$ALICE_ROOT/JETAN -I$ALICE_ROOT/JETAN/fastjet");

    gROOT->LoadMacro("../objects/AliFlowTTreeEvent.cxx+");
    gROOT->LoadMacro("../objects/AliFlowTTreeTrack.cxx+");
    gROOT->LoadMacro("../objects/AliAnalysisTaskTTreeFilter.cxx+");

    // load the addtask
    gROOT->LoadMacro("AddTaskTTreeFilter.C");

    // launch the task
    AddTaskTTreeFilter();

    // check if we can initialize the manager
    if(!mgr->InitAnalysis()) return;
    // print the status of the manager to screen
    mgr->PrintStatus();
    // print to screen how the analysis is progressing
    mgr->SetUseProgressBar(1, 25);
    // start the analysis locally, reading the events from the tchain
    mgr->StartAnalysis("local", chain);
}
<|endoftext|>


<commit_before><commit_msg>updates<commit_after><|endoftext|>


<commit_before>//******************************************************************************************************
//  RoutingTables.cpp - Gbtc
//
//  Copyright  2019, Grid Protection Alliance.  All Rights Reserved.
//
//  Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
//  the NOTICE file distributed with this work for additional information regarding copyright ownership.
//  The GPA licenses this file to you under the MIT License (MIT), the "License"; you may not use this
//  file except in compliance with the License. You may obtain a copy of the License at:
//
//      http://opensource.org/licenses/MIT
//
//  Unless agreed to in writing, the subject software distributed under the License is distributed on an
//  "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
//  License for the specific language governing permissions and limitations.
//
//  Code Modification History:
//  ----------------------------------------------------------------------------------------------------
//  03/28/2019 - J. Ritchie Carroll
//       Generated original version of source code.
//
//******************************************************************************************************

#include "RoutingTables.h"

using namespace std;
using namespace GSF;
using namespace GSF::TimeSeries;
using namespace GSF::TimeSeries::Transport;

RoutingTables::RoutingTables() :
    m_activeRoutes(NewSharedPtr<RoutingTable>()),
    m_enabled(true)
{
    Thread([this]()
    {
        while (m_enabled)
        {
            m_routingTableOperations.WaitForData();
            const auto operation = m_routingTableOperations.Dequeue();
            operation.first(*this, operation.second);
        }
    });
}

RoutingTables::~RoutingTables()
{
    m_enabled = false;
    m_routingTableOperations.Release();
}

RoutingTables::RoutingTablePtr RoutingTables::CloneActiveRoutes()
{
    ReaderLock readLock(m_activeRoutesLock);
    RoutingTablePtr clonedRoutes = NewSharedPtr<RoutingTable>(*m_activeRoutes);
    return clonedRoutes;
}

void RoutingTables::SetActiveRoutes(RoutingTablePtr activeRoutes)
{
    WriterLock writeLock(m_activeRoutesLock);
    m_activeRoutes = std::move(activeRoutes);
}

void RoutingTables::UpdateRoutesOperation(RoutingTables& routingTables, const DestinationRoutes& destinationRoutes)
{
    const RoutingTablePtr activeRoutesPtr = routingTables.CloneActiveRoutes();
    RoutingTable& activeRoutes = *activeRoutesPtr;
    const SubscriberConnectionPtr& destination = destinationRoutes.first;
    const unordered_set<GSF::Guid>& routes = destinationRoutes.second;

    // Remove subscriber connection from undesired measurement route destinations
    for (auto& pair : activeRoutes)
    {
        if (routes.find(pair.first) != routes.end())
            pair.second->erase(destination);
    }

    // Add subscriber connection to desired measurement route destinations
    for (auto& signalID : routes)
    {
        DestinationsPtr destinations;

        if (!TryGetValue(activeRoutes, signalID, destinations, destinations))
        {
            destinations = NewSharedPtr<Destinations>();
            activeRoutes.emplace(signalID, destinations);
        }

        destinations->insert(destination);
    }

    routingTables.SetActiveRoutes(activeRoutesPtr);
}

void RoutingTables::RemoveRoutesOperation(RoutingTables& routingTables, const DestinationRoutes& destinationRoutes)
{
    const RoutingTablePtr activeRoutesPtr = routingTables.CloneActiveRoutes();
    const RoutingTable& activeRoutes = *activeRoutesPtr;
    const SubscriberConnectionPtr& destination = destinationRoutes.first;

    // Remove subscriber connection from existing measurement route destinations
    for (auto& pair : activeRoutes)
        pair.second->erase(destination);

    routingTables.SetActiveRoutes(activeRoutesPtr);
}

void RoutingTables::UpdateRoutes(const SubscriberConnectionPtr& destination, const unordered_set<Guid>& routes)
{
    // Queue update routes operation
    m_routingTableOperations.Enqueue(RoutingTableOperation(&UpdateRoutesOperation, DestinationRoutes(destination, routes)));
}

void RoutingTables::RemoveRoutes(const SubscriberConnectionPtr& destination)
{
    // Queue remove routes operation
    m_routingTableOperations.Enqueue(RoutingTableOperation(&RemoveRoutesOperation, DestinationRoutes(destination, unordered_set<Guid>())));
}

void RoutingTables::PublishMeasurements(const vector<MeasurementPtr>& measurements)
{
    typedef vector<MeasurementPtr> Measurements;
    typedef SharedPtr<Measurements> MeasurementsPtr;
    unordered_map<SubscriberConnectionPtr, MeasurementsPtr> routedMeasurementMap;
    const size_t size = measurements.size();

    // Constrain read lock to this block
    {
        ReaderLock readLock(m_activeRoutesLock);
        const RoutingTable& activeRoutes = *m_activeRoutes;

        for (auto& measurement : measurements)
        {
            DestinationsPtr destinationsPtr;

            if (TryGetValue(activeRoutes, measurement->SignalID, destinationsPtr, destinationsPtr))
            {
                const Destinations& destinations = *destinationsPtr;

                for (auto& destination : destinations)
                {
                    MeasurementsPtr routedMeasurements;

                    if (!TryGetValue(routedMeasurementMap, destination, routedMeasurements, routedMeasurements))
                    {
                        routedMeasurements = NewSharedPtr<Measurements>();
                        routedMeasurements->reserve(size);
                        routedMeasurementMap.emplace(destination, routedMeasurements);
                    }

                    routedMeasurements->push_back(measurement);
                }
            }
        }
    }

    // Publish routed measurements
    for (auto& pair : routedMeasurementMap)
    {
        auto& destination = pair.first;

        if (destination->GetIsSubscribed() && !destination->GetIsTemporalSubscription())
            destination->PublishMeasurements(*pair.second);
    }
}
<commit_msg>TimeSeriesPlatformLibrary: RoutingTable post testing cleanup.<commit_after>//******************************************************************************************************
//  RoutingTables.cpp - Gbtc
//
//  Copyright  2019, Grid Protection Alliance.  All Rights Reserved.
//
//  Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
//  the NOTICE file distributed with this work for additional information regarding copyright ownership.
//  The GPA licenses this file to you under the MIT License (MIT), the "License"; you may not use this
//  file except in compliance with the License. You may obtain a copy of the License at:
//
//      http://opensource.org/licenses/MIT
//
//  Unless agreed to in writing, the subject software distributed under the License is distributed on an
//  "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
//  License for the specific language governing permissions and limitations.
//
//  Code Modification History:
//  ----------------------------------------------------------------------------------------------------
//  03/28/2019 - J. Ritchie Carroll
//       Generated original version of source code.
//
//******************************************************************************************************

#include "RoutingTables.h"

using namespace std;
using namespace GSF;
using namespace GSF::TimeSeries;
using namespace GSF::TimeSeries::Transport;

RoutingTables::RoutingTables() :
    m_activeRoutes(NewSharedPtr<RoutingTable>()),
    m_enabled(true)
{
    Thread([this]()
    {
        while (m_enabled)
        {
            m_routingTableOperations.WaitForData();
            const auto operation = m_routingTableOperations.Dequeue();
            operation.first(*this, operation.second);
        }
    });
}

RoutingTables::~RoutingTables()
{
    m_enabled = false;
    m_routingTableOperations.Release();
}

RoutingTables::RoutingTablePtr RoutingTables::CloneActiveRoutes()
{
    ReaderLock readLock(m_activeRoutesLock);
    RoutingTablePtr clonedRoutes = NewSharedPtr<RoutingTable>(*m_activeRoutes);
    return clonedRoutes;
}

void RoutingTables::SetActiveRoutes(RoutingTablePtr activeRoutes)
{
    WriterLock writeLock(m_activeRoutesLock);
    m_activeRoutes = std::move(activeRoutes);
}

void RoutingTables::UpdateRoutesOperation(RoutingTables& routingTables, const DestinationRoutes& destinationRoutes)
{
    const RoutingTablePtr activeRoutesPtr = routingTables.CloneActiveRoutes();
    RoutingTable& activeRoutes = *activeRoutesPtr;
    const SubscriberConnectionPtr& destination = destinationRoutes.first;
    const unordered_set<GSF::Guid>& routes = destinationRoutes.second;

    // Remove subscriber connection from undesired measurement route destinations
    for (auto& pair : activeRoutes)
    {
        if (routes.find(pair.first) != routes.end())
            pair.second->erase(destination);
    }

    // Add subscriber connection to desired measurement route destinations
    for (auto& signalID : routes)
    {
        DestinationsPtr destinations;

        if (!TryGetValue(activeRoutes, signalID, destinations, destinations))
        {
            destinations = NewSharedPtr<Destinations>();
            activeRoutes.emplace(signalID, destinations);
        }

        destinations->insert(destination);
    }

    routingTables.SetActiveRoutes(activeRoutesPtr);
}

void RoutingTables::RemoveRoutesOperation(RoutingTables& routingTables, const DestinationRoutes& destinationRoutes)
{
    const RoutingTablePtr activeRoutesPtr = routingTables.CloneActiveRoutes();
    const RoutingTable& activeRoutes = *activeRoutesPtr;
    const SubscriberConnectionPtr& destination = destinationRoutes.first;

    // Remove subscriber connection from existing measurement route destinations
    for (auto& pair : activeRoutes)
        pair.second->erase(destination);

    routingTables.SetActiveRoutes(activeRoutesPtr);
}

void RoutingTables::UpdateRoutes(const SubscriberConnectionPtr& destination, const unordered_set<Guid>& routes)
{
    // Queue update routes operation
    m_routingTableOperations.Enqueue(RoutingTableOperation(&UpdateRoutesOperation, DestinationRoutes(destination, routes)));
}

void RoutingTables::RemoveRoutes(const SubscriberConnectionPtr& destination)
{
    // Queue remove routes operation
    m_routingTableOperations.Enqueue(RoutingTableOperation(&RemoveRoutesOperation, DestinationRoutes(destination, unordered_set<Guid>())));
}

void RoutingTables::PublishMeasurements(const vector<MeasurementPtr>& measurements)
{
    typedef vector<MeasurementPtr> Measurements;
    typedef SharedPtr<Measurements> MeasurementsPtr;
    unordered_map<SubscriberConnectionPtr, MeasurementsPtr> routedMeasurementMap;
    const size_t size = measurements.size();

    // Constrain read lock to this block
    {
        ReaderLock readLock(m_activeRoutesLock);
        const RoutingTable& activeRoutes = *m_activeRoutes;

        for (auto& measurement : measurements)
        {
            DestinationsPtr destinationsPtr;

            if (TryGetValue(activeRoutes, measurement->SignalID, destinationsPtr, destinationsPtr))
            {
                const Destinations& destinations = *destinationsPtr;

                for (auto& destination : destinations)
                {
                    MeasurementsPtr routedMeasurements;

                    if (!TryGetValue(routedMeasurementMap, destination, routedMeasurements, routedMeasurements))
                    {
                        routedMeasurements = NewSharedPtr<Measurements>();
                        routedMeasurements->reserve(size);
                        routedMeasurementMap.emplace(destination, routedMeasurements);
                    }

                    routedMeasurements->push_back(measurement);
                }
            }
        }
    }

    // Publish routed measurements
    for (auto& pair : routedMeasurementMap)
    {
        auto& destination = *pair.first;

        if (destination.GetIsSubscribed() && !destination.GetIsTemporalSubscription())
            destination.PublishMeasurements(*pair.second);
    }
}
<|endoftext|>


<commit_before>#pragma once

#include "string_view.hh"

class ArgvParser {
	uint argc_;
	char** argv_;

public:
	ArgvParser(int argc, char** argv)
	   : argc_(std::max(argc - 1, 0)), argv_(argv + 1) {}

	ArgvParser(const ArgvParser&) = default;
	ArgvParser(ArgvParser&&) noexcept = default;
	ArgvParser& operator=(const ArgvParser&) = default;
	ArgvParser& operator=(ArgvParser&&) noexcept = default;

	uint size() const noexcept { return argc_; }

	CStringView operator[](uint n) const noexcept {
		return (n < argc_ ? CStringView(argv_[n]) : CStringView());
	}

	CStringView next() const noexcept { return operator[](0); }

	CStringView extract_next() noexcept {
		if (argc_ > 0) {
			--argc_;
			return CStringView(argv_++[0]);
		} else {
			return {};
		}
	}
};
<commit_msg>ArgvParser: made it not skip the first argument and made it accept const char**<commit_after>#pragma once

#include "string_view.hh"

class ArgvParser {
	uint argc_;
	const char* const* argv_;

public:
	ArgvParser(int argc, const char* const* argv)
	   : argc_(std::max(argc, 0)), argv_(argv) {}

	ArgvParser(const ArgvParser&) = default;
	ArgvParser(ArgvParser&&) noexcept = default;
	ArgvParser& operator=(const ArgvParser&) = default;
	ArgvParser& operator=(ArgvParser&&) noexcept = default;

	uint size() const noexcept { return argc_; }

	CStringView operator[](uint n) const noexcept {
		return (n < argc_ ? CStringView(argv_[n]) : CStringView());
	}

	CStringView next() const noexcept { return operator[](0); }

	CStringView extract_next() noexcept {
		if (argc_ > 0) {
			--argc_;
			return CStringView(argv_++[0]);
		} else {
			return {};
		}
	}
};
<|endoftext|>


<commit_before>/** @file
    @brief App that looks at each step of the patterns to find simultaneously
   bright beacons, records them all pairwise, and outputs them sorted by
   straight-line distance.

    @date 2016

    @author
    Sensics, Inc.
    <http://sensics.com/osvr>
*/

// Copyright 2016 Sensics, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//        http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Internal Includes
#include "Patterns.h"
#include "Positions.h"

// Library/third-party includes
#include <Eigen/Eigen>

// Standard includes
#include <utility>
#include <vector>
#include <iostream>
#include <cmath>
#include <tuple> // for std::tie to make comparisons simpler.

/// These are beacons we've chosen to mask off or disable, typically based on
/// the results from this tool.
#define APPLY_MASK
static const auto MASKED_ONEBASED_BEACONIDS = {5, 13, 16};

using BeaconList = std::vector<int>;
using Eigen::Vector3d;

inline double beaconSquaredDistance(int a, int b) {
  return (Vector3d::Map(OsvrHdkLedLocations_SENSOR0[a].data()) -
          Vector3d::Map(OsvrHdkLedLocations_SENSOR0[b].data()))
      .squaredNorm();
}

struct BeaconAdjacentBright {
  BeaconAdjacentBright(int idA, int idB, int patternStepNum)
      : beaconA(std::min(idA, idB)), beaconB(std::max(idA, idB)),
        patternStep(patternStepNum),
        squaredDistance(beaconSquaredDistance(beaconA, beaconB)) {}
  int beaconA;
  int beaconB;
  int patternStep;
  double squaredDistance;
};

std::ostream &operator<<(std::ostream &os, BeaconAdjacentBright const &adj) {
  os << "(" << adj.beaconA + 1 << "--" << adj.beaconB + 1 << ") @ "
     << adj.patternStep << " [" << std::sqrt(adj.squaredDistance) << " mm]";
  return os;
}

using AdjacentBrightnessList = std::vector<BeaconAdjacentBright>;

class BrightnessTracking {
public:
  void startPatternStep(int patternStep) { currentPatternStep_ = patternStep; }

  void recordBrightBeacon(int newBright) {
    for (auto &existingBright : brightBeacons_) {
      adjacentBrightness_.emplace_back(existingBright, newBright,
                                       currentPatternStep_);
      listSorted_ = false;
    }
    brightBeacons_.push_back(newBright);
  }

  void endPatternStep() { moveBrightBeaconsToList(); }

  /// Gets the list, lazily sorted if required, on demand
  AdjacentBrightnessList const &getSortedAdjacentBrightnessList() {
    if (!listSorted_) {
      sortAdjacentList();
    }
    return adjacentBrightness_;
  }

private:
  void moveBrightBeaconsToList() {
    brightBeaconsPerStep_.emplace_back(std::move(brightBeacons_));
    brightBeacons_.clear();
  }
  void sortAdjacentList() {

#if 0
    /// sort by distance, then by pattern step.
    auto comparison = [](BeaconAdjacentBright const &a,
                         BeaconAdjacentBright const &b) {
      return a.squaredDistance < b.squaredDistance ||
             (a.squaredDistance == b.squaredDistance &&
              a.patternStep < b.patternStep);
    };
#else
    /// sort by distance, then by pattern step.
    auto comparison = [](BeaconAdjacentBright const &a,
                         BeaconAdjacentBright const &b) {
      return std::tie(a.squaredDistance, a.patternStep, a.beaconA, a.beaconB) <
             std::tie(b.squaredDistance, b.patternStep, b.beaconA, b.beaconB);

    };
#endif

    std::sort(begin(adjacentBrightness_), end(adjacentBrightness_), comparison);
    listSorted_ = true;
  }
  std::vector<BeaconList> brightBeaconsPerStep_;
  AdjacentBrightnessList adjacentBrightness_;
  bool listSorted_ = false;
  BeaconList brightBeacons_;
  int currentPatternStep_;
};

int main() {
  initPatterns();

  auto numLeds = static_cast<int>(NUM_LEDS_SENSOR0);
  auto patternLength = static_cast<int>(PATTERN_LENGTH);

#ifdef APPLY_MASK
  /// Replace the pattern in every "masked" LED with all dim for the purposes of
  /// this tool.
  auto maskString = std::string(PATTERN_LENGTH, '.');
  for (auto &&maskId : MASKED_ONEBASED_BEACONIDS) {
    OsvrHdkLedIdentifier_SENSOR0_PATTERNS[maskId - 1] = maskString;
  }
#endif

  BrightnessTracking brightness;

  /// For each pattern step...
  for (int patternStep = 0; patternStep < patternLength; ++patternStep) {

    brightness.startPatternStep(patternStep);

    /// go through each beacon...
    for (int ledNum = 0; ledNum < numLeds; ++ledNum) {

      /// checking to see if it's bright
      if (OsvrHdkLedIdentifier_SENSOR0_PATTERNS[ledNum][patternStep] == '*') {
        /// and if so, recording it with the brightness tracker (which takes
        /// care of the pairwise comparison, etc)
        brightness.recordBrightBeacon(ledNum);
      }
    }
    brightness.endPatternStep();
  }

  for (auto &adj : brightness.getSortedAdjacentBrightnessList()) {
    std::cout << adj << std::endl;
  }
  return 0;
}
<commit_msg>Add a greedy algorithm to select which LEDs to mask<commit_after>/** @file
    @brief App that looks at each step of the patterns to find simultaneously
   bright beacons, records them all pairwise, and outputs them sorted by
   straight-line distance.

    @date 2016

    @author
    Sensics, Inc.
    <http://sensics.com/osvr>
*/

// Copyright 2016 Sensics, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//        http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Internal Includes
#include "Patterns.h"
#include "Positions.h"

// Library/third-party includes
#include <Eigen/Eigen>

// Standard includes
#include <utility>
#include <vector>
#include <iostream>
#include <iomanip>
#include <cmath>
#include <tuple> // for std::tie to make comparisons simpler.
#include <stdexcept>
#include <numeric>
#include <cstddef>
#include <sstream>

static const int MAX_AUTO_RUNS = 7;

using BeaconList = std::vector<int>;
using Eigen::Vector3d;

inline double beaconSquaredDistance(Point3Vector const &locationVec, int a,
                                    int b) {
  return (Vector3d::Map(locationVec[a].data()) -
          Vector3d::Map(locationVec[b].data()))
      .squaredNorm();
}

struct BeaconAdjacentBright {
  BeaconAdjacentBright(Point3Vector const &locationVec, int idA, int idB,
                       int patternStepNum)
      : beaconA_(std::min(idA, idB)), beaconB_(std::max(idA, idB)),
        patternStep_(patternStepNum), squaredDistance_(beaconSquaredDistance(
                                          locationVec, beaconA_, beaconB_)) {}
  int beaconA() const { return beaconA_; }
  int beaconB() const { return beaconB_; }
  int patternStep() const { return patternStep_; }
  double squaredDistance() const { return squaredDistance_; }
  int oneBasedBeaconA() const { return beaconA_ + 1; }
  int oneBasedBeaconB() const { return beaconB_ + 1; }
  double distance() const { return std::sqrt(squaredDistance()); }
  double cost() const { return 1. / squaredDistance(); }

  friend bool operator<(BeaconAdjacentBright const &a,
                        BeaconAdjacentBright const &b);

private:
  int beaconA_;
  int beaconB_;
  int patternStep_;
  double squaredDistance_;
};

inline bool operator<(BeaconAdjacentBright const &a,
                      BeaconAdjacentBright const &b) {
  /// sort by distance, then by pattern step.
  return std::tie(a.squaredDistance_, a.patternStep_, a.beaconA_, a.beaconB_) <
         std::tie(b.squaredDistance_, b.patternStep_, b.beaconA_, b.beaconB_);
}

std::ostream &operator<<(std::ostream &os, BeaconAdjacentBright const &adj) {
  os << "(" << std::setw(2) << adj.oneBasedBeaconA();
  os << "--" << std::setw(2) << adj.oneBasedBeaconB();
  os << ") @ " << std::setw(2) << adj.patternStep();
  os << " [" << std::setw(8) << adj.distance() << " mm]";
  return os;
}

using AdjacentBrightnessList = std::vector<BeaconAdjacentBright>;

namespace detail {
class BrightnessTracking {
public:
  explicit BrightnessTracking(Point3Vector const &locationVec)
      : locationVec_(locationVec) {}

  BrightnessTracking &operator=(BrightnessTracking const &) = delete;

  void startPatternStep(int patternStep) { currentPatternStep_ = patternStep; }

  void recordBrightBeacon(int newBright) {
    for (auto &existingBright : brightBeacons_) {
      adjacentBrightness_.emplace_back(locationVec_, existingBright, newBright,
                                       currentPatternStep_);
      listSorted_ = false;
    }
    brightBeacons_.push_back(newBright);
  }

  void endPatternStep() { moveBrightBeaconsToList(); }

  /// Gets the list, lazily sorted if required, on demand
  AdjacentBrightnessList const &getSortedAdjacentBrightnessList() {
    if (!listSorted_) {
      sortAdjacentList();
    }
    return adjacentBrightness_;
  }

private:
  void moveBrightBeaconsToList() {
    brightBeaconsPerStep_.emplace_back(std::move(brightBeacons_));
    brightBeacons_.clear();
  }
  void sortAdjacentList() {
#if 0
    auto comparison = [](BeaconAdjacentBright const &a,
                         BeaconAdjacentBright const &b) {
      return std::tie(a.squaredDistance, a.patternStep, a.beaconA, a.beaconB) <
             std::tie(b.squaredDistance, b.patternStep, b.beaconA, b.beaconB);

    };
#endif
    std::sort(begin(adjacentBrightness_), end(adjacentBrightness_));
    listSorted_ = true;
  }
  Point3Vector const &locationVec_;
  std::vector<BeaconList> brightBeaconsPerStep_;
  AdjacentBrightnessList adjacentBrightness_;
  bool listSorted_ = false;
  BeaconList brightBeacons_;
  int currentPatternStep_;
};
} // namespace detail

/// Takes in parallel location and pattern vectors, as well as an optional list
/// of one-based beacon IDs to "mask" (in this case, mark as being always dim),
/// and returns the completed, sorted AdjacentBrightnessList.
AdjacentBrightnessList computeAdjacentBrightnessList(
    Point3Vector const &locationVec, std::vector<std::string> patternVec,
    std::vector<int> const &oneBasedBeaconIdsToMask = {}) {
  if (locationVec.size() != patternVec.size()) {
    throw std::length_error("Location vec and pattern vec were different "
                            "sizes, but must be the same!");
  }

  // Took the patternVec by value since we want a locally-writable copy.
  auto patternLength = static_cast<int>(patternVec.back().size());
  auto numLeds = static_cast<int>(patternVec.size());

  /// Replace the pattern in every "masked" LED with all dim for the purposes of
  /// this tool.
  auto maskString = std::string(PATTERN_LENGTH, DIM_CHAR);
  for (auto &maskId : oneBasedBeaconIdsToMask) {
    // going to do range checking here
    patternVec.at(maskId - 1) = maskString;
  }

  /// Set up helper object for the remainder of the computation.
  auto brightness = detail::BrightnessTracking{locationVec};

  /// For each pattern step...
  for (int patternStep = 0; patternStep < patternLength; ++patternStep) {

    brightness.startPatternStep(patternStep);

    /// go through each beacon...
    for (int ledNum = 0; ledNum < numLeds; ++ledNum) {

      /// checking to see if it's bright
      if (patternVec[ledNum][patternStep] == BRIGHT_CHAR) {
        /// and if so, recording it with the brightness tracker (which takes
        /// care of the pairwise comparison, etc)
        brightness.recordBrightBeacon(ledNum);
      }
    }
    brightness.endPatternStep();
  }
  return brightness.getSortedAdjacentBrightnessList();
}

struct BeaconCost {
  int id;
  std::size_t count;
  double totalCost;
  double avgCost() const { return totalCost / static_cast<double>(count); }
  int oneBasedId() const { return id + 1; }
};

using BeaconCostComparator =
    std::function<bool(BeaconCost const &lhs, BeaconCost const &rhs)>;

/// operator > on the total (distance-based) cost, then count, then I suppose
/// the ID just for comparison sake.
inline bool compareBeaconCostByTotalDistanceCost(BeaconCost const &lhs,
                                                 BeaconCost const &rhs) {
  return std::tie(lhs.totalCost, lhs.count, lhs.id) >
         std::tie(rhs.totalCost, lhs.count, rhs.id);
}

/// operator > on the count, then total (distance-based) cost, then I suppose
/// the ID just for comparison sake.
inline bool compareBeaconCostByCount(BeaconCost const &lhs,
                                     BeaconCost const &rhs) {
  return std::tie(lhs.count, lhs.totalCost, lhs.id) >
         std::tie(rhs.count, rhs.totalCost, rhs.id);
}

/// @param comparator A greater-than comparator of some sort that will bring
/// your most-expensive (by your desired operational definition of that term) to
/// the top.
std::vector<BeaconCost> getMostExpensiveLeds(
    AdjacentBrightnessList const &adj,
    BeaconCostComparator comparator = &compareBeaconCostByTotalDistanceCost) {
  using IndivCosts = std::vector<double>;
  // Each beacon with a simultaneous bright will have a vector of the "cost" of
  // each simultaneous bright period.
  std::vector<IndivCosts> allCosts;
  auto recordCost = [&](int id, double cost) {
    if (!(id < allCosts.size())) {
      // we need to enlarge the vector
      allCosts.resize(id + 1);
    }
    allCosts.at(id).push_back(cost);
  };
  // Go through and record the costs of each beacon.
  for (auto &adjElt : adj) {
    auto cost = adjElt.cost();
    recordCost(adjElt.beaconA(), cost);
    recordCost(adjElt.beaconB(), cost);
  }

  std::vector<BeaconCost> ret;

  // Now, we need to somehow reduce the vector of costs to a single cost per
  // LED. Right now, just doing a mean.
  auto n = static_cast<int>(allCosts.size());
  for (int id = 0; id < n; ++id) {
    auto const &thisBeaconCosts = allCosts[id];
    if (thisBeaconCosts.empty()) {
      // no costs for this beacon
      continue;
    }
    auto count = thisBeaconCosts.size();
    auto totalCost =
        std::accumulate(begin(thisBeaconCosts), end(thisBeaconCosts), 0.);
    ret.push_back(BeaconCost{id, count, totalCost});
  }

  /// Finally, the sort: want operator > in some sense.
  std::sort(begin(ret), end(ret), comparator);
  return ret;
}

struct OverallCosts {
  double totalCost = 0.;
  int count = 0;
  double avgCostPerPair() const {
    return totalCost / static_cast<double>(count);
  }
};

OverallCosts computeCostOfFullList(AdjacentBrightnessList const &adj) {
  OverallCosts ret;
  ret.count = adj.size();
  auto accumHelper = [](double prev, BeaconAdjacentBright const &cur) {
    return prev + cur.cost();
  };
  ret.totalCost = std::accumulate(begin(adj), end(adj), 0., accumHelper);
  return ret;
}

void printOutput(int runNumber, std::vector<int> const &maskList,
                 AdjacentBrightnessList const &adj,
                 std::vector<BeaconCost> const &beaconCost,
                 OverallCosts const &overall) {
  /// make and immediately call the lambda, so we can use a stringstream to
  /// create and effectively return a string while keeping scopes narrow.
  auto makeRunNumberId = [](int run) {
    std::ostringstream os;
    os << " (Run #" << run << ")";
    return os.str();
  };
  const std::string runNumberId = makeRunNumberId(runNumber);

  static const auto DIVIDING_LINE = "--------------------\n";
  std::cout << DIVIDING_LINE;
  std::cout << "Run Information" << runNumberId << "\n" << DIVIDING_LINE
            << std::endl;
  auto printMaskList = [&] {
    std::cout << "Masked LEDs:" << runNumberId << "\n";
    for (auto &mask : maskList) {
      std::cout << mask << std::endl;
    }
    std::cout << "\n";
  };
  printMaskList();

  std::cout << "Adjacent brightness list" << runNumberId << "\n"
            << DIVIDING_LINE;

  for (auto &adjElt : adj) {
    std::cout << adjElt << std::endl;
  }

  std::cout << "\n\n\n";

  std::cout << "Beacon expense list" << runNumberId << "\n" << DIVIDING_LINE;
  for (auto &beacon : beaconCost) {
    std::cout << "Beacon: " << beacon.oneBasedId()
              << " \tCount: " << beacon.count
              << " \tTotal Cost: " << beacon.totalCost
              << " \tAvg rt Cost: " << std::sqrt(beacon.avgCost()) << std::endl;
  }

  std::cout << "\n\n\n";

  std::cout << "Overall expense" << runNumberId << "\n" << DIVIDING_LINE;
  std::cout << "Total number of pairs:\t" << overall.count << std::endl;
  std::cout << "Total cost (counting each pair once):\t" << overall.totalCost
            << std::endl;
  std::cout << "Average cost per pair:\t" << overall.avgCostPerPair()
            << std::endl;
  std::cout << "\n";

  printMaskList();
  std::cout << "\n\n End of output for run" << runNumberId << "\n"
            << DIVIDING_LINE << "\n";
}

void autoCreateMask(int maxRuns, BeaconCostComparator const &comparator) {
  std::vector<int> maskList;
  /// turn off up to 4 leds (running 5 passes)
  for (int i = 0; i < MAX_AUTO_RUNS; ++i) {
    auto adj = computeAdjacentBrightnessList(
        OsvrHdkLedLocations_SENSOR0, OsvrHdkLedIdentifier_SENSOR0_PATTERNS,
        maskList);
    auto beaconCosts = getMostExpensiveLeds(adj, comparator);
    auto overall = computeCostOfFullList(adj);
    /// Dump current output.
    printOutput(i, maskList, adj, beaconCosts, overall);

    /// Now, add the most expensive beacon to the mask list for next round.
    auto newMaskOneBased = beaconCosts.front().oneBasedId();
    std::cout << "Adding one-based beacon ID " << newMaskOneBased
              << " to the mask list for next round." << std::endl;
    maskList.push_back(newMaskOneBased);
  }
}

int main() {
  initPatterns();
  // autoCreateMask(MAX_AUTO_RUNS, &compareBeaconCostByCount);
  autoCreateMask(MAX_AUTO_RUNS, &compareBeaconCostByTotalDistanceCost);

  return 0;
}
<|endoftext|>


<commit_before>//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2008 by Denton Woods
// Last modified: 08/29/2008
//
// Filename: src-IL/src/il_exr.cpp
//
// Description: Reads from an OpenEXR (.exr) file.
//
//-----------------------------------------------------------------------------

#include "il_internal.h"
#ifndef IL_NO_EXR

#include "il_exr.h"
#include <ImfRgba.h>
#include <ImfArray.h>
#include <ImfRgbaFile.h>
//#include <ImfTiledRgbaFile.h>
//#include <ImfInputFile.h>
//#include <ImfTiledInputFile.h>
//#include <ImfPreviewImage.h>
//#include <ImfChannelList.h>

using namespace Imath;
using namespace Imf;
using namespace std;

//! Reads an icon file.
ILboolean ilLoadExr(ILconst_string FileName)
{
	return iLoadExrInternal(FileName);
}

ILboolean iLoadExrInternal(const char FileName[])
{
	Array<Rgba> pixels;
	Box2i displayWindow, dataWindow;
	float pixelAspectRatio;
    RgbaInputFile in (FileName);

    displayWindow = in.displayWindow();
    dataWindow = in.dataWindow();
    pixelAspectRatio = in.pixelAspectRatio();

    int dw, dh, dx, dy;

    dw = dataWindow.max.x - dataWindow.min.x + 1;
    dh = dataWindow.max.y - dataWindow.min.y + 1;
    dx = dataWindow.min.x;
    dy = dataWindow.min.y;

    pixels.resizeErase (dw * dh);
    in.setFrameBuffer (pixels - dx - dy * dw, 1, dw);

    //try
    //{
		in.readPixels (dataWindow.min.y, dataWindow.max.y);
    //}
    //catch (const exception &e)
    //{
	//
	// If some of the pixels in the file cannot be read,
	// print an error message, and return a partial image
	// to the caller.
	//

	//	return IL_FALSE;
    //}

	return ilTexImage(dw, dh, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, NULL);
}

#endif //IL_NO_EXR
<commit_msg>*** empty log message ***<commit_after>//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2008 by Denton Woods
// Last modified: 08/29/2008
//
// Filename: src-IL/src/il_exr.cpp
//
// Description: Reads from an OpenEXR (.exr) file.
//
//-----------------------------------------------------------------------------

#include "il_internal.h"
#ifndef IL_NO_EXR

#include "il_exr.h"
#include <ImfRgba.h>
#include <ImfArray.h>
#include <ImfRgbaFile.h>
//#include <ImfTiledRgbaFile.h>
//#include <ImfInputFile.h>
//#include <ImfTiledInputFile.h>
//#include <ImfPreviewImage.h>
//#include <ImfChannelList.h>

//! Reads an .exr file.
ILboolean ilLoadExr(ILconst_string FileName)
{
	return iLoadExrInternal(FileName);
}

using namespace Imath;
using namespace Imf;
using namespace std;

ILboolean iLoadExrInternal(const char FileName[])
{
	Array<Rgba> pixels;
	Box2i displayWindow, dataWindow;
	float pixelAspectRatio;
    RgbaInputFile in (FileName);

    displayWindow = in.displayWindow();
    dataWindow = in.dataWindow();
    pixelAspectRatio = in.pixelAspectRatio();

    int dw, dh, dx, dy;

    dw = dataWindow.max.x - dataWindow.min.x + 1;
    dh = dataWindow.max.y - dataWindow.min.y + 1;
    dx = dataWindow.min.x;
    dy = dataWindow.min.y;

    pixels.resizeErase (dw * dh);
    in.setFrameBuffer (pixels - dx - dy * dw, 1, dw);

    //try
    //{
		in.readPixels (dataWindow.min.y, dataWindow.max.y);
    //}
    //catch (const exception &e)
    //{
	//
	// If some of the pixels in the file cannot be read,
	// print an error message, and return a partial image
	// to the caller.
	//

	//	return IL_FALSE;
    //}

	return ilTexImage(dw, dh, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, NULL);
}

#endif //IL_NO_EXR
<|endoftext|>