/* * ASCLITE * Author: Jerome Ajot, Jon Fiscus, Nicolas Radde, Chris Laprun * * This software was developed at the National Institute of Standards and Technology by * employees of the Federal Government in the course of their official duties. Pursuant * to title 17 Section 105 of the United States Code this software is not subject to * copyright protection and is in the public domain. ASCLITE is an experimental system. * NIST assumes no responsibility whatsoever for its use by other parties, and makes no * guarantees, expressed or implied, about its quality, reliability, or any other * characteristic. We would appreciate acknowledgement if the software is used. * * THIS SOFTWARE IS PROVIDED "AS IS." With regard to this software, NIST MAKES NO EXPRESS * OR IMPLIED WARRANTY AS TO ANY MATTER WHATSOEVER, INCLUDING MERCHANTABILITY, * OR FITNESS FOR A PARTICULAR PURPOSE. */ /** * A recording contain all the data needed to score a testset. * From the argument to the list of parser (input) and generator (output report). * This is the main entry to the aligner. */ #include "recording.h" // class's header file Logger* Recording::logger = Logger::getLogger(); // class constructor Recording::Recording() { //init the input parsers inputParsers["ctm"] = new CTMInputParser; inputParsers["stm"] = new STMInputParser; inputParsers["trn"] = new TRNInputParser; inputParsers["rttm"] = new RTTMInputParser; //init the report generator reportGenerators["rsum"] = new RAWSYSReportGenerator(1); reportGenerators["sum"] = new RAWSYSReportGenerator(2); reportGenerators["sgml"] = new SGMLReportGenerator(); pSGMLGenericReportGenerator = new SGMLGenericReportGenerator(); //init the segmentor segmentors["trn"] = new TRNTRNSegmentor(); segmentors["ctmstmrttm"] = new CTMSTMRTTMSegmentor(); //init the Aligner aligner["lev"] = new Levenshtein(); //init the Scorer scorer["stt"] = new STTScorer(); //init the Filters filters["filter.spkrautooverlap"] = new SpkrAutoOverlap(); filters["filter.uem"] = new UEMFilter(); //init the Alignment result alignments = new Alignment(); //Init SpeakerMatch m_pSpeakerMatch = new SpeakerMatch(); } // class destructor Recording::~Recording() { if(m_pSpeakerMatch) delete m_pSpeakerMatch; map::iterator ipi, ipe; ipi = inputParsers.begin(); ipe = inputParsers.end(); while(ipi != ipe) { InputParser* ptr_elt = ipi->second; if(ptr_elt) delete ptr_elt; ++ipi; } inputParsers.clear(); map::iterator rgi, rge; rgi = reportGenerators.begin(); rge = reportGenerators.end(); while(rgi != rge) { ReportGenerator* ptr_elt = rgi->second; if(ptr_elt) delete ptr_elt; ++rgi; } reportGenerators.clear(); delete pSGMLGenericReportGenerator; map::iterator ai, ae; ai = aligner.begin(); ae = aligner.end(); while(ai != ae) { Aligner* ptr_elt = ai->second; if(ptr_elt) delete ptr_elt; ++ai; } aligner.clear(); map::iterator si, se; si = scorer.begin(); se = scorer.end(); while(si != se) { Scorer* ptr_elt = si->second; if(ptr_elt) delete ptr_elt; ++si; } scorer.clear(); map::iterator segi, sege; segi = segmentors.begin(); sege = segmentors.end(); while(segi != sege) { Segmentor* ptr_elt = segi->second; if(ptr_elt) delete ptr_elt; ++segi; } segmentors.clear(); map::iterator fi, fe; fi = filters.begin(); fe = filters.end(); while(fi != fe) { ::Filter* ptr_elt = fi->second; if(ptr_elt) delete ptr_elt; ++fi; } filters.clear(); delete alignments; delete references; map::iterator ssi, sse; ssi = hypothesis.begin(); sse = hypothesis.end(); while(ssi != sse) { SpeechSet* ptr_elt = ssi->second; if(ptr_elt) delete ptr_elt; ++ssi; } hypothesis.clear(); } /** * Load the reference & Hypothesis files into the system. * use the right loader based on the type. */ void Recording::Load(const string& _references, const string& _refType, const vector & _hypothesis_files, const vector & _hypothesis_titles, const vector & _hypothesis_types, const string& uemFile, const string& speakeralignfile) { m_bGenericAlignment = false; if(string("true").compare(Properties::GetProperty("align.speakeroptimization")) == 0) m_pSpeakerMatch->LoadFile(speakeralignfile); if(string("true").compare(Properties::GetProperty("filter.uem")) == 0) filters["filter.uem"]->LoadFile(uemFile); //init the segmentor if(_refType == string("trn")) segmentor = segmentors["trn"]; else segmentor = segmentors["ctmstmrttm"]; //load reference LOG_INFO(logger, "Load 1 reference of type "+_refType); references = inputParsers[_refType]->loadFile(_references); references->SetOrigin("ref"); //load hypothesis char buffer[BUFFER_SIZE]; sprintf(buffer, "Load %lu hypothesis", _hypothesis_files.size()); LOG_INFO(logger, buffer); string title_temp; for (size_t i=0 ; i < _hypothesis_files.size() ; ++i) { if(string("rttm") == _hypothesis_types[i]) inputParsers[_hypothesis_types[i]]->SetOneTokenPerSegment(true); SpeechSet* hyps_loaded = inputParsers[_hypothesis_types[i]]->loadFile(_hypothesis_files[i]); hyps_loaded->SetOrigin("hyp"); if (_hypothesis_titles[i] == "") title_temp = _hypothesis_files[i]; else title_temp = _hypothesis_titles[i]; hyps_loaded->SetTitle(title_temp); hypothesis[title_temp] = hyps_loaded; alignments->AddSystem(_hypothesis_files[i], title_temp); } } void Recording::Load(const vector & _hypothesis_files, const vector & _hypothesis_titles, const vector & _hypothesis_types, const string& _uemFile, const string& _speakeralignfile) { m_bGenericAlignment = true; if(string("true").compare(Properties::GetProperty("align.speakeroptimization")) == 0) m_pSpeakerMatch->LoadFile(_speakeralignfile); if(string("true").compare(Properties::GetProperty("filter.uem")) == 0) filters["filter.uem"]->LoadFile(_uemFile); //init the segmentor segmentor = segmentors["ctmstmrttm"]; //load hypothesis char buffer[BUFFER_SIZE]; sprintf(buffer, "Load %lu hypothesis", _hypothesis_files.size()); LOG_INFO(logger, buffer); string title_temp; for (size_t i=0 ; i < _hypothesis_files.size() ; ++i) { if(string("rttm") == _hypothesis_types[i]) inputParsers[_hypothesis_types[i]]->SetOneTokenPerSegment(true); SpeechSet* hyps_loaded = inputParsers[_hypothesis_types[i]]->loadFile(_hypothesis_files[i]); hyps_loaded->SetOrigin("gen"); if (_hypothesis_titles[i] == "") title_temp = _hypothesis_files[i]; else title_temp = _hypothesis_titles[i]; hyps_loaded->SetTitle(title_temp); hypothesis[title_temp] = hyps_loaded; pSGMLGenericReportGenerator->AddTitleAndFilename(_hypothesis_files[i], title_temp); } } /** * Filter the references and hypothesis with the availables filters. */ void Recording::Filter(const vector & _filters) { unsigned long int nbErr = 0; for (size_t i=0 ; i < _filters.size() ; ++i) { LOG_INFO(logger, "Filtering ==> " +_filters[i] + " - pass 1"); string refhypboth = Properties::GetProperty(_filters[i] + ".option"); if( (string(refhypboth).compare("ref") == 0) || (string(refhypboth).compare("both") == 0) ) { LOG_INFO(logger, "Filtering ==> " + _filters[i] + " references"); for (size_t j=0 ; j < references->GetNumberOfSpeech() ; ++j) nbErr += filters[_filters[i]]->ProcessSingleSpeech(references->GetSpeech(j)); } if( (string(refhypboth).compare("hyp") == 0) || (string(refhypboth).compare("both") == 0) ) { LOG_INFO(logger, "Filtering ==> " + _filters[i] + " hypotheses"); map::iterator hi = hypothesis.begin(); map::iterator hei = hypothesis.end(); while(hi != hei) { SpeechSet* spkset = hi->second; for(size_t j = 0; j < spkset->GetNumberOfSpeech(); ++j) nbErr += filters[_filters[i]]->ProcessSingleSpeech(spkset->GetSpeech(j)); ++hi; } } } for (size_t i=0 ; i < _filters.size() ; ++i) { LOG_INFO(logger, "Filtering ==> " +_filters[i] + " - pass 2"); if(filters[_filters[i]]->isProcessAllSpeechSet()) { LOG_INFO(logger, "Filtering ==> " + _filters[i] + " processing"); nbErr += filters[_filters[i]]->ProcessSpeechSet(references, hypothesis); } } // Check the speaker mapping if(string("true").compare(Properties::GetProperty("align.speakeroptimization")) == 0) { bool foundmatch = false; for(size_t i=0 ; i < references->GetNumberOfSpeech() ; ++i) { for(size_t j=0 ; j < references->GetSpeech(i)->NbOfSegments() ; ++j) { string file1 = references->GetSpeech(i)->GetSegment(j)->GetSource(); string channel1 = references->GetSpeech(i)->GetSegment(j)->GetChannel(); string speaker1 = references->GetSpeech(i)->GetSegment(j)->GetSpeakerId(); //transform(speaker1.begin(), speaker1.end(), speaker1.begin(), (int(*)(int)) toupper); map::iterator hi = hypothesis.begin(); map::iterator hei = hypothesis.end(); while(hi != hei) { SpeechSet* spkset = hi->second; for(size_t k = 0; k < spkset->GetNumberOfSpeech(); ++k) { for(size_t l=0 ; l < spkset->GetSpeech(k)->NbOfSegments() ; ++l) { string file2 = spkset->GetSpeech(k)->GetSegment(l)->GetSource(); string channel2 = spkset->GetSpeech(k)->GetSegment(l)->GetChannel(); string speaker2 = spkset->GetSpeech(k)->GetSegment(l)->GetSpeakerId(); //transform(speaker2.begin(), speaker2.end(), speaker2.begin(), (int(*)(int)) toupper); if( (file1 == file2) && (channel1 == channel2) && (m_pSpeakerMatch->GetRef(file1, channel1, speaker1) == speaker2) ) foundmatch = true; } } ++hi; } } } if(!foundmatch) { char buffer[BUFFER_SIZE]; sprintf(buffer, "Speaker map checking - No matching Detected"); LOG_WARN(logger, buffer); if(string("true").compare(Properties::GetProperty("filter.spkrmap")) == 0) nbErr++; } } if (nbErr != 0) { char buffer[BUFFER_SIZE]; sprintf(buffer, "%li Error(s) in the input files during the filtering", nbErr); LOG_FATAL(logger, buffer); exit(E_FILTER); } } /** * Align the ref/gen with the select align algo */ void Recording::AlignGeneric() { uint max_spkrOverlaping = atoi(Properties::GetProperty("recording.maxspeakeroverlaping").c_str()); uint min_spkrOverlaping = atoi(Properties::GetProperty("recording.minspeakeroverlaping").c_str()); ulint OnlySG_ID = 0; bool bOnlySG = (string("true").compare(Properties::GetProperty("recording.bonlysg")) == 0); if(bOnlySG) OnlySG_ID = atoi(Properties::GetProperty("recording.onlysg").c_str()); ullint max_nb_gb = static_cast(ceil(1024*1024*1024*atof(Properties::GetProperty("recording.maxnbofgb").c_str())/sizeof(int))); ullint max_nb_2gb = static_cast(ceil(2.0*1024*1024*1024/sizeof(int))); bool bForceMemoryCompression = (string("true").compare(Properties::GetProperty("align.forcememorycompression")) == 0); bool bDifficultyLimit = (string("true").compare(Properties::GetProperty("recording.difficultygb")) == 0); bool bMinDifficultyLimit = (string("true").compare(Properties::GetProperty("recording.mindifficultygb")) == 0); if(logger->isAlignLogON()) LOG_ALIGN(logger, "Aligned,SegGrpID,File,Channel,Eval[,RefSegID,RefSegBT,RefSegET,RefSpkrID,RefTknID,RefTknBT,RefTknET,RefTknTxt,RefTknConf,RefTknPrev,RefTknNext]*"); LOG_INFO(logger, "Processing system"); SegmentsGroup* segmentsGroup; segmentor->ResetGeneric(hypothesis); while (segmentor->HasNext()) { segmentsGroup = segmentor->NextGeneric(); ullint cellnumber = segmentsGroup->GetDifficultyNumber(); double KBused = ((static_cast(cellnumber))/1024.0) * (static_cast(sizeof(int))); double MBused = KBused/1024.0; double GBused = MBused/1024.0; double TBused = GBused/1024.0; char buffer_size[BUFFER_SIZE]; if(TBused > 1.0) sprintf(buffer_size, "%.2f TB", TBused); else if(GBused > 1.0) sprintf(buffer_size, "%.2f GB", GBused); else if(MBused > 1.0) sprintf(buffer_size, "%.2f MB", MBused); else sprintf(buffer_size, "%.2f kB", KBused); char buffer[BUFFER_SIZE]; sprintf(buffer, "Align SG %lu [%s] %lu dimensions, Difficulty: %llu (%s) ---> bt=%.3f et=%.3f", static_cast(segmentsGroup->GetsID()), segmentsGroup->GetDifficultyString().c_str(), static_cast(segmentsGroup->GetNumberOfHypothesis()), cellnumber, buffer_size, segmentsGroup->GetMinTime()/1000.0, segmentsGroup->GetMaxTime()/1000.0); LOG_DEBUG(logger, buffer); bool ignoreSegs = false; bool buseCompArray = false; if(segmentsGroup->GetNumberOfHypothesis() <= /*1*/ 0) { //ignoreSegs = true; sprintf(buffer, "Skip this group of segments (%lu): no hypothesis/dimension", static_cast(segmentsGroup->GetsID()) ); LOG_WARN(logger, buffer); } if(!ignoreSegs && (segmentsGroup->isIgnoreInScoring()) ) { ignoreSegs = true; sprintf(buffer, "Skip this group of segments (%lu): Ignore this time segments in scoring set into the references", static_cast(segmentsGroup->GetsID()) ); LOG_WARN(logger, buffer); } if(!ignoreSegs && bOnlySG ) { if(segmentsGroup->GetsID() != OnlySG_ID) { ignoreSegs = true; sprintf(buffer, "Skip this group of segments (%lu): Only scoring %lu", static_cast( segmentsGroup->GetsID()), OnlySG_ID); LOG_WARN(logger, buffer); } } if(!ignoreSegs && (segmentsGroup->GetNumberOfReferences() > max_spkrOverlaping) ) { ignoreSegs = true; sprintf(buffer, "Skip this group of segments (%lu): nb of reference speaker (%lu) overlaping to high (limit: %lu)", static_cast(segmentsGroup->GetsID()), static_cast(segmentsGroup->GetNumberOfReferences()), static_cast(max_spkrOverlaping)); LOG_WARN(logger, buffer); } if(!ignoreSegs && (segmentsGroup->GetNumberOfReferences() < min_spkrOverlaping) ) { ignoreSegs = true; sprintf(buffer, "Skip this group of segments (%lu): nb of reference speaker (%lu) overlaping to small (limit: %lu)", static_cast(segmentsGroup->GetsID()), static_cast(segmentsGroup->GetNumberOfReferences()), static_cast(min_spkrOverlaping)); LOG_WARN(logger, buffer); } if(!ignoreSegs && (bDifficultyLimit) ) { ullint difficulty_nb_gb = static_cast(ceil(1024*1024*1024*atof(Properties::GetProperty("recording.nbrdifficultygb").c_str())/sizeof(int))); if(cellnumber > difficulty_nb_gb) { ignoreSegs = true; sprintf(buffer, "Skip this group of segments (%lu): the graph size will be too large (%llu [%s]) regarding the difficulty limit (%llu [%.2f GB])", static_cast(segmentsGroup->GetsID()), cellnumber, buffer_size, difficulty_nb_gb, atof(Properties::GetProperty("recording.nbrdifficultygb").c_str())); LOG_WARN(logger, buffer); } } if(!ignoreSegs && (bMinDifficultyLimit) ) { ullint mindifficulty_nb_gb = static_cast(ceil(1024*1024*1024*atof(Properties::GetProperty("recording.minnbrdifficultygb").c_str())/sizeof(int))); if(cellnumber < mindifficulty_nb_gb) { ignoreSegs = true; sprintf(buffer, "Skip this group of segments (%lu): the graph size will be too small (%llu [%s]) regarding the min difficulty limit (%llu [%.2f GB])", static_cast(segmentsGroup->GetsID()), cellnumber, buffer_size, mindifficulty_nb_gb, atof(Properties::GetProperty("recording.minnbrdifficultygb").c_str())); LOG_WARN(logger, buffer); } } if(!ignoreSegs && ( (cellnumber > max_nb_gb) || (cellnumber > max_nb_2gb) ) ) { bool m_bUseCompression = (string("true").compare(Properties::GetProperty("align.memorycompression")) == 0) || bForceMemoryCompression; if(!m_bUseCompression) { ignoreSegs = true; sprintf(buffer, "Skip this group of segments (%lu): the graph size will be too large (%llu [%s]) regarding the memory limit (%llu [%.2f GB]) and no compression have been set", static_cast(segmentsGroup->GetsID()), cellnumber, buffer_size, (cellnumber > max_nb_gb) ? max_nb_gb : max_nb_2gb, (cellnumber > max_nb_gb) ? atof(Properties::GetProperty("recording.maxnbofgb").c_str()) : 2.0); LOG_WARN(logger, buffer); } else { buseCompArray = true; sprintf(buffer, "Using Levenshtein Matrix Compression Algorithm for group of segments (%lu)", static_cast(segmentsGroup->GetsID())); LOG_INFO(logger, buffer); } } if(!ignoreSegs && (bForceMemoryCompression) ) { buseCompArray = true; sprintf(buffer, "Forcing Levenshtein Matrix Compression Algorihm for group of segments (%lu)", static_cast(segmentsGroup->GetsID())); LOG_INFO(logger, buffer); } if(segmentsGroup) { if(logger->isAlignLogON()) segmentsGroup->LoggingAlignment(m_bGenericAlignment, string("SG")); } //Special case where the SegmentGroup contain a segment time to ignore if (!ignoreSegs) { Aligner* aligner_instance = aligner["lev"]; aligner_instance->SetSegments(segmentsGroup, m_pSpeakerMatch, buseCompArray); aligner_instance->Align(); GraphAlignedSegment* gas = aligner_instance->GetResults(); //cout << gas->ToString() << endl; pSGMLGenericReportGenerator->AddGraphAlignSegment(gas); sprintf(buffer, "%li GAS cost: (%d)", gas->GetNbOfGraphAlignedToken(), (dynamic_cast(aligner_instance)->GetCost())); LOG_DEBUG(logger, buffer); if(logger->isAlignLogON()) gas->LoggingAlignment(segmentsGroup->GetsID()); //delete gas; } else //segmentsGroup ignored { if(logger->isAlignLogON()) segmentsGroup->LoggingAlignment(m_bGenericAlignment, string("NO")); } if(segmentsGroup) delete segmentsGroup; } } void Recording::AlignHypRef() { uint max_spkrOverlaping = atoi(Properties::GetProperty("recording.maxspeakeroverlaping").c_str()); uint min_spkrOverlaping = atoi(Properties::GetProperty("recording.minspeakeroverlaping").c_str()); ulint OnlySG_ID = 0; bool bOnlySG = (string("true").compare(Properties::GetProperty("recording.bonlysg")) == 0); if(bOnlySG) OnlySG_ID = atoi(Properties::GetProperty("recording.onlysg").c_str()); ullint max_nb_gb = static_cast( ceil(1024*1024*1024*atof(Properties::GetProperty("recording.maxnbofgb").c_str())/sizeof(int)) ); ullint max_nb_2gb = static_cast( ceil(2.0*1024*1024*1024/sizeof(int)) ); bool bForceMemoryCompression = (string("true").compare(Properties::GetProperty("align.forcememorycompression")) == 0); bool bDifficultyLimit = (string("true").compare(Properties::GetProperty("recording.difficultygb")) == 0); bool bMinDifficultyLimit = (string("true").compare(Properties::GetProperty("recording.mindifficultygb")) == 0); map::iterator i = hypothesis.begin(); map::iterator ei = hypothesis.end(); if(logger->isAlignLogON()) LOG_ALIGN(logger, "Aligned,SegGrpID,File,Channel,Eval,RefSegID,RefSegBT,RefSegET,RefSpkrID,RefTknID,RefTknBT,RefTknET,RefTknTxt,RefTknConf,RefTknPrev,RefTknNext,HypSegID,HypSegBT,HypSegET,HypSpkrID,HypTknID,HypTknBT,HypTknET,HypTknTxt,HypTknConf,HypTknPrev,HypTknNext"); while(i != ei) { string hyp_name = i->first; LOG_INFO(logger, "Processing system "+hyp_name); SegmentsGroup* segmentsGroup; segmentor->Reset(references, hypothesis[hyp_name]); while (segmentor->HasNext()) { segmentsGroup = segmentor->Next(); //LOG_INFO(logger, segmentsGroup->ToString()); //cerr << "Nbr ref: " << segmentsGroup->GetNumberOfReferences() << endl; //cerr << "Nbr hyp: " << segmentsGroup->GetNumberOfHypothesis() << endl; //cerr << "SG:" << segmentsGroup->GetsID() << endl; //cerr << segmentsGroup->ToString() << endl; bool emptyHypvsISG = false; //Special case where there is no hyp if (segmentsGroup->GetNumberOfHypothesis() == 0) { //May need to put the segment time Segment* emptyseg = Segment::CreateWithEndTime(0, 0, NULL); emptyseg->SetAsSegmentExcludeFromScoring(); segmentsGroup->AddHypothesis(emptyseg); if(segmentsGroup->GetNumberOfReferences() == 1) { if( segmentsGroup->GetReference(0)[0]->GetSpeakerId() == string("inter_segment_gap") ) emptyHypvsISG = true; } } ullint cellnumber = segmentsGroup->GetDifficultyNumber(); double KBused = (static_cast(cellnumber)/1024.0) * static_cast(sizeof(int)); double MBused = KBused/1024.0; double GBused = MBused/1024.0; double TBused = GBused/1024.0; char buffer_size[BUFFER_SIZE]; if(TBused > 1.0) sprintf(buffer_size, "%.2f TB", TBused); else if(GBused > 1.0) sprintf(buffer_size, "%.2f GB", GBused); else if(MBused > 1.0) sprintf(buffer_size, "%.2f MB", MBused); else sprintf(buffer_size, "%.2f kB", KBused); char buffer[BUFFER_SIZE]; sprintf(buffer, "Align SG %lu [%s] %lu dimensions, Difficulty: %llu (%s) ---> bt=%.3f et=%.3f", static_cast(segmentsGroup->GetsID()), segmentsGroup->GetDifficultyString().c_str(), static_cast(segmentsGroup->GetNumberOfHypothesis()+segmentsGroup->GetNumberOfReferences()), cellnumber, buffer_size, segmentsGroup->GetMinTime()/1000.0, segmentsGroup->GetMaxTime()/1000.0); LOG_DEBUG(logger, buffer); bool ignoreSegs = false; bool buseCompArray = false; if(emptyHypvsISG) { //ignoreSegs = true; sprintf(buffer, "Skip this group of segments (%lu): Inter Segment Gap versus Empty Hyp", static_cast( segmentsGroup->GetsID()) ); LOG_WARN(logger, buffer); } if(!ignoreSegs && (segmentsGroup->isIgnoreInScoring()) ) { ignoreSegs = true; sprintf(buffer, "Skip this group of segments (%lu): Ignore this time segments in scoring set into the references", static_cast( segmentsGroup->GetsID()) ); LOG_WARN(logger, buffer); } if(!ignoreSegs && bOnlySG ) { if(segmentsGroup->GetsID() != OnlySG_ID) { ignoreSegs = true; sprintf(buffer, "Skip this group of segments (%lu): Only scoring %lu", static_cast( segmentsGroup->GetsID()), OnlySG_ID); LOG_WARN(logger, buffer); } } if(!ignoreSegs && (segmentsGroup->GetNumberOfReferences() > max_spkrOverlaping) ) { ignoreSegs = true; sprintf(buffer, "Skip this group of segments (%lu): nb of reference speaker (%lu) overlaping to high (limit: %lu)", static_cast( segmentsGroup->GetsID() ), static_cast( segmentsGroup->GetNumberOfReferences() ), static_cast( max_spkrOverlaping) ); LOG_WARN(logger, buffer); } if(!ignoreSegs && (segmentsGroup->GetNumberOfReferences() < min_spkrOverlaping) ) { ignoreSegs = true; sprintf(buffer, "Skip this group of segments (%lu): nb of reference speaker (%lu) overlaping to small (limit: %lu)", static_cast(segmentsGroup->GetsID()), static_cast(segmentsGroup->GetNumberOfReferences()), static_cast(min_spkrOverlaping)); LOG_WARN(logger, buffer); } if(!ignoreSegs && (bDifficultyLimit) ) { ullint difficulty_nb_gb = static_cast( ceil(1024*1024*1024*atof(Properties::GetProperty("recording.nbrdifficultygb").c_str())/sizeof(int)) ); if(cellnumber > difficulty_nb_gb) { ignoreSegs = true; sprintf(buffer, "Skip this group of segments (%lu): the graph size will be too large (%llu [%s]) regarding the difficulty limit (%llu [%.2f GB])", static_cast( segmentsGroup->GetsID() ), cellnumber, buffer_size, difficulty_nb_gb, atof(Properties::GetProperty("recording.nbrdifficultygb").c_str())); LOG_WARN(logger, buffer); } } if(!ignoreSegs && (bMinDifficultyLimit) ) { ullint mindifficulty_nb_gb = static_cast( ceil(1024*1024*1024*atof(Properties::GetProperty("recording.minnbrdifficultygb").c_str())/sizeof(int)) ); if(cellnumber < mindifficulty_nb_gb) { ignoreSegs = true; sprintf(buffer, "Skip this group of segments (%lu): the graph size will be too small (%llu [%s]) regarding the min difficulty limit (%llu [%.2f GB])", static_cast( segmentsGroup->GetsID() ), cellnumber, buffer_size, mindifficulty_nb_gb, atof(Properties::GetProperty("recording.minnbrdifficultygb").c_str())); LOG_WARN(logger, buffer); } } if(!ignoreSegs && ( (cellnumber > max_nb_gb) || (cellnumber > max_nb_2gb) ) ) { bool m_bUseCompression = (string("true").compare(Properties::GetProperty("align.memorycompression")) == 0) || bForceMemoryCompression; if(!m_bUseCompression) { ignoreSegs = true; sprintf(buffer, "Skip this group of segments (%lu): the graph size will be too large (%llu [%s]) regarding the memory limit (%llu [%.2f GB]) and no compression have been set", static_cast( segmentsGroup->GetsID() ), cellnumber, buffer_size, (cellnumber > max_nb_gb) ? max_nb_gb : max_nb_2gb, (cellnumber > max_nb_gb) ? atof(Properties::GetProperty("recording.maxnbofgb").c_str()) : 2.0); LOG_WARN(logger, buffer); } else { buseCompArray = true; sprintf(buffer, "Using Levenshtein Matrix Compression Algorithm for group of segments (%lu)", static_cast( segmentsGroup->GetsID() ) ); LOG_INFO(logger, buffer); } } if(!ignoreSegs && (bForceMemoryCompression) ) { buseCompArray = true; sprintf(buffer, "Forcing Levenshtein Matrix Compression Algorihm for group of segments (%lu)", static_cast( segmentsGroup->GetsID() ) ); LOG_INFO(logger, buffer); } //Special case where the SegmentGroup contain a segment time to ignore if (!ignoreSegs) { //cerr << segmentsGroup->ToString() << endl; Aligner* aligner_instance = aligner["lev"]; aligner_instance->SetSegments(segmentsGroup, m_pSpeakerMatch, buseCompArray); aligner_instance->Align(); GraphAlignedSegment* gas = aligner_instance->GetResults(); //cerr << gas->ToString() << endl; sprintf(buffer, "Store %li GAS for hyp: '%s' cost: (%d)", gas->GetNbOfGraphAlignedToken(), hyp_name.c_str(), (dynamic_cast(aligner_instance))->GetCost()); LOG_DEBUG(logger, buffer); alignments->AddGraphAlignedSegment(gas, hyp_name, segmentsGroup); delete gas; } else //segmentsGroup ignored { if(logger->isAlignLogON() && !emptyHypvsISG) segmentsGroup->LoggingAlignment(m_bGenericAlignment, string("NO")); } if(segmentsGroup) { if(logger->isAlignLogON() && !emptyHypvsISG) segmentsGroup->LoggingAlignment(m_bGenericAlignment, string("SG")); delete segmentsGroup; } } ++i; } } /** * Score the Alignment with the selected scoring system */ void Recording::Score() { if(!m_bGenericAlignment) { Scorer* scorer_instance = scorer["stt"]; scorer_instance->Score(alignments, m_pSpeakerMatch); } } /** * Generate the reports based on the scored alignment. */ void Recording::GenerateReport(const vector & reportsType) { int outputint = 1; for (size_t i=0 ; i < reportsType.size() ; ++i) if(reportsType[i] == "stdout") outputint = 0; if(!m_bGenericAlignment) { for (size_t i=0 ; i < reportsType.size() ; ++i) if(reportsType[i] != "stdout") reportGenerators[reportsType[i]]->Generate(alignments, outputint); } else { pSGMLGenericReportGenerator->Generate(outputint); } }