Skip to content
Snippets Groups Projects
entry.cpp 13.9 KiB
Newer Older
  • Learn to ignore specific revisions
  • #include "stdafx.h"
    
    
    #include "entry.h"
    
    #include "external.h"
    
    #include "parameter.h"
    
    #include "print.h"
    #include "operation.h"
    #include "dtw.h"
    #include "lcss.h"
    #include "pdtw.h"
    #include "help.h"
    #include "calcul.h"
    #include "draw.h"
    
    
    using namespace std;
    
    
    ///Main entry point of the application.
    
    ///@param[in] args application arguments
    
    void entry::entryBase(vtr<string> const &args)
    
    	if (args.size() < 1)
    	{
    		cout << "error: Invalid number of arguments." << endl;
    		exit(0);
    	}
    
    
    	auto script = parser::parseScript(args);
    	parameter params;
    
    	if (script.size() == 0)
    	{
    
    		params.setParameters(args);
    
    	else
    
    		for (size_t i = 0; i < script.size(); i++)
    		{
    
    			params.setParameters(params.applyParameter(script[i], args));
    
    ///Main logic function of the application.
    
    ///@param[in] params parameters
    ///@param[in] unit if true: called from unit test application
    ///@return operation results
    
    resultOperation entry::entryLogic(parameter const &params, bool unit)
    
    	auto begin = chrono::steady_clock::now();
    
    	times.parsing = chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - begin).count();
    
    	begin = chrono::steady_clock::now();
    
    	preprocessData(data, params);
    
    	times.preprocesing = chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - begin).count();
    
    
    		cout << print::input(data.input, 30) << endl; // print for debug comment or delete if not needed
    		cout << print::input(data.query, 30) << endl; // print for debug comment or delete if not needed
    	}
    
    	begin = chrono::steady_clock::now();
    
    	auto result = runOperation(data, params);
    
    	times.opeartion = chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - begin).count();
    
    		printResult(result, params);
    		writeResult(data, result, times, params);
    
    ///Loads input data.
    
    ///@param[in] params parameters
    ///@return input data
    
    inputData entry::parseData(parameter const &params)
    
    		data.files.input = parser::getAllFileNames(params.inPath);				//file path of all input files
    		data.files.query = parser::getAllFileNames(params.inQuery);				//file path of all input files
    		data.files.keyInput = parser::getAllFileNames(params.inKeyInput);		//file path of all input files
    		data.files.keyQuery = parser::getAllFileNames(params.inKeyQuery);		//file path of all input files
    
    		data.files.sort();
    
    		data.input = parser::readData<double>(data.files.input);				//parsing
    
    		if (data.input.size() < 1)
    
    			throw runtime_error("problem occurred when loading input data");
    
    		if (params.distance == 4)
    
    			data.keyInput = parser::readData<int>(data.files.keyInput);
    
    
    		if (params.isQuery())
    		{
    
    			data.query = parser::readData<double>(data.files.query);			//parsing
    
    			if (data.query.size() < 1)
    
    				throw runtime_error("problem occurred when loading query data");
    
    			if (params.distance == 4)
    
    				data.keyQuery = parser::readData<int>(data.files.keyQuery);
    
    		if (params.isGroundTruth())	//parsing clusters file 
    
    			auto clusterTmp = parser::parseGroundTruth(data.files.query, params.inGroundTruthPath);
    			data.clusters = parser::parseGroundTruth(data.files.input, params.inGroundTruthPath);
    
    
    			int clusterSize = (int)data.clusters.ids.size();
    			for (size_t i = 0; i < clusterTmp.ids.size(); i++)
    
    				data.clusters.ids[(int)i + clusterSize + 1] = clusterTmp.ids.at((int)i + 1);
    
    	catch (const std::exception &e)
    
    	{
    		cout << e.what() << endl;
    		exit(0);
    	}
    
    
    	if (params.debugInfo)
    
    		cout << print::vector(data.files.query);
    		cout << print::vector(data.files.input);
    
    		cout << print::input(data.query, 30) << endl;			//print for debug comment or delete if not needed
    		cout << print::input(data.input, 30) << endl;			//print for debug comment or delete if not needed
    
    		cout << print::inputStats(data.input, 30);
    		cout << print::inputStats(data.query, 30);
    
    ///Executes chosen operation.
    
    ///@param[in] data input data
    ///@param[in] params parameters
    ///@return operation results
    
    resultOperation entry::runOperation(inputData const &data, parameter const &params)
    
    
    	if (data.isQuery() && !params.forceSingle)
    
    		result = operation::operationDual(data, params);
    
    		auto single = data.convertInputDataSingle();
    		result = operation::operationSingle(single, params);
    
    ///Main logic for external calls. EXPERIMENT
    
    ///@param[in] input input data
    ///@param[in] args application arguments
    ///@return operation results
    
    resultOperation entry::externLogic(vtr3<double> const &input, vtr<string> const &args)
    
    	parameter params;
    	params.setParameters(args);
    
    
    	//INPUT DATA PARSING
    
    
    	data.input = input;
    
    	vtr<string> inputFiles(input.size());
    	for (size_t i = 0; i < input.size(); i++)
    	{
    		inputFiles[i] = "ext" + to_string((int)i + 1);
    	}
    	data.files.input = inputFiles;
    
    
    	auto begin = chrono::steady_clock::now();
    
    	preprocessData(data, params);
    
    	times.preprocesing = chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - begin).count();
    
    
    	if (params.debugInfo)
    
    		cout << print::input(data.input, 30) << endl; // print for debug comment or delete if not needed
    
    	begin = chrono::steady_clock::now();
    
    	auto result = runOperation(data, params);
    
    	times.opeartion = chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - begin).count();
    
    	printResult(result, params);
    	writeResult(data, result, times, params);
    
    ///Pre-processes input data (depends on used switches).
    
    ///@param[in] data input data
    ///@param[in] params parameters
    
    void entry::preprocessData(inputData &data, parameter const& params)
    
    {
    	//DATA PREPROCESSING
    	
    
    		preprocess::reduce<double>(data.input, params.preReduce);
    		preprocess::reduce<double>(data.query, params.preReduce);
    		preprocess::reduce<int>(data.keyInput, params.preReduce);
    		preprocess::reduce<int>(data.keyQuery, params.preReduce);
    
    		preprocess::paa<double>(data.input, params.prePaa);
    		preprocess::paa<double>(data.query, params.prePaa);
    		preprocess::paa<int>(data.keyInput, params.prePaa);
    		preprocess::paa<int>(data.keyQuery, params.prePaa);
    
    		preprocess::sax(data.input, params.preSax);
    		preprocess::sax(data.query, params.preSax);
    
    		preprocess::prolong<double>(data.input, params.preProlong);
    		preprocess::prolong<double>(data.query, params.preProlong);
    		preprocess::prolong<int>(data.keyInput, params.preProlong);
    		preprocess::prolong<int>(data.keyQuery, params.preProlong);
    
    		preprocess::interpolate(data.input);
    		preprocess::interpolate(data.query);
    
    	if (params.isNormalizeBy()) 
    	{
    
    		preprocess::normalizeBy(data.input, params.preNormalizeBy);
    		preprocess::normalizeBy(data.query, params.preNormalizeBy);
    
    		preprocess::smooth(data.input, params.preSmooth);
    		preprocess::smooth(data.query, params.preSmooth);
    
    ///Prints final results to the console.
    
    ///@param[in] result operation results
    ///@param[in] params parameters
    
    void entry::printResult(resultOperation &result, parameter const &params)
    
    	if (!result.dtw.score.empty())
    		cout << print::vector(result.dtw.score);
    
    	if (params.printOutput)
    	{
    
    		if (!result.matrixSimilarity.empty())
    
    			cout << print::matrix(result.matrixSimilarity[params.scoreType], params);
    
    		if (!result.matrixCluster.empty())
    
    			cout << print::matrix(result.matrixCluster[params.scoreType], params);
    
    	if (params.operation == 3)
    
    		cout << print::scoresClustering(result, params.precision);
    
    	if (params.time)
    
    		cout << print::timeMeasures(result.time);
    
    ///Writes final results to the disk.
    
    ///@param[in] data input data
    ///@param[in] result operation results
    
    ///@param[in] times elapsed times measurements during various phases
    
    void entry::writeResult(inputData const &data, resultOperation &result, resultTime &times, parameter const &params)
    
    	//WRITE LOG FILES
    
    	if (params.isWriteOutput()) 
    	{
    
    		print::write(print::matrix(result.matrixSimilarity[params.scoreType], params), params.outputPath + ".matrix", false);
    
    		print::write(print::scoresClustering(result, params.precision), params.outputPath + ".score", false);
    
    	{
    		print::write(
    			/*print::printParameterString(args) + "</br>" +*/
    
    			print::scoresClustering(result, params.precision) +
    			print::htmlClusters(data.input, result.matrixCluster[0], data.clusters), params.outputPath + ".html", true);
    
    		print::write(print::gdf(data.files.input, data.input, result.matrixSimilarity[params.scoreType], data.clusters), params.outputPath + ".gdf", false);
    
    	if (params.isWriteOutput())
    
    		print::write(print::args(params.arguments) + print::timeMeasures(times), params.outputPath + ".info", false);
    }
    
    
    ///Contains predefined constat data structures.
    
    	///Contains 15 basic RGB colors.
    
    	extern const float colorsBase[15][3] = {
    		{ 0, 255, 0 },				//green
    		{ 190, 190, 0 },			//darker yellow
    		{ 255, 0, 0 },				//red
    		{ 180, 180, 180 },			//gray
    		{ 255, 170, 200 },			//pink
    		{ 255, 128, 0 },			//orange
    		{ 255, 255, 255 },			//white
    		{ 0, 128, 255 },			//lighter blue
    		{ 128, 255, 0 },			//lime
    		{ 128, 64, 0 },				//brown
    		{ 255, 255, 0 },			//yellow
    		{ 0, 0, 255 },				//blue
    		{ 0, 255, 255 },			//teal (light blue)
    		{ 255, 0, 255 },			//purple
    		{ 0, 155, 155 }				//darker teal
    	};
    
    	///Contains hex codes for colors.
    	extern const vtr<std::string> colorsMass = {
    		"000000", "FFFF00", "1CE6FF", "FF34FF", "FF4A46", "008941", "006FA6", "A30059",
    		"FFDBE5", "7A4900", "0000A6", "63FFAC", "B79762", "004D43", "8FB0FF", "997D87",
    		"5A0007", "809693", "FEFFE6", "1B4400", "4FC601", "3B5DFF", "4A3B53", "FF2F80",
    		"61615A", "BA0900", "6B7900", "00C2A0", "FFAA92", "FF90C9", "B903AA", "D16100",
    		"DDEFFF", "000035", "7B4F4B", "A1C299", "300018", "0AA6D8", "013349", "00846F",
    		"372101", "FFB500", "C2FFED", "A079BF", "CC0744", "C0B9B2", "C2FF99", "001E09",
    		"00489C", "6F0062", "0CBD66", "EEC3FF", "456D75", "B77B68", "7A87A1", "788D66",
    		"885578", "FAD09F", "FF8A9A", "D157A0", "BEC459", "456648", "0086ED", "886F4C",
    		"34362D", "B4A8BD", "00A6AA", "452C2C", "636375", "A3C8C9", "FF913F", "938A81",
    		"575329", "00FECF", "B05B6F", "8CD0FF", "3B9700", "04F757", "C8A1A1", "1E6E00",
    		"7900D7", "A77500", "6367A9", "A05837", "6B002C", "772600", "D790FF", "9B9700",
    		"549E79", "FFF69F", "201625", "72418F", "BC23FF", "99ADC0", "3A2465", "922329",
    		"5B4534", "FDE8DC", "404E55", "0089A3", "CB7E98", "A4E804", "324E72", "6A3A4C",
    		"83AB58", "001C1E", "D1F7CE", "004B28", "C8D0F6", "A3A489", "806C66", "222800",
    		"BF5650", "E83000", "66796D", "DA007C", "FF1A59", "8ADBB4", "1E0200", "5B4E51",
    		"C895C5", "320033", "FF6832", "66E1D3", "CFCDAC", "D0AC94", "7ED379", "012C58",
    		"7A7BFF", "D68E01", "353339", "78AFA1", "FEB2C6", "75797C", "837393", "943A4D",
    		"B5F4FF", "D2DCD5", "9556BD", "6A714A", "001325", "02525F", "0AA3F7", "E98176",
    		"DBD5DD", "5EBCD1", "3D4F44", "7E6405", "02684E", "962B75", "8D8546", "9695C5",
    		"E773CE", "D86A78", "3E89BE", "CA834E", "518A87", "5B113C", "55813B", "E704C4",
    		"00005F", "A97399", "4B8160", "59738A", "FF5DA7", "F7C9BF", "643127", "513A01",
    		"6B94AA", "51A058", "A45B02", "1D1702", "E20027", "E7AB63", "4C6001", "9C6966",
    		"64547B", "97979E", "006A66", "391406", "F4D749", "0045D2", "006C31", "DDB6D0",
    		"7C6571", "9FB2A4", "00D891", "15A08A", "BC65E9", "FFFFFE", "C6DC99", "203B3C",
    		"671190", "6B3A64", "F5E1FF", "FFA0F2", "CCAA35", "374527", "8BB400", "797868",
    		"C6005A", "3B000A", "C86240", "29607C", "402334", "7D5A44", "CCB87C", "B88183",
    		"AA5199", "B5D6C3", "A38469", "9F94F0", "A74571", "B894A6", "71BB8C", "00B433",
    		"789EC9", "6D80BA", "953F00", "5EFF03", "E4FFFC", "1BE177", "BCB1E5", "76912F"
    	};
    
    
    	///Contains chord scale (used in the CSI chroma distance, switch: -dist 3).
    	extern const vtr2<bool> scaleChord {
    
    		{ 1,0,0,0,1,0,0,1,0,0,0,0 },	//12 major triad scale vectors
    		{ 0,1,0,0,0,1,0,0,1,0,0,0 },
    		{ 0,0,1,0,0,0,1,0,0,1,0,0 },
    		{ 0,0,0,1,0,0,0,1,0,0,1,0 },
    		{ 0,0,0,0,1,0,0,0,1,0,0,1 },
    		{ 1,0,0,0,0,1,0,0,0,1,0,0 },
    		{ 0,1,0,0,0,0,1,0,0,0,1,0 },
    		{ 0,0,1,0,0,0,0,1,0,0,0,1 },
    		{ 1,0,0,1,0,0,0,0,1,0,0,0 },
    		{ 0,1,0,0,1,0,0,0,0,1,0,0 },
    		{ 0,0,1,0,0,1,0,0,0,0,1,0 },
    		{ 0,0,0,1,0,0,1,0,0,0,0,1 },
    
    		{ 1,0,0,1,0,0,0,1,0,0,0,0 },	//12 minor triad scale vectors
    		{ 0,1,0,0,1,0,0,0,1,0,0,0 },
    		{ 0,0,1,0,0,1,0,0,0,1,0,0 },
    		{ 0,0,0,1,0,0,1,0,0,0,1,0 },
    		{ 0,0,0,0,1,0,0,1,0,0,0,1 },
    		{ 1,0,0,0,0,1,0,0,1,0,0,0 },
    		{ 0,1,0,0,0,0,1,0,0,1,0,0 },
    		{ 0,0,1,0,0,0,0,1,0,0,1,0 },
    		{ 0,0,0,1,0,0,0,0,1,0,0,1 },
    		{ 1,0,0,0,1,0,0,0,0,1,0,0 },
    		{ 0,1,0,0,0,1,0,0,0,0,1,0 },
    		{ 0,0,1,0,0,0,1,0,0,0,0,1 },
    	};
    
    
    	///Contains key scale (used in the CSI chord distance, switch: -dist 4).
    
    	extern const vtr2<bool> scaleKey {
    
    		{ 1,0,1,0,1,1,0,1,0,1,0,1 },  //12 major triad scale vectors
    		{ 1,1,0,1,0,1,1,0,1,0,1,0 },
    		{ 0,1,1,0,1,0,1,1,0,1,0,1 },
    		{ 1,0,1,1,0,1,0,1,1,0,1,0 },
    		{ 0,1,0,1,1,0,1,0,1,1,0,1 },
    		{ 1,0,1,0,1,1,0,1,0,1,1,0 },
    		{ 0,1,0,1,0,1,1,0,1,0,1,1 },
    		{ 1,0,1,0,1,0,1,1,0,1,0,1 },
    		{ 1,1,0,1,0,1,0,1,1,0,1,0 },
    		{ 0,1,1,0,1,0,1,0,1,1,0,1 },
    		{ 1,0,1,1,0,1,0,1,0,1,1,0 },
    		{ 0,1,0,1,1,0,1,0,1,0,1,1 },
    
    
    		//{ 1,0,1,1,0,1,0,1,1,0,1,0 },  //12 minor triad scale vectors
    		//{ 0,1,0,1,1,0,1,0,1,1,0,1 },
    		//{ 1,0,1,0,1,1,0,1,0,1,1,0 },
    		//{ 0,1,0,1,0,1,1,0,1,0,1,1 },
    		//{ 1,0,1,0,1,0,1,1,0,1,0,1 },
    		//{ 1,1,0,1,0,1,0,1,1,0,1,0 },
    		//{ 0,1,1,0,1,0,1,0,1,1,0,1 },
    		//{ 1,0,1,1,0,1,0,1,0,1,1,0 },
    		//{ 0,1,0,1,1,0,1,0,1,0,1,1 },
    		//{ 1,0,1,0,1,1,0,1,0,1,0,1 },
    		//{ 1,1,0,1,0,1,1,0,1,0,1,0 },
    		//{ 0,1,1,0,1,0,1,1,0,1,0,1 },
    
    	///Contains circle of fifth distances (used in the chord distance, switch: -dist 4). 
    
    	extern const std::map<int, int> cofDistance = {
    		{ 0,0 },
    		{ 1,5 },
    		{ 2,2 },
    		{ 3,3 },
    		{ 4,4 },
    		{ 5,1 },
    		{ 6,6 },
    		{ 7,1 },
    		{ 8,4 },
    		{ 9,3 },
    		{ 10,2 },
    		{ 11,5 },
    	};