Marsyas
0.6.0-alpha
|
00001 /* 00002 ** Copyright (C) 1998-2010 George Tzanetakis <gtzan@cs.uvic.ca> 00003 ** 00004 ** This program is free software; you can redistribute it and/or modify 00005 ** it under the terms of the GNU General Public License as published by 00006 ** the Free Software Foundation; either version 2 of the License, or 00007 ** (at your option) any later version. 00008 ** 00009 ** This program is distributed in the hope that it will be useful, 00010 ** but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 ** GNU General Public License for more details. 00013 ** \ 00014 ** You should have received a copy of the GNU General Public License 00015 ** along with this program; if not, write to the Free Software 00016 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00017 */ 00018 00019 #include "BeatReferee.h" 00020 #include "../common_source.h" 00021 00022 using namespace std; 00023 using namespace Marsyas; 00024 00025 #define NONE 0.0 00026 #define BEAT 1.0 00027 #define EVAL 2.0 00028 00029 #define INNER 3.0 00030 #define OUTTER 4.0 00031 00032 #define MINIMUMREAL 0.000001 //(0.000001 minimum float recognized) 00033 #define NA -10000.0 //undefined value flag (just a big negative nr) 00034 00035 BeatReferee::BeatReferee(mrs_string name):MarSystem("BeatReferee", name) 00036 { 00037 addControls(); 00038 00039 bestScore_ = NA; //To allow initial negative scores 00040 bestAgentIndex_ = -1; //-1 by default 00041 timeElapsed_ = 0; 00042 outputCount_ = 0; 00043 triggerCount_ = 0; 00044 lastBeatTime_ = (mrs_natural) NA; 00045 lastBeatPeriod_ = -1; 00046 bestFinalAgent_ = -1; 00047 processInduction_ = false; 00048 triggerInduction_ = false; 00049 startSystem_ = true; 00050 startTracking_ = false; 00051 lostGTBeatsCount_ = 0; 00052 lastGTBeatPos_ = -1; 00053 backtraceEndTime_ = -1; 00054 bestAgentBeforeTrigger_ = -1; 00055 lastGTFalsePos_ = false; 00056 logFile_ = false; 00057 // these will be overwritten later 00058 nrAgents_ = 100; 00059 maxNrBeats_ = 100; 00060 // 00061 initialization(); 00062 } 00063 00064 BeatReferee::BeatReferee(const BeatReferee& a) : MarSystem(a) 00065 { 00066 // For any MarControlPtr in a MarSystem 00067 // it is necessary to perform this getctrl 00068 // in the copy constructor in order for cloning to work 00069 ctrl_mutedAgents_ = getctrl("mrs_realvec/mutedAgents"); 00070 ctrl_inductionEnabler_ = getctrl("mrs_realvec/inductionEnabler"); 00071 ctrl_firstHypotheses_ = getctrl("mrs_realvec/beatHypotheses"); 00072 ctrl_inductionTime_ = getctrl("mrs_natural/inductionTime"); 00073 ctrl_hopSize_ = getctrl("mrs_natural/hopSize"); 00074 ctrl_srcFs_ = getctrl("mrs_real/srcFs"); 00075 ctrl_maxPeriod_ = getctrl("mrs_natural/maxPeriod"); 00076 ctrl_minPeriod_ = getctrl("mrs_natural/minPeriod"); 00077 ctrl_agentControl_ = getctrl("mrs_realvec/agentControl"); 00078 ctrl_beatDetected_ = getctrl("mrs_real/beatDetected"); 00079 ctrl_tickCount_ = getctrl("mrs_natural/tickCount"); 00080 ctrl_obsoleteFactor_ = getctrl("mrs_real/obsoleteFactor"); 00081 ctrl_lostFactor_ = getctrl("mrs_natural/lostFactor"); 00082 ctrl_childrenScoreFactor_ = getctrl("mrs_real/childrenScoreFactor"); 00083 ctrl_bestFactor_ = getctrl("mrs_real/bestFactor"); 00084 ctrl_eqPhase_ = getctrl("mrs_natural/eqPhase"); 00085 ctrl_eqPeriod_ = getctrl("mrs_natural/eqPeriod"); 00086 ctrl_corFactor_ = getctrl("mrs_real/corFactor"); 00087 ctrl_child1Factor_ = getctrl("mrs_real/child1Factor"); 00088 ctrl_child2Factor_ = getctrl("mrs_real/child2Factor"); 00089 ctrl_child3Factor_ = getctrl("mrs_real/child3Factor"); 00090 ctrl_backtrace_ = getctrl("mrs_bool/backtrace"); 00091 ctrl_logFile_ = getctrl("mrs_string/logFile"); 00092 ctrl_logFileName_= getctrl("mrs_string/logFileName"); 00093 ctrl_soundFileSize_= getctrl("mrs_natural/soundFileSize"); 00094 ctrl_bestFinalAgentHistory_= getctrl("mrs_realvec/bestFinalAgentHistory"); 00095 ctrl_nonCausal_ = getctrl("mrs_bool/nonCausal"); 00096 ctrl_triggerInduction_ = getctrl("mrs_bool/triggerInduction"); 00097 ctrl_triggerInductionExternalRequest_ = getctrl("mrs_bool/triggerInductionExternalRequest"); 00098 ctrl_gtInductionMode_ = getctrl("mrs_string/gtInductionMode"); 00099 ctrl_triggerGtTolerance_ = getctrl("mrs_natural/triggerGtTolerance"); 00100 ctrl_gtBeatsFile_ = getctrl("mrs_string/gtBeatsFile"); 00101 ctrl_curBestScore_ = getctrl("mrs_real/curBestScore"); 00102 ctrl_adjustment_ = getctrl("mrs_natural/adjustment"); 00103 ctrl_inductionMode_ = getctrl("mrs_string/inductionMode"); 00104 ctrl_beatTransitionTol_ = getctrl("mrs_real/beatTransitionTol"); 00105 ctrl_destFileName_ = getctrl("mrs_string/destFileName"); 00106 ctrl_triggerTimesFile_ = getctrl("mrs_string/triggerTimesFile"); 00107 ctrl_resetAfterNewInduction_ = getctrl("mrs_bool/resetAfterNewInduction"); 00108 ctrl_resetFeatWindow_ = getctrl("mrs_bool/resetFeatWindow"); 00109 ctrl_supervisedTriggerThres_ = getctrl("mrs_real/supervisedTriggerThres"); 00110 00111 beatTransitionTol_ = a.beatTransitionTol_; 00112 considerAgentTransitionBeat_ = a.considerAgentTransitionBeat_; 00113 considerFatherTransitionBeat_ = a.considerFatherTransitionBeat_; 00114 timeElapsed_ = a.timeElapsed_; 00115 lastBeatPeriod_ = a.lastBeatPeriod_; 00116 historyCount_ = a.historyCount_; 00117 historyBeatTimes_ = a.historyBeatTimes_; 00118 lastBeatTime_ = a.lastBeatTime_; 00119 bestScore_ = a.bestScore_; 00120 bestAgentIndex_ = a.bestAgentIndex_; 00121 outputCount_ = a.outputCount_; 00122 initPeriod_ = a.initPeriod_; 00123 corFactor_ = a.corFactor_; 00124 backtrace_ = a.backtrace_; 00125 logFile_ = a.logFile_; 00126 logFileName_ = a.logFileName_; 00127 logFileUnits_ = a.logFileUnits_; 00128 triggerInduction_ = a.triggerInduction_; 00129 triggerInductionExternalRequest_ = a.triggerInductionExternalRequest_; 00130 processInduction_ = a.processInduction_; 00131 triggerInductionTime_ = a.triggerInductionTime_; 00132 inductionMode_ = a.inductionMode_; 00133 startSystem_ = a.startSystem_; 00134 startTracking_ = a.startTracking_; 00135 agentsHistory_ = a.agentsHistory_; 00136 agentsFamilyHist_ = a.agentsFamilyHist_; 00137 lostGTBeatsCount_ = a.lostGTBeatsCount_; 00138 lastGTBeatPos_ = a.lastGTBeatPos_; 00139 lastGTFileBeat_ = a.lastGTFileBeat_; 00140 triggerGtTolerance_ = a.triggerGtTolerance_; 00141 backtraceEndTime_ = a.backtraceEndTime_; 00142 bestAgentBeforeTrigger_ = a.bestAgentBeforeTrigger_; 00143 frames2SecsAdjustment_ = a.frames2SecsAdjustment_; 00144 lastGTFalsePos_ = a.lastGTFalsePos_; 00145 triggerTimes_ = a.triggerTimes_; 00146 transitionTimes_ = a.transitionTimes_; 00147 transitionsConsidered_ = a.transitionsConsidered_; 00148 resetAfterNewInduction_ = a.resetAfterNewInduction_; 00149 supervisedTriggerThres_ = a.supervisedTriggerThres_; 00150 } 00151 00152 BeatReferee::~BeatReferee() 00153 { 00154 } 00155 00156 MarSystem* 00157 BeatReferee::clone() const 00158 { 00159 return new BeatReferee(*this); 00160 } 00161 00162 void 00163 BeatReferee::addControls() 00164 { 00165 //Add specific controls needed by this MarSystem. 00166 addctrl("mrs_realvec/mutedAgents", realvec(), ctrl_mutedAgents_); 00167 addctrl("mrs_realvec/inductionEnabler", realvec(2,2), ctrl_inductionEnabler_); 00168 addctrl("mrs_realvec/beatHypotheses", realvec(), ctrl_firstHypotheses_); 00169 addctrl("mrs_natural/inductionTime", -1, ctrl_inductionTime_); 00170 addctrl("mrs_natural/hopSize", -1, ctrl_hopSize_); 00171 setctrlState("mrs_natural/hopSize", true); 00172 addctrl("mrs_real/srcFs", -1.0, ctrl_srcFs_); 00173 setctrlState("mrs_real/srcFs", true); 00174 addctrl("mrs_natural/maxPeriod", -1, ctrl_maxPeriod_); 00175 setctrlState("mrs_natural/maxPeriod", true); 00176 addctrl("mrs_natural/minPeriod", -1, ctrl_minPeriod_); 00177 setctrlState("mrs_natural/minPeriod", true); 00178 addctrl("mrs_realvec/agentControl", realvec(50,4), ctrl_agentControl_); 00179 addctrl("mrs_real/beatDetected", 0.0, ctrl_beatDetected_); 00180 addctrl("mrs_natural/tickCount", 0, ctrl_tickCount_); 00181 addctrl("mrs_real/obsoleteFactor", 0.8, ctrl_obsoleteFactor_); 00182 setctrlState("mrs_real/obsoleteFactor", true); 00183 addctrl("mrs_natural/lostFactor", 4, ctrl_lostFactor_); 00184 setctrlState("mrs_natural/lostFactor", true); 00185 addctrl("mrs_real/childrenScoreFactor", 0.8, ctrl_childrenScoreFactor_); 00186 setctrlState("mrs_real/childrenScoreFactor", true); 00187 addctrl("mrs_real/bestFactor", 1.1, ctrl_bestFactor_); 00188 setctrlState("mrs_real/bestFactor", true); 00189 addctrl("mrs_natural/eqPhase", 2, ctrl_eqPhase_); 00190 setctrlState("mrs_natural/eqPhase", true); 00191 addctrl("mrs_natural/eqPeriod", 1, ctrl_eqPeriod_); 00192 setctrlState("mrs_natural/eqPeriod", true); 00193 addctrl("mrs_real/corFactor", 0.5, ctrl_corFactor_); 00194 setctrlState("mrs_real/corFactor", true); 00195 addctrl("mrs_real/child1Factor", 2.0, ctrl_child1Factor_); 00196 setctrlState("mrs_real/child1Factor", true); 00197 addctrl("mrs_real/child2Factor", 0.5, ctrl_child2Factor_); 00198 setctrlState("mrs_real/child2Factor", true); 00199 addctrl("mrs_real/child3Factor", 1.0, ctrl_child3Factor_); 00200 setctrlState("mrs_real/child3Factor", true); 00201 addctrl("mrs_bool/backtrace", false, ctrl_backtrace_); 00202 setctrlState("mrs_bool/backtrace", true); 00203 addctrl("mrs_string/logFile", "-1", ctrl_logFile_); 00204 addctrl("mrs_string/logFileName", "log.txt", ctrl_logFileName_); 00205 addctrl("mrs_natural/soundFileSize", 0, ctrl_soundFileSize_); 00206 setctrlState("mrs_natural/soundFileSize", true); 00207 addctrl("mrs_realvec/bestFinalAgentHistory", realvec(), ctrl_bestFinalAgentHistory_); 00208 addctrl("mrs_bool/nonCausal", false, ctrl_nonCausal_); 00209 setctrlState("mrs_bool/nonCausal", true); 00210 addctrl("mrs_bool/triggerInduction", false, ctrl_triggerInduction_); 00211 setctrlState("mrs_bool/triggerInduction", true); 00212 addctrl("mrs_bool/triggerInductionExternalRequest", false, ctrl_triggerInductionExternalRequest_); 00213 setctrlState("mrs_bool/triggerInductionExternalRequest", true); 00214 addctrl("mrs_string/gtInductionMode", "-1", ctrl_gtInductionMode_); 00215 setctrlState("mrs_string/gtInductionMode", true); 00216 addctrl("mrs_natural/triggerGtTolerance", 5, ctrl_triggerGtTolerance_); 00217 setctrlState("mrs_natural/triggerGtTolerance", true); 00218 addctrl("mrs_string/gtBeatsFile", "input.txt", ctrl_gtBeatsFile_); 00219 addctrl("mrs_real/curBestScore", NA, ctrl_curBestScore_); 00220 setctrlState("mrs_real/curBestScore", true); 00221 addctrl("mrs_natural/adjustment", 0, ctrl_adjustment_); 00222 setctrlState("mrs_natural/adjustment", true); 00223 addctrl("mrs_string/inductionMode", "single", ctrl_inductionMode_); 00224 addctrl("mrs_real/beatTransitionTol", 0.6, ctrl_beatTransitionTol_); 00225 addctrl("mrs_string/destFileName", "output", ctrl_destFileName_); 00226 addctrl("mrs_string/triggerTimesFile", "input_trigger.txt", ctrl_triggerTimesFile_); 00227 addctrl("mrs_bool/resetAfterNewInduction", true, ctrl_resetAfterNewInduction_); 00228 setctrlState("mrs_bool/resetAfterNewInduction", true); 00229 addctrl("mrs_bool/resetFeatWindow", true, ctrl_resetFeatWindow_); 00230 setctrlState("mrs_bool/resetFeatWindow", true); 00231 addctrl("mrs_real/supervisedTriggerThres", 0.0, ctrl_supervisedTriggerThres_); 00232 } 00233 00234 void 00235 BeatReferee::myUpdate(MarControlPtr sender) 00236 { 00237 (void) sender; //suppress warning of unused parameter(s) 00238 MRSDIAG("BeatReferee.cpp - BeatReferee:myUpdate"); 00239 00240 ctrl_onSamples_->setValue(1, NOUPDATE); 00241 ctrl_onObservations_->setValue(1, NOUPDATE); 00242 ctrl_osrate_->setValue(ctrl_israte_, NOUPDATE); 00243 00244 lostFactor_ = ctrl_lostFactor_->to<mrs_natural>(); 00245 obsoleteFactor_ = ctrl_obsoleteFactor_->to<mrs_real>(); 00246 childrenScoreFactor_ = ctrl_childrenScoreFactor_->to<mrs_real>(); 00247 bestFactor_ = ctrl_bestFactor_->to<mrs_real>(); 00248 eqPhase_ = ctrl_eqPhase_->to<mrs_natural>(); 00249 eqPeriod_ = ctrl_eqPeriod_->to<mrs_natural>(); 00250 corFactor_ = ctrl_corFactor_->to<mrs_real>(); 00251 child1Factor_ = ctrl_child1Factor_->to<mrs_real>(); 00252 child2Factor_ = ctrl_child2Factor_->to<mrs_real>(); 00253 child3Factor_ = ctrl_child3Factor_->to<mrs_real>(); 00254 backtrace_ = ctrl_backtrace_->to<mrs_bool>(); 00255 hopSize_ = ctrl_hopSize_->to<mrs_natural>(); 00256 srcFs_ = ctrl_srcFs_->to<mrs_real>(); 00257 maxPeriod_ = ctrl_maxPeriod_->to<mrs_natural>(); 00258 minPeriod_ = ctrl_minPeriod_->to<mrs_natural>(); 00259 nonCausal_ = ctrl_nonCausal_->to<mrs_bool>(); 00260 inductionMode_ = ctrl_inductionMode_->to<mrs_string>(); 00261 gtBeatsFile_ = ctrl_gtBeatsFile_->to<mrs_string>(); 00262 triggerGtTolerance_ = ctrl_triggerGtTolerance_->to<mrs_natural>(); 00263 frames2SecsAdjustment_ = ctrl_adjustment_->to<mrs_natural>(); 00264 beatTransitionTol_ = ctrl_beatTransitionTol_->to<mrs_real>(); 00265 triggerTimesFile_ = ctrl_triggerTimesFile_->to<mrs_string>(); 00266 resetAfterNewInduction_ = ctrl_resetAfterNewInduction_->to<mrs_bool>(); 00267 supervisedTriggerThres_ = ctrl_supervisedTriggerThres_->to<mrs_real>(); 00268 00269 //cout << "TRIGGERTIME @ " << timeElapsed_ << ": " << triggerInductionTime_ << endl; 00270 //triggerInductionTime_ = ctrl_triggerInductionTime_->to<mrs_natural>(); 00271 //cout << "TRIGGERTIME @ " << timeElapsed_ << ": " << triggerInductionTime_ << endl; 00272 00273 //inObservations_ = number of BeatAgents in the pool 00274 nrAgents_ = inObservations_; 00275 historyCount_.create(nrAgents_); //1index for each agent 00276 agentsJustCreated_.create(nrAgents_); //to know which agents were created on current frame 00277 00278 soundFileSize_ = ctrl_soundFileSize_->to<mrs_natural>(); 00279 //max possible nr. of beats in the analysed sound file (*1.2 - tolerance due to possible limit surpassing) 00280 maxNrBeats_ = (mrs_natural) (ceil(((mrs_real) soundFileSize_) / ((mrs_real) minPeriod_)) * 1.2); 00281 00282 inductionTime_ = ctrl_inductionTime_->to<mrs_natural>(); 00283 inductionEnabler_ = ctrl_inductionEnabler_->to<mrs_realvec>(); 00284 00285 //wait timeBeforeKill secs before considering killing obsolete agents 00286 mrs_real timeBeforeKill = 0.0; 00287 timeBeforeKilling_ = (mrs_natural)(timeBeforeKill*srcFs_/hopSize_); 00288 } 00289 00290 mrs_bool 00291 BeatReferee::loadTriggerTimes(mrs_string triggerTimesFile) 00292 { 00293 if (fopen(triggerTimesFile.c_str(), "r")) 00294 { 00295 cerr << "TriggerTimes File: " << triggerTimesFile.c_str() << endl; 00296 00297 ifstream inStream; 00298 mrs_string line; 00299 inStream.open(triggerTimesFile.c_str()); 00300 getline (inStream, line); 00301 00302 mrs_natural countTriggers = 0; 00303 while(strtod(line.c_str(), NULL) > 0.0) 00304 { 00305 getline (inStream, line); 00306 countTriggers++; 00307 } 00308 triggerTimes_.create(countTriggers); 00309 transitionTimes_.create(countTriggers); 00310 transitionsConsidered_.create(countTriggers); 00311 inStream.close(); 00312 inStream.open(triggerTimesFile.c_str()); 00313 mrs_natural validTriggersCount = 0; 00314 mrs_real indTimeSecs = ((inductionTime_ * hopSize_) - (frames2SecsAdjustment_)) / srcFs_; 00315 for(mrs_natural i = 0; i < countTriggers; i++) 00316 { 00317 getline (inStream, line); 00318 mrs_real triggerTime = strtod(line.c_str(), NULL); 00319 //cout << "triggerTime: " << triggerTime << "; inductionTime: " << indTimeSecs << endl; 00320 if(triggerTime >= indTimeSecs) 00321 { 00322 //sum the size of the induction window to every trigger time 00323 //so the actual trigger is only activated one window after 00324 transitionTimes_(validTriggersCount) = ((mrs_natural) (triggerTime * (srcFs_/hopSize_) + 0.5)); 00325 triggerTimes_(validTriggersCount) = transitionTimes_(validTriggersCount) + inductionTime_; 00326 transitionsConsidered_(validTriggersCount) = 0.0; 00327 validTriggersCount++; 00328 } 00329 } 00330 00331 //cout << "trigger times (" << countTriggers << "): "; 00332 //for(mrs_natural i = 0; i < triggerTimes_.getSize(); i++) 00333 //{ 00334 // cout << triggerTimes_(i) << " "; 00335 //} 00336 //cout << endl; 00337 00338 inStream.close(); 00339 00340 return true; 00341 } 00342 else 00343 { 00344 cerr << "Bad or nonexistent transition times file: " << triggerTimesFile.c_str() << "\nPlease specify a supported one." << endl; 00345 return false; 00346 } 00347 } 00348 00349 mrs_bool 00350 BeatReferee::isGTFileInLine(mrs_string line) 00351 { 00352 00353 //for beat groundtruth files (in line, separated by spaces): 00354 mrs_natural pos0; 00355 pos0 = (mrs_natural) line.find_first_of(" ", 0); //initial delimiter 00356 00357 //if pos0 < 0 => one beat time per line 00358 return (pos0 > 0 ? true : false); 00359 } 00360 00361 //Routine for comparing the current detected beat to the correspondent ground-truth beat-time 00362 //(to be used in trigger induction ground-truth mode): 00363 //0-> beat matches! 00364 //1-> false positive! 00365 //n-> nr. of false negatives 00366 mrs_natural 00367 BeatReferee::checkBeatInGTFile() 00368 { 00369 mrs_natural localBeatErrorCount = 0; 00370 mrs_real fMeasureTol = 0.07; //70ms used in Fmeasure tolerance 00371 mrs_real beatTime = ((timeElapsed_ * hopSize_) - (frames2SecsAdjustment_)) / srcFs_; 00372 //cout << "\nchecking: " << gtBeatsFile_ << "; beatTime: " << beatTime << endl; 00373 00374 ifstream inStream; 00375 mrs_string line; 00376 inStream.open(gtBeatsFile_.c_str()); 00377 getline (inStream, line); //get first line 00378 00379 //if beat times in gt file are all given in the first line (separated by spaces) 00380 if(isGTFileInLine(line)) 00381 { 00382 mrs_bool beatPosFound = false; 00383 mrs_natural curGTBeatPos, firstGTBeatPos; 00384 mrs_real lastGTBeatTime = 0, curGTBeatTime; 00385 mrs_real lastDiffBeats; //just a big number 00386 mrs_real diffBeats = 0; 00387 mrs_real tolWinLft, tolWinRgt; 00388 00389 //check gtfile for eof at first run 00390 if(lastGTBeatPos_ < 0) 00391 { 00392 std::istringstream iss(line); 00393 char c[10]; //big enough array 00394 while (iss >> c) //space ("") delimiter 00395 { 00396 //last c contains last value in file 00397 lastGTFileBeat_ = atof(c); //save end value 00398 } 00399 iss.clear(); 00400 } 00401 00402 //check if end of file 00403 mrs_real beatTimeCheck = (((timeElapsed_+2) * hopSize_) - (frames2SecsAdjustment_)) / srcFs_; //(timeElapsed_+1 (+1 tolerance) because induction is always called in the next tick) 00404 if(beatTimeCheck >= lastGTFileBeat_) 00405 return 0; 00406 00407 //cout << "pos1: " << pos1 << "; pos2: " << pos2 << "; pos3: " << pos3 << "bt: " << strtod(line.substr(pos1, pos2).c_str(), NULL) << endl; 00408 00409 //discard initial induction time if in real-time mode (no backtrace) 00410 if((backtraceEndTime_ == -1 && !backtrace_) || timeElapsed_ > backtraceEndTime_) 00411 { 00412 mrs_real indTimeSecs = ((inductionTime_ * hopSize_) - (frames2SecsAdjustment_)) / srcFs_; 00413 do 00414 { 00415 //cout << "1-lastGTBeatTime: " << lastGTBeatTime << "; indTime: " << indTimeSecs << endl; 00416 curGTBeatPos = (mrs_natural) line.find_first_of(" ", lastGTBeatPos_); //current delimiter 00417 lastGTBeatTime = strtod(line.substr(lastGTBeatPos_+1, curGTBeatPos).c_str(), NULL); 00418 00419 if(lastGTBeatTime >= indTimeSecs) break; 00420 00421 lastGTBeatPos_ = (mrs_natural) line.find_first_of(" ", lastGTBeatPos_+1); //current last delimiter 00422 00423 } while(lastGTBeatTime < indTimeSecs); 00424 } 00425 else //retrieve first gt beat time (starting from previous call) [First iteration must be outside cycle!!] 00426 { 00427 //cout << "1-BeatTime: " << beatTime << "; GTBeatTime: " << lastGTBeatTime << "; lasGTPos: " << lastGTBeatPos_ << endl; 00428 00429 lastGTBeatPos_ = (mrs_natural) line.find_first_of(" ", lastGTBeatPos_); //current last delimiter 00430 curGTBeatPos = (mrs_natural) line.find_first_of(" ", lastGTBeatPos_+1); //current delimiter 00431 lastGTBeatTime = strtod(line.substr(lastGTBeatPos_+1, curGTBeatPos).c_str(), NULL); 00432 } 00433 00434 firstGTBeatPos = lastGTBeatPos_; //save current first gt beat position 00435 00436 //cout << "2-BeatTime: " << beatTime << "; GTBeatTime: " << lastGTBeatTime << "; lasGTPos: " << lastGTBeatPos_ << endl; 00437 00438 //first match check: 00439 tolWinLft = lastGTBeatTime - fMeasureTol; 00440 tolWinRgt = lastGTBeatTime + fMeasureTol; 00441 if(beatTime >= tolWinLft && beatTime <= tolWinRgt) 00442 { 00443 localBeatErrorCount = 0; 00444 lastGTBeatPos_ = (mrs_natural) line.find_first_of(" ", lastGTBeatPos_+1); //go to next position (for next computed beat) 00445 //cout << "MATCHES1-> B: " << beatTime << "; gtB: " << lastGTBeatTime << "; tolL: " << tolWinLft << "; tolR: " << tolWinRgt << endl; 00446 } 00447 else //if first gt not matches: 00448 { 00449 //FALSE NEGATIVE: 00450 //if last error was a false positive 00451 if(beatTime > tolWinRgt && lastGTFalsePos_) 00452 { 00453 //advance one ground-truth beat (due to transition beat between FP and FN) 00454 lastGTBeatPos_ = (mrs_natural) line.find_first_of(" ", lastGTBeatPos_+1); //current last delimiter 00455 curGTBeatPos = (mrs_natural) line.find_first_of(" ", lastGTBeatPos_+1); //current delimiter 00456 lastGTBeatTime = strtod(line.substr(lastGTBeatPos_+1, curGTBeatPos).c_str(), NULL); 00457 tolWinLft = lastGTBeatTime - fMeasureTol; 00458 00459 tolWinRgt = lastGTBeatTime + fMeasureTol; 00460 00461 //cout << "2.2-BeatTime: " << beatTime << "; GTBeatTime: " << lastGTBeatTime << "; lasGTPos: " << lastGTBeatPos_ << endl; 00462 00463 firstGTBeatPos = lastGTBeatPos_; //update current first gt beat position 00464 00465 lastGTFalsePos_ = false; 00466 } 00467 00468 lastDiffBeats = abs(beatTime - lastGTBeatTime); 00469 00470 //cout << "(1)gtCurBeat: " << lastGTBeatTime << "(" << tolWinRgt << ") beatTime: " << beatTime << endl; 00471 //STILL FALSE NEGATIVE 00472 if(beatTime > tolWinRgt) 00473 { 00474 //start false negative search with current global errors 00475 mrs_natural beatErrorCount = 0; 00476 00477 //cout << "FALSE_NEG(S)-> "; 00478 //count nr. of false negatives 00479 do { 00480 beatErrorCount++; 00481 00482 //cout << "bT: " << beatTime << "; lastGTBT: " << lastGTBeatTime << " bE: " << beatErrorCount << " bT: " << triggerGtTolerance_ << endl; 00483 00484 lastGTBeatPos_ = (mrs_natural) line.find_first_of(" ", lastGTBeatPos_+1); //current last delimiter 00485 curGTBeatPos = (mrs_natural) line.find_first_of(" ", lastGTBeatPos_+1); //current delimiter 00486 lastGTBeatTime = strtod(line.substr(lastGTBeatPos_+1, curGTBeatPos).c_str(), NULL); 00487 tolWinLft = lastGTBeatTime - fMeasureTol; 00488 tolWinRgt = lastGTBeatTime + fMeasureTol; 00489 00490 //cout << lastGTBeatTime << "; "; 00491 00492 //when beat-time matches current ground-truth beat-time: 00493 //- clean the global beat error count if < triggerGtTolerance_ 00494 //- assign value to global error if surpasses triggerGtTolerance_ (for triggering induction) 00495 if(beatTime >= tolWinLft && beatTime <= tolWinRgt) 00496 { 00497 00498 if((beatErrorCount + lostGTBeatsCount_) < triggerGtTolerance_) 00499 beatErrorCount = 0; 00500 00501 //go to next delimiter 00502 lastGTBeatPos_ = (mrs_natural) line.find_first_of(" ", lastGTBeatPos_+1); 00503 00504 break; //finishes false negative search when beat matches! 00505 } 00506 else if(beatTime <= tolWinRgt) break; //finishes false negative search when beat surpasses gt beat-time! 00507 00508 } while(beatTime > tolWinRgt); 00509 00510 localBeatErrorCount = beatErrorCount; 00511 //go to next delimiter 00512 //lastGTBeatPos_ = (mrs_natural) line.find_first_of(" ", lastGTBeatPos_+1); 00513 00514 //cout << "(" << beatTime << ")" << endl; 00515 } 00516 //FALSE POSITIVE 00517 else 00518 { 00519 //mrs_real keepInitGTBeatTime = lastGTBeatTime; //keep it for printing in FP error 00520 do //check if false postive (reinforcement -> one iteration should be enough) 00521 { 00522 lastGTBeatPos_ = (mrs_natural) line.find_first_of(" ", lastGTBeatPos_+1); //current last delimiter 00523 curGTBeatPos = (mrs_natural) line.find_first_of(" ", lastGTBeatPos_+1); //current delimiter 00524 curGTBeatTime = strtod(line.substr(lastGTBeatPos_+1, curGTBeatPos).c_str(), NULL); 00525 00526 diffBeats = abs(beatTime - curGTBeatTime); 00527 //cout << "gtCurBeat: " << curGTBeatTime << "; beatTime: " << beatTime << "; diff: " << diffBeats << endl; 00528 00529 //find min distance between computed and annotated beat time 00530 if(diffBeats > lastDiffBeats) //if current distance bigger than previous => check if computed is correct 00531 { 00532 //computed beat is correct if it matches the annotated beat within a tolerance window 00533 tolWinLft = lastGTBeatTime - fMeasureTol; 00534 tolWinRgt = lastGTBeatTime + fMeasureTol; 00535 00536 //cout << "tolLft: " << tolWinLft << "; tolRgt: " << tolWinRgt << endl; 00537 if(beatTime >= tolWinLft && beatTime <= tolWinRgt) //for safecheck 00538 { 00539 //beat matches! 00540 localBeatErrorCount = 0; 00541 //cout << "MATCHES2-> B: " << beatTime << "; gtB: " << lastGTBeatTime << "; tolL: " << tolWinLft << "; tolR: " << tolWinRgt << endl; 00542 } 00543 else //false positive! 00544 { 00545 localBeatErrorCount = 1; 00546 //cout << "FALSE_POS-> B: " << beatTime << " (" << keepInitGTBeatTime << ") -> GT: " << lastGTBeatTime << endl; 00547 lastGTBeatPos_ = firstGTBeatPos; //go back to previous beat 00548 lastGTFalsePos_ = true; 00549 } 00550 00551 beatPosFound = true; 00552 break; 00553 } 00554 lastDiffBeats = diffBeats; 00555 lastGTBeatTime = curGTBeatTime; 00556 00557 } while(beatPosFound == false); 00558 } 00559 } 00560 } 00561 /* 00562 else //if beat times given in column (one beat times per line) 00563 { 00564 00565 } 00566 */ 00567 /* 00568 //if more than two beatTimes given in the annotation file 00569 //discart initial beatTime (due to inconsistencies in the beggining of some annotation files) 00570 if(pos1 >= 0) 00571 { 00572 gtBeatTime1_ = strtod(line.substr(pos0+1, pos1).c_str(), NULL); 00573 gtBeatTime2_ = strtod(line.substr(pos1+1, pos2).c_str(), NULL); 00574 gtAfter2ndBeat_ = true; 00575 } 00576 else //if only two beatTimes given keep them as they are 00577 { 00578 gtBeatTime1_ = strtod(line_.substr(0, pos1).c_str(), NULL); 00579 gtBeatTime2_ = strtod(line_.substr(pos0+1, pos1).c_str(), NULL); 00580 } 00581 00582 //========================================================== 00583 00584 //to assure that it could read from file => beatFile in column (ifnot => beatFile in row) 00585 if(gtBeatTime1_ == gtBeatTime2_ || gtBeatTime2_ == 0.0 || gtBeatTime2_ > 40) 00586 { 00587 gtBeatTime1_ = atof(line_.c_str()); 00588 getline (inStream_, line_); 00589 gtBeatTime2_ = atof(line_.c_str()); 00590 00591 //if more than two beatTimes given in the annotation file 00592 //discart initial beatTime (due to inconsistencies in the beggining of some annotation files) 00593 if(getline (inStream_, line_) > 0) 00594 { 00595 gtBeatTime1_ = gtBeatTime2_; 00596 gtBeatTime2_ = atof(line_.c_str()); 00597 gtAfter2ndBeat_ = true; 00598 } 00599 } 00600 */ 00601 //for printing: 00602 //mrs_natural curGTBeatPos = (mrs_natural) line.find_first_of(" ", lastGTBeatPos_+1); //current delimiter 00603 //mrs_real lastGTBeatTime = strtod(line.substr(lastGTBeatPos_+1, curGTBeatPos).c_str(), NULL); 00604 //cout << "nextGTBeatTime: " << lastGTBeatTime << endl; 00605 //cout << "beatError: " << localBeatErrorCount << endl; 00606 return localBeatErrorCount; 00607 } 00608 00609 void 00610 BeatReferee::grantPoolSpaceForTriggerAgents(mrs_realvec triggerAgentsHypotheses) 00611 { 00612 mrs_real agentInitScore; 00613 for(int a = 0; a < triggerAgentsHypotheses.getRows(); a++) 00614 { 00615 agentInitScore = triggerAgentsHypotheses(a, 2); 00616 grantPoolSpace(-1, agentInitScore); 00617 00618 //cout << timeElapsed_ << ": CHECKING POOL SPACE for score: " << agentInitScore << endl; 00619 00620 00621 00622 } 00623 } 00624 00625 //define clusters of similar periods 00626 //(like IBI histograms -> Dixon2001) 00627 mrs_realvec 00628 BeatReferee::clusterIBIs() 00629 { 00630 mrs_natural similarityTol = 2; //(2frames tol => ~23ms with hopSize = 512 && srcFr = 44100) 00631 mrs_real minPerDiff = MAXREAL; 00632 mrs_natural cluster = -1; 00633 mrs_realvec periodClusters(nrAgents_, nrAgents_); //(agents belonging to that cluster, per cluster index) 00634 mrs_realvec periodClustersInfo(nrAgents_, 2); //(nr. of cluster members, per cluster index; mean Period of each cluster, per cluster index) 00635 mrs_real agentPeriod; 00636 mrs_natural nrClusterMembers; 00637 mrs_real clusterPerMean; 00638 00639 for(int a = 0; a < nrAgents_; a++) //for all agents 00640 { 00641 //if(!mutedAgentsTmp_(a)) //if agent exists 00642 //only consider alive agents, which existed before (not created in this frame - to avoid adoption between brothers of the same generation) 00643 if(!mutedAgentsTmp_(a) && !agentsJustCreated_(a) && agentsFamilyHist_(a, ((mrs_natural) beatCounter_(a)-1)) == a) 00644 { 00645 agentPeriod = lastPeriods_(a); 00646 00647 //cout << "AGENT " << a << ": PERIOD: " << agentPeriod << endl; 00648 00649 for(int c = 0; c < nrAgents_; c++) //for all clusters 00650 { 00651 nrClusterMembers = (mrs_natural)periodClustersInfo(c, 0); 00652 clusterPerMean = periodClustersInfo(c, 1); 00653 00654 //cout << "\nCluster: " << c << "; nrMembers: " << nrClusterMembers << "; perMean: " << clusterPerMean; 00655 00656 if(nrClusterMembers > 0) //if cluster already have members 00657 { 00658 //calc diff between period and cluster current mean 00659 mrs_real perDiff = fabs(agentPeriod - clusterPerMean); 00660 00661 //cout << "; perDiff: " << perDiff << "; minDiff: " << minPerDiff << endl; 00662 00663 if(perDiff <= similarityTol) //check if diff respects tolerance 00664 { 00665 //check minimum difference to assign period to that cluster 00666 if(perDiff < minPerDiff) 00667 { 00668 minPerDiff = perDiff; 00669 cluster = c; //keep cluster index which presents minimum difference 00670 00671 //cout << "Agent " << a << " tmp assigned to " << cluster << endl; 00672 } 00673 } //if not below tolerance keepon searching for a similar cluster 00674 } 00675 } 00676 00677 if(cluster >= 0) //if cluster exists => assign agent and its period to chosen cluster 00678 { 00679 mrs_natural selectedClusterNrMembers = (mrs_natural)periodClustersInfo(cluster, 0); 00680 mrs_real selectedClusterMean = 0.0; 00681 00682 periodClusters(cluster, selectedClusterNrMembers) = a; //save agent in free cluster index 00683 00684 selectedClusterNrMembers++; 00685 //calculate cluster mean period 00686 for(int m = 0; m < selectedClusterNrMembers; m++) 00687 { 00688 selectedClusterMean += lastPeriods_((mrs_natural)periodClusters(cluster, m)); 00689 //if(timeElapsed_ == 3898) 00690 // cout << "curClMean: " << selectedClusterMean << "; curPer: " << lastPeriods_((mrs_natural)periodClusters(cluster, m)) 00691 // << " from " << periodClusters(cluster, m) << endl; 00692 } 00693 selectedClusterMean = selectedClusterMean / selectedClusterNrMembers; 00694 00695 //if(timeElapsed_ == 3898) 00696 // cout << "\nAgent " << a << "(" << periodClusters(cluster, selectedClusterNrMembers-1) << ") ASSIGNED TO " 00697 // << cluster << "; newPer: " << agentPeriod << "; lastMean: " << periodClustersInfo(cluster, 1) 00698 // << "; updMembers: " << selectedClusterNrMembers << "; updClPerMean: " << selectedClusterMean << endl; 00699 00700 periodClustersInfo(cluster, 0) = selectedClusterNrMembers; 00701 periodClustersInfo(cluster, 1) = selectedClusterMean; 00702 00703 minPerDiff = MAXREAL; 00704 cluster = -1; //reset selected cluster 00705 } 00706 else //if not -> create new cluster with this agent as first member 00707 { 00708 //cout << "NEW CLUSTER FOR AGENT " << a << endl; 00709 00710 for(int c = 0; c < nrAgents_; c++) //for all clusters -> select first empty 00711 { 00712 nrClusterMembers = (mrs_natural)periodClustersInfo(c, 0); 00713 if(nrClusterMembers == 0) //if cluster is empty 00714 { 00715 periodClusters(c, nrClusterMembers) = a; 00716 periodClustersInfo(c, 0) = 1; 00717 periodClustersInfo(c, 1) = agentPeriod; //initial cluster mean period 00718 00719 //cout << "Agent " << a << "(" << periodClusters(c, nrClusterMembers) << ") ASSIGNED TO NEW: " << c 00720 // << "; updMembers: " << periodClustersInfo(c, 0) << "; updClPerMean: " << periodClustersInfo(c, 1) << endl; 00721 00722 break; 00723 } 00724 } 00725 } 00726 } 00727 } 00728 00729 //MATLAB_PUT(periodClusters, "clustersPer1"); 00730 //MATLAB_PUT(periodClustersInfo, "clustersPerInfo1"); 00731 00732 //in the end cluster similar clusters due to cluster period mean being constantly updated during search above 00733 //(use same tolerance to cluster them) 00734 mrs_natural nrClusterMembers1, nrClusterMembers2, nrClusterMembersTot; 00735 mrs_real clusterPerMean1, clusterPerMean2; 00736 mrs_real clusterPerMeanTot = 0.0; 00737 for(int c = 0; c < nrAgents_; c++) //for all clusters 00738 { 00739 nrClusterMembers1 = (mrs_natural)periodClustersInfo(c, 0); 00740 00741 //cout << "\nVERIFYING cluster1: " << c << "; memb1: " << nrClusterMembers1; 00742 00743 if(nrClusterMembers1 > 0) //if cluster exists 00744 { 00745 clusterPerMean1 = periodClustersInfo(c, 1); 00746 00747 //cout << "; perMean1: " << clusterPerMean1; 00748 00749 for(int cc = 0; cc < nrAgents_; cc++) //for all other clusters 00750 { 00751 nrClusterMembers2 = (mrs_natural)periodClustersInfo(cc, 0); 00752 00753 //cout << "\nCOMP with2: " << cc << "; meb2: " << nrClusterMembers2; 00754 00755 if(cc != c && nrClusterMembers2 > 0) //if 2nd cluster is different than first, and it also exists 00756 { 00757 clusterPerMean2 = periodClustersInfo(cc, 1); 00758 00759 //cout << "; perMean2: " << clusterPerMean2 << endl; 00760 00761 //if both clusters are considered similar 00762 if(fabs(clusterPerMean1 - clusterPerMean2) <= similarityTol) 00763 { 00764 //transfer all info from second cluster to first and erase second 00765 nrClusterMembersTot = nrClusterMembers1 + nrClusterMembers2; 00766 for(int i = 0; i < nrClusterMembers2; i++) 00767 { 00768 periodClusters(c, nrClusterMembers1+i) = periodClusters(cc, i); 00769 periodClusters(cc, i) = 0.0; 00770 } 00771 00772 //calculate cluster mean period 00773 for(int m = 0; m < nrClusterMembersTot; m++) 00774 clusterPerMeanTot += lastPeriods_((mrs_natural)periodClusters(c, m)); 00775 00776 clusterPerMeanTot = clusterPerMeanTot / nrClusterMembersTot; 00777 00778 //update first cluster info 00779 periodClustersInfo(c, 0) = nrClusterMembersTot; 00780 periodClustersInfo(c, 1) = clusterPerMeanTot; 00781 //erase second cluster info 00782 periodClustersInfo(cc, 0) = 0.0; 00783 periodClustersInfo(cc, 1) = 0.0; 00784 00785 //cout << "CLUSTER2: " << cc << " CLUSTERED WITH1: " << c << endl; 00786 } 00787 } 00788 } 00789 } 00790 } 00791 00792 //MATLAB_PUT(periodClusters, "clustersPer2"); 00793 //MATLAB_PUT(periodClustersInfo, "clustersPerInfo2"); 00794 00795 //cout << "\n===================!!OK!!====================" << endl; 00796 00797 //return all clusters members, per cluster index (per line); and last two columns with nrElems; meanPer of each cluster 00798 mrs_realvec completedClustersPer(nrAgents_, nrAgents_+2); 00799 //copy periodClusters realvec 00800 for(int i = 0; i < nrAgents_; i++) 00801 { 00802 for(int j = 0; j < nrAgents_; j++) 00803 { 00804 completedClustersPer(i, j) = periodClusters(i, j); 00805 //cout << "copied " << i << " + " << j << "; completedClustersPer: " << completedClustersPer(i, j) << endl; 00806 } 00807 00808 //add column with mean periods of each cluster 00809 completedClustersPer(i, nrAgents_) = periodClustersInfo(i, 0); 00810 completedClustersPer(i, nrAgents_+1) = periodClustersInfo(i, 1); 00811 00812 //MATLAB_PUT(completedClustersPer, "completedClustersPerTMP"); 00813 00814 //cout << "copied " << i << " + " << nrAgents_ << ": " << completedClustersPer(i, nrAgents_) << "; info: " << periodClustersInfo(i, 1) << endl; 00815 } 00816 00817 //cout << "\n===================!!OKTOTAL!!====================" << endl; 00818 00819 //MATLAB_PUT(completedClustersPer, "completedClustersPer"); 00820 00821 return completedClustersPer; 00822 } 00823 00824 //Get best similar agent to selected -> pick the best agent from the most similar period cluster 00825 mrs_natural 00826 BeatReferee::getBestSimilarAgent3(mrs_natural newAgentPeriod, mrs_realvec completedClustersPer) 00827 { 00828 //if(timeElapsed_ == 3583) 00829 // MATLAB_PUT(completedClustersPer, "ClusterPerBestSimilar"); 00830 00831 //if(timeElapsed_ == 3583) 00832 // cout << "GET BEST SIMILAR FOR PERIOD " << newAgentPeriod << endl; 00833 00834 //check to each period cluster belongs the new agent 00835 mrs_real minPerDiff = MAXREAL; 00836 mrs_natural selectedCluster = -1; 00837 for(int c = 0; c < nrAgents_; c++) //for all clusters 00838 { 00839 if(completedClustersPer(c, nrAgents_) > 0.0) //if cluster exists 00840 { 00841 mrs_real clusterPeriod = completedClustersPer(c, nrAgents_+1); 00842 mrs_real perDiff = fabs(newAgentPeriod - clusterPeriod); 00843 00844 //cout << "\nCLUSTER " << c << "; clusterPer: " << clusterPeriod << "; perDiff: " << perDiff << "; minDiff: " << minPerDiff << endl; 00845 00846 //check min diff between with all clusters 00847 if(perDiff < minPerDiff) 00848 { 00849 minPerDiff = perDiff; 00850 selectedCluster = c; 00851 00852 //cout << "Tmp assigned to cluster " << selectedCluster << " with diff: " << perDiff << endl; 00853 } 00854 } 00855 } 00856 00857 //pick best agent from selected period cluster 00858 mrs_real bestClusterScore = NA; 00859 mrs_natural bestClusterAgent = -1; 00860 mrs_natural clusterAgent; 00861 mrs_natural nrSelectedClusterMembers = (mrs_natural) completedClustersPer(selectedCluster, nrAgents_); 00862 00863 //if(timeElapsed_ == 3898) 00864 // cout << "\nASSIGNED TO CLUSTER " << selectedCluster << " WITH " << nrSelectedClusterMembers 00865 // << " ELEMENTS and " << completedClustersPer(selectedCluster, nrAgents_+1) 00866 // << " PERIOD for Agentperiod: " << newAgentPeriod << endl; 00867 00868 for(int a = 0; a < nrSelectedClusterMembers; a++) 00869 { 00870 clusterAgent = (mrs_natural) completedClustersPer(selectedCluster, a); 00871 00872 //cout << "From Cluster " << selectedCluster << "; agent: " << clusterAgent << "; Score: " << score_(clusterAgent) 00873 // << "; bestClSc: " << bestClusterScore << endl; 00874 00875 if(!mutedAgents_(clusterAgent) && (clusterAgent) > bestClusterScore) //verify if agent really exists 00876 { 00877 bestClusterScore = score_(clusterAgent); 00878 bestClusterAgent = clusterAgent; 00879 00880 //cout << "Tmp Best Similar: " << bestClusterAgent << "; bestClSc: " << bestClusterScore << endl; 00881 } 00882 } 00883 00884 //if(timeElapsed_ == 3100) 00885 // cout << "BEST CLUSTER AGENT: " << bestClusterAgent << " WITH SCORE: " << bestClusterScore << "(" << score_(clusterAgent) << ")" << endl; 00886 00887 return bestClusterAgent; 00888 } 00889 00890 //Get best similar agent to selected -> based on heuristics 00891 //[CHANGE -> IGNORE PHASE IN HEURISTICS -> transition phase is handled by handleAgentsTansition()!!!] 00892 mrs_natural 00893 BeatReferee::getBestSimilarAgent(mrs_natural newAgentPeriod, mrs_natural newAgentInitPhase, mrs_real newAgentScore) 00894 { 00895 mrs_real bestSimilarScore = NA; //just a big negative nr 00896 mrs_natural bestSimilarAgent = -1; 00897 mrs_natural period, phaseRaw, phase, k; 00898 mrs_realvec periodDiffs(nrAgents_); 00899 mrs_realvec phaseDiffs(nrAgents_); 00900 mrs_realvec bestSimilarity(nrAgents_); 00901 mrs_real fraction; 00902 00903 //if(timeElapsed_ == 2461 && newAgentPeriod == 57) 00904 // cout << "NEW AGENT-> period: " << newAgentPeriod << "; phase: " << newAgentInitPhase << endl; 00905 00906 //Grant available space in the pool, by removing the worst agent, if needed 00907 grantPoolSpace(-1, newAgentScore); 00908 00909 //calculate maximum possible difference (for normalizing the best similarity heuristics) 00910 //maximum difference occur when one agent has the maxPeriod and other the minPeriod 00911 //=> maximum phase difference for this period difference = minPeriod 00912 mrs_real maxHypDiff = (3 * (maxPeriod_ - minPeriod_) + minPeriod_); 00913 //save all period and phase differences with each agent 00914 for(int a = 0; a < nrAgents_; a++) 00915 { 00916 //only consider alive agents, which existed before (not created in this frame - to avoid adoption between brothers of the same generation) 00917 //if(!mutedAgentsTmp_(a) && !agentsJustCreated_(a)) 00918 if(!mutedAgentsTmp_(a) && !agentsJustCreated_(a) && agentsFamilyHist_(a, ((mrs_natural) beatCounter_(a)-1)) == a) 00919 { 00920 //cout << "Agent " << a << " ok: " << agentsFamilyHist_(a, ((mrs_natural) beatCounter_(a)-1)) << endl; 00921 period = (mrs_natural) lastPeriods_(a); 00922 phaseRaw = (mrs_natural) lastPhases_(a); 00923 00924 //transpose compared agent phase to new agent phase location 00925 k = (mrs_natural) (((mrs_real)(newAgentInitPhase - phaseRaw) / period) + 0.5); 00926 phase = phaseRaw + k * period; 00927 00928 periodDiffs(a) = abs(newAgentPeriod - period); 00929 phaseDiffs(a) = abs(newAgentInitPhase - phase); 00930 00931 //heuristics for calculating degree of best similarity with each agent 00932 //compared agent's score proportion of (3*periodDiff + 1*phaseDiff) [give 3x more relevance to period than phase] 00933 //bestSimilarity(a) = ((1/(3*periodDiffs(a))) + (1/phaseDiffs(a))) * score_(a); 00934 fraction = (1 - ((3*periodDiffs(a) + phaseDiffs(a)) / maxHypDiff)); 00935 00936 if(score_(a) > 0) //to avoid bestScore inversions 00937 bestSimilarity(a) = fraction * score_(a); 00938 else 00939 bestSimilarity(a) = score_(a) / fraction; 00940 00941 //check who's best similar based on heuristics above 00942 if(bestSimilarity(a) > bestSimilarScore) 00943 { 00944 //if(timeElapsed_ == 2461 && newAgentPeriod == 57) 00945 // cout << "============ curBestSimilarScore: " << bestSimilarScore << "; new from " << a << ": " << bestSimilarity(a) << endl; 00946 bestSimilarScore = bestSimilarity(a); 00947 bestSimilarAgent = a; 00948 } 00949 00950 //if(timeElapsed_ == 2461 && newAgentPeriod == 57) 00951 // cout << "Agent " << a << "; period: " << period << "; phaseRaw: " << phaseRaw << "; phase: " << phase << "(" << k 00952 // << "); perDiff: " << periodDiffs(a) << "; phDiff: " << phaseDiffs(a) << "; fraction: " << fraction 00953 // << "; score: " << score_(a) << "; simSc: " << bestSimilarity(a) << " (" << bestSimilarScore << "->" 00954 // << bestSimilarAgent << ")" << endl; 00955 } 00956 } 00957 00958 //if(timeElapsed_ == 2461 && newAgentPeriod == 57) 00959 // cout << "BEST SIMILAR AGENT: " << bestSimilarAgent << endl; 00960 00961 return bestSimilarAgent; 00962 } 00963 00964 /* 00965 //get similar existing agent with best score 00966 //[MAYBE CHANGE THIS TO (1/PERIODDIFF)*SCORE] 00967 mrs_natural 00968 BeatReferee::getBestSimilarAgent2(mrs_natural newAgentPeriod, mrs_natural newAgentInitPhase) 00969 { 00970 mrs_natural nrSimilar = 3; //nr of considered most simlar agents 00971 mrs_real bestSimilarScore = NA; 00972 mrs_natural bestSimilarAgent = -1; 00973 mrs_natural period; 00974 mrs_natural minPerDiff = 1000; //just a big number 00975 mrs_natural mostSimilarAgent = -1; 00976 mrs_realvec periodDiffs(nrAgents_); 00977 00978 //save all period differences with each agent 00979 for(int a = 0; a < nrAgents_; a++) 00980 { 00981 period = (mrs_natural) lastPeriods_(a); 00982 periodDiffs(a) = abs(newAgentPeriod - period); 00983 } 00984 00985 //cout << "NewAgent!" << endl; 00986 00987 //sort periodDiffs realvec 00988 mrs_realvec periodDiffsSorted = periodDiffs; 00989 periodDiffsSorted.sort(); 00990 mrs_natural maxPeriodDiff = (mrs_natural) periodDiffsSorted(nrSimilar); 00991 00992 //check nrSimilar most similar agents 00993 for(int a = 0; a < nrAgents_; a++) 00994 { 00995 //cout << "Diff " << a << ": " << periodDiffsSorted(a) << "; UnSort: " << periodDiffs(a) << "; Score: " << score_(a) << endl; 00996 if((mrs_natural) periodDiffs(a) <= maxPeriodDiff) //only consider nrSimilar most similar agents 00997 { 00998 //check who's best 00999 if(score_(a) > bestSimilarScore) 01000 { 01001 bestSimilarScore = score_(a); 01002 bestSimilarAgent = a; 01003 01004 //cout << "BestSimilar: " << bestSimilarAgent << "; Score: " << bestSimilarScore << endl; 01005 } 01006 } 01007 } 01008 01009 return bestSimilarAgent; 01010 } 01011 */ 01012 01013 //Routine for backtracing the first beat of the first created agents (for backtrace mode) 01014 mrs_natural 01015 BeatReferee::calcFirstBacktracedBeat(mrs_natural initPeriod, mrs_natural initPhase) 01016 { 01017 mrs_natural count = - (mrs_natural) ((initPhase / (mrs_real)initPeriod)-MINIMUMREAL); 01018 mrs_natural firstBeat = (initPhase + initPeriod * count); 01019 01020 //cout << "Period: " << initPeriod << "; Phase: " << initPhase << "; firstBeat: " << firstBeat << endl; 01021 return firstBeat; 01022 } 01023 01024 //Routine for calculating the first beat time of the first created agents (after induction): 01025 //(for continuous signal - no backtracing (induction window offset -> first beat must occur after the induction stage)): 01026 /* 01027 mrs_natural 01028 BeatReferee::calcFirstBeat(mrs_natural initPeriod, mrs_natural initPhase) 01029 { 01030 mrs_natural count = (mrs_natural) ceil((inductionTime_ - initPhase) / (mrs_real)initPeriod); 01031 mrs_natural firstBeat = (initPhase + initPeriod * count); 01032 01033 //Due to the compensation bellow we must grant that nextBeat is bigger than inductionTime_ 01034 //If it is equal than we must postpone the nextBeat to a period after 01035 if(firstBeat == inductionTime_) 01036 { 01037 firstBeat += initPeriod; 01038 } 01039 01040 //cout << "initPeriod:" << initPeriod << "; initPhase:" << initPhase << "; firstBeat:" << firstBeat << endl; 01041 01042 return firstBeat; 01043 } 01044 */ 01045 01046 mrs_natural 01047 BeatReferee::existEqualBetterAgents(mrs_natural agentIndex, mrs_natural agentPeriod, mrs_natural agentPhase, mrs_real newAgentScore) 01048 { 01049 //cout << timeElapsed_ << ": isEqualAgents? period: " << agentPeriod << "; phase: " << agentPhase << endl; 01050 01051 mrs_natural firstEqualBetterAgent = -1; 01052 mrs_realvec equalAgents = getEqualAgents(agentIndex, agentPeriod, agentPhase); 01053 01054 for(mrs_natural a = 0; a < nrAgents_; a++) 01055 { 01056 if((mrs_natural) equalAgents(a) == 1) 01057 { 01058 if(score_(a) >= newAgentScore) 01059 { 01060 firstEqualBetterAgent = a; 01061 break; 01062 } 01063 } 01064 } 01065 01066 return firstEqualBetterAgent; 01067 } 01068 01069 //return -1 if no existing equal agents or index of first equal agent 01070 mrs_natural 01071 BeatReferee::existEqualAgents(mrs_natural agentIndex, mrs_natural agentPeriod, mrs_natural agentPhase) 01072 { 01073 //cout << timeElapsed_ << ": isEqualAgents? period: " << agentPeriod << "; phase: " << agentPhase << endl; 01074 01075 mrs_natural firstEqualAgent = -1; 01076 mrs_realvec equalAgents = getEqualAgents(agentIndex, agentPeriod, agentPhase); 01077 01078 for(mrs_natural a = 0; a < nrAgents_; a++) 01079 { 01080 if((mrs_natural) equalAgents(a) == 1) 01081 { 01082 firstEqualAgent = a; 01083 break; 01084 } 01085 } 01086 01087 return firstEqualAgent; 01088 } 01089 01090 //get a vector with all agents equal to agentIndex 01091 mrs_realvec 01092 BeatReferee::getEqualAgents(mrs_natural agentIndex, mrs_natural agentPeriod, mrs_natural agentPhase) 01093 { 01094 mrs_realvec equalAgents(nrAgents_); 01095 01096 for(mrs_natural a = 0; a < nrAgents_; a++) 01097 { 01098 //if considered agent is not equal to the agent we want to compare 01099 //&& if the angent we want to compare is alive (i.e. exists) => then procede with comparison 01100 //(agenIndex == -1 => call after trigger induction) 01101 if(agentIndex == -1 || (agentIndex != a && !mutedAgentsTmp_(a))) 01102 { 01103 //2 agents are considered equal if their periods don't differ 01104 //more than 10ms (eq. 1frame) and their phases no more than 20ms (eq. 2frames) 01105 mrs_real phaseDiff = abs((agentPhase - lastPhases_(a)) / agentPeriod); 01106 mrs_natural periodDiff = abs(agentPeriod - (mrs_natural)lastPeriods_(a)); 01107 01108 //if(timeElapsed_ == 3949 || timeElapsed_ == 3968) 01109 // cout << "Comparing " << agentIndex << " w/ per: " << agentPeriod << " & ph: " << agentPhase << " with Agent " 01110 // << a << "; period: " << lastPeriods_(a) << "; phase: " << lastPhases_(a) 01111 // << "; periodDiff: " << periodDiff << "(" << eqPeriod_ << "); phaseDiff:" << (phaseDiff - floor(phaseDiff)) 01112 // << "(" << ((mrs_real)eqPhase_/(mrs_real)agentPeriod) << ")" << endl; 01113 01114 if((periodDiff <= eqPeriod_) && ((phaseDiff - floor(phaseDiff)) <= ((mrs_real)eqPhase_/(mrs_real)agentPeriod) 01115 || (phaseDiff - floor(phaseDiff)) >= (1-((mrs_real)eqPhase_/(mrs_real)agentPeriod)))) 01116 { 01117 equalAgents(a) = 1; //set agent index as true if equal 01118 01119 //if(timeElapsed_ == 3949) 01120 // cout << "====================" << timeElapsed_ << ": Agent " << agentIndex << " has EQUAL: " << a << endl; 01121 } 01122 } 01123 } 01124 01125 return equalAgents; 01126 } 01127 01128 //checks and kill the worse from all existing equal agents to agentIndex 01129 void 01130 BeatReferee::checkAndKillEqualAgents(mrs_natural agentIndex) 01131 { 01132 //if(timeElapsed_ == 3949) 01133 // cout << timeElapsed_ << ": REGULARLY CHECKING EQUAL AGENTS" << endl; 01134 01135 mrs_realvec equalAgents = getEqualAgents(agentIndex, (mrs_natural) lastPeriods_(agentIndex), (mrs_natural) lastPhases_(agentIndex)); 01136 01137 for(mrs_natural a = 0; a < nrAgents_; a++) 01138 { 01139 if((mrs_natural)equalAgents(a) == 1) //if equal agent 01140 { 01141 //cout << "EQ!: " << agentIndex << "=" << a << endl; 01142 //From the two equal agents kill the one with lower score (if it isn't the current best agent) 01143 //(always kill the equal agents created at triggered inductions) 01144 ostringstream motif; 01145 if(score_(agentIndex) >= score_(a)) 01146 { 01147 if(a != bestAgentIndex_) 01148 { 01149 motif << "EQ"; 01150 killAgent(a, motif.str(), agentIndex); 01151 01152 //cout << "1-KILL Agent " << a << " (" << score_(a) << ") EQUAL TO Agent " << agentIndex 01153 // << " (" << score_(agentIndex) << ")" << endl; 01154 } 01155 else //if in trigger induction always kill just created agent (agentIndex), if equal to existing 01156 { 01157 motif << "EQ"; 01158 killAgent(agentIndex, motif.str(), a); 01159 break; //in this case breaks because considered agent no longer exists. 01160 01161 //cout << timeElapsed_ << ": 2-KILL Agent " << agentIndex << " (" << score_(agentIndex) 01162 // << ") EQUAL TO Agent " << a << " (" << score_(a) << ")" << endl; 01163 } 01164 } 01165 else 01166 { 01167 if(agentIndex != bestAgentIndex_) 01168 { 01169 motif << "EQ"; 01170 killAgent(agentIndex, motif.str(), a); 01171 break; //in this case breaks because considered agent no longer exists. 01172 01173 //cout << "3-KILL Agent " << agentIndex << " (" << score_(agentIndex) << ") EQUAL TO Agent " 01174 // << a << " (" << score_(a) << ")" << endl; 01175 } 01176 else 01177 { 01178 motif << "EQ"; 01179 killAgent(a, motif.str(), agentIndex); 01180 01181 //cout << "1-KILL Agent " << a << " (" << score_(a) << ") EQUAL TO Agent " 01182 // << agentIndex << " (" << score_(agentIndex) << ")" << endl; 01183 } 01184 } 01185 } 01186 } 01187 } 01188 01189 //returns true if agent created at trigered induction is killed due to be equal to existing agent 01190 /* 01191 mrs_bool 01192 BeatReferee::checkAndKillEqualAgents(mrs_natural agentIndex, mrs_bool triggerInductionCheck) 01193 { 01194 mrs_bool killedAgentIndex = false; 01195 for(mrs_natural a = 0; a < nrAgents_; a++) 01196 { 01197 //if considered agent is not equal to the agent we want to compare 01198 //&& if the angent we want to compare is alive (i.e. exists) => then procede with comparison 01199 if(agentIndex != a && !mutedAgentsTmp_(a)) 01200 { 01201 //2 agents are considered equal if their periods don't differ 01202 //more than 10ms (eq. 1frame) and their phases no more than 20ms (eq. 2frames) 01203 if((abs(lastPeriods_(agentIndex) - lastPeriods_(a)) <= eqPeriod_) && 01204 (abs((lastPhases_(agentIndex) - lastPhases_(a)) / lastPeriods_(agentIndex)) <= (eqPhase_/lastPeriods_(agentIndex)))) 01205 { 01206 //cout << "EQ!: " << agentIndex << "=" << a << endl; 01207 //From the two equal agents kill the one with lower score (if it isn't the current best agent) 01208 //(always kill the equal agents created at triggered inductions) 01209 ostringstream motif; 01210 if(score_(agentIndex) >= score_(a)) 01211 { 01212 //if(a != bestAgentIndex_) 01213 if(a != bestAgentIndex_ && !triggerInductionCheck) 01214 { 01215 motif << "EQ"; 01216 killAgent(a, motif.str(), agentIndex); 01217 killedAgentIndex = false; 01218 01219 //cout << "1-KILL Agent " << a << " (" << score_(a) << ") EQUAL TO Agent " << agentIndex 01220 // << " (" << score_(agentIndex) << ")" << endl; 01221 } 01222 else //if in trigger induction always kill just created agent (agentIndex), if equal to existing 01223 { 01224 motif << "EQ"; 01225 killAgent(agentIndex, motif.str(), a); 01226 killedAgentIndex = true; 01227 break; //in this case breaks because considered agent no longer exists. 01228 01229 //if(triggerInductionCheck) 01230 // cout << timeElapsed_ << ": 2-KILL Agent " << agentIndex << " (" << score_(agentIndex) 01231 // << ") EQUAL TO Agent " << a << " (" << score_(a) << ")" << endl; 01232 } 01233 } 01234 else 01235 { 01236 if(agentIndex != bestAgentIndex_) 01237 { 01238 motif << "EQ"; 01239 killAgent(agentIndex, motif.str(), a); 01240 killedAgentIndex = true; 01241 break; //in this case breaks because considered agent no longer exists. 01242 01243 //cout << "3-KILL Agent " << agentIndex << " (" << score_(agentIndex) << ") EQUAL TO Agent " 01244 // << a << " (" << score_(a) << ")" << endl; 01245 } 01246 else 01247 { 01248 motif << "EQ"; 01249 killAgent(a, motif.str(), agentIndex); 01250 killedAgentIndex = false; 01251 01252 //cout << "1-KILL Agent " << a << " (" << score_(a) << ") EQUAL TO Agent " 01253 // << agentIndex << " (" << score_(agentIndex) << ")" << endl; 01254 } 01255 } 01256 } 01257 } 01258 } 01259 return killedAgentIndex; 01260 } 01261 */ 01262 01263 mrs_natural 01264 BeatReferee::getFirstAliveAgent() 01265 { 01266 mrs_natural firstAlive = 0; 01267 for(mrs_natural a = 0; a < nrAgents_; a++) 01268 { 01269 if(!mutedAgentsTmp_(a)) 01270 { 01271 firstAlive = a; 01272 break; 01273 } 01274 } 01275 return firstAlive; 01276 } 01277 01278 //Get the current worst agent of the pool: 01279 mrs_natural 01280 BeatReferee::getWorstAgent(mrs_natural callAgent) 01281 { 01282 //By default lowest score = score from first agent 01283 //mrs_natural firstAlive= getFirstAliveAgent(); 01284 //mrs_real lowestScore = score_(firstAlive); 01285 01286 mrs_real lowestScore = MAXREAL; 01287 mrs_natural lowestIndex = 0; 01288 01289 //if(timeElapsed_ == 3100) 01290 // cout << "Getting Worst Agent - FIRST: " << lowestIndex << "; sc: " << lowestScore << "; mutedAgentsTmp: " << mutedAgentsTmp_(lowestIndex); 01291 01292 for(mrs_natural a = lowestIndex; a < nrAgents_; a++) 01293 { 01294 //never kill bestAgentBeforeTrigger && verify that agent really exists and it's not the call agent 01295 if(a != bestAgentBeforeTrigger_ && !mutedAgentsTmp_(a) && a != callAgent && score_(a) < lowestScore) 01296 { 01297 lowestScore = score_(a); 01298 lowestIndex = a; 01299 01300 //if(timeElapsed_ == 876) 01301 // cout << "; Actual: " << lowestIndex << "; sc: " << lowestScore << "; Agent: " << a 01302 // << "; bestAgentBeforeTrigger: " << bestAgentBeforeTrigger_ << endl; 01303 } 01304 } 01305 01306 //if(timeElapsed_ == 3100) 01307 // cout << endl; 01308 01309 //return worst agent 01310 return lowestIndex; 01311 } 01312 01313 mrs_realvec 01314 BeatReferee::calculateNewHypothesis(mrs_natural agentIndex, mrs_natural oldPeriod, mrs_natural prevBeat, mrs_natural error) 01315 { 01316 (void) agentIndex; // [!] what was this supposed to do? 01317 mrs_natural newPeriod; 01318 mrs_natural nextBeat; 01319 /* 01320 //To avoid too small or big periods, or too distanced from agent's initial period: 01321 if(newPeriod > minPeriod_ && newPeriod < maxPeriod_ && 01322 fabs(initPeriod_(agentIndex) - newPeriod) < 0.1*initPeriod_(agentIndex)) 01323 */ 01324 01325 newPeriod = oldPeriod + ((mrs_natural) ((error*corFactor_) + ((error/abs(error)) * 0.5))); 01326 01327 //To avoid too small or big periods 01328 if(newPeriod < minPeriod_ || newPeriod > maxPeriod_) 01329 newPeriod = oldPeriod; 01330 01331 nextBeat = prevBeat + newPeriod + ((mrs_natural) ((error*corFactor_) + ((error/abs(error))) * 0.5)); 01332 01333 01334 /* 01335 newPeriod = oldPeriod + error; 01336 if(newPeriod < minPeriod_ || newPeriod > maxPeriod_) 01337 newPeriod = oldPeriod; 01338 nextBeat = prevBeat + newPeriod; 01339 */ 01340 //if(agentIndex == bestAgentIndex_) 01341 // cout << "Agent" << agentIndex << ": Error:" << error << "; AgentPeriod:" << newPeriod << endl; 01342 01343 //cout << "Agent " << agentIndex << "; oldPeriod: " << oldPeriod << "; NewPeriod: " << newPeriod << 01344 // "; NextBeat: " << nextBeat << "; Error: " << error << "; Correction: " << correction << endl; 01345 //cout << "Agent " << agentIndex << " History: " << historyCount_(agentIndex) << endl; 01346 01347 mrs_realvec newHypothesis(2); 01348 newHypothesis(0) = newPeriod; 01349 newHypothesis(1) = nextBeat; 01350 01351 return newHypothesis; 01352 } 01353 01354 mrs_natural 01355 BeatReferee::calcNewPeriod(mrs_natural oldPeriod, mrs_natural error, mrs_real beta) 01356 { 01357 //cout << "error: " << error << "; beta: " << beta << endl; 01358 mrs_natural newPeriod = oldPeriod + ((mrs_natural) ((error * beta) + (error/abs(error)) * 0.5)); 01359 01360 if(newPeriod < minPeriod_ || newPeriod > maxPeriod_) 01361 newPeriod = oldPeriod; 01362 01363 //cout << "oldPeriod: " << oldPeriod << "; newPeriod: " << newPeriod << "; Error: " << error << 01364 // "; Beta: " << beta << "; maxPer: " << maxPeriod_ << "; minPer: " << minPeriod_ << endl; 01365 01366 return newPeriod; 01367 } 01368 01369 mrs_realvec 01370 BeatReferee::calcChildrenHypothesis(mrs_natural oldPeriod, mrs_natural prevBeat, mrs_natural error) 01371 { 01372 mrs_natural nextBeat1 = -100, nextBeat2 = -100, nextBeat3 = -100; 01373 mrs_natural newPeriod1 = -100, newPeriod2 = -100, newPeriod3 = -100; 01374 mrs_realvec newHypotheses(3,3); //for 3 children 01375 01376 //cout << "ChildFactor1:" << child1Factor_ << "; ChildFactor2:" << child2Factor_ << "; ChildFactor3:" << child3Factor_ << endl; 01377 01378 //(if childiFactor = -1.0 then only phase adjusted) 01379 if(child1Factor_ == 2.0) 01380 { 01381 newPeriod1 = oldPeriod; 01382 nextBeat1 = prevBeat + newPeriod1 + error; 01383 } 01384 else 01385 { 01386 newPeriod1 = calcNewPeriod(oldPeriod, error, child1Factor_); 01387 //if newPeriod surprasses bpm interval then do only full phase adjustment 01388 //if(newPeriod < minPeriod_ || newPeriod > maxPeriod_) 01389 // nextBeat = prevBeat + oldPeriod + error; 01390 //else 01391 nextBeat1 = prevBeat + newPeriod1 + ((mrs_natural) ((error*child1Factor_) + ((error/abs(error))) * 0.5)); 01392 //nextBeat = prevBeat + newPeriod; 01393 } 01394 newHypotheses(0,0) = newPeriod1; 01395 newHypotheses(0,1) = nextBeat1; 01396 newHypotheses(0,2) = 1; 01397 01398 if(child2Factor_ == 2.0) 01399 { 01400 newPeriod2 = oldPeriod; 01401 nextBeat2 = prevBeat + newPeriod2 + error; 01402 } 01403 else 01404 { 01405 /* 01406 newPeriod = oldPeriod + error; 01407 if(newPeriod < minPeriod_ || newPeriod > maxPeriod_) 01408 newPeriod = oldPeriod; 01409 nextBeat = prevBeat + newPeriod; 01410 */ 01411 01412 newPeriod2 = calcNewPeriod(oldPeriod, error, child2Factor_); 01413 //if newPeriod surprasses bpm interval then do only full phase adjustment 01414 //if(newPeriod < minPeriod_ || newPeriod > maxPeriod_) 01415 // nextBeat = prevBeat + oldPeriod + error; 01416 //else 01417 nextBeat2 = prevBeat + newPeriod2 + ((mrs_natural) ((error*child2Factor_) + ((error/abs(error))) * 0.5)); 01418 } 01419 newHypotheses(1,0) = newPeriod2; 01420 newHypotheses(1,1) = nextBeat2; 01421 01422 //To avoid creating equal agents: 01423 if(abs(newPeriod2 - newPeriod1) <= eqPeriod_ && abs(nextBeat2 - nextBeat1) <= eqPhase_) 01424 newHypotheses(1,2) = 0; 01425 else newHypotheses(1,2) = 1; 01426 01427 if(child3Factor_ == 2.0) 01428 { 01429 newPeriod3 = oldPeriod; 01430 nextBeat3 = prevBeat + newPeriod3 + error; 01431 } 01432 else 01433 { 01434 newPeriod3 = calcNewPeriod(oldPeriod, error, child3Factor_); 01435 //if newPeriod surprasses bpm interval then do only full phase adjustment 01436 //if(newPeriod < minPeriod_ || newPeriod > maxPeriod_) 01437 // nextBeat = prevBeat + oldPeriod + error; 01438 //else 01439 nextBeat3 = prevBeat + newPeriod3 + ((mrs_natural) ((error*child3Factor_) + ((error/abs(error))) * 0.5)); 01440 } 01441 newHypotheses(2,0) = newPeriod3; 01442 newHypotheses(2,1) = nextBeat3; 01443 01444 //To avoid creating equal agents: 01445 if((abs(newPeriod3 - newPeriod1) <= eqPeriod_ && abs(nextBeat3 - nextBeat1) <= eqPhase_) 01446 || (abs(newPeriod3 - newPeriod2) <= eqPeriod_ && abs(nextBeat3 - nextBeat2) <= eqPhase_)) 01447 newHypotheses(2,2) = 0; 01448 else newHypotheses(2,2) = 1; 01449 01450 //cout << "oldPeriod: " << oldPeriod << "; newPeriod: " << newPeriod << "; Error: " << error << 01451 // "; prevBeat: " << prevBeat << "; nextBeat: " << nextBeat << endl; 01452 01453 return newHypotheses; 01454 } 01455 01456 //Routine for creating new agents from existent one 01457 void 01458 BeatReferee::createChildren(mrs_natural agentIndex, mrs_natural oldPeriod, mrs_natural prevBeat, mrs_natural error, 01459 mrs_real agentScore, mrs_real beatCount) 01460 { 01461 //mrs_real deltaS = fabs(childrenScoreFactor_ * agentScore); 01462 //mrs_real newScore = agentScore - deltaS; 01463 01464 //if(timeElapsed_ == 687) 01465 // cout << "CREATE AGENTS FROM: " << agentIndex << "; error: " << error << "; per: " << oldPeriod << "; ph: " << prevBeat << endl; 01466 01467 mrs_real newScore; 01468 if(agentScore >= 0.0) 01469 newScore = agentScore * childrenScoreFactor_; 01470 else 01471 newScore = agentScore / childrenScoreFactor_; 01472 01473 mrs_realvec newHypotheses = calcChildrenHypothesis(oldPeriod, prevBeat, error); 01474 01475 //mrs_realvec newHypothesis = calculateNewHypothesis(agentIndex, oldPeriod, prevBeat, error); 01476 //setNewHypothesis(agentIndex, (mrs_natural) newHypothesis(0), (mrs_natural) newHypothesis(1)); 01477 01478 if(child1Factor_ != -1.0) 01479 createNewAgent((mrs_natural) newHypotheses(0,0), (mrs_natural) newHypotheses(0,1), newScore, beatCount, agentIndex); 01480 if(child2Factor_ != -1.0 && newHypotheses(1,2) == 1) 01481 createNewAgent((mrs_natural) newHypotheses(1,0), (mrs_natural) newHypotheses(1,1), newScore, beatCount, agentIndex); 01482 if(child3Factor_ != -1.0 && newHypotheses(2,2) == 1) 01483 createNewAgent((mrs_natural) newHypotheses(2,0), (mrs_natural) newHypotheses(2,1), newScore, beatCount, agentIndex); 01484 01485 //Display Created BeatAgent: 01486 //if(timeElapsed_ == 2046) 01487 // cout << "NEW AGENT(" << timeElapsed_ << "-" << ((timeElapsed_ * hopSize_) - (hopSize_/2)) / srcFs_ << ") (reqBy:" << agentIndex << 01488 // ") -> PrevBeat:" << prevBeat << " Period:" << oldPeriod << " NextBeat1:" << newHypotheses(0,1) << " NewPeriod1:" << 01489 // newHypotheses(0,0) << " NextBeat2:" << newHypotheses(1,1) << " NewPeriod2:" << newHypotheses(1,0) << 01490 // " NextBeat3:" << newHypotheses(2,1) << " NewPeriod3:" << newHypotheses(2,0) << 01491 // " Error:" << error << " Score:" << newScore << endl; 01492 } 01493 01494 //Routine for updating existent agent hypothesis 01495 //(Used when beat of agent is found inside its inner tolerance with some error): 01496 void 01497 BeatReferee::updateAgentHypothesis(mrs_natural agentIndex, mrs_natural oldPeriod, 01498 mrs_natural prevBeat, mrs_natural error) 01499 { 01500 //if agent effectively exists (for safechecking) 01501 if(!mutedAgentsTmp_(agentIndex)) 01502 { 01503 mrs_realvec newHypothesis = calculateNewHypothesis(agentIndex, oldPeriod, prevBeat, error); 01504 setNewHypothesis(agentIndex, (mrs_natural) newHypothesis(0), (mrs_natural) newHypothesis(1)); 01505 } 01506 01507 //Display Updated BeatAgent: 01508 //cout << "UPDATING AGENT" << agentIndex <<" (" << timeElapsed_ << ")" << " -> oldPeriod: " << oldPeriod << 01509 // " newPeriod: " << newHypothesis(0) << " prevBeat: " << prevBeat << " nextBeat: " << newHypothesis(1) << 01510 // " Error: " << error << endl; 01511 } 01512 01513 //Define new Hypothesis in indexed AgentControl Matrix: 01514 void 01515 BeatReferee::setNewHypothesis(mrs_natural agentIndex, mrs_natural newPeriod, mrs_natural nextBeat) 01516 { 01517 agentControl_(agentIndex, 0) = 1.0; //is New or Updated 01518 agentControl_(agentIndex, 1) = newPeriod; 01519 agentControl_(agentIndex, 2) = nextBeat; 01520 agentControl_(agentIndex, 3) = timeElapsed_; 01521 01522 updControl(ctrl_agentControl_, agentControl_); 01523 01524 lastPeriods_(agentIndex) = newPeriod; 01525 } 01526 01527 //grantPoolSpace given the nr of elements in the newAgentsScore realvec 01528 void 01529 BeatReferee::grantPoolSpace2(mrs_natural callAgent, mrs_natural nrRequired, mrs_realvec newAgentsScore) 01530 01531 { 01532 01533 //if(timeElapsed_ == 3100) 01534 //{ 01535 // for(int i = 0; i < nrRequired; i++) 01536 // cout << "NEW " << i << "-> Agents Score: " << newAgentsScore(i) << "; elems: " << nrRequired << endl; 01537 //} 01538 01539 mrs_natural nrAvailable = 0; 01540 for(int a = 0; a < mutedAgentsTmp_.getSize(); a++) 01541 { 01542 if(mutedAgentsTmp_(a)) 01543 nrAvailable++; 01544 } 01545 01546 //if(timeElapsed_ == 3100) 01547 // cout << "t: " << timeElapsed_ << ": AVAILABLE POOLSPACE: " << nrAvailable << "; required: " << nrRequired << endl; 01548 01549 nrRequired = nrRequired - nrAvailable; //updated nr of required spaces given the ammount of free ones 01550 01551 //if there are no free agents -> remove worsts! 01552 while(nrRequired > 0) 01553 { 01554 mrs_natural agentInd2Kill = getWorstAgent(callAgent); 01555 01556 //if(timeElapsed_ == 3100) 01557 // cout << "t: " << timeElapsed_ << ": KillWorstAgent: " << agentInd2Kill << "; newAgentSc: " << newAgentsScore(nrRequired-1) << "; worstScore: " << score_(agentInd2Kill) << endl; 01558 01559 //only kills current worst agent in the pool if its score is smaller than the new agent score 01560 if(score_(agentInd2Kill) <= newAgentsScore(nrRequired-1)) 01561 killAgent(agentInd2Kill, "POOL", callAgent); 01562 01563 nrRequired--; 01564 } 01565 } 01566 01567 void 01568 BeatReferee::grantPoolSpace(mrs_natural callAgent, mrs_real newAgentScore) 01569 { 01570 mrs_bool isAvailable = false; 01571 01572 for(int a = 0; a < mutedAgentsTmp_.getSize(); a++) 01573 { 01574 //if(timeElapsed_ == 876) 01575 // cout << "t: " << timeElapsed_ << ": CHECKING POOLSPACE @: " << a << "; newAgentSc: " << newAgentScore << endl; 01576 01577 if(mutedAgentsTmp_(a)) 01578 { 01579 //if(timeElapsed_ == 876) 01580 // cout << "t: " << timeElapsed_ << ": FREE POOLSPACE @: " << a << "; newAgentSc: " << newAgentScore << endl; 01581 01582 isAvailable = true; 01583 break; 01584 } 01585 } 01586 01587 //if there are no free agents -> remove worst! 01588 if(!isAvailable) 01589 { 01590 mrs_natural agentInd2Kill = getWorstAgent(callAgent); 01591 01592 //if(timeElapsed_ == 876) 01593 // cout << "t: " << timeElapsed_ << ": KillWorstAgent: " << agentInd2Kill << "; newAgentSc: " << newAgentScore << "; worstScore: " << score_(agentInd2Kill) << endl; 01594 01595 //only kills current worst agent in the pool if its score is smaller than the new agent score 01596 if(score_(agentInd2Kill) <= newAgentScore) 01597 killAgent(agentInd2Kill, "POOL", callAgent); 01598 //else if(logFile_) 01599 // debugAddEvent("NO_POOL", callAgent, -1, -1, newAgentScore, score_(agentInd2Kill), agentInd2Kill); 01600 } 01601 } 01602 01603 //routine for checking and recovering beat at transition bewteen father and son (for non-causal mode) 01604 void 01605 BeatReferee::handleAgentsTansition(mrs_natural agent) 01606 { 01607 /*if(agent == 8 && timeElapsed_ >= 900) 01608 { 01609 cout << timeElapsed_ << "-> FLAG- "; 01610 for(int j = 0; j < considerFatherTransitionBeat_.getCols(); j++) 01611 cout << j << ": " << considerFatherTransitionBeat_(agent, j) << "; "; 01612 01613 cout << endl; 01614 }*/ 01615 01616 mrs_natural fatherAgent, sonAgent; 01617 if(considerAgentTransitionBeat_(agent) == -1) //unconsider first beat from agent 01618 { 01619 sonAgent = agent; 01620 01621 //if(sonAgent == 19 && timeElapsed_ >= 2461) 01622 //if(timeElapsed_ == 3946) 01623 //{ 01624 // cout << timeElapsed_ << ": TRANS_REM from " << sonAgent << "-> BEAT " << (beatCounter_(sonAgent)) << ": " 01625 // << agentsHistory_(sonAgent, (mrs_natural) (beatCounter_(sonAgent))) << "(" 01626 // << (((agentsHistory_(sonAgent, (mrs_natural) (beatCounter_(sonAgent))) * hopSize_) - frames2SecsAdjustment_) / srcFs_) 01627 // << ") by: " << agentsFamilyHist_(sonAgent, (mrs_natural) (beatCounter_(sonAgent))) << endl; 01628 // cout << timeElapsed_ << ": BEAT COUNT " << sonAgent << " = " << beatCounter_(sonAgent) << endl; 01629 //} 01630 01631 agentsHistory_(sonAgent, (mrs_natural) beatCounter_(sonAgent)) = -1; 01632 agentsFamilyHist_(agent, (mrs_natural) beatCounter_(sonAgent)) = -1; 01633 01634 beatCounter_(sonAgent)--; //decrement one count because it is incremented just after 01635 01636 considerAgentTransitionBeat_(agent) = NA; //clean flag 01637 } 01638 01639 fatherAgent = agent; 01640 //process all array to account for every sons' request 01641 for(int j = 0; j < considerFatherTransitionBeat_.getCols(); j++) 01642 { 01643 if(considerFatherTransitionBeat_(agent, j) >= 0) //consider all valid positions in father's flag array 01644 { 01645 sonAgent = (mrs_natural) considerFatherTransitionBeat_(agent, j); 01646 01647 agentsHistory_(sonAgent, (mrs_natural) beatCounter_(sonAgent)) 01648 = agentsHistory_(fatherAgent, (mrs_natural) beatCounter_(fatherAgent)); 01649 agentsFamilyHist_(sonAgent, (mrs_natural) beatCounter_(sonAgent)) 01650 = agentsFamilyHist_(fatherAgent, (mrs_natural) beatCounter_(fatherAgent)); 01651 01652 //if(sonAgent == 27 && fatherAgent == 8) 01653 //if(timeElapsed_ == 3946) 01654 //{ 01655 // cout << timeElapsed_ << ": TRANS_ADD to "<< sonAgent << "-> BEAT " << (beatCounter_(sonAgent)) << ": " 01656 // << agentsHistory_(sonAgent, (mrs_natural) (beatCounter_(sonAgent))) << "(" 01657 // << (((agentsHistory_(sonAgent, (mrs_natural) (beatCounter_(sonAgent))) * hopSize_) - frames2SecsAdjustment_) / srcFs_) 01658 // << ") by: " << agentsFamilyHist_(sonAgent, (mrs_natural) (beatCounter_(sonAgent))) << endl; 01659 // cout << timeElapsed_ << ": BEAT COUNT " << sonAgent << " = " << beatCounter_(sonAgent)+1 << endl; 01660 //} 01661 01662 beatCounter_(sonAgent)++; 01663 01664 considerFatherTransitionBeat_(agent, j) = NA; //clean flag 01665 } 01666 } 01667 } 01668 //clean agent's transition flag and its call in its father's flag 01669 void 01670 BeatReferee::cleanAgentAndFatherTransitionFlags(mrs_natural agentIndex) 01671 { 01672 //if(agentIndex == 17 && timeElapsed_ == 1416) 01673 // cout << "Agent: " << agentIndex << "; agentFlag: " << considerAgentTransitionBeat_(agentIndex) << endl; 01674 01675 if(considerAgentTransitionBeat_(agentIndex) >= 0) //if it already has an assigned father whom requested its flag 01676 { 01677 mrs_natural fatherRequested = (mrs_natural) considerAgentTransitionBeat_(agentIndex); 01678 01679 //if(agentIndex == 17 && timeElapsed_ == 1416) 01680 // cout << timeElapsed_ << ": Agent: " << agentIndex << " CHECKING fatherAgentFLAG: " << fatherRequested << endl; 01681 01682 //look in its father array for cleaning 01683 for(int j = 0; j < considerFatherTransitionBeat_.getCols(); j++) 01684 { 01685 if(considerFatherTransitionBeat_(fatherRequested, j) == agentIndex) 01686 { 01687 //if(timeElapsed_ == 3946) 01688 //if(agentIndex == 17 && timeElapsed_ == 1416) 01689 // cout << timeElapsed_ << ": CLEANED agent " << agentIndex << "; from FATHER: " << fatherRequested << endl; 01690 01691 considerFatherTransitionBeat_(fatherRequested, j) = NA; 01692 break; 01693 } 01694 } 01695 } 01696 considerAgentTransitionBeat_(agentIndex) = NA; 01697 } 01698 01699 01700 //Generic routine for creating new agents given their hypotheses: 01701 mrs_natural 01702 BeatReferee::createNewAgent(mrs_natural newPeriod, mrs_natural firstBeat, 01703 mrs_real newScore, mrs_real beatCount, mrs_natural fatherAgent) 01704 { 01705 //if father agent died in the same timestep as it requests a son creation then this request is unconsidered 01706 if(fatherAgent >= 0 && mutedAgentsTmp_(fatherAgent) == 1.0) 01707 { 01708 if(logFile_) 01709 debugAddEvent("CREATE_REF_KF", -1, newPeriod, firstBeat, newScore, bestScore_, fatherAgent); 01710 return -1; 01711 } 01712 //or if the score of the new agent is obsolete the newAgent request is also unconsidered 01713 else if (timeElapsed_ > timeBeforeKilling_ && newScore < bestScore_ && fabs(bestScore_-newScore) > 0.1 01714 && fabs(bestScore_ - newScore) > fabs(bestScore_ * obsoleteFactor_)) 01715 { 01716 if(logFile_) 01717 debugAddEvent("CREATE_REF_SCORE", -1, newPeriod, firstBeat, newScore, bestScore_, fatherAgent); 01718 return -1; 01719 } 01720 01721 //if(timeElapsed_ == 876) 01722 // cout << " CREATED: Agent at: " << timeElapsed_ << "; Pe: " << newPeriod << "; Ph: " << firstBeat << endl; 01723 01724 //Grant available space in the pool, by removing the worst agent, if needed 01725 grantPoolSpace(fatherAgent, newScore); 01726 01727 mrs_natural returnCreatedAgent = -1; 01728 for(int a = 0; a < mutedAgentsTmp_.getSize(); a++) 01729 { 01730 //Look for first disabled agent (in temporary vector): 01731 if(mutedAgentsTmp_(a)) 01732 { 01733 //Activate new agent 01734 //mutedAgents_(a) = 0.0; 01735 //updControl(ctrl_mutedAgents_, mutedAgents_); 01736 01737 mutedAgentsTmp_(a) = 0.0; 01738 updControl(ctrl_mutedAgents_, mutedAgentsTmp_); 01739 01740 //Diplay Created BeatAgent: 01741 //if(timeElapsed_ == 876) 01742 // cout << " CREATED: Agent " << a << " at: " << timeElapsed_ << "; Pe: " << newPeriod << "; Ph: " << firstBeat << endl; 01743 01744 //Defines new hypothesis for this agent: 01745 setNewHypothesis(a, newPeriod, firstBeat); 01746 01747 //Update score: 01748 score_(a) = newScore; 01749 01750 //if(timeElapsed_ == 3100) 01751 // cout << "t: " << timeElapsed_ << "; CREATED AGENT: " << a << "; beatCountBef: " << beatCounter_(a) << "; bc4Bef: " << beatCounter_(4); 01752 01753 //beatCounter of this agent equals beatCounter of its father 01754 beatCounter_(a) = beatCount; 01755 01756 //if(timeElapsed_ > 3707) 01757 // cout << "; beatCountAfter: " << beatCounter_(a) << "; bc4After: " << beatCounter_(4) << endl; 01758 01759 //Update Agents' Periods and Phases (for equality checking) 01760 lastPeriods_(a) = newPeriod; //(Periods in frames) 01761 //lastPhases_(a) = firstBeat; //(Phases in frames 01762 lastPhases_(a) = (firstBeat - newPeriod); //(assuem last phase equal to first beat - agentPeriod) 01763 01764 initPeriod_(a) = newPeriod; //save agent's initial IBI 01765 missedBeatsCount_(a) = 0.0; //reset missed beats counter 01766 01767 //statsPeriods_(a, timeElapsed_) = newPeriod; 01768 //statsPhases_(a, timeElapsed_) = firstBeat; 01769 01770 //statsAgentsLifeCycle_(a, timeElapsed_) = 1.0; 01771 01772 //force timing update when agent is created 01773 //(don't know why when a new agent is created its time, in agentControl, keeps 01774 //the time of the previous tick) 01775 agentControl_(a, 3) = timeElapsed_+1; 01776 updControl(ctrl_agentControl_, agentControl_); 01777 01778 returnCreatedAgent = a; 01779 01780 agentsJustCreated_(a) = 1.0; 01781 01782 if(logFile_) 01783 debugAddEvent("CREATE", a, newPeriod, firstBeat, score_(a), bestScore_, fatherAgent); 01784 01785 //in nonCausalAnalysis keep agents history till the end of the analysis 01786 if(nonCausal_) 01787 { 01788 //if(timeElapsed_ == 1382 || timeElapsed_ == 1441) 01789 // cout << "============t: " << timeElapsed_ << " - created new agent: " << a << " from: " << fatherAgent << endl; 01790 01791 if(fatherAgent >= 0) 01792 { 01793 mrs_natural lastFlagInd = 0; 01794 01795 //if(timeElapsed_ == 3946) 01796 //if(a == 9 && fatherAgent == 8 && timeElapsed_ == 3946) 01797 // cout << "firstBeat: " << firstBeat << "; fatherAgent: " << fatherAgent << "; agent: " 01798 // << a << "; lastFPh: " << lastPhases_(fatherAgent) << "; FPer: " << lastPeriods_(fatherAgent) 01799 // << "; transFlag: " << considerFatherTransitionBeat_(a, 0) << "; agentTrans: " 01800 // << considerAgentTransitionBeat_(a) << endl; 01801 01802 //clean agent's transition flag and its call in its father's flag 01803 //(just to be sure since it could be updated within the same frame) 01804 cleanAgentAndFatherTransitionFlags(a); 01805 01806 //check beat at transition between father and son: 01807 //if(((firstBeat - lastPhases_(fatherAgent)) / lastPeriods_(fatherAgent)) < -1.6) 01808 //if((abs(firstBeat - lastPhases_(fatherAgent)) / lastPeriods_(fatherAgent)) < 0.6) 01809 if((abs(firstBeat - lastPhases_(fatherAgent)) / lastPeriods_(fatherAgent)) < beatTransitionTol_) 01810 { 01811 //last beat from father and first beat from son are too close (in comparison to last father's ibi) 01812 //unconsider less than 60% difference => unconsider first son's beat 01813 //(set considerTransitionBeatFlag to -1) 01814 considerAgentTransitionBeat_(a) = -1; 01815 01816 if(logFile_) 01817 debugAddEvent("TRANSITION_REM", a, (mrs_natural) lastPeriods_(a), 01818 (mrs_natural) (firstBeat), score_(a), bestScore_, fatherAgent); 01819 01820 01821 //cout << timeElapsed_ << ": REQUEST UNCONSIDER: " << a << "; firstBeat: " << firstBeat << "; lastPhFather: " << lastPhases_(fatherAgent) 01822 // << " (" << (abs(firstBeat - lastPhases_(fatherAgent))) << "); lastPerFather: " << lastPeriods_(fatherAgent) 01823 // << "(" << (0.7 * lastPeriods_(fatherAgent)) << "); Flag: " << considerAgentTransitionBeat_(a) << endl; 01824 } 01825 //last beat from father and first beat from son are too far (in comparison to last father's ibi) 01826 //consider more than 60% difference => consider next father's beat as first son's beat 01827 //(set considerTransitionBeatFlag to agent's index onto his father's index) 01828 //if(((firstBeat - lastPhases_(fatherAgent)) / lastPeriods_(fatherAgent)) > 1.6) 01829 else if((abs(firstBeat - lastPhases_(fatherAgent)) / lastPeriods_(fatherAgent)) > (1+beatTransitionTol_)) 01830 { 01831 //considerFatherTransitionBeat_(fatherAgent) = a; 01832 //retrieve first available position in the flag 01833 lastFlagInd = 0; 01834 for(int j = 0; j < considerFatherTransitionBeat_.getCols(); j++) 01835 { 01836 if(considerFatherTransitionBeat_(fatherAgent, j) < 0) 01837 { 01838 //if(a == 27 && fatherAgent == 8 && timeElapsed_ == 933) 01839 // cout << timeElapsed_ << ": FREE FATHER " << fatherAgent << " w/ Flag @ ind: " << j << endl; 01840 01841 lastFlagInd = j; 01842 break; 01843 } 01844 } 01845 considerFatherTransitionBeat_(fatherAgent, lastFlagInd) = a; 01846 01847 considerAgentTransitionBeat_(a) = fatherAgent; //register son's call 01848 01849 if(logFile_) 01850 debugAddEvent("TRANSITION_ADD", a, (mrs_natural) lastPeriods_(a), 01851 (mrs_natural) (firstBeat+lastPeriods_(a)), score_(a), bestScore_, fatherAgent); 01852 01853 //if(a == 27 && fatherAgent == 8 && timeElapsed_ == 933) 01854 // cout << timeElapsed_ << ": REQUEST RECONSIDER: " << a << " from Father: " << fatherAgent << "; firstBeat: " << firstBeat 01855 // << "; lastPhFather: " << lastPhases_(fatherAgent) << " (" << (abs(firstBeat - lastPhases_(fatherAgent))) 01856 // << "); lastPerFather: " << lastPeriods_(fatherAgent) << "(" << (1.9 * lastPeriods_(fatherAgent)) 01857 // << "); FatherFlag: " << considerFatherTransitionBeat_(fatherAgent, lastFlagInd) << "; sonFlag: " 01858 // << considerAgentTransitionBeat_(a) << endl; 01859 } 01860 01861 //pass history (beats and family) of father agent to created one 01862 for(int i = 0; i < beatCount; i++) 01863 { 01864 agentsHistory_(a, i) = agentsHistory_(fatherAgent, i); //beats history 01865 agentsFamilyHist_(a, i) = agentsFamilyHist_(fatherAgent, i); 01866 01867 //if((a == 1 && fatherAgent == 2 && timeElapsed_ == 1382) || (a == 0 && fatherAgent == 1 && timeElapsed_ == 1441)) 01868 //if(a == 27 && fatherAgent == 8 && timeElapsed_ == 933) 01869 //if(timeElapsed_ == 3946) 01870 //{ 01871 // cout << timeElapsed_ << ": Agent " << a << " created by " << fatherAgent << "-> BEAT " << i << ": " 01872 // << (agentsHistory_(a, i)) << " by: " << agentsFamilyHist_(a, i) << endl; 01873 // cout << "t: " << timeElapsed_ << "-BEAT " << i << ": " << (((agentsHistory_(a, i) * hopSize_) - hopSize_/2) / srcFs_) 01874 // << " by: " << agentsFamilyHist_(a, i) << endl; 01875 // cout << "Diff btw " << a << " and Father " << fatherAgent << ": " << (abs(firstBeat - lastPhases_(fatherAgent)) / lastPeriods_(fatherAgent)) << endl; 01876 //} 01877 } 01878 01879 //if((a == 1 && fatherAgent == 2 && timeElapsed_ == 1382) || (a == 0 && fatherAgent == 1 && timeElapsed_ == 1441)) 01880 //if(timeElapsed_ == 3946) 01881 //if(a == 9 && fatherAgent == 8 && timeElapsed_ == 3946) 01882 // cout << "2-BEAT " << beatCount << ": " << (((agentsHistory_(a, beatCount) * hopSize_) - hopSize_/2) / srcFs_) 01883 // << " by: " << agentsFamilyHist_(a, beatCount) << "; TRANSFLAG: " << considerFatherTransitionBeat_(a, 0) 01884 // << "; fatherTRANSFLAG: " << considerFatherTransitionBeat_(fatherAgent, lastFlagInd) << "; AgentFlag: " 01885 // << considerAgentTransitionBeat_(a) << endl; 01886 } 01887 } 01888 01889 break; 01890 } 01891 } 01892 01893 return returnCreatedAgent; 01894 } 01895 01896 //Routine for killing all agents -> reseting the system 01897 void 01898 BeatReferee::resetSystem(mrs_natural saveAgent) 01899 { 01900 //kill all agents 01901 for(int a = 0; a < mutedAgentsTmp_.getSize(); a++) 01902 { 01903 if(a != saveAgent) killAgent(a, "RESET"); 01904 } 01905 01906 //reset best score 01907 bestScore_ = NA; //To allow initial negative scores 01908 01909 if(logFile_) 01910 debugAddEvent("RESET_SYSTEM", -1, -1, -1, -1, bestScore_, saveAgent); 01911 } 01912 01913 //Generic routine for killing agents: 01914 void 01915 BeatReferee::killAgent(mrs_natural agentIndex, mrs_string motif, mrs_natural callAgent) 01916 { 01917 //Never kill a best agent or a best before trigger agent (for enforcing security) -> a best agent must live until being replaced by a better one 01918 //&& verify that agent effectively exists (for safechecking) 01919 if(strcmp(motif.c_str(), "RESET") == 0 || (agentIndex != bestAgentBeforeTrigger_ && agentIndex != bestAgentIndex_ && !mutedAgentsTmp_(agentIndex))) 01920 { 01921 //Diplay killed BeatAgent: 01922 //if(timeElapsed_ == 1416) 01923 // cout << "KILLED AGENT " << agentIndex << " (" << motif << ") With Score: " << score_(agentIndex) << " / " << bestScore_ << endl; 01924 01925 if(logFile_) 01926 { 01927 ostringstream killMotif; 01928 killMotif << "KILL_" << motif; 01929 debugAddEvent(killMotif.str(), agentIndex, (mrs_natural) lastPeriods_(agentIndex), 01930 (mrs_natural) lastPhases_(agentIndex), score_(agentIndex), bestScore_, callAgent); 01931 } 01932 01933 //mutedAgents_(agentIndex) = 1.0; 01934 //updControl(ctrl_mutedAgents_, mutedAgents_); 01935 mutedAgentsTmp_(agentIndex) = 1.0; 01936 updControl(ctrl_mutedAgents_, mutedAgentsTmp_); 01937 01938 score_(agentIndex) = NA; 01939 beatCounter_(agentIndex) = 0.0; 01940 01941 //statsAgentsLifeCycle_(agentIndex, timeElapsed_) = -1; 01942 lastPeriods_(agentIndex) = 0.0; //(Periods in frames) 01943 lastPhases_(agentIndex) = 0.0; //(Phases in frames) 01944 01945 missedBeatsCount_(agentIndex) = 0.0; //reset missed beats counter 01946 01947 //erase transition flags from this agent -> to be sure it is no longer considered 01948 cleanAgentAndFatherTransitionFlags(agentIndex); 01949 for (int j = 0; j < considerFatherTransitionBeat_.getCols(); j++) 01950 considerFatherTransitionBeat_(agentIndex, j) = NA; 01951 01952 //if(timeElapsed_ == 1416) 01953 // cout << "Killed Agent " << agentIndex << "; muted: " << mutedAgentsTmp_(agentIndex) << "; sc: " << score_(agentIndex) 01954 // << "; bc: " << beatCounter_(agentIndex) << "; lper: " << lastPeriods_(agentIndex) << "; lph: " << lastPhases_(agentIndex) 01955 // << "; mbc: " << missedBeatsCount_(agentIndex) << endl; 01956 } 01957 else if(logFile_) 01958 { 01959 ostringstream killMotif; 01960 killMotif << "BESTKILL_" << motif; 01961 debugAddEvent(killMotif.str(), agentIndex, (mrs_natural) lastPeriods_(agentIndex), 01962 (mrs_natural) lastPhases_(agentIndex), score_(agentIndex), bestScore_, callAgent); 01963 } 01964 } 01965 01966 void 01967 BeatReferee::calcAbsoluteBestScore() 01968 { 01969 mrs_natural firstAliveAgent = getFirstAliveAgent(); 01970 mrs_real bestLocalScore = score_(firstAliveAgent); 01971 mrs_natural bestLocalAgent = firstAliveAgent; 01972 for (mrs_natural o = firstAliveAgent+1; o < nrAgents_; o++) 01973 { 01974 //Only consider alive agents: 01975 if(!mutedAgentsTmp_(o)) 01976 { 01977 if(score_(o) > bestLocalScore) 01978 { 01979 bestLocalScore = score_(o); 01980 bestLocalAgent = o; 01981 } 01982 } 01983 } 01984 01985 if((bestScore_ >= 0 && bestLocalScore > bestFactor_ * bestScore_) || 01986 (bestScore_ < 0 && bestLocalScore > bestScore_ / bestFactor_)) 01987 { 01988 if(logFile_) 01989 debugAddEvent("BEST", bestLocalAgent, (mrs_natural) lastPeriods_(bestLocalAgent), 01990 (mrs_natural) lastPhases_(bestLocalAgent), bestLocalScore, bestScore_); 01991 01992 bestScore_ = bestLocalScore; 01993 bestAgentIndex_ = bestLocalAgent; 01994 bestFinalAgent_ = bestAgentIndex_; 01995 } 01996 //cout << "Absolute Best Agent: " << bestAgentIndex_ << " BestScore: " << bestScore_ << endl; 01997 } 01998 01999 void 02000 BeatReferee::debugCreateFile() 02001 { 02002 mrs_string beatTrackingMode, triggerGTTol; 02003 if(nonCausal_) 02004 beatTrackingMode = "non-causal"; 02005 else beatTrackingMode = "causal"; 02006 if(strcmp(inductionMode_.c_str(), "groundtruth") == 0) 02007 { 02008 stringstream tmp; 02009 tmp << triggerGtTolerance_; 02010 triggerGTTol = tmp.str(); 02011 } 02012 else triggerGTTol = "NA"; 02013 02014 fstream outStream; 02015 outStream.open(logFileName_.c_str(), ios::out|ios::trunc); 02016 outStream << "Beat-Tracking: " << beatTrackingMode << "; Induction-Mode: " << inductionMode_ << "; TriggerGtTol: " 02017 << triggerGTTol << "; Induction: " << ctrl_gtInductionMode_->to<mrs_string>() << "; Induction-Time: " << inductionTime_ << "<<" 02018 << (((inductionTime_ * hopSize_) - frames2SecsAdjustment_) / srcFs_) << ">>" << endl; 02019 cerr << "Log File in " << logFileUnits_ << ": " << logFileName_ << endl; 02020 outStream.close(); 02021 } 02022 02023 void 02024 BeatReferee::debugAddEvent(mrs_string ibtEvent, mrs_natural agentIndex, 02025 mrs_natural period, mrs_natural lastBeat, mrs_real score, mrs_real bestScore, mrs_natural callAgent) 02026 { 02027 //event is appended in the end of the file 02028 fstream outStream; 02029 outStream.open(logFileName_.c_str(), ios::out|ios::app); 02030 02031 if(strcmp(logFileUnits_.c_str(), "frames") == 0) //timesteps in frames 02032 { 02033 outStream << ibtEvent << "|" << timeElapsed_ << "|" << agentIndex << "|" << period << "|" << lastBeat 02034 << "|" << score << "|" << bestScore << "|" << callAgent << endl; 02035 } 02036 else if(strcmp(logFileUnits_.c_str(), "seconds") == 0) //timesteps in seconds 02037 outStream << ibtEvent << "|" << (((timeElapsed_ * hopSize_) - frames2SecsAdjustment_) / srcFs_) << "|" << agentIndex << "|" 02038 << period << "|" << (((lastBeat * hopSize_) - frames2SecsAdjustment_) / srcFs_) << "|" << score << "|" 02039 << bestScore << "|" << callAgent << endl; 02040 else if(strcmp(logFileUnits_.c_str(), "frames+seconds") == 0) //timesteps in frames + seconds 02041 outStream << ibtEvent << "|" << timeElapsed_ << "<<" << (((timeElapsed_ * hopSize_) - frames2SecsAdjustment_) / srcFs_) << ">>|" 02042 << agentIndex << "|" << period << "|" << lastBeat << "<<" << (((lastBeat * hopSize_) - frames2SecsAdjustment_) / srcFs_) 02043 << ">>|" << score << "|" << bestScore << "|" << callAgent << endl; 02044 02045 //cout << ibtEvent << "|" << timeElapsed_ << "|" << agentIndex << "|" << period << "|" << lastBeat 02046 // << "|" << score << "|" << bestScore << "|" << callAgent << endl; 02047 02048 outStream.close(); 02049 } 02050 02051 void 02052 BeatReferee::debugAddMsg(mrs_string ibtMsg) 02053 { 02054 fstream outStream; 02055 outStream.open(logFileName_.c_str(), ios::out|ios::app); 02056 02057 if(strcmp(logFileUnits_.c_str(), "frames") == 0) //timesteps in frames 02058 outStream << ibtMsg << "|" << timeElapsed_ << endl; 02059 else if(strcmp(logFileUnits_.c_str(), "seconds") == 0) //timesteps in seconds 02060 outStream << ibtMsg << "|" << (((timeElapsed_ * hopSize_) - frames2SecsAdjustment_) / srcFs_) << endl; 02061 else if(strcmp(logFileUnits_.c_str(), "frames+seconds") == 0) //timesteps in frames + seconds 02062 outStream << ibtMsg << "|" << timeElapsed_ << "<<" << (((timeElapsed_ * hopSize_) - frames2SecsAdjustment_) / srcFs_) << ">>" << endl; 02063 02064 outStream.close(); 02065 02066 } 02067 02068 void //system intialization (at absolute t=0) 02069 BeatReferee::initialization() 02070 { 02071 agentsHistory_.create(nrAgents_, maxNrBeats_); 02072 agentsFamilyHist_.create(nrAgents_, maxNrBeats_); 02073 generationCount_.create(nrAgents_); //1index for each agent 02074 score_.create(nrAgents_); //1index for each agent 02075 lastPeriods_.create(nrAgents_); //1index for each agent 02076 lastPhases_.create(nrAgents_); //1index for each agent 02077 mutedAgents_.create(nrAgents_);//1index for each agent 02078 mutedAgentsTmp_.create(nrAgents_);//1index for each agent 02079 beatCounter_.create(nrAgents_);//1index for each agent 02080 initPeriod_.create(nrAgents_);//1index for each agent 02081 missedBeatsCount_.create(nrAgents_);//1index for each agent 02082 considerAgentTransitionBeat_.create(nrAgents_);//1index for each agent 02083 considerFatherTransitionBeat_.create(nrAgents_,10);//10 indexes (would be enough) for each agent 02084 02085 //Agent control indexed matrix 02086 //Each line(observation) accounts for an agent 02087 //[New/Update_Flag|Period|Phase|Timming] 02088 agentControl_.create(nrAgents_, 4); 02089 updControl(ctrl_agentControl_, agentControl_); 02090 02091 //intialize mutedAgents vectors 02092 for(int i = 0; i < nrAgents_; i++) 02093 { 02094 mutedAgents_(0, i) = 1.0; //initially all agents are muted 02095 mutedAgentsTmp_(0, i) = 1.0; //initially all agents are muted 02096 02097 //by default consider every beat at transition bewteen father and son (for non-causal) 02098 for (int j = 0; j < considerFatherTransitionBeat_.getCols(); j++) 02099 considerFatherTransitionBeat_(i, j) = NA; 02100 02101 considerAgentTransitionBeat_(i) = NA; 02102 } 02103 updControl(ctrl_mutedAgents_, mutedAgents_); //initially deactivate all agents 02104 02105 inductionEnabler_ = ctrl_inductionEnabler_->to<mrs_realvec>(); 02106 //in the new vesion of IBT onsets are no more considered in the induction process (so deactivate this!!) 02107 //(deactivated instead of removed for not changing the overall network structure) 02108 inductionEnabler_(1, 0) = 1.0; //diable = muted 02109 02110 //initially deactivate induction's period estimation (ACF) -> computer expensive 02111 inductionEnabler_(0, 0) = 1.0; //diable = muted 02112 updControl(ctrl_inductionEnabler_, inductionEnabler_); 02113 02114 if(!strcmp(ctrl_logFile_->to<mrs_string>().c_str(), "-1") == 0 && 02115 !strcmp(ctrl_logFile_->to<mrs_string>().c_str(), "trigger") == 0) 02116 { 02117 logFileName_ = ctrl_logFileName_->to<mrs_string>(); 02118 logFileUnits_ = ctrl_logFile_->to<mrs_string>(); 02119 logFile_ = true; 02120 debugCreateFile(); 02121 } 02122 02123 //if induction in "givetransitions" mode -> load groundtruth transition times 02124 if(strcmp(inductionMode_.c_str(), "givetransitions") == 0) 02125 loadTriggerTimes(triggerTimesFile_); 02126 else if(strcmp(inductionMode_.c_str(), "supervised") == 0) 02127 { 02128 supervisedBestScores_.resize(1); //minimum size 02129 supervisedBestScoresMeans_.resize(1); //minimum size 02130 lastTriggerInductionTime_ = 0; 02131 lastBestScoreMeanDiff_ = supervisedTriggerThres_; 02132 } 02133 02134 triggerInductionTime_ = inductionTime_; //initially assume first induction time 02135 } 02136 02137 void 02138 BeatReferee::myProcess(realvec& in, realvec& out) 02139 { 02140 //run initialization at the very begining of the analysis 02141 if(startSystem_) 02142 { 02143 initialization(); 02144 startSystem_ = false; 02145 } 02146 02147 //if(timeElapsed_ == 3100) 02148 // cout << "BR: " << timeElapsed_ << "; beatTransTol: " << beatTransitionTol_ << endl; 02149 02150 //cout << "BR: " << timeElapsed_ << "; triggerInd: " << triggerInduction_ << "; backtrace: " << backtrace_ 02151 // << "; maxPer: " << maxPeriod_ << "; minPer: " << minPeriod_ << endl; 02152 02153 //while no best beat detected => outputs 0 (no beat) 02154 out.setval(0.0); 02155 ctrl_beatDetected_->setValue(0.0); 02156 02157 agentControl_ = ctrl_agentControl_->to<mrs_realvec>(); 02158 //always updates every agents' timming to equalize referee's (+1 for considering next time frame) 02159 for(mrs_natural i = 0; i < agentControl_.getRows(); i++) 02160 { 02161 agentControl_(i, 3) = timeElapsed_+1; 02162 updControl(ctrl_agentControl_, agentControl_); 02163 agentsJustCreated_(i) = 0.0; //reset at all frames 02164 } 02165 //also pass timer value to the other MarSystems (+1 for considering next time frame) 02166 ctrl_tickCount_->setValue(timeElapsed_+1); 02167 02168 //cout << "BRef: " << timeElapsed_ << "; Ind: " << inductionTime_ << "; Sc: " << bestScore_ << "; BA: " << bestAgentIndex_ << endl; 02169 02170 //realvec with the enable flag of all the BeatAgents in the pool 02171 //(0 -> agent active; 1 -> agent desactivated) 02172 mutedAgents_ = ctrl_mutedAgents_->to<mrs_realvec>(); 02173 //created tmp agents vector for just updating mutedAgents_ vector in the next tick 02174 mutedAgentsTmp_ = ctrl_mutedAgents_->to<mrs_realvec>(); 02175 02176 /* 02177 if(timeElapsed_ >= inductionTime_-1) 02178 { 02179 //Display Input from BeatAgents: 02180 cout << "INPUT (" << timeElapsed_ << "): "; 02181 for(mrs_natural a = 0; a < nrAgents_; a++) 02182 //cout << "\n" << a << "-> " << in(a, 0) << " | " << in(a, 1) << " | " << in(a, 2) << " | " << in(a, 3); 02183 cout << "\n" << a << "-> " << lastPeriods_(a) << " | " << lastPhases_(a) << " | " << score_(a) << " | " << bestScore_; 02184 cout << endl; 02185 } 02186 */ 02187 02188 //Start beat-tracking after 1st induction: 02189 if(startTracking_) 02190 { 02191 //INPUT: [Beat/Eval/None|Period|PrevBeat|Inner/Outter|Error|Score] -> inSamples_ = 6 02192 mrs_real agentFlag; 02193 mrs_natural agentPeriod; 02194 mrs_natural agentPrevBeat; 02195 mrs_real agentTolerance; 02196 mrs_natural agentError; 02197 mrs_real agentDScore; 02198 02199 //Process all the agent pool for score, tempo and phase updates: 02200 for (mrs_natural o = 0; o < nrAgents_; o++) 02201 { 02202 agentFlag = in(o, 0); 02203 02204 //statsPeriods_(o, timeElapsed_) = lastPeriods_(o); 02205 //statsPhases_(o, timeElapsed_) = lastPhases_(o); 02206 //statsAgentsScore_(o, timeElapsed_) = score_(o); 02207 //statsMuted_(o, timeElapsed_) = mutedAgents_(o); 02208 02209 //Only consider alive agents that send new evaluation: 02210 //(Remind that each ouputed beat by the agents is only 02211 //evaluated at the end of its beat position + outterWindow tolerance) 02212 if(!mutedAgents_(o) && !mutedAgentsTmp_(o) && agentFlag == EVAL) 02213 { 02214 agentDScore = in(o, 5); 02215 agentPeriod = (mrs_natural) in(o, 1); 02216 agentPrevBeat = (mrs_natural) in(o, 2); 02217 02218 //Update Agents' Periods and Phases (for equality checking) 02219 lastPeriods_(o) = agentPeriod; //(Periods in frames) 02220 lastPhases_(o) = agentPrevBeat; //(Phases in frames) 02221 02222 //statsPeriods_(o, timeElapsed_) = agentPeriod; 02223 //statsPhases_(o, timeElapsed_) = agentPrevBeat; 02224 02225 //Update Agents' Score 02226 score_(o) += agentDScore; 02227 02228 //if(o == bestAgentIndex_) 02229 // cout << "Agent" << o << "-dScore:" << agentDScore << "; agentScore:" << score_(o) 02230 // << "(" << bestScore_ << ")" << endl; 02231 02232 //If the bestAgent drops or increases its score the BestScore has to drop correspondingly 02233 //if((score_(bestAgentIndex_) < bestScore_) || (score_(bestAgentIndex_) > bestScore_)) 02234 if(score_(bestAgentIndex_) != bestScore_) 02235 { 02236 //cout << "t:" << timeElapsed_ << "; Updating bestScore: " << "OLD: " << bestScore_ 02237 // << " from Agent" << bestAgentIndex_ << "-NEW: " << score_(bestAgentIndex_) << endl; 02238 bestScore_ = score_(bestAgentIndex_); 02239 //calcAbsoluteBestScore(); 02240 } 02241 //Kill agent if it is overly erroneous (many consecutive beats found outside the predicted tolerance inner window) 02242 if(missedBeatsCount_(o) >= lostFactor_) 02243 { 02244 killAgent(o, "LOST"); 02245 } 02246 //Kill Agent if its score is bellow minimum (wait 5seconds before taking it into consideration) 02247 else if(timeElapsed_ > timeBeforeKilling_ && score_(o) < bestScore_ && fabs(bestScore_-score_(o)) > 0.1 02248 && fabs(bestScore_ - score_(o)) > fabs(bestScore_ * obsoleteFactor_)) 02249 { 02250 //cout << "Agent " << o << " Killed: Score below minimum (" << score_(o) << "\\" << bestScore_ << ")" << endl; 02251 killAgent(o, "OBS"); 02252 } 02253 else //Checks if there are equal agents to current EVALuated one 02254 checkAndKillEqualAgents(o); 02255 02256 //statsAgentsScore_(o, timeElapsed_) = score_(o); 02257 02258 //Display Scores from BeatAgents: 02259 /* cout << "SCORES(" << timeElapsed_ << ") (reqBy:" << o << "): " << endl; 02260 for(mrs_natural a = 0; a < nrAgents_; a++) 02261 cout << a << "-> " << score_(a) << " "; 02262 cout << endl; 02263 */ 02264 02265 02266 } 02267 } 02268 02269 //Process all the agent pool for testing best beat and consider 02270 //the generation of new beats or the killing of existent ones 02271 for (mrs_natural o = 0; o < nrAgents_; o++) 02272 { 02273 //Only consider alive agents that send new evaluation: 02274 //(unconsider agents created in the current frame) 02275 if(!mutedAgents_(o) && !mutedAgentsTmp_(o) && !agentsJustCreated_(o)) 02276 { 02277 agentFlag = in(o, 0); 02278 02279 if(agentFlag == EVAL) 02280 { 02281 agentPeriod = (mrs_natural) in(o, 1); 02282 agentPrevBeat = (mrs_natural) in(o, 2); 02283 agentTolerance = in(o, 3); 02284 agentError = (mrs_natural) in(o, 4); 02285 agentDScore = in(o, 5); 02286 02287 //if(o == 21) 02288 // cout << "T: " << timeElapsed_ << " EVAL - Agent: " << o << "; ERROR: " << agentError << endl; 02289 02290 //If a beat of an agent is inside its Inner tolerance but it has an error: 02291 //Update agent phase and period hypotheses: 02292 if(agentTolerance == INNER) 02293 { 02294 if(logFile_) 02295 debugAddEvent("UPDATE", o, agentPeriod, agentPrevBeat, score_(o), bestScore_, o); 02296 02297 missedBeatsCount_(o) = 0.0; //reset (consecutive) missed beats counter for this agent 02298 02299 if(abs(agentError) > 0) 02300 { 02301 updateAgentHypothesis(o, agentPeriod, agentPrevBeat, agentError); 02302 } 02303 } 02304 02305 //If a beat of an agent is detected outside its Inner tolerance window: 02306 //Is created another agent that keeps this agent hypothesis, and updates its phase 02307 //and period to account for the given error: 02308 if(agentTolerance == OUTTER) 02309 { 02310 if(logFile_) 02311 debugAddEvent("UPD_OUTTER", o, agentPeriod, agentPrevBeat, score_(o), bestScore_, o); 02312 02313 //CREATE NEW AGENT WITH THIS NEW HYPOTHESIS KEEPING THE SCORE OF o-delta: 02314 //(the agent that generates a new one keeps its original hypothesis); 02315 //New agent must look for a new beat on the next (updated) period 02316 createChildren(o, agentPeriod, agentPrevBeat, agentError, score_(o), beatCounter_(o)); 02317 //statsAgentsLifeCycle_(o, timeElapsed_) = 2; 02318 02319 missedBeatsCount_(o)++; //increment missed beats counter for this agent 02320 } 02321 } 02322 02323 if(agentFlag == BEAT) 02324 { 02325 //in nonCausal analysis keep agents' beat history 02326 if(nonCausal_) 02327 { 02328 agentsHistory_(o, (mrs_natural) beatCounter_(o)) = timeElapsed_; //save beat-time 02329 agentsFamilyHist_(o, (mrs_natural) beatCounter_(o)) = o; //save agent whose beat-time is 02330 02331 //if(o == 26 && timeElapsed_ >= 4546) 02332 // cout << "=========t: " << timeElapsed_ << "; BC: " << beatCounter_(o) << "; BEAT: " << agentsHistory_(o, (mrs_natural) beatCounter_(o)) << endl; 02333 02334 handleAgentsTansition(o); 02335 } 02336 02337 //if(timeElapsed_ >= 4196 && (o == 15 || o == 24)) 02338 // cout << "t:" << timeElapsed_ << "-BEAT CHECK " << beatCounter_(o) << ": " << (((agentsHistory_(o, beatCounter_(o)) * hopSize_) - hopSize_/2) / srcFs_) 02339 // << " by: " << agentsFamilyHist_(o, beatCounter_(o)) << endl; 02340 02341 //Increment beat counter of each agent 02342 beatCounter_(o)++; 02343 02344 //update agent's last phase 02345 lastPhases_(o) = timeElapsed_; //(Phases in frames) 02346 02347 //Display Beats from BeatAgents: 02348 //if(o == 8) 02349 // cout << "t: " << timeElapsed_ << "; BEAT - Agent " << o << "(" << ((timeElapsed_ * hopSize_) - (hopSize_/2)) / srcFs_ 02350 // << ") -> AgentPeriod: " << lastPeriods_(o) << "; AgentScore: " << score_(o) << " BestAgent: " 02351 // << bestAgentIndex_ << " BestScore: " << bestScore_ << " BeatCount: " << beatCounter_(o) << endl; 02352 02353 //if best agent sends beat => outputs best beat 02354 if(o == bestAgentIndex_) 02355 { 02356 //beat transition safecheck-> to avoid beats given by different agents distanced less than a tolerance (60% of current ibi) 02357 //(ignore this requirement in the beat just after reseting the system, with trigger induction) 02358 //if((timeElapsed_ - lastBeatTime_) >= 0.6*lastBeatPeriod_) 02359 if((timeElapsed_ - lastBeatTime_) >= beatTransitionTol_*lastBeatPeriod_) 02360 { 02361 //Display Outputted Beat: 02362 //cout << "OUTPUT(" << timeElapsed_ << "-" << ((timeElapsed_ * hopSize_) - (hopSize_/2)) / srcFs_ << "):Beat from Agent " << bestAgentIndex_ << 02363 // " BestScore:" << bestScore_ << " (" << score_(bestAgentIndex_) << ")"; 02364 //cout << ":" << (60.0 / (timeElapsed_ - lastBeatTime_)) * (ctrl_srcFs_->to<mrs_real>() / ctrl_hopSize_->to<mrs_natural>()) << "BPM" << endl; 02365 //cout << "BEST_AgentPeriod: " << lastPeriods_(bestAgentIndex_) << "(" << (timeElapsed_ - lastBeatTime_) << ")" << endl; 02366 02367 //SEND BEAT COMMAND! 02368 ctrl_beatDetected_->setValue(1.0); 02369 out.setval(1.0); 02370 02371 //Updates agent history, which accounts for the total number 02372 //of the detected best (considered) beats of each agent: 02373 historyCount_(o)++; 02374 //historyBeatTimes_(o, outputCount_) = timeElapsed_; 02375 outputCount_ ++; 02376 lastBeatTime_ = timeElapsed_; 02377 lastBeatPeriod_ = (mrs_natural) lastPeriods_(o); 02378 02379 if(logFile_) 02380 debugAddEvent("==========> BEAT", o, (mrs_natural) lastPeriods_(o), 02381 (mrs_natural) lastPhases_(o), score_(o), bestScore_); 02382 02383 //if trigger mode defined as ground_truth 02384 if(strcmp(inductionMode_.c_str(), "groundtruth") == 0) 02385 { 02386 //check beat-time distance to ground-truth (check if any false positive or negative) 02387 mrs_natural localBeatError = checkBeatInGTFile(); 02388 localBeatError == 0 ? lostGTBeatsCount_ = 0 : lostGTBeatsCount_+=localBeatError; 02389 //cout << "lostBeatsCount: " << lostGTBeatsCount_ << endl; 02390 02391 //while beat error count = 0 -> assign bestAgentBeforeTrigger as current best agent 02392 if(lostGTBeatsCount_ == 0) 02393 { 02394 bestAgentBeforeTrigger_ = bestAgentIndex_; 02395 02396 if(logFile_) 02397 debugAddEvent("BEST_TRIGGER", bestAgentBeforeTrigger_, (mrs_natural) lastPeriods_(bestAgentBeforeTrigger_), 02398 (mrs_natural) lastPhases_(bestAgentBeforeTrigger_), score_(bestAgentBeforeTrigger_), bestScore_); 02399 02400 //cout << timeElapsed_ << "=======: bestAgentBeforeTrigger: " << bestAgentBeforeTrigger_ 02401 // << "; bestAgent: " << bestAgentBeforeTrigger_ << endl; 02402 } 02403 02404 //request new induction if detected more consecutive beat misses than the tolerated 02405 if(lostGTBeatsCount_ >= triggerGtTolerance_) 02406 { 02407 //cout << "LOST req TRIGGER at: " << timeElapsed_ << " (" << ((timeElapsed_ * hopSize_) - (hopSize_/2)) / srcFs_ << ")" << endl; 02408 lostGTBeatsCount_ = 0; //reset beat error count 02409 triggerInductionExternalRequest_ = true; 02410 02411 //cout << "2: " << ctrl_logFile_->to<mrs_string>().c_str() << endl; 02412 02413 //trigger logfile: 02414 if(strcmp(ctrl_logFile_->to<mrs_string>().c_str(), "trigger") == 0) 02415 { 02416 triggerCount_++; //counts the number of triggers for the trigger logfile 02417 ostringstream oss; 02418 oss << ctrl_destFileName_->to<mrs_string>() << "_logTrigger.txt"; 02419 ofstream trigCountStream; 02420 trigCountStream.open(oss.str().c_str(), ios::out|ios::trunc); 02421 trigCountStream << triggerCount_ << endl; 02422 trigCountStream.close(); 02423 } 02424 } 02425 } 02426 else if(strcmp(inductionMode_.c_str(), "repeated") == 0 || 02427 (strcmp(inductionMode_.c_str(), "random") == 0) || 02428 (strcmp(inductionMode_.c_str(), "supervised") == 0)) 02429 { 02430 //in trigger modes other than "groundtruth" assign the bestAgentBeforeTrigger as the bestAgent at every estimated beat 02431 bestAgentBeforeTrigger_ = bestAgentIndex_; 02432 02433 if(logFile_) 02434 debugAddEvent("BEST_TRIGGER", bestAgentBeforeTrigger_, (mrs_natural) lastPeriods_(bestAgentBeforeTrigger_), 02435 (mrs_natural) lastPhases_(bestAgentBeforeTrigger_), score_(bestAgentBeforeTrigger_), bestScore_); 02436 } 02437 //in triggertimes trigger mode consider the bestAgentBeforeTrigger as the best agent at the last beat-time before the effective transitions 02438 else if(strcmp(inductionMode_.c_str(), "givetransitions") == 0 && 02439 (timeElapsed_ + (mrs_natural)lastPeriods_(bestAgentIndex_)) >= transitionTimes_(triggerCount_) && transitionsConsidered_(triggerCount_) == 0.0) 02440 { 02441 bestAgentBeforeTrigger_ = bestAgentIndex_; 02442 resetSystem(bestAgentBeforeTrigger_); //kill everyone except the bestAgent before trigger 02443 transitionsConsidered_(triggerCount_) = 1; 02444 02445 if(logFile_) 02446 debugAddEvent("BEST_TRIGGER", bestAgentBeforeTrigger_, (mrs_natural) lastPeriods_(bestAgentBeforeTrigger_), 02447 (mrs_natural) lastPhases_(bestAgentBeforeTrigger_), score_(bestAgentBeforeTrigger_), bestScore_); 02448 } 02449 } 02450 else if(logFile_) 02451 debugAddEvent("BEAT CANCEL", o, (mrs_natural) lastPeriods_(o), 02452 (mrs_natural) lastPhases_(o), score_(o), bestScore_); 02453 02454 //redo agents' scores calculation 02455 calcAbsoluteBestScore(); 02456 } 02457 } 02458 } 02459 } 02460 } 02461 02462 //Create the first BeatAgents with new hypotheses just after Tseconds of induction: 02463 if(processInduction_) 02464 { 02465 if(logFile_) 02466 debugAddMsg("=========== INDUCTION ==========="); 02467 02468 firstHypotheses_ = ctrl_firstHypotheses_->to<mrs_realvec>(); 02469 02470 //update values for eventual forced periods in induction stage 02471 maxPeriod_ = ctrl_maxPeriod_->to<mrs_natural>(); 02472 minPeriod_ = ctrl_minPeriod_->to<mrs_natural>(); 02473 //max possible nr. of beats in the analysed sound file (*1.7 - tolerance due to possible limit surpassing) 02474 maxNrBeats_ = (mrs_natural) (ceil(((mrs_real) soundFileSize_) / ((mrs_real) minPeriod_)) * 1.7); 02475 agentsHistory_.stretch(nrAgents_, maxNrBeats_); 02476 agentsFamilyHist_.stretch(nrAgents_, maxNrBeats_); 02477 02478 mrs_natural newAgentPeriod; 02479 mrs_natural newAgentPhase; 02480 mrs_real newAgentScore; 02481 02482 if(strcmp(inductionMode_.c_str(), "givetransitions") == 0) 02483 bestAgentBeforeTrigger_ = bestAgentIndex_; 02484 if(startTracking_ && resetAfterNewInduction_) 02485 { 02486 resetSystem(bestAgentBeforeTrigger_); //kill everyone except the bestAgent at transition 02487 lastBeatPeriod_ = 0; //reset lastBeatPeriod to avoid BEAT_CANCEL int the first beat after a system reset 02488 } 02489 02490 //cout << "TRIGGER AGENTS @ " << timeElapsed_ << endl; 02491 02492 //before getting IBI clusters we need to make sure which agents will be killed 02493 //for don't consider them as possible fathers to adopt trigger agents 02494 mrs_realvec newAgentsScore(firstHypotheses_.getRows()); 02495 mrs_natural count = 0; 02496 for(int i = 0; i < firstHypotheses_.getRows(); i++) 02497 { 02498 if((mrs_natural) firstHypotheses_(i,0) > 0) //only consider valid hypothesis: 02499 { 02500 //firstHypotheses_ -> matrix with i generated beat hypotheses + score, in the induction stage 02501 //[ BPMi | Beati | Score i ] 02502 newAgentPeriod = (mrs_natural) firstHypotheses_(i,0); 02503 newAgentPhase = (mrs_natural) firstHypotheses_(i,1); 02504 newAgentScore = firstHypotheses_(i,2); 02505 02506 if(!resetAfterNewInduction_) //only consider below in non RESET trigger mode 02507 { 02508 //only considered agents which aren't replicated 02509 if(existEqualBetterAgents(-1, newAgentPeriod, newAgentPhase, newAgentScore) == -1) 02510 { 02511 newAgentsScore(count) = newAgentScore; 02512 02513 //if(timeElapsed_ == 3100) 02514 // cout << "NEW1 " << i << "-> Agents Score: " << newAgentsScore(count) << "; period: " 02515 // << newAgentPeriod << "; elems: " << count << endl; 02516 02517 count++; 02518 } 02519 else //if existed equal agents erase hypotheses (so this agent is not considered for creation) 02520 { 02521 firstHypotheses_(i,0) = 0.0; 02522 firstHypotheses_(i,1) = 0.0; 02523 firstHypotheses_(i,2) = 0.0; 02524 02525 if(logFile_) 02526 debugAddEvent("EQ_TRIGGER", -1, newAgentPeriod, newAgentPhase, newAgentScore, 02527 bestScore_, existEqualAgents(-1, newAgentPeriod, newAgentPhase)); 02528 } 02529 } 02530 } 02531 02532 02533 grantPoolSpace2(-1, count, newAgentsScore); //grant pool space for all needed agents to be created 02534 } 02535 02536 //Updating initial bestScore and creating first agents: 02537 //(nr of initial agents equals nr of bpm hypotheses) 02538 for(mrs_natural i = 0; i < firstHypotheses_.getRows(); i++) 02539 { 02540 if((mrs_natural) firstHypotheses_(i,0) > 0) //only consider valid hypothesis: 02541 { 02542 //firstHypotheses_ -> matrix with i generated beat hypotheses + score, in the induction stage 02543 //[ BPMi | Beati | Score i ] 02544 newAgentPeriod = (mrs_natural) firstHypotheses_(i,0); 02545 newAgentPhase = (mrs_natural) firstHypotheses_(i,1); 02546 newAgentScore = firstHypotheses_(i,2); 02547 02548 //cout << "t: " << timeElapsed_ << "; nAP: " << newAgentPeriod << "; nAPh: " << newAgentPhase << "; Score" << i << ": " << newAgentScore << endl; 02549 02550 //create new agent 02551 mrs_natural createdAgent = -1; 02552 if(startTracking_) 02553 { 02554 //after first induction, at each trigger all agents derive from last best good agent 02555 createdAgent = createNewAgent(newAgentPeriod, newAgentPhase, newAgentScore, beatCounter_(bestAgentBeforeTrigger_), bestAgentBeforeTrigger_); 02556 } 02557 else //at first induction all agents are created as first generation 02558 createdAgent = createNewAgent(newAgentPeriod, newAgentPhase, newAgentScore, 0, -1); 02559 02560 //cout << "t: " << timeElapsed_ << "; BESTAGENT: " << bestAgentIndex_ << endl; 02561 02562 //only if agent is actually created it is considered for best check 02563 if(createdAgent >= 0) 02564 { 02565 if(newAgentScore > bestScore_) 02566 { 02567 bestScore_ = newAgentScore; 02568 bestAgentIndex_ = createdAgent; 02569 bestFinalAgent_ = bestAgentIndex_; 02570 02571 //at the initial induction the best agent before trigger is assigned as the best initial agent 02572 if(!startTracking_) 02573 { 02574 bestAgentBeforeTrigger_ = bestAgentIndex_; 02575 02576 if(logFile_) 02577 debugAddEvent("BEST_TRIGGER", bestAgentBeforeTrigger_, (mrs_natural) lastPeriods_(bestAgentBeforeTrigger_), 02578 (mrs_natural) lastPhases_(bestAgentBeforeTrigger_), score_(bestAgentBeforeTrigger_), bestScore_); 02579 } 02580 02581 if(logFile_) 02582 debugAddEvent("BEST", bestAgentIndex_, newAgentPeriod, newAgentPhase, newAgentScore, bestScore_); 02583 } 02584 } 02585 //else cout << timeElapsed_ << ": AGENT " << createdAgent << " KILLED BY EQUAL CHECK!" << endl; 02586 02587 if(i == nrAgents_-1) 02588 { 02589 MRSWARN("Last hypotheses discarted because the nr. of hypotheses surpasses the nr. of BeatAgents"); 02590 break; 02591 } 02592 02593 if(newAgentPeriod == 0) 02594 { 02595 MRSWARN("Last hypotheses discarted because no more periods considered"); 02596 break; 02597 } 02598 } 02599 02600 //multiplied by sqrt(period) for disinflating the faster agents (with smaller periods) 02601 //bestScore_ *= sqrt((mrs_real)maxPeriod_); 02602 02603 //reset supervisedBestScores buffers at every induction 02604 if(strcmp(inductionMode_.c_str(), "supervised") == 0) 02605 { 02606 supervisedBestScores_.resize(1); //minimum size 02607 supervisedBestScoresMeans_.resize(1); //minimum size 02608 lastTriggerInductionTime_ = timeElapsed_; //keep last induction time 02609 lastBestScoreMeanDiff_ = supervisedTriggerThres_; 02610 } 02611 02612 } 02613 02614 //if backtrace restart tick counter 02615 //(timing updated here, for backtracing, for being contablized in the log file) 02616 if(backtrace_) 02617 { 02618 backtraceEndTime_ = timeElapsed_; //save end time as time when backtrace requested 02619 02620 //retrocede all MarSystem's timer by inductionTime: 02621 for(mrs_natural i = 0; i < agentControl_.getRows(); i++) 02622 { 02623 agentControl_(i, 3) = timeElapsed_-inductionTime_; 02624 updControl(ctrl_agentControl_, agentControl_); 02625 } 02626 ctrl_tickCount_->setValue(timeElapsed_-inductionTime_); 02627 02628 timeElapsed_ = timeElapsed_-inductionTime_-1; //-1 because timer is updated by the end of the cycle (so next cycle is the actual 0) 02629 //cout << "Back: " << timeElapsed_ << "; newT: " << timeElapsed_ << "with ind: " << inductionTime_ << endl; 02630 02631 //disable backtrace after first induction (for non-causal mode) 02632 updControl(ctrl_backtrace_, false); 02633 } 02634 //incremented for counting inductionTime_ after induction before enabling obsolete killing 02635 else 02636 timeBeforeKilling_+=inductionTime_; 02637 02638 //After finnishing induction deactivate induction's period estimation (ACF) -> computer expensive 02639 inductionEnabler_(0, 0) = 1.0; //diable = muted 02640 updControl(ctrl_inductionEnabler_, inductionEnabler_); 02641 02642 if(startTracking_ && resetAfterNewInduction_) 02643 { 02644 killAgent(bestAgentBeforeTrigger_, "RESET", -1); //kill bestAgent at transition 02645 calcAbsoluteBestScore(); 02646 } 02647 02648 processInduction_ = false; 02649 startTracking_ = true; //start tracking (after first induction, tracking keeps on running) 02650 updControl(ctrl_triggerInduction_, false); //deactivate trigger induction!! 02651 02652 } 02653 02654 //MATLAB_PUT(agentsHistory_, "agentsHistory"); 02655 //MATLAB_PUT(bestFinalAgent_, "bestFinalAgent"); 02656 02657 //clean first half of the feature window buffer before every new induction 02658 if(timeElapsed_ > backtraceEndTime_ && ((ctrl_triggerInductionExternalRequest_->to<mrs_bool>() || timeElapsed_ == triggerInductionTime_-2) 02659 || (strcmp(inductionMode_.c_str(), "givetransitions") == 0 && timeElapsed_ == triggerTimes_(triggerCount_)-2))) 02660 { 02661 updControl(ctrl_resetFeatWindow_, true); 02662 02663 if(ctrl_triggerInductionExternalRequest_->to<mrs_bool>()) 02664 { 02665 triggerInductionExternalRequest_ = false; 02666 triggerInduction_ = true; 02667 } 02668 02669 } 02670 //just before the induction triggering activate periodicity estimation (via ACF peaks) 02671 //(don't call this wihtin backtrace window) 02672 else if(timeElapsed_ > backtraceEndTime_ && ((triggerInduction_ || timeElapsed_ == triggerInductionTime_-1) 02673 || (strcmp(inductionMode_.c_str(), "givetransitions") == 0 && timeElapsed_ == triggerTimes_(triggerCount_)-1))) 02674 { 02675 mrs_real outTmp = out(0,0); //[!!] don't know why when calling updControl() out is reset 02676 02677 //cout << "Trigger Mode: " << inductionMode_ << endl; 02678 02679 //activate periodicity estimation (via ACF peaks) 02680 inductionEnabler_(0, 0) = 0.0; //enable = unmuted 02681 updControl(ctrl_inductionEnabler_, inductionEnabler_); 02682 //cout << "Induction triggered at: " << timeElapsed_ << endl; 02683 02684 //cout << "triggerInd: " << triggerInduction_ << "@" << timeElapsed_ 02685 // << "; bestAgent: " << bestAgentBeforeTrigger_ << endl; 02686 02687 //send current and inductionTime before best agents score to new induction stage 02688 if(startTracking_) 02689 { 02690 if(resetAfterNewInduction_) bestScore_ = NA; 02691 else //update current best score before trigger 02692 { 02693 calcAbsoluteBestScore(); 02694 } 02695 } 02696 02697 updControl(ctrl_curBestScore_, bestScore_); 02698 02699 updControl(ctrl_triggerInduction_, true); //request induction!! 02700 02701 processInduction_ = true; //update system with new induction values 02702 triggerInduction_ = false; 02703 02704 //recover value above 02705 out.setval(outTmp); 02706 02707 if(startTracking_) 02708 triggerCount_++; //counts the number of triggers 02709 02710 if(strcmp(inductionMode_.c_str(), "repeated") == 0 || 02711 strcmp(inductionMode_.c_str(), "random") == 0 || 02712 strcmp(inductionMode_.c_str(), "supervised") == 0) 02713 { 02714 if(strcmp(inductionMode_.c_str(), "repeated") == 0) //repeat induction mode (repeated every induction time) 02715 triggerInductionTime_ += 100; //for testing repeated induction x in x secs 02716 else if(strcmp(inductionMode_.c_str(), "random") == 0) 02717 { 02718 mrs_natural minTriggerRep = maxPeriod_; 02719 mrs_natural maxTriggerRep = inductionTime_ * 3; 02720 srand((mrs_natural)(timeElapsed_+time(NULL))); //just a random seed 02721 02722 mrs_natural randTriggerRep = (mrs_natural) ((rand() % (maxTriggerRep-minTriggerRep)) + minTriggerRep); 02723 02724 //cout << "lastIndTime:" << triggerInductionTime_; 02725 02726 triggerInductionTime_ += randTriggerRep; 02727 } 02728 02729 //trigger logfile: 02730 if(strcmp(ctrl_logFile_->to<mrs_string>().c_str(), "trigger") == 0) 02731 { 02732 ostringstream oss; 02733 oss << ctrl_destFileName_->to<mrs_string>() << "_logTrigger.txt"; 02734 ofstream trigCountStream; 02735 trigCountStream.open(oss.str().c_str(), ios::out|ios::trunc); 02736 trigCountStream << triggerCount_ << endl; 02737 trigCountStream.close(); 02738 } 02739 02740 } 02741 else triggerInductionTime_ = -1; //avoid another induction by time when backtracing 02742 } 02743 02744 //if in nonCausalMode save last best agent history as the final output 02745 if(nonCausal_) 02746 { 02747 soundFileSize_ = ctrl_soundFileSize_->to<mrs_natural>(); 02748 02749 //cout << "T: " << timeElapsed_ << "; soundFileSize: " << soundFileSize_ << endl; 02750 02751 //by the end of the audio analysis: 02752 if(timeElapsed_ == soundFileSize_-1) //[! -1 for acouting on time of timing reset on backtrace mode] 02753 { 02754 mrs_natural bestAgentHistorySize = (mrs_natural) beatCounter_(bestFinalAgent_); 02755 bestFinalAgentHistory_.create(bestAgentHistorySize); 02756 02757 if(logFile_) 02758 debugAddMsg("=========== NON-CAUSAL BEAT-TIMES ==========="); 02759 02760 for(int i = 0; i < bestAgentHistorySize; i++) 02761 { 02762 //cout << "I: " << i << "; History: " << agentsHistory_(bestFinalAgent_, i) << endl; 02763 bestFinalAgentHistory_(i) = agentsHistory_(bestFinalAgent_, i); //Output Vector 02764 02765 if(logFile_) 02766 { 02767 //prints non-causal beat-times 02768 mrs_natural agent = (mrs_natural) agentsFamilyHist_(bestFinalAgent_, i); 02769 debugAddEvent("BEAT", agent, -1, (mrs_natural) bestFinalAgentHistory_(i), -1, -1); 02770 } 02771 } 02772 02773 if(logFile_) 02774 debugAddMsg("=========================="); 02775 02776 /* 02777 cout << "BEST FAMILY: " << endl; 02778 for(int i = 0; i < bestAgentHistorySize; i++) 02779 { 02780 cout << agentsFamilyHist_(bestFinalAgent_, i) << "; "; 02781 } 02782 */ 02783 02784 if(bestAgentHistorySize == 0) //if no beats detected [to avoid crash] 02785 { 02786 bestFinalAgentHistory_.create(1); 02787 bestFinalAgentHistory_(0) = -1.0; 02788 } 02789 02790 updControl(ctrl_bestFinalAgentHistory_, bestFinalAgentHistory_); 02791 } 02792 } 02793 02794 //in supervised induction mode: 02795 //1- keep a buffer with all bestScore values since previous induction 02796 //2- do a mean of all bestScores in a window with the size of the induction at 1sec increments 02797 //3- subtract every mean of bestScores with the previous: 02798 // if difference < supervisedTriggerThres -> request new induction 02799 if(strcmp(inductionMode_.c_str(), "supervised") == 0) 02800 { 02801 mrs_natural smoothResolution = 3; //3secs resolution 02802 smoothResolution = (mrs_natural) (smoothResolution * (srcFs_/hopSize_)); 02803 //supervision logfile: 02804 ofstream diffBS, meanBS, rawBS; 02805 if(strcmp(ctrl_logFile_->to<mrs_string>().c_str(), "trigger") == 0) 02806 { 02807 ostringstream ossDiff, ossMean, ossBS; 02808 ossDiff << ctrl_destFileName_->to<mrs_string>() << "_diffBestScore.txt"; 02809 ossMean << ctrl_destFileName_->to<mrs_string>() << "_meanBestScore.txt"; 02810 ossBS << ctrl_destFileName_->to<mrs_string>() << "_bestScore.txt"; 02811 02812 if(timeElapsed_ == 0) 02813 { 02814 diffBS.open(ossDiff.str().c_str(), ios::out|ios::trunc); 02815 meanBS.open(ossMean.str().c_str(), ios::out|ios::trunc); 02816 rawBS.open(ossBS.str().c_str(), ios::out|ios::trunc); 02817 } 02818 else 02819 { 02820 diffBS.open(ossDiff.str().c_str(), ios::out|ios::app); 02821 meanBS.open(ossMean.str().c_str(), ios::out|ios::app); 02822 rawBS.open(ossBS.str().c_str(), ios::out|ios::app); 02823 } 02824 02825 rawBS << bestScore_ << endl; 02826 rawBS.close(); 02827 } 02828 02829 if(bestScore_ == NA) 02830 supervisedBestScores_.push_back(0.0); 02831 else supervisedBestScores_.push_back(bestScore_); 02832 02833 //cout << "time: " << timeElapsed_ << "; BS: " << supervisedBestScores_.at(supervisedBestScores_.size()-1) 02834 // << "; Size: " << supervisedBestScores_.size() << endl; 02835 02836 //wait the first induction time to fill the supervisedBestScores buffer 02837 if(timeElapsed_ >= lastTriggerInductionTime_ + inductionTime_) 02838 { 02839 mrs_natural stepTime = timeElapsed_ - (lastTriggerInductionTime_ + inductionTime_); 02840 mrs_natural stepSize = 1; // 1 second 02841 stepSize = (mrs_natural) (stepSize * (srcFs_/hopSize_)); 02842 if(!(stepTime % stepSize)) 02843 { 02844 mrs_real sum = 0.0; 02845 for(mrs_natural s = (mrs_natural) (supervisedBestScores_.size()-smoothResolution); s < (mrs_natural) supervisedBestScores_.size(); s++) 02846 sum += supervisedBestScores_.at(s); 02847 mrs_real mean = sum /= smoothResolution; 02848 supervisedBestScoresMeans_.push_back(mean); 02849 02850 mrs_real bestScoreMeanDiff = 0.1; 02851 if(supervisedBestScoresMeans_.size() > 1) 02852 02853 02854 bestScoreMeanDiff = supervisedBestScoresMeans_.at(supervisedBestScoresMeans_.size()-1)-supervisedBestScoresMeans_.at(supervisedBestScoresMeans_.size()-2); 02855 02856 //cout << "AKI @ " << timeElapsed_ << "; stepTime: " << stepTime << "; min: " 02857 //<< (supervisedBestScores_.size()-inductionTime_) << "; max: " << supervisedBestScores_.size() //<< "; BSMeanDiff: " << bestScoreMeanDiff 02858 //<< "; thisMean: " << supervisedBestScoresMeans_.at(supervisedBestScoresMeans_.size()-1) 02859 //<< "; lastMean: " << supervisedBestScoresMeans_.at(supervisedBestScoresMeans_.size()-2) << endl; 02860 //<< "; thisDiff: " << bestScoreMeanDiff << "; lastDiff: " << lastBestScoreMeanDiff_ << endl; 02861 02862 if(strcmp(ctrl_logFile_->to<mrs_string>().c_str(), "trigger") == 0) 02863 { 02864 diffBS << bestScoreMeanDiff << endl; 02865 diffBS.close(); 02866 meanBS << supervisedBestScoresMeans_.at(supervisedBestScoresMeans_.size()-1) << endl; 02867 meanBS.close(); 02868 } 02869 02870 //trigger induction time after signalization 02871 if((bestScoreMeanDiff < (supervisedTriggerThres_*supervisedBestScoresMeans_.at(supervisedBestScoresMeans_.size()-1))) 02872 && (lastBestScoreMeanDiff_ > (supervisedTriggerThres_*supervisedBestScoresMeans_.at(supervisedBestScoresMeans_.size()-2)))) 02873 { 02874 //save lastTriggerInductionTime for plotting 02875 //mrs_natural lastTriggerInductionTime = triggerInductionTime_; 02876 02877 triggerInductionTime_ = timeElapsed_ + 3; //trigger new induction now (sum needed 3 frames) 02878 02879 //supervision logfile: 02880 if(strcmp(ctrl_logFile_->to<mrs_string>().c_str(), "trigger") == 0) 02881 { 02882 ostringstream oss; 02883 oss << ctrl_destFileName_->to<mrs_string>() << "_triggerTimes.txt"; 02884 ofstream triggerBS; 02885 if(lastTriggerInductionTime_ == inductionTime_) 02886 triggerBS.open(oss.str().c_str(), ios::out|ios::trunc); 02887 else triggerBS.open(oss.str().c_str(), ios::out|ios::app); 02888 02889 triggerBS << triggerInductionTime_ << endl; 02890 triggerBS.close(); 02891 } 02892 02893 //cout << "TRIGGER @ " << timeElapsed_ << "; TT: " << triggerInductionTime_ << endl; 02894 //cout << "THRES: " << supervisedTriggerThres_ << endl; 02895 } 02896 02897 lastBestScoreMeanDiff_ = bestScoreMeanDiff; 02898 } 02899 else if(strcmp(ctrl_logFile_->to<mrs_string>().c_str(), "trigger") == 0) //DEBUGGING 02900 { 02901 diffBS << NA << endl; 02902 diffBS.close(); 02903 meanBS << NA << endl; 02904 meanBS.close(); 02905 } 02906 } 02907 else if(strcmp(ctrl_logFile_->to<mrs_string>().c_str(), "trigger") == 0) //DEBUGGING 02908 { 02909 diffBS << NA << endl; 02910 diffBS.close(); 02911 meanBS << NA << endl; 02912 meanBS.close(); 02913 } 02914 } 02915 02916 02917 //MATLAB_PUT(statsAgentsScore_, "agentsScore"); 02918 //MATLAB_PUT(in, "BeatAgents"); 02919 02920 //MATLAB_PUT(out, "BeatReferee"); 02921 /* 02922 MATLAB_PUT(historyBeatTimes_, "HistoryBeatTimes"); 02923 MATLAB_PUT(historyCount_, "HistoryCount"); 02924 MATLAB_PUT(statsPeriods_, "statsPeriods"); 02925 MATLAB_PUT(statsAgentsLifeCycle_, "statsAgentsLifeCycle"); 02926 02927 MATLAB_PUT(bestScore_, "bestScore"); 02928 MATLAB_EVAL("bestAgentScore = [bestAgentScore bestScore];"); 02929 */ 02930 //MATLAB_EVAL("FinalBeats = [FinalBeats, BeatReferee];"); 02931 02932 //MATLAB_EVAL("hold on;"); 02933 //MATLAB_EVAL("plot(BeatAgentsTS)"); 02934 //MATLAB_EVAL("stem(t, 1, 'r');"); 02935 //MATLAB_EVAL("hold off;"); 02936 02937 timeElapsed_++; //increment timer by the end of each cycle 02938 02939 }