//----------------------------------------------------------------------------//
// module ThrOpenProject.cpp //
// //
// Thread function: Loads model, tuning results and data as specifed in //
// given TProjectG object. Calls back to given c-style function when //
// finished. //
// //
// copyright (c) 2003 by Lars Haendel //
// home: www.newty.de //
// //
// This program is free software and can be used under the terms of the //
// GNU licence. See header file for further information and disclaimer. //
// //
//----------------------------------------------------------------------------//
#include <vcl.h>
#pragma hdrstop
# include "ThrOpenProject.h"
#pragma package(smart_init)
#include "exception.h" // due to: TExceptionU
//----------------------------------------------------------------------------------------------------------------------
// constructor
__fastcall ThrOpenProject::ThrOpenProject(bool CreateSuspended, void (*_FinishFunc)(), TProjectG*const& _prj,
const char*const& _szModelFile, const char*const& _szTuningFile, const bool*const& _f_Stop/*=NULL*/)
: TThread(CreateSuspended)
{
FinishFunc = _FinishFunc; // callback function; called when finished
prj = _prj; // project
szModelFile = _szModelFile;
szTuningFile = _szTuningFile;
f_Stop = _f_Stop; // stop flag
Priority = tpNormal; // set thread's properties
OnTerminate = &OnFinish;
FreeOnTerminate = true;
data_L = NULL; // initialize to NULL
data_T = NULL;
model = NULL;
tuningResults = NULL;
szFilename = NULL; // "delete" filename
// note: Ini of f_IsWithOutput not necessary
}
//----------------------------------------------------------------------------------------------------------------------
// execute function gets called when thread object is created
void __fastcall ThrOpenProject::Execute()
{
try
{
// a) load model if filename is given
const TDataData* ddata = NULL; // ini
szFilename = szModelFile; // set filename pointer
if(szFilename[0]!='\0')
{
ifstream file(szFilename); // open model file
IfTrueThrowTypeU(!file, "Unable to open file '%s'!", szFilename); // and check success
model = new TCluster(); // new model
int line = 1;
model->Load(file, line); // load model
file.close(); // close file
ddata = model->GetDataData(); // set ddata object which will be checked against data
}
// b) load learn data
szFilename = prj->GetData1FileName(); // set filename pointer
data_L = new TData(); // new learn data object
data_L->Load(szFilename, f_Stop, ddata); // load data using TData::Load()
// MayBe: check if loaded data matches with ddata object (if there is one) ?? No, would be better but it's not
// necessary because once the model is learned it relies only on the ddata object, there would not be a problem
// although the situation is clearly an error.
szFilename = "project file"; // (hack!)
prj->Synchronize(data_L);
// calculate feature weights and standard parameter values
szFilename = prj->GetData1FileName(); // set filename
data_L->CalculateWeights(prj->Get_N_Bins(), !prj->Regression(), prj->EqualWidthBinning()); // feature weights
// c) load tuning results if filename is given
szFilename = szTuningFile; // set filename pointer
if(szFilename[0]!='\0')
{
ifstream file(szFilename); // open model file
IfTrueThrowTypeU(!file, "Unable to open file '%s'!", szFilename); // and check success
tuningResults = new TTune(prj, data_L); // new object
int line = 1;
tuningResults->Load(file, line); // load tuning results
file.close(); // close file
}
// d) load test data
szFilename = prj->GetData2FileName(); // set filename pointer
if(szFilename[0]!='\0') // if test data file name is given
{
// check if model is loaded cause otherwise no test data can be loaded
IfTrueThrowTypeU(!ddata, "You cannot specify a test data file if no model is given!");
data_T = new TData(); // new test data object
data_T->Load(prj->GetData2FileName(), f_Stop, ddata); // load data using TData::Load()
// set output column and variable types and throw error if they cannot be set
f_IsWithOutput = data_T->MakeCompatible(ddata);
}
}
catch(TExceptionU excp)
{ // exception handling 'type U' exception
strcpy(szText, excp.GetErrorText()); // copy error message ...
Synchronize(MessageBox); // ... and display it in a message box
Synchronize(Clear); // release data and model again
}
catch(TExceptionAB excp)
{ // exception handling 'type AB' exception
strcpy(szText, excp.GetErrorText()); // copy error message ...
Synchronize(MessageBox); // ... and display it in a message box
Synchronize(Clear); // release data and model again
}
catch(...)
{ // all other exceptions
strcpy(szText, "C++ Exception ;-) (ThrOpenProject::Execute)"); // copy error message ...
Synchronize(MessageBox); // ... and display it in a message box
Synchronize(Clear); // release data and model again
}
}
//----------------------------------------------------------------------------------------------------------------------
// return status text
const char* ThrOpenProject::Status()
{
if(data_T)
return data_T->StatusText();
else
if(data_L)
return data_L->StatusText();
else
if(model)
return "Loading model ...";
else
return "Initializing";
}
//----------------------------------------------------------------------------------------------------------------------
// return current progress
float ThrOpenProject::Progress()
{
if(data_T)
return data_T->LoadDataProgress();
else
if(data_L)
return data_L->LoadDataProgress();
else
return 0;
}
//----------------------------------------------------------------------------------------------------------------------
// return actually processed filename
const char* ThrOpenProject::Filename()
{
if(szFilename)
return szFilename;
else
return "";
}
//----------------------------------------------------------------------------------------------------------------------
// display error message
void __fastcall ThrOpenProject::MessageBox()
{
char szCaption[256];
sprintf(szCaption, "Error loading %s", szFilename);
Application->MessageBox(szText, szCaption, MB_OK | MB_ICONERROR);
}
//----------------------------------------------------------------------------------------------------------------------
// release data and model again (in case of an error) and set pointer to NULL
void __fastcall ThrOpenProject::Clear()
{
if(data_L) // release data
data_L->Release();
if(data_T)
data_T->Release();
data_L = data_T = NULL;
if(model) // release model
delete model;
model = NULL;
}