ComputeTest.cpp

Go to the documentation of this file.
00001 /*
00002 This file is part of LIA_RAL which is a set of software based on ALIZE
00003 toolkit for speaker recognition. ALIZE toolkit is required to use LIA_RAL.
00004 
00005 LIA_RAL project is a development project was initiated by the computer
00006 science laboratory of Avignon / France (Laboratoire Informatique d'Avignon -
00007 LIA) [http://lia.univ-avignon.fr <http://lia.univ-avignon.fr/>]. Then it
00008 was supported by two national projects of the French Research Ministry:
00009         - TECHNOLANGUE program [http://www.technolangue.net]
00010         - MISTRAL program [http://mistral.univ-avignon.fr]
00011 
00012 LIA_RAL is free software: you can redistribute it and/or modify
00013 it under the terms of the GNU Lesser General Public License as
00014 published by the Free Software Foundation, either version 3 of
00015 the License, or any later version.
00016 
00017 LIA_RAL is distributed in the hope that it will be useful,
00018 but WITHOUT ANY WARRANTY; without even the implied warranty of
00019 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00020 GNU Lesser General Public License for more details.
00021 
00022 You should have received a copy of the GNU Lesser General Public
00023 License along with LIA_RAL.
00024 If not, see [http://www.gnu.org/licenses/].
00025 
00026 The LIA team as well as the LIA_RAL project team wants to highlight the
00027 limits of voice authentication in a forensic context.
00028 The "Person Authentification by Voice: A Need of Caution" paper
00029 proposes a good overview of this point (cf. "Person
00030 Authentification by Voice: A Need of Caution", Bonastre J.F.,
00031 Bimbot F., Boe L.J., Campbell J.P., Douglas D.A., Magrin-
00032 chagnolleau I., Eurospeech 2003, Genova].
00033 The conclusion of the paper of the paper is proposed bellow:
00034 [Currently, it is not possible to completely determine whether the
00035 similarity between two recordings is due to the speaker or to other
00036 factors, especially when: (a) the speaker does not cooperate, (b) there
00037 is no control over recording equipment, (c) recording conditions are not
00038 known, (d) one does not know whether the voice was disguised and, to a
00039 lesser extent, (e) the linguistic content of the message is not
00040 controlled. Caution and judgment must be exercised when applying speaker
00041 recognition techniques, whether human or automatic, to account for these
00042 uncontrolled factors. Under more constrained or calibrated situations,
00043 or as an aid for investigative purposes, judicious application of these
00044 techniques may be suitable, provided they are not considered as infallible.
00045 At the present time, there is no scientific process that enables one to
00046 uniquely characterize a persones voice or to identify with absolute
00047 certainty an individual from his or her voice.]
00048 
00049 Copyright (C) 2004-2010
00050 Laboratoire d'informatique d'Avignon [http://lia.univ-avignon.fr]
00051 LIA_RAL admin [alize@univ-avignon.fr]
00052 Jean-Francois Bonastre [jean-francois.bonastre@univ-avignon.fr]
00053 */
00054 
00055 #if !defined(ALIZE_ComputeTest_cpp)
00056 #define ALIZE_ComputeTest_cpp
00057  
00058 #include <iostream>
00059 #include <fstream> 
00060 #include <cassert> 
00061 #include <cmath> 
00062 #include <liatools.h>
00063 #include "ComputeTest.h"
00064 #include "AccumulateJFAStat.h"
00065 #include <sys/stat.h>
00066 
00067 using namespace alize;
00068 using namespace std;
00069 
00070 // Compute the mean LLR between the test files and the target models
00071 // Input NDX Style format with lines "test ID1 ID2" 
00072 // where test is the basename of the test file ID1 and ID2 the ID of the clients
00073 // Output  NIST style Format, depend on value of (segmentalMode)
00074 // completeLLR - all the segments from the testfile are selected are used for computing one LLR by target
00075 //               a line "gender ID decision test score" is added by target
00076 // segmentLLR  - a LLR is computed for each segment of the testfile and each ID
00077 //               a line "ge
00078 
00079 int fexist(char *filename ) {
00080   struct stat buffer;
00081   if ( stat(filename, &buffer ) ) return 1 ;
00082   return 0 ;
00083 }
00084 // WindowLLR class - deals with LLR outputed by set of frames
00085 class WindowLLR{
00086     bool _set;               // flag, indicates if the windowmode is on
00087     unsigned long _size;     // size of the window, in frames
00088     unsigned long _dec;      // shift of the window, in frames, gives the number of outputs
00089     unsigned long _nClient;  // number of different client, 1 by default;
00090     Matrix <double> *_llrM;  // contains the LLR for the window
00091     DoubleVector *_accLlrA;   // contains the accumulated LLR for the window
00092     ULongVector *_idxA;      // contains the idx of frames in the window
00093     unsigned long _bIdx;     // idx of first frame in the circular window
00094     unsigned long _count;    // nb of saved values in the circular window
00095     void _initMem();         // internal use, init the mem booking for score window
00096     void _freeMem();         // internal use, free the memory for
00097 
00098 public:
00099     WindowLLR(Config &config); 
00100     ~WindowLLR();
00101     bool isSet(){return _set;}  
00102     void setNbClient(unsigned long nClient){_nClient=nClient;_initMem();}
00103     unsigned long getIdxBegin(){return (*_idxA)[_bIdx];}
00104     unsigned long getIdxEnd(){return (*_idxA)[(_bIdx+_count-1)%_size];}
00105     void showConfig();
00106     void accLLR(unsigned long clientIdx,double llr);
00107     double getLLR(unsigned long clientIdx);
00108     bool isEnd();
00109     unsigned long wCount(); // gives the number of data/frame in the window 
00110     void dec(unsigned long idxFrame);
00111 };
00112 // windowLLr functions
00113 void WindowLLR::_initMem(){
00114     _freeMem();
00115     _idxA= new ULongVector(_size,_size);
00116     _accLlrA = new DoubleVector(_nClient,_nClient);
00117     _llrM= new Matrix <double>(_size,_nClient);
00118     for (unsigned long idxC=0;idxC<_nClient;idxC++){
00119         for (unsigned long idxF=0;idxF<_size;idxF++)
00120             (*_llrM)(idxF,idxC)=0;
00121         (*_accLlrA)[idxC]=0;
00122     }
00123    
00124     _bIdx=0;
00125     _count=0;
00126 }
00127 void WindowLLR::_freeMem(){
00128     if (_llrM) {
00129         delete _llrM;
00130         delete _accLlrA;
00131         delete _idxA;
00132     }
00133     _llrM=NULL;
00134 }
00135 WindowLLR::WindowLLR(Config &config){
00136     _set=false;
00137     _size=0;
00138     _dec=0;
00139     _bIdx=0;
00140     _count=0;
00141     _nClient=0;
00142     _llrM=NULL;
00143     if (config.existsParam("windowLLR")) _set=config.getParam("windowLLR").toBool();
00144     if (_set){
00145         if (config.existsParam("windowLLRSize")) _size=config.getParam("windowLLRSize").toLong();
00146         else _size=30;
00147         if (config.existsParam("windowLLRDec")) _dec=config.getParam("windowLLRDec").toLong();
00148         else _dec=_size;        
00149         _nClient=1;
00150         _initMem();
00151     }
00152 }
00153 WindowLLR::~WindowLLR(){
00154     _freeMem();}
00155 void WindowLLR::showConfig(){
00156     if (_set) cout<<"windowLLR mode size["<<_size<<"] dec["<<_dec<<"]"<<endl; 
00157 }
00158 unsigned long WindowLLR::wCount(){
00159     return (_count);
00160 }
00161 void WindowLLR::dec(unsigned long idxFrame){
00162     if (_count<_size){       //window is not full
00163         _count++;
00164         unsigned long eIdx=(_bIdx+_count-1)%_size;
00165         (*_idxA)[eIdx]=idxFrame;
00166     }
00167     else{// window is full, real dec (shift the window, step _dec frame)
00168         for (unsigned long wIdx=0;wIdx<_dec;wIdx++){
00169             //suppress the begin value
00170             for (unsigned long cIdx=0;cIdx<_nClient;cIdx++)
00171                 (*_accLlrA)[cIdx]-=(*_llrM)(_bIdx,cIdx);                    
00172             _bIdx=(_bIdx+1)%_size;
00173         }       _count-=(_dec-1);
00174         (*_idxA)[(_bIdx+_count-1)%_size]=idxFrame;      
00175     }   
00176 }
00177 void WindowLLR::accLLR(unsigned long clientIdx,double llr){
00178     (*_llrM)((_bIdx+_count-1)%_size,clientIdx)=llr;
00179     (*_accLlrA)[clientIdx]+=llr;
00180 }
00181 double WindowLLR::getLLR(unsigned long clientIdx){
00182     return (*_accLlrA)[clientIdx]/(double)_size;
00183 }   
00184 bool WindowLLR::isEnd(){
00185     return (wCount()==_size);
00186 }
00187 
00188 
00189 //-------------------------------------------------------------------------------------------------------
00190 int ComputeTest(Config& config)
00191 {
00192   String inputNDXFileName = config.getParam("ndxFilename");                        // NDX inputfile filename - described the experience 
00193   String inputWorldFilename = config.getParam("inputWorldFilename");                   // World model file used for the LLR computation
00194   String outputNISTFileName = config.getParam("outputFilename");                       // Result file in NIST style (.nist) result file format
00195   String labelSelectedFrames =config.getParam("labelSelectedFrames");              // label for selected frames - Only the frames from segments 
00196                                                                                    // with this label  will be used
00197   bool segmentalMode=false;
00198   if (config.existsParam("segmentLLR")) segmentalMode=config.getParam("segmentLLR").toBool();  // selected mode for segmental computation (1 LLR by segment)
00199   String gender=config.getParam("gender");                                         // gives the gender for compatibility reasons with NIST standard output file
00200   WindowLLR windowLLR(config); // Initialize the windowLLR mode if requested
00201   windowLLR.showConfig();
00202   real_t decisionThreshold;
00203   if (config.existsParam("decisionThreshold"))                                     // Define the threshold if needed
00204     decisionThreshold=config.getParam("decisionthreshold").toDouble();
00205   else decisionThreshold=0;
00206   unsigned long maxClientLine=CST_MAX_CLIENT_LINE;                                 // Max of target Id for a ndx line
00207   if (config.existsParam("maxTargetLine")) maxClientLine=config.getParam("maxTargetLine").toLong();
00208   double frameLength = config.getParam("frameLength").toDouble();                  // length in s of a frame
00209   unsigned long nbMaxMixtureInMemory=0;
00210   if (config.existsParam("nbMaxMixtureInMemory")) nbMaxMixtureInMemory=config.getParam("nbMaxMixtureInMemory").toLong();
00211   unsigned long worldDecime=1;
00212   if (config.existsParam("worldDecime")) 
00213     worldDecime=config.getParam("worldDecime").toLong(); 
00214   if (verbose){
00215     cout << "Compute Test, Decime mode["<<worldDecime<<"] ";
00216     if (segmentalMode) cout << " Segmental Mode - 1 LLr by segment"<<endl;
00217     else cout << "File Mode- 1 LLR by file" <<endl;
00218   }
00219   try{
00220     XList ndx(inputNDXFileName,config);                                    // Read the test definition file (ndx)
00221     XLine *linep;                                                          // Pointor on the current test line
00222     ndx.getLine(0);
00223     MixtureServer ms(config);
00224     StatServer ss(config, ms);
00225     MixtureGD& world = ms.loadMixtureGD(inputWorldFilename);               // Load the world model
00226     TabClientLine tabClientLine(ms,config,maxClientLine);                  // Initialize the client tab with 0 preload client
00227     ofstream outNist(outputNISTFileName.c_str(),ios::out | ios::trunc);    // Initialise the output file
00228     while ((linep=ndx.getLine()) != NULL){                                 // Loop on each line of the ndx input file
00229       String &featureFileName=linep->getElement(0);                        // Get the testfile basename
00230       FeatureServer fs(config,featureFileName);                            // Reading the feature file
00231       SegServer segmentsServer;                                                             // Create the segment server for managing the segments/clusters
00232       LabelServer labelServer;                                                              // Create the lable server, for indexing the segments/clusters
00233       initializeClusters(featureFileName,segmentsServer,labelServer,config);                // Reading the segmentation files for each feature input file
00234       verifyClusterFile(segmentsServer,fs,config);                                          // Verify if the segments ending before the end of the feature files...
00235       long codeSelectedFrame=labelServer.getLabelIndexByString(labelSelectedFrames);        // Get the index of the cluster with in interest audio segments
00236       if (codeSelectedFrame==-1)                                                            // The file is empty
00237         cout << "ATTENTION, TEST FILE ["<<featureFileName<<"] is empty"<<endl;
00238       else{
00239         SegCluster& selectedSegments=segmentsServer.getCluster(codeSelectedFrame); // Gives the cluster of the selected/used segments   
00240         TabClientLine tabClientLine(ms,config);                                  // Load if needed the client models
00241         tabClientLine.loadLine(linep);
00242         if (windowLLR.isSet()) windowLLR.setNbClient(tabClientLine.nbClientLine()); // If needed reset the score/LLR window using the good number of client
00243         if (verbose)cout << "test seg["<<featureFileName<<"]"<< endl;
00244         MixtureGDStat &worldAcc=ss.createAndStoreMixtureGDStat(world);
00245         worldAcc.resetLLK();                                                               // Reset the world LLK accumulator
00246         RefVector <MixtureGDStat> clientAcc(tabClientLine.nbClientLine());
00247         for (unsigned int i=0; i<tabClientLine.nbClientLine();i++) {
00248                 clientAcc.addObject(ss.createAndStoreMixtureGDStat(tabClientLine.getClientModel(i)));
00249                 clientAcc[i].resetLLK();                                                           // Reset client i LLK accumulator
00250         }
00251         Seg* seg;                                                                         // reset the reader at the begin of the input stream
00252         selectedSegments.rewind();      
00253         while((seg=selectedSegments.getSeg())!=NULL){                                     // For each of the selected segments
00254           unsigned long idxBeginFrame=seg->begin()+fs.getFirstFeatureIndexOfASource(seg->sourceName()); 
00255           fs.seekFeature(idxBeginFrame); 
00256           Feature f;
00257           for (unsigned long idxFrame=0;idxFrame<seg->length();idxFrame++){               // For each frame of the segment
00258               double llkw=0;
00259               double llkc=0;
00260               fs.readFeature(f);
00261             if ((idxFrame%worldDecime)==0)                                                // We want to compute the world LLK and the top gaussian
00262                 llkw=worldAcc.computeAndAccumulateLLK(f,1.0,DETERMINE_TOP_DISTRIBS);    // Determine the top components and compute wrld LLK
00263             else worldAcc.computeAndAccumulateLLK(f,1.0,USE_TOP_DISTRIBS);       // Determine the top components and compute wrld LLK
00264             if (windowLLR.isSet()) windowLLR.dec(idxBeginFrame+idxFrame);
00265             for (unsigned long i=0;i<tabClientLine.nbClientLine();i++){                             // For each client, compute LLK using the winning
00266                 llkc=clientAcc[i].computeAndAccumulateLLK(f,1.0,USE_TOP_DISTRIBS);
00267                 if (windowLLR.isSet()) windowLLR.accLLR(i,llkc-llkw);
00268             }
00269             if (windowLLR.isSet() && windowLLR.isEnd()){
00270                 for (unsigned long i=0;i < tabClientLine.nbClientLine();i++){                  // For each client
00271                     double LLRClient=windowLLR.getLLR(i);
00272                     char decision=setDecision(LLRClient,decisionThreshold);                     // take a decision 
00273                     outputResultLine(LLRClient, tabClientLine.getClientName(i),                 // Output the result
00274                                      featureFileName, frameIdxToTime(windowLLR.getIdxBegin(),frameLength),frameIdxToTime(windowLLR.getIdxEnd(),frameLength),
00275                                      gender ,decision,outNist);
00276                     if (verboseLevel>1) outputResultLine(LLRClient, tabClientLine.getClientName(i),                 // Output the result
00277                                                          featureFileName, frameIdxToTime(windowLLR.getIdxBegin(),frameLength),frameIdxToTime(windowLLR.getIdxEnd(),frameLength),
00278                                                          gender ,decision,cout);
00279                 }       
00280             }
00281           }  
00282           if (segmentalMode){                                                             // A result is needed for each segment
00283             double LLKWorld=worldAcc.getMeanLLK();                                        // Take the world LLK 
00284             for (unsigned int i=0;i < tabClientLine.nbClientLine();i++){                  // For each client
00285                 double LLKClient=clientAcc[i].getMeanLLK();                               // Get the mean LLK 
00286                 double LLRClient=LLKClient-LLKWorld;                                      // Compute the LLR
00287                 char decision=setDecision(LLRClient,decisionThreshold);                   // take a decision 
00288                 outputResultLine(LLRClient, tabClientLine.getClientName(i),               // Output the result
00289                                  featureFileName, frameIdxToTime(idxBeginFrame,frameLength),frameIdxToTime(idxBeginFrame+seg->length(),frameLength),
00290                                  gender ,decision,outNist);
00291                 if (verboseLevel>1) outputResultLine(LLRClient, tabClientLine.getClientName(i),             
00292                                                      featureFileName, frameIdxToTime(idxBeginFrame,frameLength),frameIdxToTime(idxBeginFrame+seg->length(),frameLength),
00293                                                      gender,decision ,cout);
00294                 clientAcc[i].resetLLK();                                                   // Reset client i LLK accumulator
00295             }  
00296             worldAcc.resetLLK();                                                            // Reset the world LLK accumulator  
00297           }
00298         }
00299         if (segmentalMode==false){                                                          // One result by file and by ID
00300           double LLKWorld=worldAcc.getMeanLLK();                                                 // Take the world LLK
00301           for (unsigned int i=0;i < tabClientLine.nbClientLine();i++){                             // For each client
00302             double LLKClient=clientAcc[i].getMeanLLK();            // Get the mean LLK            
00303             double LLRClient=LLKClient-LLKWorld;                                          // Compute the LLR
00304             char decision=setDecision(LLRClient,decisionThreshold);                       // take a decision 
00305             outputResultLine(LLRClient, tabClientLine.getClientName(i),featureFileName ,gender ,decision,outNist);
00306             if (verboseLevel>1) {
00307               outputResultLine(LLRClient, tabClientLine.getClientName(i),featureFileName ,gender ,decision,cout); 
00308               if (verboseLevel>2) cout<<"** Client LLK:"<<LLKClient<<" UBM LLk:"<<LLKWorld<<endl;
00309             }
00310           }  
00311         }  
00312         clientAcc.deleteAllObjects();
00313       }
00314       if ((nbMaxMixtureInMemory>0)&&(ms.getMixtureCount()>nbMaxMixtureInMemory)){
00315         if (verbose) cout <<"Cleaning the mixture server from 1 to "<<ms.getMixtureCount()<<endl;
00316         ms.deleteMixtures(1,ms.getMixtureCount());  
00317         ms.deleteUnusedDistribs();
00318       } 
00319     }                                                                                   // end of the NDX line loop
00320     outNist.close();
00321   } // fin try
00322   catch (Exception& e){ 
00323     cout << e.toString().c_str() << endl;
00324   }
00325   return 0;
00326 }
00327 
00328 //-------------------------------------------------------------------------------------------------------
00329 //      Compute Test using Dot Product in the JFA framework
00330 //-------------------------------------------------------------------------------------------------------
00331 int ComputeTestDotProduct(Config& config){ 
00332         
00333         String inputNDXFileName = config.getParam("ndxFilename");                                       // NDX inputfile filename - described the experience 
00334         String inputWorldFilename = config.getParam("inputWorldFilename");                      // World model file used for the LLR computation
00335         String outputNISTFileName = config.getParam("outputFilename");                          // Result file in NIST style (.nist) result file format
00336         String labelSelectedFrames =config.getParam("labelSelectedFrames");                     // label for selected frames - Only the frames from segments 
00337         // with this label  will be used
00338         
00339         String gender=config.getParam("gender");                                                                        // gives the gender for compatibility reasons with NIST standard output file
00340         real_t decisionThreshold;
00341         if (config.existsParam("decisionThreshold"))                                                                    // Define the threshold if needed
00342                 decisionThreshold=config.getParam("decisionthreshold").toDouble();
00343         else decisionThreshold=0;
00344         unsigned long maxClientLine=CST_MAX_CLIENT_LINE;                                                // Max of target Id for a ndx line
00345         if (config.existsParam("maxTargetLine"))        maxClientLine=config.getParam("maxTargetLine").toLong();
00346         
00347         if (config.getParam_debug())debug=true;  else debug=false;
00348         
00349         try{   
00350                 XList ndx(inputNDXFileName,config);                                                                     // Read the test definition file (ndx)
00351                 XLine *linep;                                                                                                                   // Pointor on the current test line
00352                 ndx.getLine(0);
00353                 MixtureServer ms(config);
00354                 StatServer ss(config, ms);
00355                 MixtureGD& world = ms.loadMixtureGD(inputWorldFilename);                                // Load the world model
00356                 ofstream outNist(outputNISTFileName.c_str(),ios::out | ios::trunc);                     // Initialise the output file
00357                 
00358                 //Load JFA MAtrices
00359                 Matrix<double> U, V; 
00360                 DoubleVector D;
00361                 
00362                 //Initialise EC matrix
00363                 if(config.existsParam("eigenChannelMatrix")){
00364                         String uName = config.getParam("matrixFilesPath") + config.getParam("eigenChannelMatrix") + config.getParam("loadMatrixFilesExtension");
00365                         U.load (uName, config);
00366                 }
00367                 else{
00368                         unsigned long sS = world.getVectSize() * world.getDistribCount();
00369                         U.setDimensions(1,sS);
00370                         U.setAllValues(0.0);
00371                 }
00372                 
00373                 //Initialise EV matrix
00374                 if(config.existsParam("eigenVoiceMatrix")){
00375                         String vName = config.getParam("matrixFilesPath") + config.getParam("eigenVoiceMatrix") + config.getParam("loadMatrixFilesExtension");
00376                         V.load (vName, config);
00377                 }
00378                 else{
00379                         unsigned long sS = world.getVectSize() * world.getDistribCount();
00380                         V.setDimensions(1,sS);
00381                         V.setAllValues(0.0);
00382                 }
00383                 
00384                 //Initialise D matrix
00385                 if(config.existsParam("DMatrix")){
00386                         String dName = config.getParam("matrixFilesPath") + config.getParam("DMatrix") + config.getParam("loadMatrixFilesExtension");
00387                         Matrix<double> tmpD(dName, config);
00388                         
00389                         if( (tmpD.rows() != 1) || ( tmpD.cols() != world.getVectSize()*world.getDistribCount() ) ){
00390                                 throw Exception("Incorrect dimension of D Matrix",__FILE__,__LINE__);
00391                         }
00392                         else{
00393                                 D.setSize(world.getVectSize()*world.getDistribCount());
00394                                 D.setAllValues(0.0);
00395                                 for(unsigned long i=0; i<world.getVectSize()*world.getDistribCount(); i++){
00396                                         D[i] = tmpD(0,i);
00397                                 }
00398                         }
00399                 }
00400                 else{
00401                         unsigned long sS = world.getVectSize() * world.getDistribCount();
00402                         D.setSize(sS,sS);
00403                         D.setAllValues(0.0);
00404                 }
00405                 
00406                 //Test Loop
00407                 while ((linep=ndx.getLine()) != NULL){
00408                         
00409                         String &featureFileName=linep->getElement(0);                                           //get the testfile basename
00410                         XLine featureFileListp;
00411                         featureFileListp.addElement(linep->getElement(0));                                              //read the name of the test segment file
00412                         XList ndx; ndx.addLine() = featureFileListp;
00413                         JFAAcc jfaAcc(ndx,config);
00414                         
00415                         //Load existing JFA matrices
00416                         jfaAcc.loadEV(V, config); jfaAcc.loadEC(U, config); jfaAcc.loadD(D); 
00417                         
00418                         //Compute JFA stats
00419                         jfaAcc.computeAndAccumulateJFAStat(config);
00420                         
00421                         //Estimate uEuT for the test
00422                         jfaAcc.estimateUEUT(config);
00423                         
00424                         //Estimate and inverse L matrices
00425                         jfaAcc.estimateAndInverseL_EC(config);
00426                         
00427                         //Substract the UBM mean vector from the test segment (Y and X are null at this time)
00428                         jfaAcc.substractMplusVYplusDZ(config);
00429                         
00430                         //Estimate X for the test segment
00431                         jfaAcc.estimateX(config);
00432                         
00433                         //substract (M + Ux)*N
00434                         jfaAcc.substractMplusUX();
00435                         
00436                         double sumN = 0.0;
00437                         double *n = jfaAcc.getN().getArray();
00438                         for(unsigned long i=0; i<jfaAcc.getNDistrib(); i++){
00439                                 sumN += n[i];
00440                         }
00441                         
00442                         double *f_x = jfaAcc.getF_X().getArray();
00443                         for(unsigned long i=0; i<jfaAcc.getSvSize();i++){
00444                                 f_x[i] /=  sumN;
00445                         }
00446                         
00447                         //Target loop
00448                         for(unsigned long i = 1; i< linep->getElementCount(); i++){
00449                                 String &fileName=linep->getElement(i); 
00450                                 
00451                                 //Load client supervector
00452                                 String clientSvFile = config.getParam("vectorFilesPath") + "/" + fileName + config.getParam("vectorFilesExtension");
00453                                 Matrix<double> clientSV( clientSvFile , config);
00454                                 
00455                                 //scores = M*F';
00456                                 double score = 0.0;
00457                                 double *clientsv = clientSV.getArray();
00458                                 for(unsigned long j=0; j<jfaAcc.getSvSize(); j++){
00459                                         score += clientsv[j] * f_x[j];
00460                                 }
00461                                 
00462                                 //Write the score
00463                                 char decision=setDecision(score,decisionThreshold);                       // take a decision
00464                                 outputResultLine(score, fileName,featureFileName ,gender ,decision,outNist);    
00465                         }
00466                 }                                                                                   // end of the NDX line loop
00467                 outNist.close(); 
00468         } // end try
00469         catch (Exception& e){ 
00470                 cout << e.toString().c_str() << endl;
00471         }
00472         return 0;
00473 }
00474 
00475 
00476 //-------------------------------------------------------------------------------------------------------
00477 //      Compute Test using classical GMM in the JFA framework
00478 //-------------------------------------------------------------------------------------------------------
00479 int ComputeTestJFA(Config& config){
00480         
00481         String inputNDXFileName = config.getParam("ndxFilename");                                               // NDX inputfile filename - described the experience 
00482         String inputWorldFilename = config.getParam("inputWorldFilename");                              // World model file used for the LLR computation
00483         String outputNISTFileName = config.getParam("outputFilename");                                  // Result file in NIST style (.nist) result file format
00484         String labelSelectedFrames =config.getParam("labelSelectedFrames");                             // label for selected frames - Only the frames from segments 
00485         // with this label  will be used
00486         
00487         String gender=config.getParam("gender");                                                                        // gives the gender for compatibility reasons with NIST standard output file
00488         real_t decisionThreshold;
00489         if (config.existsParam("decisionThreshold"))                                                                    // Define the threshold if needed
00490                 decisionThreshold=config.getParam("decisionthreshold").toDouble();
00491         else decisionThreshold=0;
00492         unsigned long maxClientLine=CST_MAX_CLIENT_LINE;                                                // Max of target Id for a ndx line
00493         if (config.existsParam("maxTargetLine")) maxClientLine=config.getParam("maxTargetLine").toLong();
00494         unsigned long nbMaxMixtureInMemory=1;                                                           //delete models
00495         if (config.existsParam("nbMaxMixtureInMemory")) nbMaxMixtureInMemory=config.getParam("nbMaxMixtureInMemory").toLong();
00496         unsigned long worldDecime=1;
00497         if (config.existsParam("worldDecime")) 
00498                 worldDecime=config.getParam("worldDecime").toLong(); 
00499         if (config.getParam_debug())debug=true;  else debug=false;
00500         if (verbose){
00501                 cout << "Compute Test, Decime mode["<<worldDecime<<"] ";
00502                 cout << "File Mode- 1 LLR by file" <<endl;
00503         }
00504         
00505         try{   
00506                 
00507                 XList ndx(inputNDXFileName,config);                                                                             // Read the test definition file (ndx)
00508                 XLine *linep;                                                                                                                   // Pointor on the current test line
00509                 ndx.getLine(0);
00510                 MixtureServer ms(config);
00511                 StatServer ss(config, ms);
00512                 MixtureGD& world = ms.loadMixtureGD(inputWorldFilename);                                        // Load the world model
00513                 ofstream outNist(outputNISTFileName.c_str(),ios::out | ios::trunc);                             // Initialise the output file
00514                 
00515                 //Load JFA MAtrices
00516                 Matrix<double> U, V; 
00517                 DoubleVector D;
00518                 
00519                 //Initialise EC matrix
00520                 if(config.existsParam("eigenChannelMatrix")){
00521                         String uName = config.getParam("matrixFilesPath") + config.getParam("eigenChannelMatrix") + config.getParam("loadMatrixFilesExtension");
00522                         U.load (uName, config);
00523                 }
00524                 else{
00525                         U.setDimensions(1,world.getVectSize());
00526                         U.setAllValues(0.0);
00527                 }
00528                 
00529                 //Initialise EV matrix
00530                 if(config.existsParam("eigenVoiceMatrix")){
00531                         String vName = config.getParam("matrixFilesPath") + config.getParam("eigenVoiceMatrix") + config.getParam("loadMatrixFilesExtension");
00532                         V.load (vName, config);
00533                 }
00534                 else{
00535                         V.setDimensions(1,world.getVectSize());
00536                         V.setAllValues(0.0);
00537                 }
00538                 
00539                 //Initialise D matrix
00540                 if(config.existsParam("DMatrix")){
00541                         String dName = config.getParam("matrixFilesPath") + config.getParam("DMatrix") + config.getParam("loadMatrixFilesExtension");
00542                         Matrix<double> tmpD(dName, config);
00543                         
00544                         if( (tmpD.rows() != 1) || ( tmpD.cols() != world.getVectSize()*world.getDistribCount() ) ){
00545                                 throw Exception("Incorrect dimension of D Matrix",__FILE__,__LINE__);
00546                         }
00547                         else{
00548                                 D.setSize(world.getVectSize()*world.getDistribCount());
00549                                 D.setAllValues(0.0);
00550                                 for(unsigned long i=0; i<world.getVectSize()*world.getDistribCount(); i++){
00551                                         D[i] = tmpD(0,i);
00552                                 }
00553                         }
00554                 }
00555                 else{
00556                         D.setSize(world.getVectSize(),world.getVectSize()*world.getDistribCount());
00557                         D.setAllValues(0.0);
00558                 }
00559                 
00560                 //Test Loop
00561                 while ((linep=ndx.getLine()) != NULL){
00562                         
00563                         String &featureFileName=linep->getElement(0);                                                   //get the testfile basename
00564                         XLine featureFileListp;
00565                         featureFileListp.addElement(linep->getElement(0));                                                      //read the name of the test segment file
00566                         XList ndx; ndx.addLine() = featureFileListp;
00567                         JFAAcc jfaAcc(ndx,config);
00568                         
00569                         //ajout
00570                         MixtureGD & tmpWorld=ms.duplicateMixture (ms.getMixtureGD(0), DUPL_DISTRIB);
00571                         
00573                         jfaAcc.loadEV(V, config); jfaAcc.loadEC(U, config); jfaAcc.loadD(D); 
00574                         
00576                         jfaAcc.computeAndAccumulateJFAStat(config);
00577                         
00578                         //IL FAUT FAIRE COMME POUR LE TRAIN : ESTIMATION CONJOINTE DE Y ET X, ENSUITE ON SPLIT
00579                         //ET ON NORMALISE LES TRAMES AVEC UX
00580                         
00581                         
00583                         jfaAcc.estimateUEUT(config);
00584                         
00586                         jfaAcc.estimateAndInverseL_EC(config);
00587                         
00589                         jfaAcc.substractMplusVYplusDZ(config);
00590                         
00592                         jfaAcc.estimateX(config);
00593                         
00595                         FeatureServer fs(config,featureFileName);
00596                         jfaAcc.substractUXfromFeatures(fs,config);
00597                         
00599                         //on estime Ux sur le segment de test
00600                         //DoubleVector UX(jfaAcc.getSvSize()); UX.setSize(jfaAcc.getSvSize());
00601                         //double *ux=UX.getArray();
00602                         //jfaAcc.getUX(UX,featureFileName);
00603                         
00604                         //on shift l'ubm
00605                         //cerr<<"SHIFT THE UBM"<<endl;
00606                         //for(unsigned long i=0; i<jfaAcc.getNDistrib(); i++){
00607                         //      for(unsigned long j=0; j<jfaAcc.getVectSize(); j++){
00608                         //              double sh = ux[i*jfaAcc.getVectSize() + j]+ world.getDistrib(i).getMean(j) ;    
00609                         //              tmpWorld.getDistrib(i).setMean(sh, j);
00610                         //      }
00611                         //}
00613                         
00614                         if (verbose)cout << "---> LogLikelihood Ratio Computation of test segment ["<<featureFileName<<"]"<< endl;      
00615                         
00616                         TabClientLine tabClientLine(ms,config);                                  // Load if needed the client models    
00617                         tabClientLine.loadLine(linep);
00618                         
00619                         
00621                         //for (unsigned int i=0; i<tabClientLine.nbClientLine();i++){           // for each client of the current line
00622                         //      //shift the model by adding UX from the test segment
00623                         //cerr<<"SHIFT THE speaker "<<i<<endl;
00624                         //      for(unsigned long k=0; k<jfaAcc.getNDistrib(); k++){
00625                         //              for(unsigned long j=0; j<jfaAcc.getVectSize(); j++){
00626                         //                      double sh = ux[i*jfaAcc.getVectSize() + j]  + tabClientLine.getClientModel(i).getDistrib(k).getMean(j) ;
00627                         //                      
00628                         //                      tabClientLine.getClientModel(i).getDistrib(k).setMean(sh,j);
00629                         //              }
00630                         //      }
00631                         //}
00633                         
00634                         SegServer segmentsServer;                                                   
00635                         LabelServer labelServer;   
00636                         initializeClusters(featureFileName,segmentsServer,labelServer,config);    
00637                         verifyClusterFile(segmentsServer,fs,config); 
00638                         long codeSelectedFrame=labelServer.getLabelIndexByString(labelSelectedFrames);  
00639                         SegCluster& selectedSegments=segmentsServer.getCluster(codeSelectedFrame); 
00640                         
00641                         MixtureGDStat &worldAcc=ss.createAndStoreMixtureGDStat(world);
00642                         //MixtureGDStat &tmpWorldAcc=ss.createAndStoreMixtureGDStat(tmpWorld);
00643                         
00644                         
00645                         worldAcc.resetLLK();                                                                                                    // Reset the world LLK accumulator
00646                         //tmpWorldAcc.resetLLK();
00647                         
00648                         RefVector <MixtureGDStat> clientAcc(tabClientLine.nbClientLine());
00649                         for (unsigned int i=0; i<tabClientLine.nbClientLine();i++) {
00650                                 clientAcc.addObject(ss.createAndStoreMixtureGDStat(tabClientLine.getClientModel(i)));
00651                                 clientAcc[i].resetLLK();                                                                                        // Reset client i LLK accumulator
00652                         }
00653                         
00654                         Seg* seg;                                                                                                               // reset the reader at the begin of the input stream
00655                         selectedSegments.rewind();      
00656                         while((seg=selectedSegments.getSeg())!=NULL){                                                   // For each of the selected segments
00657                                 unsigned long idxBeginFrame=seg->begin()+fs.getFirstFeatureIndexOfASource(seg->sourceName()); 
00658                                 fs.seekFeature(idxBeginFrame); 
00659                                 Feature f;
00660                                 for (unsigned long idxFrame=0;idxFrame<seg->length();idxFrame++){               // For each frame of the segment
00661                                         double llkw;
00662                                         double llkc;
00663                                         fs.readFeature(f);
00664                                         if ((idxFrame%worldDecime)==0)                                                                                  // We want to compute the world LLK and the top gaussian
00665                                                 llkw=worldAcc.computeAndAccumulateLLK(f,1.0,DETERMINE_TOP_DISTRIBS);            // Determine the top components and compute wrld LLK
00666                                         //llkw=tmpWorldAcc.computeAndAccumulateLLK(f,1.0,DETERMINE_TOP_DISTRIBS);
00667                                         else{ 
00668                                                 worldAcc.computeAndAccumulateLLK(f,1.0,USE_TOP_DISTRIBS);                               // Determine the top components and compute wrld LLK
00669                                                 //tmpWorldAcc.computeAndAccumulateLLK(f,1.0,USE_TOP_DISTRIBS);
00670                                         }
00671                                         for (unsigned long i=0;i<tabClientLine.nbClientLine();i++){                                             // For each client, compute LLK using the winning
00672                                                 llkc=clientAcc[i].computeAndAccumulateLLK(f,1.0,USE_TOP_DISTRIBS);
00673                                         }
00674                                 }  
00675                         }
00676                         
00677                         double LLKWorld=worldAcc.getMeanLLK();                                                          // Take the world LLK
00678                         //double LLKWorld=tmpWorldAcc.getMeanLLK(); 
00679                         for (unsigned int i=0;i < tabClientLine.nbClientLine();i++){                                    // For each client
00680                                 double LLKClient=clientAcc[i].getMeanLLK();            // Get the mean LLK                
00681                                 double LLRClient=LLKClient-LLKWorld;                                          // Compute the LLR
00682                                 char decision=setDecision(LLRClient,decisionThreshold);                       // take a decision 
00683                                 outputResultLine(LLRClient, tabClientLine.getClientName(i),featureFileName ,gender ,decision,outNist);
00684                                 if (verboseLevel>0) {
00685                                         outputResultLine(LLRClient, tabClientLine.getClientName(i),featureFileName ,gender ,decision,cout); 
00686                                         if (verboseLevel>0) cout<<"** Client LLK:"<<LLKClient<<" UBM LLk:"<<LLKWorld<<endl;
00687                                 }
00688                         }  
00689                         clientAcc.deleteAllObjects();
00690                         
00691                         if (verboseLevel > 2) cout << "To be deleted" <<  ms.toString() << endl;          
00692                         if ((nbMaxMixtureInMemory>0)&&(ms.getMixtureCount()>nbMaxMixtureInMemory)){
00693                                 if (verboseLevel >1) cout <<"Cleaning the mixture server from 1 to "<<ms.getMixtureCount()<<endl;
00694                                 ms.deleteMixtures(1,ms.getMixtureCount());  
00695                                 ms.deleteUnusedDistribs();
00696                                 if (verboseLevel > 2) cout << "deleted" <<  ms.toString() << endl;              
00697                         }
00698                         
00699                         
00700                         
00701                         
00702                 }               // end of the NDX line loop
00703                 outNist.close(); 
00704                 
00705         }// fin try
00706         catch (Exception& e){ 
00707                 cout << e.toString().c_str() << endl;
00708         }
00709         return 0;
00710 }
00711 
00712 //-------------------------------------------------------------------------------------------------------
00713 //      Compute Test using classical GMM in the LFA framework
00714 //-------------------------------------------------------------------------------------------------------
00715 int ComputeTestLFA(Config& config){
00716         
00717         String inputNDXFileName = config.getParam("ndxFilename");                                               // NDX inputfile filename - described the experience 
00718         String inputWorldFilename = config.getParam("inputWorldFilename");                              // World model file used for the LLR computation
00719         String outputNISTFileName = config.getParam("outputFilename");                                  // Result file in NIST style (.nist) result file format
00720         String labelSelectedFrames =config.getParam("labelSelectedFrames");                             // label for selected frames - Only the frames from segments 
00721         // with this label  will be used
00722         
00723         String gender=config.getParam("gender");                                                                        // gives the gender for compatibility reasons with NIST standard output file
00724         real_t decisionThreshold;
00725         if (config.existsParam("decisionThreshold"))                                                                    // Define the threshold if needed
00726                 decisionThreshold=config.getParam("decisionthreshold").toDouble();
00727         else decisionThreshold=0;
00728         unsigned long maxClientLine=CST_MAX_CLIENT_LINE;                                                // Max of target Id for a ndx line
00729         if (config.existsParam("maxTargetLine")) maxClientLine=config.getParam("maxTargetLine").toLong();
00730         unsigned long nbMaxMixtureInMemory=1;                                                           //delete models
00731         if (config.existsParam("nbMaxMixtureInMemory")) nbMaxMixtureInMemory=config.getParam("nbMaxMixtureInMemory").toLong();
00732         unsigned long worldDecime=1;
00733         if (config.existsParam("worldDecime")) 
00734                 worldDecime=config.getParam("worldDecime").toLong(); 
00735         if (config.getParam_debug())debug=true;  else debug=false;
00736         if (verbose){
00737                 cout << "Compute Test, Decime mode["<<worldDecime<<"] ";
00738                 cout << "File Mode- 1 LLR by file" <<endl;
00739         }
00740         
00741         try{   
00742                 
00743                 XList ndx(inputNDXFileName,config);                                                                             // Read the test definition file (ndx)
00744                 XLine *linep;                                                                                                                   // Pointor on the current test line
00745                 ndx.getLine(0);
00746                 MixtureServer ms(config);
00747                 StatServer ss(config, ms);
00748                 MixtureGD& world = ms.loadMixtureGD(inputWorldFilename);                                        // Load the world model
00749                 ofstream outNist(outputNISTFileName.c_str(),ios::out | ios::trunc);                             // Initialise the output file
00750                 
00751                 //Load JFA MAtrices
00752                 unsigned long svsize=world.getVectSize()*world.getDistribCount();
00753                 Matrix<double> U, V; 
00754                 DoubleVector D(svsize,svsize);
00755                 
00756                 
00757                 //Initialise EC matrix
00758                 if(config.existsParam("eigenChannelMatrix")){
00759                         String uName = config.getParam("matrixFilesPath") + config.getParam("eigenChannelMatrix") + config.getParam("loadMatrixFilesExtension");
00760                         U.load (uName, config);
00761                 }
00762                 else{
00763                         U.setDimensions(1,world.getVectSize());
00764                         U.setAllValues(0.0);
00765                 }
00766                 
00767                 //Initialise EV matrix
00768                 if(config.existsParam("eigenVoiceMatrix")){
00769                         String vName = config.getParam("matrixFilesPath") + config.getParam("eigenVoiceMatrix") + config.getParam("loadMatrixFilesExtension");
00770                         V.load (vName, config);
00771                 }
00772                 else{
00773                         V.setDimensions(1,world.getVectSize());
00774                         V.setAllValues(0.0);
00775                 }
00776                 
00777                 //Initialise D matrix
00778                 for(unsigned long i=0; i<world.getDistribCount(); i++){
00779                         for(unsigned long j = 0; j<world.getVectSize(); j++){
00780                                 D[i*world.getVectSize()+j] = sqrt(1.0/(world.getDistrib(i).getCovInv(j)*config.getParam("regulationFactor").toDouble()));
00781                         }
00782                 }
00783                 
00784                 //Test Loop
00785                 while ((linep=ndx.getLine()) != NULL){
00786                         
00787                         String &featureFileName=linep->getElement(0);                                                   //get the testfile basename
00788                         XLine featureFileListp;
00789                         
00790                         featureFileListp.addElement(linep->getElement(0));                                                      //read the name of the test segment file
00791                         
00792                         XList ndx; ndx.addLine() = featureFileListp;
00793                         
00794                         JFAAcc jfaAcc(ndx,config);
00795                         
00796                         if(verboseLevel >= 1) cout<<"Compute Likelihood ratio of test segment [ "<<featureFileName<<" ]"<<endl;
00797                         
00799                         jfaAcc.loadEV(V, config); jfaAcc.loadEC(U, config); jfaAcc.loadD(D); 
00800                         
00802                         jfaAcc.computeAndAccumulateJFAStat(config);
00803                         
00804                         jfaAcc.substractMplusDZByChannel();
00805                         jfaAcc.substractMplusUX();
00806                         
00808                         jfaAcc.estimateUEUT(config);
00809                         
00811                         jfaAcc.estimateAndInverseL_EC(config);
00812                         
00814                         jfaAcc.estimateX(config);
00815                         
00816                         jfaAcc.estimateZMAP(config.getParam("regulationFactor").toLong());
00817                         
00818                         FeatureServer fs(config,featureFileName);
00819                         
00821                         jfaAcc.substractUXfromFeatures(fs,config);
00822                         
00823                         //***************************
00824                         //AJOUT LFA, a tester ou mettre en option ???
00825                         //***************************
00826                         if(config.getParam("cms").toBool()){
00827                                 cms(featureFileName,fs,config);
00828                         }
00829                         //***************************
00830                         
00831                         TabClientLine tabClientLine(ms,config);                                  // Load if needed the client models    
00832                         tabClientLine.loadLine(linep);
00833                         
00834                         SegServer segmentsServer;                                                   
00835                         LabelServer labelServer;   
00836                         initializeClusters(featureFileName,segmentsServer,labelServer,config);    
00837                         verifyClusterFile(segmentsServer,fs,config); 
00838                         long codeSelectedFrame=labelServer.getLabelIndexByString(labelSelectedFrames);  
00839                         SegCluster& selectedSegments=segmentsServer.getCluster(codeSelectedFrame); 
00840                         
00841                         MixtureGDStat &worldAcc=ss.createAndStoreMixtureGDStat(world);
00842                         worldAcc.resetLLK(); 
00843                         
00844                         
00845                         RefVector <MixtureGDStat> clientAcc(tabClientLine.nbClientLine());
00846                         for (unsigned int i=0; i<tabClientLine.nbClientLine();i++) {
00847                                 clientAcc.addObject(ss.createAndStoreMixtureGDStat(tabClientLine.getClientModel(i)));
00848                                 clientAcc[i].resetLLK();                                                                                        // Reset client i LLK accumulator
00849                         }
00850                         
00851                         Seg* seg;                                                                                                               // reset the reader at the begin of the input stream
00852                         selectedSegments.rewind();      
00853                         while((seg=selectedSegments.getSeg())!=NULL){                                                   // For each of the selected segments
00854                                 unsigned long idxBeginFrame=seg->begin()+fs.getFirstFeatureIndexOfASource(seg->sourceName()); 
00855                                 fs.seekFeature(idxBeginFrame); 
00856                                 Feature f;
00857                                 for (unsigned long idxFrame=0;idxFrame<seg->length();idxFrame++){               // For each frame of the segment
00858                                         double llkw;
00859                                         double llkc;
00860                                         fs.readFeature(f);
00861                                         if ((idxFrame%worldDecime)==0)                                                                                  // We want to compute the world LLK and the top gaussian
00862                                                 llkw=worldAcc.computeAndAccumulateLLK(f,1.0,DETERMINE_TOP_DISTRIBS);            // Determine the top components and compute wrld LLK
00863                                         
00864                                         else{ 
00865                                                 worldAcc.computeAndAccumulateLLK(f,1.0,USE_TOP_DISTRIBS);                               // Determine the top components and compute wrld LLK
00866                                         }
00867                                         for (unsigned long i=0;i<tabClientLine.nbClientLine();i++){                                             // For each client, compute LLK using the winning
00868                                                 llkc=clientAcc[i].computeAndAccumulateLLK(f,1.0,USE_TOP_DISTRIBS);
00869                                         }
00870                                 }  
00871                         }
00872                         
00873                         double LLKWorld=worldAcc.getMeanLLK();                                              // Take the world LLK
00874                         
00875                         for (unsigned int i=0;i < tabClientLine.nbClientLine();i++){                                            // For each client
00876                                 double LLKClient=clientAcc[i].getMeanLLK();                                                                             // Get the mean LLK               
00877                                 double LLRClient=LLKClient-LLKWorld;                                                                                            // Compute the LLR
00878                                 char decision=setDecision(LLRClient,decisionThreshold);                                                 // take a decision 
00879                                 outputResultLine(LLRClient, tabClientLine.getClientName(i),featureFileName ,gender ,decision,outNist);
00880                                 if (verboseLevel>0) {
00881                                         outputResultLine(LLRClient, tabClientLine.getClientName(i),featureFileName ,gender ,decision,cout); 
00882                                         if (verboseLevel>0) cout<<"** Client LLK:"<<LLKClient<<" UBM LLk:"<<LLKWorld<<endl;
00883                                 }
00884                         }  
00885                         clientAcc.deleteAllObjects();
00886                         
00887                         if (verboseLevel > 2) cout << "To be deleted" <<  ms.toString() << endl;          
00888                         if ((nbMaxMixtureInMemory>0)&&(ms.getMixtureCount()>nbMaxMixtureInMemory)){
00889                                 if (verboseLevel >1) cout <<"Cleaning the mixture server from 1 to "<<ms.getMixtureCount()<<endl;
00890                                 ms.deleteMixtures(1,ms.getMixtureCount());  
00891                                 ms.deleteUnusedDistribs();
00892                                 if (verboseLevel > 2) cout << "deleted" <<  ms.toString() << endl;              
00893                         }
00894                 }               // end of the NDX line loop
00895                 outNist.close(); 
00896                 
00897         }// fin try
00898         catch (Exception& e){ 
00899                 cout << e.toString().c_str() << endl;
00900         }
00901         return 0;
00902 }
00903 
00904 int ComputeTestFA(Config& config)
00905 { 
00906   String inputNDXFileName = config.getParam("ndxFilename");                        // NDX inputfile filename - described the experience 
00907   String inputWorldFilename = config.getParam("inputWorldFilename");                   // World model file used for the LLR computation
00908   String outputNISTFileName = config.getParam("outputFilename");                       // Result file in NIST style (.nist) result file format
00909   String labelSelectedFrames =config.getParam("labelSelectedFrames");              // label for selected frames - Only the frames from segments 
00910                                                                                    // with this label  will be used
00911   bool segmentalMode=(config.getParam("segmentalMode")=="segmentLLR");             // selected mode for segmental computation (1 LLR by file or by segment)
00912   String gender=config.getParam("gender");                                         // gives the gender for compatibility reasons with NIST standard output file
00913   real_t decisionThreshold;
00914   if (config.existsParam("decisionThreshold"))                                     // Define the threshold if needed
00915     decisionThreshold=config.getParam("decisionthreshold").toDouble();
00916   else decisionThreshold=0;
00917   unsigned long maxClientLine=CST_MAX_CLIENT_LINE;                                 // Max of target Id for a ndx line
00918   if (config.existsParam("maxTargetLine")) maxClientLine=config.getParam("maxTargetLine").toLong();
00919   //double frameLength = config.getParam("frameLength").toDouble();                  // length in s of a frame    
00920   unsigned long nbMaxMixtureInMemory=1;
00921   if (config.existsParam("nbMaxMixtureInMemory")) nbMaxMixtureInMemory=config.getParam("nbMaxMixtureInMemory").toLong();
00922   unsigned long worldDecime=1;
00923   if (config.existsParam("worldDecime")) 
00924     worldDecime=config.getParam("worldDecime").toLong(); 
00925   if (config.getParam_debug())debug=true;  else debug=false;
00926     if (verbose){
00927     cout << "(Compute Test) Decime mode["<<worldDecime<<"] ";
00928     if (segmentalMode) cout << " Segmental Mode - 1 LLr by segment"<<endl;
00929     else cout << "File Mode- 1 LLR by file" <<endl;
00930     }
00931         if (verbose) cout << "(ComputeTest) Factor Analysis mode for channel effect" << endl; 
00932 
00933             
00934  try{   
00935     XList ndx(inputNDXFileName,config);                                    // Read the test definition file (ndx)
00936     XLine *linep;                                                          // Pointor on the current test line
00937     ndx.getLine(0);
00938     MixtureServer ms(config);
00939     StatServer ss(config, ms);
00940     MixtureGD& world = ms.loadMixtureGD(inputWorldFilename);               // Load the world model
00941     TabClientLine tabClientLine(ms,config,maxClientLine);                  // Initialize the client tab with 0 preload client   
00942     ofstream outNist(outputNISTFileName.c_str(),ios::out | ios::trunc);    // Initialise the output file
00943     
00944     while ((linep=ndx.getLine()) != NULL){                                 // Loop on each line of the ndx input file
00945       String &featureFileName=linep->getElement(0);                        // Get the testfile basename
00946 
00947         FeatureServer fs(config,featureFileName);                            // Reading the feature file                    
00948         /*TopGauss tg;
00949         tg.compute(world,fs,featureFileName,config);
00950         tg.write(featureFileName,config); // to remove but need by generalFAStats         */  
00951         FactorAnalysisStat FAAcc(featureFileName,fs,config);        
00952         FAAcc.estimateXYAndNorm(fs,config);
00953         cms(featureFileName,fs,config);
00954 
00955         if (verbose)cout << "---> LogLikelihood Ratio Computation of test segment ["<<featureFileName<<"]"<< endl;      
00956         TabClientLine tabClientLine(ms,config);                                  // Load if needed the client models    
00957         tabClientLine.loadLine(linep);          
00958 
00959         /*********************
00960         Scoring with the TopGauss class, there is still a pb here
00961         *********************
00962         double llkw=tg.get(world,fs,featureFileName,config);    
00963         RealVector <double> llk;        
00964         llk.setSize(tabClientLine.nbClientLine());
00965         for (unsigned int i=0; i<tabClientLine.nbClientLine();i++)      
00966                 llk[i]=tg.get(tabClientLine.getClientModel(i),fs,featureFileName,config);
00967         
00968         for (unsigned int i=0;i < tabClientLine.nbClientLine();i++){                             // For each client
00969                 double LLRClient=llk[i]-llkw;                                          // Compute the LLR
00970                 char decision=setDecision(LLRClient,decisionThreshold);                       // take a decision 
00971                 if (verboseLevel>1){ 
00972                         outputResultLine(LLRClient, tabClientLine.getClientName(i),featureFileName ,gender ,decision,cout); 
00973                         cout<<"** C:"<<llk[i]<<" W:"<<llkw<<endl;        
00974                 }
00975                 outputResultLine(LLRClient, tabClientLine.getClientName(i),featureFileName ,gender ,decision,outNist);
00976         }*/
00977 
00978         SegServer segmentsServer;                                                   
00979         LabelServer labelServer;   
00980         initializeClusters(featureFileName,segmentsServer,labelServer,config);    
00981         verifyClusterFile(segmentsServer,fs,config); 
00982         long codeSelectedFrame=labelServer.getLabelIndexByString(labelSelectedFrames);  
00983         SegCluster& selectedSegments=segmentsServer.getCluster(codeSelectedFrame); 
00984         
00985         MixtureGDStat &worldAcc=ss.createAndStoreMixtureGDStat(world);
00986         worldAcc.resetLLK();                                                               // Reset the world LLK accumulator
00987         RefVector <MixtureGDStat> clientAcc(tabClientLine.nbClientLine());
00988         for (unsigned int i=0; i<tabClientLine.nbClientLine();i++) {
00989                 clientAcc.addObject(ss.createAndStoreMixtureGDStat(tabClientLine.getClientModel(i)));
00990                 clientAcc[i].resetLLK();                                                           // Reset client i LLK accumulator
00991         }
00992         Seg* seg;                                                                         // reset the reader at the begin of the input stream
00993         selectedSegments.rewind();      
00994         while((seg=selectedSegments.getSeg())!=NULL){                                      // For each of the selected segments
00995           unsigned long idxBeginFrame=seg->begin()+fs.getFirstFeatureIndexOfASource(seg->sourceName()); 
00996           fs.seekFeature(idxBeginFrame); 
00997           Feature f;
00998           for (unsigned long idxFrame=0;idxFrame<seg->length();idxFrame++){               // For each frame of the segment
00999               double llkw;
01000               double llkc;
01001               fs.readFeature(f);
01002             if ((idxFrame%worldDecime)==0)                                                // We want to compute the world LLK and the top gaussian
01003                 llkw=worldAcc.computeAndAccumulateLLK(f,1.0,DETERMINE_TOP_DISTRIBS);    // Determine the top components and compute wrld LLK
01004             else worldAcc.computeAndAccumulateLLK(f,1.0,USE_TOP_DISTRIBS);       // Determine the top components and compute wrld LLK
01005             for (unsigned long i=0;i<tabClientLine.nbClientLine();i++){                             // For each client, compute LLK using the winning
01006                 llkc=clientAcc[i].computeAndAccumulateLLK(f,1.0,USE_TOP_DISTRIBS);
01007             }
01008           }  
01009         }
01010         if (segmentalMode==false){                                                          // One result by file and by ID
01011           double LLKWorld=worldAcc.getMeanLLK();                                                 // Take the world LLK
01012           for (unsigned int i=0;i < tabClientLine.nbClientLine();i++){                             // For each client
01013             double LLKClient=clientAcc[i].getMeanLLK();            // Get the mean LLK            
01014             double LLRClient=LLKClient-LLKWorld;                                          // Compute the LLR
01015             char decision=setDecision(LLRClient,decisionThreshold);                       // take a decision 
01016             outputResultLine(LLRClient, tabClientLine.getClientName(i),featureFileName ,gender ,decision,outNist);
01017             if (verboseLevel>0) {
01018               outputResultLine(LLRClient, tabClientLine.getClientName(i),featureFileName ,gender ,decision,cout); 
01019               if (verboseLevel>0) cout<<"** Client LLK:"<<LLKClient<<" UBM LLk:"<<LLKWorld<<endl;
01020             }
01021           }  
01022         }  
01023 
01024         clientAcc.deleteAllObjects();
01025         
01026         if (verboseLevel > 2) cout << "To be deleted" <<  ms.toString() << endl;          
01027         if ((nbMaxMixtureInMemory>0)&&(ms.getMixtureCount()>nbMaxMixtureInMemory)){
01028         if (verboseLevel >1) cout <<"Cleaning the mixture server from 1 to "<<ms.getMixtureCount()<<endl;
01029         ms.deleteMixtures(1,ms.getMixtureCount());  
01030         ms.deleteUnusedDistribs();
01031         if (verboseLevel > 2) cout << "deleted" <<  ms.toString() << endl;              
01032       } 
01033     }                                                                                   // end of the NDX line loop
01034     outNist.close(); 
01035   } // fin try
01036   catch (Exception& e){ 
01037     cout << e.toString().c_str() << endl;
01038   }
01039   return 0;
01040 }
01041 
01042 int ComputeTestNAP(Config& config)
01043 {
01044   String inputNDXFileName = config.getParam("ndxFilename");                        // NDX inputfile filename - described the experience 
01045   String inputWorldFilename = config.getParam("inputWorldFilename");                   // World model file used for the LLR computation
01046   String outputNISTFileName = config.getParam("outputFilename");                       // Result file in NIST style (.nist) result file format
01047   String labelSelectedFrames =config.getParam("labelSelectedFrames");              // label for selected frames - Only the frames from segments 
01048                                                                                    // with this label  will be used
01049   bool segmentalMode=(config.getParam("segmentalMode")=="segmentLLR");             // selected mode for segmental computation (1 LLR by file or by segment)
01050   String gender=config.getParam("gender");                                         // gives the gender for compatibility reasons with NIST standard output file
01051   real_t decisionThreshold;
01052   if (config.existsParam("decisionThreshold"))                                     // Define the threshold if needed
01053     decisionThreshold=config.getParam("decisionthreshold").toDouble();
01054   else decisionThreshold=0;
01055   unsigned long maxClientLine=CST_MAX_CLIENT_LINE;                                 // Max of target Id for a ndx line
01056   if (config.existsParam("maxTargetLine")) maxClientLine=config.getParam("maxTargetLine").toLong();
01057   double frameLength = config.getParam("frameLength").toDouble();                  // length in s of a frame
01058   unsigned long nbMaxMixtureInMemory=1; //delete models
01059   if (config.existsParam("nbMaxMixtureInMemory")) nbMaxMixtureInMemory=config.getParam("nbMaxMixtureInMemory").toLong();
01060   unsigned long worldDecime=1;
01061   if (config.existsParam("worldDecime")) 
01062     worldDecime=config.getParam("worldDecime").toLong(); 
01063   if (config.getParam_debug())debug=true;  else debug=false;
01064     if (verbose){
01065     cout << "Compute Test, Decime mode["<<worldDecime<<"] ";
01066     if (segmentalMode) cout << " Segmental Mode - 1 LLr by segment"<<endl;
01067     else cout << "File Mode- 1 LLR by file" <<endl;
01068     }
01069     bool UBM=false;
01070     bool NAP=false;
01071     if (config.getParam("channelCompensation")=="NAP" && verbose) {cout << "NAP mode for channel effect" << endl; NAP=true;}
01072     else if (config.getParam("channelCompensation")=="UBM") {if (verbose) cout << "NAP mode for channel effect [W: add UBM channel effect]" << endl;UBM=true;}   
01073     else throw Exception("channelCompensation parameter is wrong",__FILE__,__LINE__);
01074             
01075  try{   
01076     XList ndx(inputNDXFileName,config);                                    // Read the test definition file (ndx)
01077     XLine *linep;                                                          // Pointor on the current test line
01078     ndx.getLine(0);
01079     MixtureServer ms(config);
01080     StatServer ss(config, ms);
01081     MixtureGD& world = ms.loadMixtureGD(inputWorldFilename);               // Load the world model
01082     TabClientLine tabClientLine(ms,config,1);              // Initialize the client tab with 0 preload client   
01083     ofstream outNist(outputNISTFileName.c_str(),ios::out | ios::trunc);    // Initialise the output file
01084     
01085     Matrix<double> ChannelMatrix;
01086     ChannelMatrix.load(config.getParam("initChannelMatrix"),config); //get Channel Matrix from args and load in a Matrix object  
01087     if (verbose) cout<< "Removing channel effect from " << config.getParam("initChannelMatrix") << " of size: ["<< ChannelMatrix.rows() << "," <<ChannelMatrix.cols() << "]" << endl; 
01088     unsigned long svSize=world.getDistribCount()*ms.getVectSize();
01089     RealVector <double> channelVector(svSize,svSize);
01090     
01091     while ((linep=ndx.getLine()) != NULL){                                 // Loop on each line of the ndx input file
01092       String &featureFileName=linep->getElement(0);                        // Get the testfile basename
01093       MixtureGD &testModel=ms.createMixtureGD();    // create mixture for test model
01094       if (NAP) ms.loadMixture(testModel,featureFileName); // for nap, get test model
01095       FeatureServer fs(config,featureFileName);                            // Reading the feature file
01096       SegServer segmentsServer;                                                             // Create the segment server for managing the segments/clusters
01097       LabelServer labelServer;                                                              // Create the lable server, for indexing the segments/clusters
01098       initializeClusters(featureFileName,segmentsServer,labelServer,config);                // Reading the segmentation files for each feature input file
01099       verifyClusterFile(segmentsServer,fs,config);                                          // Verify if the segments ending before the end of the feature files...
01100       long codeSelectedFrame=labelServer.getLabelIndexByString(labelSelectedFrames);        // Get the index of the cluster with in interest audio segments
01101       if (codeSelectedFrame==-1)                                                            // The file is empty
01102         cout << "WARNING, TEST FILE ["<<featureFileName<<"] is empty"<<endl;
01103       else{
01104         SegCluster& selectedSegments=segmentsServer.getCluster(codeSelectedFrame); // Gives the cluster of the selected/used segments   
01105         TabClientLine tabClientLine(ms,config);                                  // Load if needed the client models  
01106         tabClientLine.loadLine(linep);
01107         if (verboseLevel > 2) cout << "Load line :  " << ms.toString() << endl;
01108         for (unsigned int i=0; i<tabClientLine.nbClientLine();i++) {
01109                         if (verbose) cout << "---> Compute Test Channel effect for: [" << featureFileName <<"]["<<tabClientLine.getClientModel(i).getId()<<"]"<<endl;
01110                         if (UBM) computeNAPChannelEffect(world,tabClientLine.getClientModel(i),ChannelMatrix);                          
01111                         if (NAP) computeNAPChannelEffect(testModel,tabClientLine.getClientModel(i),ChannelMatrix);
01112         }
01113         if (verbose)cout << "---> LogLikelihood Ratio Computation of test segment ["<<featureFileName<<"]"<< endl;
01114         MixtureGDStat &worldAcc=ss.createAndStoreMixtureGDStat(world);
01115         worldAcc.resetLLK();                                                               // Reset the world LLK accumulator
01116         RefVector <MixtureGDStat> clientAcc(tabClientLine.nbClientLine());
01117         for (unsigned int i=0; i<tabClientLine.nbClientLine();i++) {
01118                 clientAcc.addObject(ss.createAndStoreMixtureGDStat(tabClientLine.getClientModel(i)));
01119                 clientAcc[i].resetLLK();                                                           // Reset client i LLK accumulator
01120         }
01121         
01122         Seg* seg;                                                                         // reset the reader at the begin of the input stream
01123         selectedSegments.rewind();      
01124 
01125         while((seg=selectedSegments.getSeg())!=NULL){                                     // For each of the selected segments
01126           unsigned long idxBeginFrame=seg->begin()+fs.getFirstFeatureIndexOfASource(seg->sourceName()); 
01127           fs.seekFeature(idxBeginFrame); 
01128           Feature f;
01129           for (unsigned long idxFrame=0;idxFrame<seg->length();idxFrame++){               // For each frame of the segment
01130             fs.readFeature(f);
01131             if ((idxFrame%worldDecime)==0)                                                // We want to compute the world LLK and the top gaussian
01132               worldAcc.computeAndAccumulateLLK(f,1.0,DETERMINE_TOP_DISTRIBS);    // Determine the top components and compute wrld LLK
01133             else worldAcc.computeAndAccumulateLLK(f,1.0,USE_TOP_DISTRIBS);       // Determine the top components and compute wrld LLK
01134             for (unsigned int i=0;i<tabClientLine.nbClientLine();i++)                             // For each client, compute LLK using the winning
01135               clientAcc[i].computeAndAccumulateLLK(f,1.0,USE_TOP_DISTRIBS);
01136           }  
01137           if (segmentalMode){                                                             // A result is needed for each segment
01138             double LLKWorld=worldAcc.getMeanLLK();                                         // Take the world LLK        
01139             for (unsigned int i=0;i < tabClientLine.nbClientLine();i++){                  // For each client
01140               double LLKClient=clientAcc[i].getMeanLLK();            // Get the mean LLK 
01141               double LLRClient=LLKClient-LLKWorld;                                        // Compute the LLR
01142               char decision=setDecision(LLRClient,decisionThreshold);                     // take a decision 
01143               outputResultLine(LLRClient, tabClientLine.getClientName(i),                 // Output the result
01144                                featureFileName, frameIdxToTime(idxBeginFrame,frameLength),frameIdxToTime(idxBeginFrame+seg->length(),frameLength),
01145                                gender ,decision,outNist);
01146               if (verboseLevel>1) outputResultLine(LLRClient, tabClientLine.getClientName(i),             
01147                                             featureFileName, frameIdxToTime(idxBeginFrame,frameLength),frameIdxToTime(idxBeginFrame+seg->length(),frameLength),
01148                                             gender,decision ,cout);
01149               clientAcc[i].resetLLK();                               // Reset client i LLK accumulator
01150             }  
01151             worldAcc.resetLLK();                                                           // Reset the world LLK accumulator  
01152           }
01153         }
01154         if (segmentalMode==false){                                                        // One result by file and by ID
01155           double LLKWorld=worldAcc.getMeanLLK();                                                 // Take the world LLK
01156           for (unsigned int i=0;i < tabClientLine.nbClientLine();i++){                             // For each client
01157             double LLKClient=clientAcc[i].getMeanLLK();            // Get the mean LLK 
01158             double LLRClient=LLKClient-LLKWorld;                                          // Compute the LLR
01159             char decision=setDecision(LLRClient,decisionThreshold);                       // take a decision 
01160             outputResultLine(LLRClient, tabClientLine.getClientName(i),featureFileName ,gender ,decision,outNist);
01161             if (verboseLevel>1) {
01162               outputResultLine(LLRClient, tabClientLine.getClientName(i),featureFileName ,gender ,decision,cout); 
01163               if (verboseLevel>2) cout<<"** C:"<<LLKClient<<" W:"<<LLKWorld<<endl;
01164             }
01165           }  
01166         }  
01167       } 
01168         if (verboseLevel > 2) cout << "To be deleted" <<  ms.toString() << endl;          
01169         if ((nbMaxMixtureInMemory>0)&&(ms.getMixtureCount()>nbMaxMixtureInMemory)){
01170         if (verboseLevel >1) cout <<"Cleaning the mixture server from 1 to "<<ms.getMixtureCount()<<endl;
01171         ms.deleteMixtures(1,ms.getMixtureCount());  
01172         ms.deleteUnusedDistribs();
01173         if (verboseLevel > 2) cout << "deleted" <<  ms.toString() << endl;              
01174       } 
01175     }                                                                                   // end of the NDX line loop
01176     outNist.close();
01177   } // fin try
01178   catch (Exception& e){ 
01179     cout << e.toString().c_str() << endl;
01180   }
01181   return 0;
01182 }
01183 
01184 
01185 //-------------------------------------------------------------------------------------------------------
01186 int ComputeTestByLabel(Config& config)
01187 {
01188   String inputNDXFileName = config.getParam("ndxFileName");                        // NDX inputfile filename - described the experience 
01189   String inputWorldFilename = config.getParam("inputWorldFilename");                   // World model file used for the LLR computation
01190   String outputNISTFileName = config.getParam("outputFile");                       // Result file in NIST style (.nist) result file format
01191   //bool segmentalMode=(config.getParam("segmentalMode")=="segmentLLR");             // selected mode for segmental computation (1 LLR by file or by segment)
01192   String gender=config.getParam("gender");                                         // gives the gender for compatibility reasons with NIST standard output file
01193   real_t decisionThreshold;
01194   if (config.existsParam("decisionThreshold"))                                     // Define the threshold if needed
01195     decisionThreshold=config.getParam("decisionthreshold").toDouble();
01196   else decisionThreshold=0;
01197   unsigned long worldDecime=1;
01198   if (config.existsParam("worldDecime")) 
01199     worldDecime=config.getParam("worldDecime").toLong(); 
01200   unsigned long maxClientLine=CST_MAX_CLIENT_LINE;                                 // Max of target Id for a ndx line
01201   if (config.existsParam("maxTargetLine")) maxClientLine=config.getParam("maxTargetLine").toLong();
01202   bool useDefaultClientModel=true;                                                 // If a label model is missing, use the client model
01203   if (config.existsParam("useDefaultClientModel"))  useDefaultClientModel=(config.getParam("useDefaultClientModel")=="true");
01204   bool byUserRep=false;
01205   if (config.existsParam("byUserRep"))  byUserRep=(config.getParam("byUserRep")=="true");
01206 
01207   bool weigthedFusion=true;
01208   if (config.existsParam("weigthedFusion"))  weigthedFusion=(config.getParam("weigthedFusion")=="true");
01209   //double frameLength = config.getParam("frameLength").toDouble();                  // length in s of a frame : N.S. useless
01210   
01211   unsigned long nbMaxMixtureInMemory=0;
01212   if (config.existsParam("nbMaxMixtureInMemory")) nbMaxMixtureInMemory=config.getParam("nbMaxMixtureInMemory").toLong();
01213   bool verboseAll=false;
01214   if (config.existsParam("verboseAll"))verboseAll=true; else verboseAll=false;
01215   if (verbose){
01216     cout << "Compute Test -by label model option, world decime["<<worldDecime<<"]";
01217     if (useDefaultClientModel) cout <<" Use default client model if a label model is missing";
01218     if (byUserRep) cout <<" the label models are in a by user rep user/user_label.gmm";
01219       cout <<endl;
01220   }
01221   try{
01222     XList ndx(inputNDXFileName,config);                                    // Read the test definition file (ndx)
01223     XLine *linep;                                                          // Pointor on the current test line
01224     ndx.getLine(0);
01225     MixtureServer ms(config);
01226     StatServer ss(config, ms);
01227     MixtureGD& world = ms.loadMixtureGD(inputWorldFilename);               // Load the world model
01228     TabClientLine tabClientLine(ms,config,maxClientLine);                  // Initialize the client tab with 0 preload client
01229     ofstream outNist(outputNISTFileName.c_str(),ios::out | ios::trunc);    // Initialise the output file
01230     while ((linep=ndx.getLine()) != NULL){                                 // Loop on each line of the ndx input file
01231       String &featureFileName=linep->getElement(0);                        // Get the testfile basename
01232       FeatureServer fs(config,featureFileName);                            // Reading the feature file
01233       SegServer segmentsServer;                                                             // Create the segment server for managing the segments/clusters
01234       LabelServer labelServer;                                                              // Create the lable server, for indexing the segments/clusters
01235       initializeClusters(featureFileName,segmentsServer,labelServer,config);                // Reading the segmentation files for each feature input file
01236       verifyClusterFile(segmentsServer,fs,config);                                          // Verify if the segments ending before the end of the feature files..
01237       TabClientLine tabClientLine(ms,config);                                         
01238       ScoreAccum accumScore;                                                                // The LLR accumulator for each client (label result fusion) 
01239       for (unsigned long codeSelectedFrame=0;codeSelectedFrame<segmentsServer.getClusterCount();codeSelectedFrame++){ // For each cluster
01240         String label=labelServer.getLabel(codeSelectedFrame).getString();                   // Get the label name for the current cluster
01241         if (verbose) cout <<"test seg["<<featureFileName<<"] Label ["<<label<<"]"<<endl;   
01242         if (tabClientLine.loadLine(linep,label,useDefaultClientModel,byUserRep)){           // Load if needed the client models by label  - return 0 if no model
01243           SegCluster& selectedSegments=segmentsServer.getCluster(codeSelectedFrame);          // Gives the current cluster    
01244           ss.resetLLK(world);                                                                 // Reset the world LLK accumulator
01245           for (unsigned int i=0; i<tabClientLine.nbClientLine();i++)
01246             ss.resetLLK(tabClientLine.getClientModel(i));                                     // Reset client i LLK accumulator
01247           Seg* seg;                                                                           // reset the reader at the begin of the input stream
01248           selectedSegments.rewind(); 
01249           unsigned long nbFrame=0;
01250           while((seg=selectedSegments.getSeg())!=NULL){                                       // For each of the selected segments
01251             unsigned long idxBeginFrame=seg->begin()+fs.getFirstFeatureIndexOfASource(seg->sourceName()); 
01252             fs.seekFeature(idxBeginFrame); 
01253             Feature f;
01254             nbFrame++;
01255             for (unsigned long idxFrame=0;idxFrame<seg->length();idxFrame++){    // For each frame of the segment
01256               fs.readFeature(f);
01257               if ((idxFrame%worldDecime)==0)                                                // We want to compute the world LLK and the top gaussian
01258                 ss.computeAndAccumulateLLK(world, f,DETERMINE_TOP_DISTRIBS);    // Determine the top components and compute wrld LLK
01259               else ss.computeAndAccumulateLLK(world, f,USE_TOP_DISTRIBS);       // Determine the top components and compute wrld LLK
01260               for (unsigned int i=0;i<tabClientLine.nbClientLine();i++)                              // For each client, compute LLK using the winning
01261                 ss.computeAndAccumulateLLK(tabClientLine.getClientModel(i),f,USE_TOP_DISTRIBS);
01262             }
01263           }
01264           double LLKWorld=ss.getMeanLLK(world);                                             // Take the world LLK       
01265           for (unsigned int i=0;i < tabClientLine.nbClientLine();i++){                               // For each client
01266             double LLKClient=ss.getMeanLLK(tabClientLine.getClientModel(i));                // Get the mean LLK 
01267             double LLRClient=LLKClient-LLKWorld;                                            // Compute the LLR
01268             char decision=setDecision(LLRClient,decisionThreshold);                         // take a decision 
01269             outputResultLine(LLRClient, tabClientLine.getClientName(i)+"_"+label,featureFileName ,gender ,decision,outNist);
01270             if (verboseAll) {
01271               outputResultLine(LLRClient, tabClientLine.getClientName(i)+"_"+label,featureFileName ,gender ,decision,cout); 
01272               cout<<"** C:"<<LLKClient<<" W:"<<LLKWorld<<endl;
01273             }
01274             if (weigthedFusion) accumScore.addAndAccumulate(tabClientLine.getClientName(i),LLRClient,nbFrame);
01275             else accumScore.addAndAccumulate(tabClientLine.getClientName(i),LLRClient,1);
01276           }
01277         } // end of test - no model in the line
01278       }                                                                                    // end of cluster loop (label loop)
01279       for (unsigned int i=0;i < accumScore.getSize();i++){                                          // For each client
01280         char decision=setDecision(accumScore.getScore(i),decisionThreshold);               // take a decision 
01281         outputResultLine(accumScore.getScore(i), accumScore.getId(i),featureFileName ,gender ,decision,outNist);
01282         if (verboseAll)outputResultLine(accumScore.getScore(i),accumScore.getId(i),featureFileName ,gender ,decision,cout);     
01283       }  
01284       if ((nbMaxMixtureInMemory>0)&&(ms.getMixtureCount()>nbMaxMixtureInMemory)){
01285         if (verbose) cout <<"Cleaning the mixture server from 1 to "<<ms.getMixtureCount()<<endl;
01286         ms.deleteMixtures(1,ms.getMixtureCount());  
01287         ms.deleteUnusedDistribs();
01288       }
01289     }                                                                                      // end of the NDX line loop
01290     outNist.close();
01291   } // fin try
01292   catch (Exception& e){ 
01293     cout << e.toString().c_str() << endl;
01294   }
01295   return 0;
01296 }
01297 
01298 //-------------------------------------------------------------------------------------------------------------
01299 // Compute Histos and OutputEntropy
01300 int ComputeTestHisto(Config& config)
01301 {
01302   String inputNDXFileName = config.getParam("ndxFileName");                        // NDX inputfile filename - described the experience 
01303   String inputWorldFilename = config.getParam("inputWorldFilename");                   // World model file used for the LLR computation
01304   String outputNISTFileName = config.getParam("outputFile");                       // Result file in NIST style (.nist) result file format
01305   String labelSelectedFrames =config.getParam("labelSelectedFrames");              // label for selected frames - Only the frames from segments 
01306                                                                                    // with this label  will be used
01307   bool segmentalMode=(config.getParam("segmentalMode")=="segmentLLR");             // selected mode for segmental computation (1 LLR by file or by segment)
01308   String gender=config.getParam("gender");                                         // gives the gender for compatibility reasons with NIST standard output file
01309   real_t decisionThreshold;
01310   if (config.existsParam("decisionThreshold"))                                     // Define the threshold if needed
01311     decisionThreshold=config.getParam("decisionthreshold").toDouble();
01312   else decisionThreshold=0;
01313   unsigned long maxClientLine=CST_MAX_CLIENT_LINE;                                 // Max of target Id for a ndx line
01314   if (config.existsParam("maxTargetLine")) maxClientLine=config.getParam("maxTargetLine").toLong();
01315   unsigned long nbBins=config.getParam("nbBins").toLong();
01316   //double frameLength = config.getParam("frameLength").toDouble();                  // length in s of a frame
01317   unsigned long nbMaxMixtureInMemory=0;
01318   if (config.existsParam("nbMaxMixtureInMemory")) nbMaxMixtureInMemory=config.getParam("nbMaxMixtureInMemory").toLong();
01319   unsigned long worldDecime=1;
01320   if (config.existsParam("worldDecime")) 
01321     worldDecime=config.getParam("worldDecime").toLong(); 
01322   if (config.existsParam("debug"))debug=true;  else debug=false;
01323   if (config.existsParam("verbose"))verbose=true; else verbose=false;
01324   bool verboseAll=false;
01325   if (config.existsParam("verboseAll"))verboseAll=true; else verboseAll=false;
01326   String scoreType=config.getParam("scoreType");
01327   if (verbose){
01328     cout << "**** Likelihood Ratio will be computed with Histo ****" << endl;
01329         if (config.getParam("scoreType")=="entropy") {cout << "**** Scores are entropies ****" << endl;}
01330         if (config.getParam("scoreType")=="mean") {cout << "**** Robust Mean using Histo ****" << endl;}
01331     cout << "Compute Test, Decime mode["<<worldDecime<<"] ";
01332     if (segmentalMode) cout << " Segmental Mode - Confidences scores will be used to discard some segments"<<endl;
01333     else cout << "File Mode- 1 LLR by file" <<endl;
01334   }
01335   try{
01336     XList ndx(inputNDXFileName,config);                                    // Read the test definition file (ndx)
01337     XLine *linep;                                                          // Pointor on the current test line
01338     ndx.getLine(0);
01339     MixtureServer ms(config);
01340     StatServer ss(config, ms);
01341     MixtureGD& world = ms.loadMixtureGD(inputWorldFilename);               // Load the world model
01342     TabClientLine tabClientLine(ms,config,maxClientLine);                  // Initialize the client tab with 0 preload client
01343     ofstream outNist(outputNISTFileName.c_str(),ios::out | ios::trunc);    // Initialise the output file
01344     while ((linep=ndx.getLine()) != NULL){                                 // Loop on each line of the ndx input file
01345       String &featureFileName=linep->getElement(0);                        // Get the testfile basename
01346       FeatureServer fs(config,featureFileName);                            // Reading the feature file
01347       SegServer segmentsServer;                                                             // Create the segment server for managing the segments/clusters
01348       LabelServer labelServer;                                                              // Create the lable server, for indexing the segments/clusters
01349       initializeClusters(featureFileName,segmentsServer,labelServer,config);                // Reading the segmentation files for each feature input file
01350       verifyClusterFile(segmentsServer,fs,config);                                          // Verify if the segments ending before the end of the feature files...
01351       long codeSelectedFrame=labelServer.getLabelIndexByString(labelSelectedFrames);        // Get the index of the cluster with in interest audio segments
01352       if (codeSelectedFrame==-1)                                                            // The file is empty
01353         cout << "ATTENTION, TEST FILE ["<<featureFileName<<"] is empty"<<endl;
01354       else{
01355         SegCluster& selectedSegments=segmentsServer.getCluster(codeSelectedFrame); // Gives the cluster of the selected/used segments   
01356         TabClientLine tabClientLine(ms,config);                                  // Load if needed the client models
01357         tabClientLine.loadLine(linep);
01358         TabHisto tabHisto(nbBins,maxClientLine); // nb Bins to estimate pdfs and maxTargetLine in an ndx
01359         ScoreAccum accumModifiedLLR;
01360         double llk_w=0.0;
01361         double llk_c=0.0;
01362         if (verbose)cout << "test seg["<<featureFileName<<"]"<< endl;
01363         ss.resetLLK(world);                                                               // Reset the world LLK accumulator
01364         for (unsigned int i=0; i<tabClientLine.nbClientLine();i++)
01365           ss.resetLLK(tabClientLine.getClientModel(i));                                   // Reset client i LLK accumulator
01366         Seg* seg;                                                                         // reset the reader at the begin of the input stream
01367         selectedSegments.rewind();      
01368         while((seg=selectedSegments.getSeg())!=NULL){                                     // For each of the selected segments
01369           unsigned long idxBeginFrame=seg->begin()+fs.getFirstFeatureIndexOfASource(seg->sourceName()); 
01370           fs.seekFeature(idxBeginFrame); 
01371           Feature f;
01372           for (unsigned long idxFrame=0;idxFrame<seg->length();idxFrame++){               // For each frame of the segment
01373             fs.readFeature(f);
01374             if ((idxFrame%worldDecime)==0)                                                // We want to compute the world LLK and the top gaussian
01375         llk_w=ss.computeAndAccumulateLLK(world, f,DETERMINE_TOP_DISTRIBS);    // Determine the top components and compute wrld LLK
01376             else ss.computeAndAccumulateLLK(world, f,USE_TOP_DISTRIBS);       // Determine the top components and compute wrld LLK
01377             for (unsigned int i=0;i<tabClientLine.nbClientLine();i++)  {                          // For each client, compute LLK using the winning
01378         llk_c=ss.computeAndAccumulateLLK(tabClientLine.getClientModel(i),f,USE_TOP_DISTRIBS);
01379         //cout <<tabClientLine.getClientName(i)<<" "<<llk_c<<" "<<llk_w<<" "<<llk_c-llk_w<<endl;
01380         tabHisto.accumulateValueInTab(tabClientLine.getClientName(i),llk_c-llk_w);}
01381                     }
01382           if (segmentalMode){                                                             // A result is needed for each segment
01383             double LLKWorld=ss.getMeanLLK(world);                                         // Take the world LLK 
01384             for (unsigned int i=0;i < tabClientLine.nbClientLine();i++){                           // For each client
01385               double LLKClient=ss.getMeanLLK(tabClientLine.getClientModel(i));            // Get the mean LLK 
01386               double LLRClient=LLKClient-LLKWorld;                                        // Compute the LLR
01387               //char decision=setDecision(LLRClient,decisionThreshold);                     // take a decision 
01388                 Histo & currentHisto=tabHisto.getHisto(tabClientLine.getClientName(i));
01389                 double entropy=computeEntropy(currentHisto);
01390                 if (verboseAll) cout << "Segment: "<<tabClientLine.getClientName(i)<< " "<<seg->begin()<<":"<<seg->length()<<"  LLR: "<< LLRClient << " Entropy: " << entropy <<endl;
01391                 //if (entropy < decisionThreshold) {
01392                 if (0) {
01393                 if (verboseAll) cerr << "Discard segment" << LLRClient << endl;
01394                         LLRClient=0.0;}
01395                 accumModifiedLLR.addAndAccumulate(tabClientLine.getClientName(i),LLRClient,1);
01396                 currentHisto.computeHisto(0);
01397 
01398               ss.resetLLK(tabClientLine.getClientModel(i));                               // Reset client i LLK accumulator
01399             }  
01400             ss.resetLLK(world);                                                           // Reset the world LLK accumulator  
01401           }
01402         }
01403         
01404         if (segmentalMode) { // output the global score
01405                 for (unsigned int i=0;i < tabClientLine.nbClientLine();i++){ 
01406                         double score=accumModifiedLLR.getScore(tabClientLine.getClientName(i));
01407                         if (verboseAll) outputResultLine(score, tabClientLine.getClientName(i),featureFileName ,gender ,0,cout);
01408                         outputResultLine(score, tabClientLine.getClientName(i),featureFileName ,gender ,0,outNist);
01409                 }
01410         }
01411         if (segmentalMode==false){                                                        // One result by file and by ID
01412                 double LLKWorld=ss.getMeanLLK(world);                                           // Take the world LLK
01413                 for (unsigned int i=0;i < tabClientLine.nbClientLine();i++){                             // For each client
01414                         tabHisto.computeHistoInTab(tabClientLine.getClientName(i));
01415                         double LLKClient=ss.getMeanLLK(tabClientLine.getClientModel(i));              // Get the mean LLK 
01416                         double LLRClient=LLKClient-LLKWorld;                                          // Compute the LLR
01417                         char decision=setDecision(LLRClient,decisionThreshold);                       // take a decision 
01418                         Histo & currentHisto=tabHisto.getHisto(tabClientLine.getClientName(i));
01419                         if (debug) currentHisto.saveGnuplot(tabClientLine.getClientName(i)+".hist");
01420                         double score=0.0;
01421                         if(scoreType=="entropy") score=computeEntropy(currentHisto);
01422                         else if(scoreType=="mean") score=computeMean(currentHisto);
01423                         else {cerr << "Error: unknown score type!" << endl;}
01424                         outputResultLine(score, tabClientLine.getClientName(i),featureFileName ,gender ,decision,outNist);
01425                         if (verboseAll) {
01426                                 outputResultLine(score, tabClientLine.getClientName(i),featureFileName ,gender ,decision,cout); 
01427                                 cout<<"** C:"<<LLKClient<<" W:"<<LLKWorld<<" LR:"<<LLRClient<<endl;
01428                         }
01429                 }  
01430         } // end non segmental mode  
01431       }// end ndx loop
01432       if ((nbMaxMixtureInMemory>0)&&(ms.getMixtureCount()>nbMaxMixtureInMemory)){
01433         if (verbose) cout <<"Cleaning the mixture server from 1 to "<<ms.getMixtureCount()<<endl;
01434         ms.deleteMixtures(1,ms.getMixtureCount());  
01435         ms.deleteUnusedDistribs();
01436       } 
01437     }                                                                                   // end of the NDX line loop
01438     outNist.close();
01439   } // fin try
01440   catch (Exception& e){ 
01441     cout << e.toString().c_str() << endl;
01442   }
01443   return 0;
01444 }
01445 
01446 
01447 #endif //!defined(ALIZE_ComputeTest_cpp)