/***************************************************************************
                          File.cpp  -  description
                             -------------------
    begin                : Don Mai 8 2003
    copyright            : (C) 2003 by klaus frieler
    email                : kgf@omniversum.de
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/
#include<cmath>
#include "File.h"
#include "Types.h"
#include "Misc.h"
#include "VectorManip.cpp"
FeatureDef File::FeatureDefs[] = {
    FeatureDef("jumpaft3","Accents (jumpaft3)", ACCENTS, ACCENT_JUMPAFT3),
    FeatureDef("jumpaft4","Accents (jumpaft3)", ACCENTS,ACCENT_JUMPAFT4),
    FeatureDef("jumpaft5","Accents (jumpaft3)", ACCENTS,ACCENT_JUMPAFT5),
    FeatureDef("jumpbef3","Accents (jumpbef3)", ACCENTS,ACCENT_JUMPBEF3),
    FeatureDef("jumpbef4","Accents (jumpbef4)", ACCENTS,ACCENT_JUMPBEF4),
    FeatureDef("jumpbef5","Accents (jumpbef5)", ACCENTS,ACCENT_JUMPBEF5),
    FeatureDef("jumpbea3","Accents (jumpbea3)", ACCENTS,ACCENT_JUMPBEA3),
    FeatureDef("jumpbea4","Accents (jumpbea4)", ACCENTS,ACCENT_JUMPBEA4),
    FeatureDef("jumpbea5","Accents (jumpbea5)", ACCENTS,ACCENT_JUMPBEA5),
    FeatureDef("jumploc", "Accents (jumploc)", ACCENTS,ACCENT_JUMPLOC ),
    FeatureDef("shortphr","Accents (shortphr)", ACCENTS,ACCENT_SHORTPHR ),
    FeatureDef("pextrem", "Accents (pextrem)", ACCENTS,ACCENT_PEXTREM ),
    FeatureDef("pextrst", "Accents (pextrst)", ACCENTS,ACCENT_PEXTRST ),
    FeatureDef("pextrmf", "Accents (pextrmf)", ACCENTS,ACCENT_PEXTRMF ),
    FeatureDef("pextrsta","Accents (pextrsta)", ACCENTS,ACCENT_PEXTRSTA),
    FeatureDef("longpr",  "Accents (longpr)", ACCENTS,ACCENT_LONGPR  ),
    FeatureDef("long2pr", "Accents (long2pr)", ACCENTS,ACCENT_LONG2PR ),
    FeatureDef("longmod", "Accents (longmod)", ACCENTS,ACCENT_LONGMOD ),
    FeatureDef("long2mod","Accents (long2mod)", ACCENTS,ACCENT_LONG2MOD),
    FeatureDef("shortpr", "Accents (shortpr)", ACCENTS,ACCENT_SHORTPR ),
    FeatureDef("short2pr","Accents (short2pr)", ACCENTS,ACCENT_SHORT2PR),
    FeatureDef("endloioi","Accents (endloioi)", ACCENTS,ACCENT_ENDLOIOI),
    FeatureDef("beat13",  "Accents (beats13)", ACCENTS,ACCENT_BEAT13  ),
    FeatureDef("beat1",   "Accents (beat1)", ACCENTS,ACCENT_BEAT1   ),
    FeatureDef("beatall", "Accents (beatall)", ACCENTS,ACCENT_BEATALL ),
    FeatureDef("sync1234", "Accents (syncop1234)", ACCENTS,ACCENT_SYNCOP1 ),
    FeatureDef("sync13", "Accents (syncop1234)", ACCENTS,ACCENT_SYNCOP2 ),
    FeatureDef("triad",   "Accents (triad)", ACCENTS,ACCENT_TRIAD   ),
    FeatureDef("triaphen","Accents (triaphen)", ACCENTS,ACCENT_TRIAPHEN),
    FeatureDef("phrasbeg","Accents (phrasbeg)", ACCENTS,ACCENT_PHRASBEG),
    FeatureDef("phrasend","Accents (phrasend)", ACCENTS,ACCENT_PHRASEND),
    FeatureDef("accents-opti1", "Optimized accents (linear model)", STATISTIC|TRANS_ACCENT_OPTI1, STAT_NONE),    
    FeatureDef("accents-opti2", "Optimized accents (tree model)", STATISTIC|TRANS_ACCENT_OPTI2, STAT_NONE),
    FeatureDef("accents-opti1-thr", "Optimized accents (linear model, thresholded)", STATISTIC|TRANS_ACC_OPTI1_THR, STAT_NONE),    
    FeatureDef("accents-opti2-thr", "Optimized accents (tree model, thresholded)", STATISTIC|TRANS_ACC_OPTI2_THR, STAT_NONE),
    FeatureDef("thom","Accents (Thomassen)", SPECIAL,ACCENT_THOMASSEN),
    FeatureDef("thom-thr","Accents (Thomassen (threshold))", SPECIAL,ACCENT_THOMASSEN|THOMASSEN_THRESHOLD),
/*
      FeatureDef("joint1",  "Accents (joint1):                                          ", ACCENTS,ACCENT_BASE|ACCENT_PEXTREM),
    FeatureDef("joint2",  "Accents (joint2):                                          ", ACCENTS,ACCENT_BASE|ACCENT_PEXTRST),
    FeatureDef("joint3",  "Accents (joint3):                                          ", ACCENTS,ACCENT_BASE|ACCENT_PEXTRMF),
    FeatureDef("joint4",  "Accents (joint4):                                          ", ACCENTS,ACCENT_BASE|ACCENT_PEXTRST|ACCENT_PEXTRSTA),
    FeatureDef("joint1w", "Accents (joint1w):                                         ", ACCENTS,ACCENT_BASE|ACCENT_PEXTREM),
    FeatureDef("joint2w", "Accents (joint2w):                                         ", ACCENTS,ACCENT_BASE|ACCENT_PEXTRST),
    FeatureDef("joint3w", "Accents (joint3w):                                         ", ACCENTS,ACCENT_BASE|ACCENT_PEXTRMF),
    FeatureDef("joint4w", "Accents (joint4w):                                         ", ACCENTS,ACCENT_BASE|ACCENT_PEXTRST|ACCENT_PEXTRSTA),    
    FeatureDef("joint41", "Accents (joint41):                                         ", ACCENTS,ACCENT_JOINT41|ACCENT_ALWAYS),
    FeatureDef("joint42", "Accents (joint42):                                         ", ACCENTS,ACCENT_JOINT42|ACCENT_ALWAYS),
    FeatureDef("joint43", "Accents (joint43):                                         ", ACCENTS,ACCENT_JOINT43|ACCENT_ALWAYS),
    FeatureDef("joint44", "Accents (joint44):                                         ", ACCENTS,ACCENT_JOINT44|ACCENT_ALWAYS),
    FeatureDef("joint45", "Accents (joint45):                                         ", ACCENTS,ACCENT_JOINT45|ACCENT_ALWAYS),
    FeatureDef("joint46", "Accents (joint46):                                         ", ACCENTS,ACCENT_JOINT46|ACCENT_ALWAYS),
    FeatureDef("joint51", "Accents (joint51):                                         ", ACCENTS,ACCENT_JOINT51|ACCENT_ALWAYS),
    FeatureDef("joint52", "Accents (joint52):                                         ", ACCENTS,ACCENT_JOINT52|ACCENT_ALWAYS),
    FeatureDef("joint53", "Accents (joint53):                                         ", ACCENTS,ACCENT_JOINT53|ACCENT_ALWAYS),
    FeatureDef("joint54", "Accents (joint54):                                         ", ACCENTS,ACCENT_JOINT54|ACCENT_ALWAYS),
    FeatureDef("joint55", "Accents (joint55):                                         ", ACCENTS,ACCENT_JOINT55|ACCENT_ALWAYS),
    FeatureDef("joint56", "Accents (joint56):                                         ", ACCENTS,ACCENT_JOINT56|ACCENT_ALWAYS),
    FeatureDef("joint57", "Accents (joint57):                                         ", ACCENTS,ACCENT_JOINT57|ACCENT_ALWAYS),
    FeatureDef("joint58", "Accents (joint58):                                         ", ACCENTS,ACCENT_JOINT58|ACCENT_ALWAYS),
    FeatureDef("joint61", "Accents (joint61):                                         ", ACCENTS,ACCENT_JOINT61|ACCENT_ALWAYS),
    FeatureDef("joint62", "Accents (joint62):                                         ", ACCENTS,ACCENT_JOINT62|ACCENT_ALWAYS),
    FeatureDef("joint63", "Accents (joint63):                                         ", ACCENTS,ACCENT_JOINT63|ACCENT_ALWAYS),
    FeatureDef("joint64", "Accents (joint64):                                         ", ACCENTS,ACCENT_JOINT64|ACCENT_ALWAYS),
    FeatureDef("joint41coh-mean", "Accentcoherence (joint41):                              ", ACCENT_COHERENCE_MEAN_KORR,ACCENT_JOINT41|ACCENT_ALWAYS),
    FeatureDef("joint42coh-mean", "Accentcoherence (joint42):                              ", ACCENT_COHERENCE_MEAN_KORR,ACCENT_JOINT42|ACCENT_ALWAYS),
    FeatureDef("joint43coh-mean", "Accentcoherence (joint43):                              ", ACCENT_COHERENCE_MEAN_KORR,ACCENT_JOINT43|ACCENT_ALWAYS),
    FeatureDef("joint44coh-mean", "Accentcoherence (joint44):                              ", ACCENT_COHERENCE_MEAN_KORR,ACCENT_JOINT44|ACCENT_ALWAYS),
    FeatureDef("joint45coh-mean", "Accentcoherence (joint45):                              ", ACCENT_COHERENCE_MEAN_KORR,ACCENT_JOINT45|ACCENT_ALWAYS),
    FeatureDef("joint46coh-mean", "Accentcoherence (joint46):                              ", ACCENT_COHERENCE_MEAN_KORR,ACCENT_JOINT46|ACCENT_ALWAYS),
    FeatureDef("joint51coh-mean", "Accentcoherence (joint51):                              ", ACCENT_COHERENCE_MEAN_KORR,ACCENT_JOINT51|ACCENT_ALWAYS),
    FeatureDef("joint52coh-mean", "Accentcoherence (joint52):                              ", ACCENT_COHERENCE_MEAN_KORR,ACCENT_JOINT52|ACCENT_ALWAYS),
    FeatureDef("joint53coh-mean", "Accentcoherence (joint53):                              ", ACCENT_COHERENCE_MEAN_KORR,ACCENT_JOINT53|ACCENT_ALWAYS),
    FeatureDef("joint54coh-mean", "Accentcoherence (joint54):                              ", ACCENT_COHERENCE_MEAN_KORR,ACCENT_JOINT54|ACCENT_ALWAYS),
    FeatureDef("joint55coh-mean", "Accentcoherence (joint55):                              ", ACCENT_COHERENCE_MEAN_KORR,ACCENT_JOINT55|ACCENT_ALWAYS),
    FeatureDef("joint56coh-mean", "Accentcoherence (joint56):                              ", ACCENT_COHERENCE_MEAN_KORR,ACCENT_JOINT56|ACCENT_ALWAYS),
    FeatureDef("joint57coh-mean", "Accentcoherence (joint57):                              ", ACCENT_COHERENCE_MEAN_KORR,ACCENT_JOINT57|ACCENT_ALWAYS),
    FeatureDef("joint58coh-mean", "Accentcoherence (joint58):                              ", ACCENT_COHERENCE_MEAN_KORR,ACCENT_JOINT58|ACCENT_ALWAYS),
    FeatureDef("joint61coh-mean", "Accentcoherence (joint61):                              ", ACCENT_COHERENCE_MEAN_KORR,ACCENT_JOINT61|ACCENT_ALWAYS),
    FeatureDef("joint62coh-mean", "Accentcoherence (joint62):                              ", ACCENT_COHERENCE_MEAN_KORR,ACCENT_JOINT62|ACCENT_ALWAYS),
    FeatureDef("joint63coh-mean", "Accentcoherence (joint63):                              ", ACCENT_COHERENCE_MEAN_KORR,ACCENT_JOINT63|ACCENT_ALWAYS),
    FeatureDef("joint64coh-mean", "Accentcoherence (joint64):                              ", ACCENT_COHERENCE_MEAN_KORR,ACCENT_JOINT64|ACCENT_ALWAYS),

    FeatureDef("joint41coh-mean-ed", "Accentcoherence (joint41):                              ", ACCENT_COHERENCE_MEAN_ED_KORR,ACCENT_JOINT41|ACCENT_ALWAYS),
    FeatureDef("joint42coh-mean-ed", "Accentcoherence (joint42):                              ", ACCENT_COHERENCE_MEAN_ED_KORR,ACCENT_JOINT42|ACCENT_ALWAYS),
    FeatureDef("joint43coh-mean-ed", "Accentcoherence (joint43):                              ", ACCENT_COHERENCE_MEAN_ED_KORR,ACCENT_JOINT43|ACCENT_ALWAYS),
    FeatureDef("joint44coh-mean-ed", "Accentcoherence (joint44):                              ", ACCENT_COHERENCE_MEAN_ED_KORR,ACCENT_JOINT44|ACCENT_ALWAYS),
    FeatureDef("joint45coh-mean-ed", "Accentcoherence (joint45):                              ", ACCENT_COHERENCE_MEAN_ED_KORR,ACCENT_JOINT45|ACCENT_ALWAYS),
    FeatureDef("joint46coh-mean-ed", "Accentcoherence (joint46):                              ", ACCENT_COHERENCE_MEAN_ED_KORR,ACCENT_JOINT46|ACCENT_ALWAYS),
    FeatureDef("joint51coh-mean-ed", "Accentcoherence (joint51):                              ", ACCENT_COHERENCE_MEAN_ED_KORR,ACCENT_JOINT51|ACCENT_ALWAYS),
    FeatureDef("joint52coh-mean-ed", "Accentcoherence (joint52):                              ", ACCENT_COHERENCE_MEAN_ED_KORR,ACCENT_JOINT52|ACCENT_ALWAYS),
    FeatureDef("joint53coh-mean-ed", "Accentcoherence (joint53):                              ", ACCENT_COHERENCE_MEAN_ED_KORR,ACCENT_JOINT53|ACCENT_ALWAYS),
    FeatureDef("joint54coh-mean-ed", "Accentcoherence (joint54):                              ", ACCENT_COHERENCE_MEAN_ED_KORR,ACCENT_JOINT54|ACCENT_ALWAYS),
    FeatureDef("joint55coh-mean-ed", "Accentcoherence (joint55):                              ", ACCENT_COHERENCE_MEAN_ED_KORR,ACCENT_JOINT55|ACCENT_ALWAYS),
    FeatureDef("joint56coh-mean-ed", "Accentcoherence (joint56):                              ", ACCENT_COHERENCE_MEAN_ED_KORR,ACCENT_JOINT56|ACCENT_ALWAYS),
    FeatureDef("joint57coh-mean-ed", "Accentcoherence (joint57):                              ", ACCENT_COHERENCE_MEAN_ED_KORR,ACCENT_JOINT57|ACCENT_ALWAYS),
    FeatureDef("joint58coh-mean-ed", "Accentcoherence (joint58):                              ", ACCENT_COHERENCE_MEAN_ED_KORR,ACCENT_JOINT58|ACCENT_ALWAYS),
    FeatureDef("joint61coh-mean-ed", "Accentcoherence (joint61):                              ", ACCENT_COHERENCE_MEAN_ED_KORR,ACCENT_JOINT61|ACCENT_ALWAYS),
    FeatureDef("joint62coh-mean-ed", "Accentcoherence (joint62):                              ", ACCENT_COHERENCE_MEAN_ED_KORR,ACCENT_JOINT62|ACCENT_ALWAYS),
    FeatureDef("joint63coh-mean-ed", "Accentcoherence (joint63):                              ", ACCENT_COHERENCE_MEAN_ED_KORR,ACCENT_JOINT63|ACCENT_ALWAYS),
    FeatureDef("joint64coh-mean-ed", "Accentcoherence (joint64):                              ", ACCENT_COHERENCE_MEAN_ED_KORR,ACCENT_JOINT64|ACCENT_ALWAYS),

    FeatureDef("joint41coh-max-var", "Accentcoherence (joint41):                              ", ACCENT_COHERENCE_MAX_VARIANCE,ACCENT_JOINT41|ACCENT_ALWAYS),
    FeatureDef("joint42coh-max-var", "Accentcoherence (joint42):                              ", ACCENT_COHERENCE_MAX_VARIANCE,ACCENT_JOINT42|ACCENT_ALWAYS),
    FeatureDef("joint43coh-max-var", "Accentcoherence (joint43):                              ", ACCENT_COHERENCE_MAX_VARIANCE,ACCENT_JOINT43|ACCENT_ALWAYS),
    FeatureDef("joint44coh-max-var", "Accentcoherence (joint44):                              ", ACCENT_COHERENCE_MAX_VARIANCE,ACCENT_JOINT44|ACCENT_ALWAYS),
    FeatureDef("joint45coh-max-var", "Accentcoherence (joint45):                              ", ACCENT_COHERENCE_MAX_VARIANCE,ACCENT_JOINT45|ACCENT_ALWAYS),
    FeatureDef("joint46coh-max-var", "Accentcoherence (joint46):                              ", ACCENT_COHERENCE_MAX_VARIANCE,ACCENT_JOINT46|ACCENT_ALWAYS),
    FeatureDef("joint51coh-max-var", "Accentcoherence (joint51):                              ", ACCENT_COHERENCE_MAX_VARIANCE,ACCENT_JOINT51|ACCENT_ALWAYS),
    FeatureDef("joint52coh-max-var", "Accentcoherence (joint52):                              ", ACCENT_COHERENCE_MAX_VARIANCE,ACCENT_JOINT52|ACCENT_ALWAYS),
    FeatureDef("joint53coh-max-var", "Accentcoherence (joint53):                              ", ACCENT_COHERENCE_MAX_VARIANCE,ACCENT_JOINT53|ACCENT_ALWAYS),
    FeatureDef("joint54coh-max-var", "Accentcoherence (joint54):                              ", ACCENT_COHERENCE_MAX_VARIANCE,ACCENT_JOINT54|ACCENT_ALWAYS),
    FeatureDef("joint55coh-max-var", "Accentcoherence (joint55):                              ", ACCENT_COHERENCE_MAX_VARIANCE,ACCENT_JOINT55|ACCENT_ALWAYS),
    FeatureDef("joint56coh-max-var", "Accentcoherence (joint56):                              ", ACCENT_COHERENCE_MAX_VARIANCE,ACCENT_JOINT56|ACCENT_ALWAYS),
    FeatureDef("joint57coh-max-var", "Accentcoherence (joint57):                              ", ACCENT_COHERENCE_MAX_VARIANCE,ACCENT_JOINT57|ACCENT_ALWAYS),
    FeatureDef("joint58coh-max-var", "Accentcoherence (joint58):                              ", ACCENT_COHERENCE_MAX_VARIANCE,ACCENT_JOINT58|ACCENT_ALWAYS),
    FeatureDef("joint61coh-max-var", "Accentcoherence (joint61):                              ", ACCENT_COHERENCE_MAX_VARIANCE,ACCENT_JOINT61|ACCENT_ALWAYS),
    FeatureDef("joint62coh-max-var", "Accentcoherence (joint62):                              ", ACCENT_COHERENCE_MAX_VARIANCE,ACCENT_JOINT62|ACCENT_ALWAYS),
    FeatureDef("joint63coh-max-var", "Accentcoherence (joint63):                              ", ACCENT_COHERENCE_MAX_VARIANCE,ACCENT_JOINT63|ACCENT_ALWAYS),
    FeatureDef("joint64coh-max-var", "Accentcoherence (joint64):                              ", ACCENT_COHERENCE_MAX_VARIANCE,ACCENT_JOINT64|ACCENT_ALWAYS),
*/

    FeatureDef("ngramintall", "Dynamic N-gram complexity of interval N-grams", NGRAM|INTERVALS,0),
    FeatureDef("ngramintallw", "Weighted dynamic N-gram complexity of interval N-grams", NGRAM|INTERVALS|WEIGHTED,0),
    FeatureDef("ngramintalle", "N-gram entropy of interval N-grams", NGRAM|INTERVALS|STAT_ENTROPY,0),
    FeatureDef("ngramint1", "N-gram complexity of interval N-grams N=1", NGRAM|INTERVALS,1),
    FeatureDef("ngramint2", "N-gram complexity of interval N-grams N<=2", NGRAM|INTERVALS,2),
    FeatureDef("ngramint3", "N-gram complexity of  interval N-grams N<=3", NGRAM|INTERVALS,3),
    FeatureDef("ngramint4", "N-gram complexity of  interval N-grams N<=4", NGRAM|INTERVALS,4),
    FeatureDef("ngramall", "Dynamic N-gram complexity of pitch N-grams", NGRAM,0),
    FeatureDef("ngramallw", "Weighted dynamic N-gram complexity of pitch N-grams", NGRAM|WEIGHTED,0),
    FeatureDef("ngramalle", "N-gram entropy of pitch N-grams", NGRAM|STAT_ENTROPY,0),
    FeatureDef("ngram1", "N-gram complexity of pitch N-grams N=1", NGRAM,1),
    FeatureDef("ngram2", "N-gram complexity of pitch N-grams N<=2", NGRAM,2),
    FeatureDef("ngram3", "N-gram complexity of pitch N-grams N<=3", NGRAM,3),
    FeatureDef("ngram4", "N-gram complexity of pitch N-grams N<=4", NGRAM,4),
    FeatureDef("ngramdurall", "Dynamic N-gram complexity of duration N-grams", NGRAM|DURATION16,0),
    FeatureDef("ngramdurallw", "Weighted dynamic N-gram complexity of duration N-grams", NGRAM|DURATION16|WEIGHTED,0),
    FeatureDef("ngramduralle", "N-gram entropy of duration N-grams", NGRAM|DURATION16|STAT_ENTROPY,0),
    FeatureDef("ngramdur1", "N-gram complexity of tatum duration N-grams N=1", NGRAM|DURATION16,1),
    FeatureDef("ngramdur2", "N-gram complexity of tatum duration N-grams N<=2", NGRAM|DURATION16,2),
    FeatureDef("ngramdur3", "N-gram complexity of tatum duration N-grams N<=3", NGRAM|DURATION16,3),
    FeatureDef("ngramdur4", "N-gram complexity of tatum duration N-grams N<=4", NGRAM|DURATION16,4),
    FeatureDef("length", "Number of tones", STATISTIC|TRANS_PITCH, STAT_COUNT),
    FeatureDef("bar-length", "Number of bars", STATISTIC|TRANS_BARS, STAT_COUNT),
    FeatureDef("synchalf", "Syncopes at level 1", STATISTIC|TRANS_SYNCOPES0, STAT_NONE),
    FeatureDef("sync0", "Syncopes at level 0", STATISTIC|TRANS_SYNCOPES1, STAT_NONE),
    FeatureDef("sync8s", "Syncopes at level -1", STATISTIC|TRANS_SYNCOPES2, STAT_NONE),
    FeatureDef("sync16s", "Syncopes at level -2", STATISTIC|TRANS_SYNCOPES3, STAT_NONE),
    FeatureDef("sync-all", "Syncopes at any level", STATISTIC|TRANS_SYNCOPES0|TRANS_SYNCOPES1|TRANS_SYNCOPES2|TRANS_SYNCOPES3, STAT_NONE),
    FeatureDef("sync1avg", "Syncopicity on level 1", STATISTIC|TRANS_SYNCOPES0, STAT_AVERAGE),
    FeatureDef("sync0avg", "Syncopicity on level 0", STATISTIC|TRANS_SYNCOPES1, STAT_AVERAGE),
    FeatureDef("sync-1av", "Syncopicity on level -1", STATISTIC|TRANS_SYNCOPES2, STAT_AVERAGE),
    FeatureDef("sync-2av", "Syncopicity on level -2", STATISTIC|TRANS_SYNCOPES3, STAT_AVERAGE),
    FeatureDef("synallav", "Syncopicity on levels 0 to -2", STATISTIC|TRANS_SYNCOPES0|TRANS_SYNCOPES1|TRANS_SYNCOPES2|TRANS_SYNCOPES3, STAT_AVERAGE),
    FeatureDef("ambitus", "Pitch ambitus ", STATISTIC|TRANS_PITCH, STAT_RANGE),
    FeatureDef("pitch-raw", "Pitch sequence", STATISTIC|TRANS_PITCH, STAT_NONE),
    FeatureDef("pitch-avg", "Avg. pitch", STATISTIC|TRANS_PITCH, STAT_AVERAGE),
    FeatureDef("pitch-modus", "Modus pitch", STATISTIC|TRANS_PITCH, STAT_MODUS),
    FeatureDef("pitch-median", "Median pitch", STATISTIC|TRANS_PITCH, STAT_MEDIAN),
    FeatureDef("pitch-variance", "Pitch variance", STATISTIC|TRANS_PITCH, STAT_VARIANCE),
    FeatureDef("pitch-min", "Minimum pitch", STATISTIC|TRANS_PITCH, STAT_MIN),
    FeatureDef("pitch-max", "Maximum pitch", STATISTIC|TRANS_PITCH, STAT_MAX),
    FeatureDef("pitch-skew", "Minimum pitch", STATISTIC|TRANS_PITCH, STAT_SKEWNESS),
    FeatureDef("pitch-kurt", "Maximum pitch", STATISTIC|TRANS_PITCH, STAT_KURTOSIS),
    FeatureDef("pitch-entropy", "Pitch entropy", STATISTIC|TRANS_PITCH, STAT_ENTROPY),
    FeatureDef("pitch-jsd", "Jensen-Shannon divergence of pitch", STATISTIC|TRANS_PITCH, STAT_JSD),
    FeatureDef("pitch-jsdm", "Max. Jensen-Shannon divergence of pitch", STATISTIC|TRANS_PITCH, STAT_JSDMAX),
    //FeatureDef("pitch-rt", "Jensen-Shannon-divergence (pitch)", STATISTIC|TRANS_PITCH, STAT_RUNTEST),
    FeatureDef("int-range", "Interval range", STATISTIC|TRANS_INTERVALS, STAT_RANGE),
    FeatureDef("int-avg", "Interval avg.", STATISTIC|TRANS_INTERVALS, STAT_AVERAGE),
    FeatureDef("int-modus", "Interval modus", STATISTIC|TRANS_INTERVALS, STAT_MODUS),
    FeatureDef("int-median", "Interval median", STATISTIC|TRANS_INTERVALS, STAT_MEDIAN),
    FeatureDef("int-variance", "Interval variance", STATISTIC|TRANS_INTERVALS, STAT_VARIANCE),
    FeatureDef("int-skew", "Interval skewness", STATISTIC|TRANS_INTERVALS, STAT_SKEWNESS),
    FeatureDef("int-kurt", "Interval kurtosis", STATISTIC|TRANS_INTERVALS, STAT_KURTOSIS),
    FeatureDef("int-min", "Minimum interval", STATISTIC|TRANS_INTERVALS, STAT_MIN),
    FeatureDef("int-max", "Maximum interval", STATISTIC|TRANS_INTERVALS, STAT_MAX),
    FeatureDef("int-entropy", "Interval entropy", STATISTIC|TRANS_INTERVALS, STAT_ENTROPY),
    FeatureDef("int-jsd", "Jensen-Shannon divergence  of intervals", STATISTIC|TRANS_INTERVALS, STAT_JSD),
    FeatureDef("int-jsdm", "Max. Jensen-Shannon divergence  of intervals", STATISTIC|TRANS_INTERVALS, STAT_JSDMAX),
    //FeatureDef("int-rt", "Jensen-Shannon divergence (intervals)", STATISTIC|TRANS_INTERVALS, STAT_RUNTEST),
    FeatureDef("dur-avg", "Avg. Pitch", STATISTIC|TRANS_DURATIONS16, STAT_AVERAGE),
    FeatureDef("dur-modus", "DurationPitch", STATISTIC|TRANS_DURATIONS16, STAT_MODUS),
    FeatureDef("dur-median", "Duration Pitch", STATISTIC|TRANS_DURATIONS16, STAT_MEDIAN),
    FeatureDef("dur-variance", "Duration variance", STATISTIC|TRANS_DURATIONS16, STAT_VARIANCE),
    FeatureDef("dur-min", "Minimum duration", STATISTIC|TRANS_DURATIONS16, STAT_MIN),
    FeatureDef("dur-max", "Maximum duration", STATISTIC|TRANS_DURATIONS16, STAT_MAX),
    FeatureDef("dur-skew", "Duration skewness", STATISTIC|TRANS_DURATIONS16, STAT_SKEWNESS),
    FeatureDef("dur-kurt", "Duration kurtosis", STATISTIC|TRANS_DURATIONS16, STAT_KURTOSIS),
    FeatureDef("dur-entropy", "Duration entropy", STATISTIC|TRANS_DURATIONS16, STAT_ENTROPY),
    FeatureDef("dur-jsd", "Jensen-Shannon divergence of durations", STATISTIC|TRANS_DURATIONS16, STAT_JSD),
    FeatureDef("dur-jsdm", "Max. Jensen-Shannon divergence of durations", STATISTIC|TRANS_DURATIONS16, STAT_JSDMAX),
    //FeatureDef("dur-rt", "Jensen-Shannon divergence (durations)", STATISTIC|TRANS_DURATIONS16, STAT_RUNTEST),
    FeatureDef("huron-contour", "Huron Contour ", TRANS_HURONCONTOUR,0),
    FeatureDef("huron-contour-agg", "Aggregated Huron contour", TRANS_HURONCONTOUR|SIMPLE, 0),
    FeatureDef("ngram-int-zipf", "Zipf comlexity of intervals", NGRAM|ZIPF|INTERVALS, 0),
    FeatureDef("ngram-int-zipf-w", "Weighted Zipf comlexity of intervals", NGRAM|ZIPF|INTERVALS|WEIGHTED, 0),
    FeatureDef("ngram1-int-zipf", "Zipf comlexity of intervals N=1", NGRAM|ZIPF|INTERVALS, 1),
    FeatureDef("ngram2-int-zipf", "Zipf comlexity of intervals N<=2", NGRAM|ZIPF|INTERVALS, 2),
    FeatureDef("ngram3-int-zipf", "Zipf comlexity of intervals N<=3", NGRAM|ZIPF|INTERVALS, 3),
    FeatureDef("ngram4-int-zipf", "Zipf comlexity of intervals N<=4", NGRAM|ZIPF|INTERVALS, 4),
    FeatureDef("ngram-zipf", "Zipf comlexity of pitch", NGRAM|ZIPF, 0),
    FeatureDef("ngram-zipf-w", "Weighted Zipf comlexity of pitch ", NGRAM|ZIPF|WEIGHTED, 0),
    FeatureDef("ngram1-zipf", "Zipf comlexity of pitch N=1", NGRAM|ZIPF, 1),
    FeatureDef("ngram2-zipf", "Zipf comlexity of pitch N<=2", NGRAM|ZIPF, 2),
    FeatureDef("ngram3-zipf", "Zipf comlexity of pitch N<=3", NGRAM|ZIPF, 3),
    FeatureDef("ngram4-zipf", "Zipf comlexity of pitch N<=4", NGRAM|ZIPF, 4),
    FeatureDef("ngram-dur-zipf", "Zipf comlexity of durations", NGRAM|DURATION16|ZIPF, 0),
    FeatureDef("ngram-dur-zipf-w", "Weighted Zipf comlexity of durations", NGRAM|DURATION16|ZIPF|WEIGHTED, 0),
    FeatureDef("ngram1-dur-zipf", "Zipf comlexity of durations N=1", NGRAM|DURATION16|ZIPF, 1),
    FeatureDef("ngram2-dur-zipf", "Zipf comlexity of durations N<=2", NGRAM|DURATION16|ZIPF, 2),
    FeatureDef("ngram3-dur-zipf", "Zipf comlexity of durations N<=2", NGRAM|DURATION16|ZIPF, 3),
    FeatureDef("ngram4-dur-zipf", "Zipf comlexity of durations N<=2", NGRAM|DURATION16|ZIPF, 4),
    FeatureDef("bar-phase", "Convert bar time to phase values", TRANS_BARS|PHASES, 0),
    FeatureDef("bar-phase-delta", "Convert bar time to phase values, using wrong bar times", TRANS_BARS|PHASES_DELTA, 0),
    FeatureDef("bar-phase-re", "Convert bar time to real part of complex value", TRANS_BARS|PHASES_RE, 0),
    FeatureDef("bar-phase-im", "Convert bar time to imaginary part of complex value", TRANS_BARS|PHASES_IM, 0),
    FeatureDef("bar-key", "Write key of each bar according to K-S", TRANS_BARS|KEY, 0),
    FeatureDef("beat-phase", "Convert sub beat times to phase values", TRANS_BARS|SUBBEAT_PHASES, 0),
    FeatureDef("tonal-phase", "Convert tonal pitch class to phase values", TRANS_BARS|TONAL_PITCH_PHASES, 0)
};

SimType File::SimTypes[] ={
    SimType("const",   "Constant 1 measure                                         ", CONSTSIM, _VOID_, NO_ACCENTS),
    SimType("rawEd",   "Raw: Edit Distance                                         ", EDIT_DISTANCE,_VOID_, NO_ACCENTS),
    SimType("rawEdw",  "Raw: Edit Distance (weighted)                              ", EDIT_DISTANCE|WEIGHTED, _VOID_, NO_ACCENTS),
    SimType("rawPC",   "Raw: Pears. Brav. Correlation                              ", PEARSON_BRAVAIS, _VOID_,NO_ACCENTS       ),
    SimType("rawPCSt", "Raw: Pears. Brav. Correlation (stretched)                  ", PEARSON_BRAVAIS|SQUASH, _VOID_,NO_ACCENTS ),
    SimType("rawPCw",  "Raw: Pears. Brav. Correlation (weighted)                   ", PEARSON_BRAVAIS|WEIGHTED, _VOID_,NO_ACCENTS ),
    SimType("rawPCwSt","Raw: Pears. Brav. Correlation (weighted, stretched)        ", PEARSON_BRAVAIS|WEIGHTED|SQUASH, _VOID_,NO_ACCENTS),
    SimType("rawCC",   "Raw: Cross Correlation                                     ", CROSS, _VOID_,NO_ACCENTS),
    SimType("rawCCw",  "Raw: Cross Correlation (weighted)                          ", CROSS|WEIGHTED, _VOID_,NO_ACCENTS),
    SimType("conSEd",  "Contour(Steinbeck): Edit Distance                          ", CONTOUR|STEINBECK|EDIT_DISTANCE, _VOID_,NO_ACCENTS),
    SimType("conSPC",  "Contour(Steinbeck): Pears. Brav. Correlation               ", CONTOUR|STEINBECK|PEARSON_BRAVAIS, _VOID_,NO_ACCENTS),
    SimType("conSPCSt","Contour(Steinbeck): Pears. Brav. Correlation (stretched)   ", CONTOUR|STEINBECK|PEARSON_BRAVAIS|SQUASH, _VOID_,NO_ACCENTS),
    SimType("conSCC",  "Contour(Steinbeck): Cross Correlation                      ", CONTOUR|STEINBECK|CROSS, _VOID_,NO_ACCENTS),
    SimType("conEd",   "Contour(M&F): Edit Distance                                ", CONTOUR|EDIT_DISTANCE, _VOID_,NO_ACCENTS),
    SimType("conPC",   "Contour(M&F):Pears. Brav. Correlation                      ", CONTOUR|PEARSON_BRAVAIS, _VOID_,NO_ACCENTS),
    SimType("conPCSt", "Contour(M&F):Pears. Brav. Correlation (stretched)          ", CONTOUR|PEARSON_BRAVAIS|SQUASH, _VOID_,NO_ACCENTS),
    SimType("conCC",   "Contour(M&F): Cross Correlation                            ", CONTOUR|CROSS,_VOID_,NO_ACCENTS),
    SimType("connEd",  "Contour(natural): Edit Distance                            ", CONTOUR|EDIT_DISTANCE|NATURAL, _VOID_,NO_ACCENTS),
    SimType("connPC",  "Contour(natural):Pears. Brav. Correlation                  ", CONTOUR|PEARSON_BRAVAIS|NATURAL, _VOID_,NO_ACCENTS),
    SimType("connPCS", "Contour(natural):Pears. Brav. Correlation (stretched)      ", CONTOUR|PEARSON_BRAVAIS||NATURAL|SQUASH, _VOID_,NO_ACCENTS),
    SimType("connCC",  "Contour(natural): Cross Correlation                        ", CONTOUR|CROSS|NATURAL,_VOID_,NO_ACCENTS),
    SimType("fourR",   "Fourier: Fourier (ranks)                                   ", FOURIER|RANKS, _VOID_,NO_ACCENTS),
    SimType("fourRSt", "Fourier: Fourier (ranks, stretch)                          ", FOURIER|RANKS|SQUASH, _VOID_,NO_ACCENTS),
    SimType("fourRw",  "Fourier: Fourier (ranks, weighted)                         ", FOURIER|RANKS|WEIGHTED, _VOID_,NO_ACCENTS),
    SimType("fourRwSt","Fourier: Fourier (ranks, weighted, stretched)              ", FOURIER|RANKS|WEIGHTED|SQUASH,_VOID_,NO_ACCENTS),
    SimType("fourRI",  "Fourier: Fourier (ranks, intervals)                        ", FOURIER|RANKS|INTERVALS, _VOID_,NO_ACCENTS),
    SimType("diffEd",  "Intervals: Edit distance                                   ", INTERVALS|EDIT_DISTANCE,_VOID_,NO_ACCENTS),
    SimType("diff",    "Intervals: Mean Difference                                 ", INTERVALS|MAXNORM2, _VOID_,NO_ACCENTS),
    SimType("diffExp", "Intervals: Mean Difference (exp)                           ", INTERVALS|EXPONENTIAL, _VOID_,NO_ACCENTS),
    SimType("diffFuz", "Intervals: Fuzzy                                           ", INTERVALS|FUZZY,_VOID_,NO_ACCENTS),
    SimType("diffFuzC","Intervals: Fuzzy contour                                   ", INTERVALS|FUZZY|CONTOUR, 3,NO_ACCENTS),
    SimType("nGrSumCo","Intervals: 3-grams  sum common                             ", INTERVALS|NGRAM|SUM_COMMON,3,NO_ACCENTS),
    SimType("nGrUkkon","Intervals: 3-grams  Ukkonnen                               ", INTERVALS|NGRAM|UKKONEN, 3,NO_ACCENTS),
    SimType("nGrCoord","Intervals: 3-grams  Count distinct                         ", INTERVALS|NGRAM|COORDINATE, 3,NO_ACCENTS),
    SimType("nGrSumCR","Intervals: 3-grams  sum common  (rough)                    ", INTERVALS|NGRAM|SUM_COMMON|PARSONS, 3,NO_ACCENTS),
    SimType("nGrUkkoR","Intervals: 3-grams  Ukkonnen  (rough)                      ", INTERVALS|NGRAM|UKKONEN|PARSONS, 3,NO_ACCENTS),
    SimType("nGrCoorR","Intervals: 3-grams  Count distinct   (rough)               ", INTERVALS|NGRAM|COORDINATE|PARSONS, 3,NO_ACCENTS),
    SimType("nGrSumCF","Intervals: 3-grams  sum common  (fuzzy)                    ", INTERVALS|NGRAM|SUM_COMMON|FUZZY, 3,NO_ACCENTS),
    SimType("nGrUkkoF","Intervals: 3-grams  Ukkonnen  (fuzzy)                      ", INTERVALS|NGRAM|UKKONEN|FUZZY, 3,NO_ACCENTS),
    SimType("nGrCoorF","Intervals: 3-grams  Count distinct   (fuzzy)               ", INTERVALS|NGRAM|COORDINATE|FUZZY, 3,NO_ACCENTS),
    SimType("nGrSumFR","Intervals: 3-grams  sum common (fuzzy rhythm)              ", NGRAM|SUM_COMMON|FUZZY|RHYTHM, 3,NO_ACCENTS),
    SimType("nGrUkkFR","Intervals: 3-grams  Ukkonnen  (fuzzy rhythm)               ", NGRAM|UKKONEN|FUZZY|RHYTHM, 3,NO_ACCENTS),
    SimType("nGrCooFR","Intervals: 3-grams  Count distinct (fuzzy rhythm)          ", NGRAM|COORDINATE|FUZZY|RHYTHM, 3,NO_ACCENTS),
    SimType("bGrSumCo","Intervals: 2-grams  sum common                             ", INTERVALS|NGRAM|SUM_COMMON,2,NO_ACCENTS),
    SimType("bGrUkkon","Intervals: 2-grams  Ukkonnen                               ", INTERVALS|NGRAM|UKKONEN, 2,NO_ACCENTS),
    SimType("bGrCoord","Intervals: 2-grams  Count distinct                         ", INTERVALS|NGRAM|COORDINATE, 2,NO_ACCENTS),
    SimType("bGrSumCR","Intervals: 2-grams  sum common  (rough)                    ", INTERVALS|NGRAM|SUM_COMMON|PARSONS, 2,NO_ACCENTS),
    SimType("bGrUkkoR","Intervals: 2-grams  Ukkonnen  (rough)                      ", INTERVALS|NGRAM|UKKONEN|PARSONS, 2,NO_ACCENTS),
    SimType("bGrCoorR","Intervals: 2-grams  Count distinct   (rough)               ", INTERVALS|NGRAM|COORDINATE|PARSONS, 2,NO_ACCENTS),
    SimType("bGrSumCF","Intervals: 2-grams  sum common  (fuzzy)                    ", INTERVALS|NGRAM|SUM_COMMON|FUZZY, 2,NO_ACCENTS),
    SimType("bGrUkkoF","Intervals: 2-grams  Ukkonnen  (fuzzy)                      ", INTERVALS|NGRAM|UKKONEN|FUZZY, 2,NO_ACCENTS),
    SimType("bGrCoorF","Intervals: 2-grams  Count distinct   (fuzzy)               ", INTERVALS|NGRAM|COORDINATE|FUZZY, 2,NO_ACCENTS),
    SimType("bGrSumFR","Intervals: 2-grams  sum common (fuzzy rhythm)              ", NGRAM|SUM_COMMON|FUZZY|RHYTHM, 2,NO_ACCENTS),
    SimType("bGrUkkFR","Intervals: 2-grams  Ukkonnen  (fuzzy rhythm)               ", NGRAM|UKKONEN|FUZZY|RHYTHM, 2,NO_ACCENTS),
    SimType("bGrCooFR","Intervals: 2-grams  Count distinct (fuzzy rhythm)          ", NGRAM|COORDINATE|FUZZY|RHYTHM, 2,NO_ACCENTS),
    SimType("qGrSumCo","Intervals: 4-grams  sum common                             ", INTERVALS|NGRAM|SUM_COMMON,4,NO_ACCENTS),
    SimType("qGrUkkon","Intervals: 4-grams  Ukkonnen                               ", INTERVALS|NGRAM|UKKONEN, 4,NO_ACCENTS),
    SimType("qGrCoord","Intervals: 4-grams  Count distinct                         ", INTERVALS|NGRAM|COORDINATE, 4,NO_ACCENTS),
    SimType("qGrSumCR","Intervals: 4-grams  sum common  (rough)                    ", INTERVALS|NGRAM|SUM_COMMON|PARSONS, 4,NO_ACCENTS),
    SimType("qGrUkkoR","Intervals: 4-grams  Ukkonnen  (rough)                      ", INTERVALS|NGRAM|UKKONEN|PARSONS, 4,NO_ACCENTS),
    SimType("qGrCoorR","Intervals: 4-grams  Count distinct   (rough)               ", INTERVALS|NGRAM|COORDINATE|PARSONS, 4,NO_ACCENTS),
    SimType("qGrSumCF","Intervals: 4-grams  sum common  (fuzzy)                    ", INTERVALS|NGRAM|SUM_COMMON|FUZZY, 4,NO_ACCENTS),
    SimType("qGrUkkoF","Intervals: 4-grams  Ukkonnen  (fuzzy)                      ", INTERVALS|NGRAM|UKKONEN|FUZZY, 4,NO_ACCENTS),
    SimType("qGrCoorF","Intervals: 4-grams  Count distinct   (fuzzy)               ", INTERVALS|NGRAM|COORDINATE|FUZZY, 4,NO_ACCENTS),
    SimType("qGrSumFR","Intervals: 4-grams  sum common (fuzzy rhythm)              ", NGRAM|SUM_COMMON|FUZZY|RHYTHM, 4,NO_ACCENTS),
    SimType("qGrUkkFR","Intervals: 4-grams  Ukkonnen  (fuzzy rhythm)               ", NGRAM|UKKONEN|FUZZY|RHYTHM, 4,NO_ACCENTS),
    SimType("qGrCooFR","Intervals: 4-grams  Count distinct (fuzzy rhythm)          ", NGRAM|COORDINATE|FUZZY|RHYTHM, 4,NO_ACCENTS),
    SimType("rhytGaus","Rhythm: Rhythm (Gauss)                                     ", RHYTHM, _VOID_,NO_ACCENTS),
    SimType("rhytFuzz","Rhythm: Rhythm (Fuzzy)                                     ", RHYTHM|FUZZY,_VOID_, NO_ACCENTS),
    SimType("rhytFuz2","Rhythm: Rhythm (Fuzzy) Ticks                               ", RHYTHM|FUZZY,TICKS, NO_ACCENTS),
   SimType("harmCorr","Harmonic correlation:                                      ", HARM_CORR, _VOID_,NO_ACCENTS),

    SimType("harmCorK","Harmonic correlation (Krumhansl):                          ", HARM_CORR|KRUMHANSL, _VOID_,NO_ACCENTS),
    SimType("harmCorE","Harmonic correlation (Edit distance):                      ", HARM_CORR|KRUMHANSL|EDIT_DISTANCE, _VOID_,NO_ACCENTS),
    SimType("harmCorC","Harmonic correlation (Cross-Corr):                         ", HARM_CORR|KRUMHANSL|CROSS, _VOID_,NO_ACCENTS),
    SimType("harmCoKA","Harmonic correlation (Krumhansl, all bars):                ", HARM_CORR|KRUMHANSL, ALL_BARS,NO_ACCENTS),
    SimType("harmCoEA","Harmonic correlation (Edit distance, all bars):            ", HARM_CORR|KRUMHANSL|EDIT_DISTANCE, ALL_BARS,NO_ACCENTS),
    SimType("harmCoCA","Harmonic correlation (Cross-Corr, all bars):               ", HARM_CORR|KRUMHANSL|CROSS, ALL_BARS,NO_ACCENTS),
    SimType("harCorrW","Harmonic correlation (weighted, ):                         ", HARM_CORR|WEIGHTED, _VOID_,NO_ACCENTS),
    SimType("harCorKW","Harmonic correlation (Krumhansl, weighted):                ", HARM_CORR|WEIGHTED|KRUMHANSL, _VOID_,NO_ACCENTS),
    SimType("harCorEW","Harmonic correlation (Edit distance, weighted):            ", HARM_CORR|WEIGHTED|KRUMHANSL|EDIT_DISTANCE, _VOID_,NO_ACCENTS),
    SimType("harCorCW","Harmonic correlation (Cross-Corr, weighted):               ", HARM_CORR|WEIGHTED|KRUMHANSL|CROSS, _VOID_,NO_ACCENTS),
    SimType("harCoKAW","Harmonic correlation (Krumhansl, weighted, all bars):      ", HARM_CORR|WEIGHTED|KRUMHANSL, ALL_BARS,NO_ACCENTS),
    SimType("harCoEAW","Harmonic correlation (Edit distance, weighted, all  bars):  ", 
       HARM_CORR|WEIGHTED|KRUMHANSL|EDIT_DISTANCE, ALL_BARS,NO_ACCENTS),
    SimType("harCoCAW","Harmonic correlation (Cross-Corr, weighted, all bars):     ", 
       HARM_CORR|WEIGHTED|KRUMHANSL|CROSS, ALL_BARS,NO_ACCENTS),
   /* 
   SimType("jumpaft3","Accents (jumpaft3):                                        ", 
      ACCENTS0, _VOID_,ACCENT_JUMPAFT3),
    SimType("jumpaft4","Accents (jumpaft3):                                        ", ACCENTS0,_VOID_,ACCENT_JUMPAFT4),
    SimType("jumpaft5","Accents (jumpaft3):                                        ", ACCENTS0,_VOID_,ACCENT_JUMPAFT5),
    SimType("jumpbef3","Accents (jumpbef3):                                        ", ACCENTS0,_VOID_,ACCENT_JUMPBEF3),
    SimType("jumpbef4","Accents (jumpbef4):                                        ", ACCENTS0,_VOID_,ACCENT_JUMPBEF4),
    SimType("jumpbef5","Accents (jumpbef5):                                        ", ACCENTS0,_VOID_,ACCENT_JUMPBEF5),
    SimType("jumpbea3","Accents (jumpbea3):                                        ", ACCENTS0,_VOID_,ACCENT_JUMPBEA3),
    SimType("jumpbea4","Accents (jumpbea4):                                        ", ACCENTS0,_VOID_,ACCENT_JUMPBEA4),
    SimType("jumpbea5","Accents (jumpbea5):                                        ", ACCENTS0,_VOID_,ACCENT_JUMPBEA5),
    SimType("jumploc", "Accents (jumploc):                                         ", ACCENTS0,_VOID_,ACCENT_JUMPLOC ),
    SimType("shortphr","Accents (shortphr):                                        ", ACCENTS0,_VOID_,ACCENT_SHORTPR ),
    SimType("pextrem", "Accents (pextrem):                                         ", ACCENTS0,_VOID_,ACCENT_PEXTREM ),
    SimType("pextrst", "Accents (pextrst):                                         ", ACCENTS0,_VOID_,ACCENT_PEXTRST ),
    SimType("pextrmf", "Accents (pextrmf):                                         ", ACCENTS0,_VOID_,ACCENT_PEXTRMF ),
    SimType("pextrsta","Accents (pextrsta):                                        ", ACCENTS0,_VOID_,ACCENT_PEXTRSTA),
    SimType("longpr",  "Accents (longpr):                                          ", ACCENTS0,_VOID_,ACCENT_LONGPR  ),
    SimType("long2pr", "Accents (long2pr):                                         ", ACCENTS0,_VOID_,ACCENT_LONG2PR ),
    SimType("longmod", "Accents (longmod):                                         ", ACCENTS0,_VOID_,ACCENT_LONGMOD ),
    SimType("long2mod","Accents (long2mod):                                        ", ACCENTS0,_VOID_,ACCENT_LONG2MOD),
    SimType("shortpr", "Accents (shortpr):                                         ", ACCENTS0,_VOID_,ACCENT_SHORTPR ),
    SimType("short2pr","Accents (short2pr):                                        ", ACCENTS0,_VOID_,ACCENT_SHORT2PR),
    SimType("endloioi","Accents (endloioi):                                        ", ACCENTS0,_VOID_,ACCENT_ENDLOIOI),
    SimType("beat13",  "Accents (beats13):                                         ", ACCENTS0,_VOID_,ACCENT_BEAT13  ),
    SimType("beat1",   "Accents (beat1)  :                                         ", ACCENTS0,_VOID_,ACCENT_BEAT1   ),
    SimType("beatall", "Accents (beatall):                                         ", ACCENTS0,_VOID_,ACCENT_BEATALL ),
    SimType("syncop1", "Accents (syncop1):                                         ", ACCENTS0,_VOID_,ACCENT_SYNCOP1 ),
    SimType("syncop2", "Accents (syncop2):                                         ", ACCENTS0,_VOID_,ACCENT_SYNCOP2 ),
    SimType("triad",   "Accents (triad):                                           ", ACCENTS0,_VOID_,ACCENT_TRIAD   ),
    SimType("triaphen","Accents (triaphen):                                        ", ACCENTS0,_VOID_,ACCENT_TRIAPHEN),
    SimType("phrasbeg","Accents (phrasbeg):                                        ", ACCENTS0,_VOID_,ACCENT_PHRASBEG),
    SimType("phrasend","Accents (phrasend):                                        ", ACCENTS0,_VOID_,ACCENT_PHRASEND),
    */
    SimType("accents-opti1","Accents (linear model):                               ", ACCENTS_OPTI1,_VOID_,0),    
    SimType("accents-opti2","Accents (tree model):                                 ", ACCENTS_OPTI2,_VOID_,0),
    /*
    SimType("joint1",  "Accents (joint1):                                          ", ACCENTS0,_VOID_,ACCENT_BASE|ACCENT_PEXTREM),
    SimType("joint2",  "Accents (joint2):                                          ", ACCENTS0,_VOID_,ACCENT_BASE|ACCENT_PEXTRST),
    SimType("joint3",  "Accents (joint3):                                          ", ACCENTS0,_VOID_,ACCENT_BASE|ACCENT_PEXTRMF),
    SimType("joint4",  "Accents (joint4):                                          ", ACCENTS0,_VOID_,ACCENT_BASE|ACCENT_PEXTRST|ACCENT_PEXTRSTA),
    SimType("joint1w", "Accents (joint1w):                                         ", ACCENTS4,_VOID_,ACCENT_BASE|ACCENT_PEXTREM),
    SimType("joint2w", "Accents (joint2w):                                         ", ACCENTS4,_VOID_,ACCENT_BASE|ACCENT_PEXTRST),
    SimType("joint3w", "Accents (joint3w):                                         ", ACCENTS4,_VOID_,ACCENT_BASE|ACCENT_PEXTRMF),
    SimType("joint4w", "Accents (joint4w):                                         ", ACCENTS4,_VOID_,ACCENT_BASE|ACCENT_PEXTRST|ACCENT_PEXTRSTA),    

    SimType("joint41", "Accents (joint41):                                         ", ACCENTS0,_VOID_,ACCENT_JOINT41|ACCENT_ALWAYS),
    SimType("joint411","Accents (joint411):                                        ", ACCENTS1,_VOID_,ACCENT_JOINT41|ACCENT_ALWAYS),
    SimType("joint412","Accents (joint412):                                        ", ACCENTS2,_VOID_,ACCENT_JOINT41|ACCENT_ALWAYS),
    SimType("joint413","Accents (joint413):                                        ", ACCENTS3,_VOID_,ACCENT_JOINT41|ACCENT_ALWAYS),
    SimType("joint414","Accents (joint414):                                        ", ACCENTS4,_VOID_,ACCENT_JOINT41|ACCENT_ALWAYS),
    SimType("joint415","Accents (joint415):                                        ", ACCENTS5,_VOID_,ACCENT_JOINT41|ACCENT_ALWAYS),

    SimType("joint42", "Accents (joint42):                                         ", ACCENTS0, _VOID_,ACCENT_JOINT42|ACCENT_ALWAYS),
    SimType("joint421","Accents (joint421):                                        ", ACCENTS1,_VOID_,ACCENT_JOINT42|ACCENT_ALWAYS),
    SimType("joint422","Accents (joint422):                                        ", ACCENTS2,_VOID_,ACCENT_JOINT42|ACCENT_ALWAYS),
    SimType("joint423","Accents (joint423):                                        ", ACCENTS3,_VOID_,ACCENT_JOINT42|ACCENT_ALWAYS),
    SimType("joint424","Accents (joint424):                                        ", ACCENTS4,_VOID_,ACCENT_JOINT42|ACCENT_ALWAYS),
    SimType("joint425","Accents (joint425):                                        ", ACCENTS5,_VOID_,ACCENT_JOINT42|ACCENT_ALWAYS),

    SimType("joint43", "Accents (joint43):                                         ", ACCENTS0,_VOID_,ACCENT_JOINT43|ACCENT_ALWAYS),
    SimType("joint431","Accents (joint431):                                        ", ACCENTS1,_VOID_,ACCENT_JOINT43|ACCENT_ALWAYS),
    SimType("joint432","Accents (joint432):                                        ", ACCENTS2,_VOID_,ACCENT_JOINT43|ACCENT_ALWAYS),
    SimType("joint433","Accents (joint433):                                        ", ACCENTS3,_VOID_,ACCENT_JOINT43|ACCENT_ALWAYS),
    SimType("joint434","Accents (joint434):                                        ", ACCENTS4,_VOID_,ACCENT_JOINT43|ACCENT_ALWAYS),
    SimType("joint435","Accents (joint435):                                        ", ACCENTS5,_VOID_,ACCENT_JOINT43|ACCENT_ALWAYS),

    SimType("joint44", "Accents (joint44):                                         ", ACCENTS0,_VOID_,ACCENT_JOINT44|ACCENT_ALWAYS),
    SimType("joint441","Accents (joint441):                                        ", ACCENTS1,_VOID_,ACCENT_JOINT44|ACCENT_ALWAYS),
    SimType("joint442","Accents (joint442):                                        ", ACCENTS2,_VOID_,ACCENT_JOINT44|ACCENT_ALWAYS),
    SimType("joint443","Accents (joint443):                                        ", ACCENTS3,_VOID_,ACCENT_JOINT44|ACCENT_ALWAYS),
    SimType("joint444","Accents (joint444):                                        ", ACCENTS4,_VOID_,ACCENT_JOINT44|ACCENT_ALWAYS),
    SimType("joint445","Accents (joint445):                                        ", ACCENTS5,_VOID_,ACCENT_JOINT44|ACCENT_ALWAYS),

    SimType("joint45", "Accents (joint45):                                         ", ACCENTS0,_VOID_,ACCENT_JOINT45|ACCENT_ALWAYS),
    SimType("joint451","Accents (joint451):                                        ", ACCENTS1,_VOID_,ACCENT_JOINT45|ACCENT_ALWAYS),
    SimType("joint452","Accents (joint452):                                        ", ACCENTS2,_VOID_,ACCENT_JOINT45|ACCENT_ALWAYS),

    SimType("joint453","Accents (joint453):                                        ", ACCENTS3,_VOID_,ACCENT_JOINT45|ACCENT_ALWAYS),
    SimType("joint454","Accents (joint454):                                        ", ACCENTS4,_VOID_,ACCENT_JOINT45|ACCENT_ALWAYS),
    SimType("joint455","Accents (joint455):                                        ", ACCENTS5,_VOID_,ACCENT_JOINT45|ACCENT_ALWAYS),

    SimType("joint46", "Accents (joint46):                                         ", ACCENTS0,_VOID_,ACCENT_JOINT46|ACCENT_ALWAYS),
    SimType("joint461","Accents (joint461):                                        ", ACCENTS1,_VOID_,ACCENT_JOINT46|ACCENT_ALWAYS),
    SimType("joint462","Accents (joint462):                                        ", ACCENTS2,_VOID_,ACCENT_JOINT46|ACCENT_ALWAYS),
    SimType("joint463","Accents (joint463):                                        ", ACCENTS3,_VOID_,ACCENT_JOINT46|ACCENT_ALWAYS),
    SimType("joint464","Accents (joint464):                                        ", ACCENTS4,_VOID_,ACCENT_JOINT46|ACCENT_ALWAYS),
    SimType("joint465","Accents (joint465):                                        ", ACCENTS5,_VOID_,ACCENT_JOINT46|ACCENT_ALWAYS),

    SimType("joint51", "Accents (joint51):                                         ", ACCENTS0,_VOID_,ACCENT_JOINT51|ACCENT_ALWAYS),
    SimType("joint511","Accents (joint511):                                        ", ACCENTS1,_VOID_,ACCENT_JOINT51|ACCENT_ALWAYS),
    SimType("joint512","Accents (joint512):                                        ", ACCENTS2,_VOID_,ACCENT_JOINT51|ACCENT_ALWAYS),
    SimType("joint513","Accents (joint513):                                        ", ACCENTS3,_VOID_,ACCENT_JOINT51|ACCENT_ALWAYS),
    SimType("joint514","Accents (joint514):                                        ", ACCENTS4,_VOID_,ACCENT_JOINT51|ACCENT_ALWAYS),
    SimType("joint515","Accents (joint515):                                        ", ACCENTS5,_VOID_,ACCENT_JOINT51|ACCENT_ALWAYS),

    SimType("joint52", "Accents (joint52):                                         ", ACCENTS0,_VOID_,ACCENT_JOINT52|ACCENT_ALWAYS),
    SimType("joint521","Accents (joint521):                                        ", ACCENTS1,_VOID_,ACCENT_JOINT52|ACCENT_ALWAYS),
    SimType("joint522","Accents (joint522):                                        ", ACCENTS2,_VOID_,ACCENT_JOINT52|ACCENT_ALWAYS),
    SimType("joint523","Accents (joint523):                                        ", ACCENTS3,_VOID_,ACCENT_JOINT52|ACCENT_ALWAYS),
    SimType("joint524","Accents (joint524):                                        ", ACCENTS4,_VOID_,ACCENT_JOINT52|ACCENT_ALWAYS),
    SimType("joint525","Accents (joint525):                                        ", ACCENTS5,_VOID_,ACCENT_JOINT52|ACCENT_ALWAYS),

    SimType("joint53", "Accents (joint53):                                         ", ACCENTS0,_VOID_,ACCENT_JOINT53|ACCENT_ALWAYS),
    SimType("joint531","Accents (joint531):                                        ", ACCENTS1,_VOID_,ACCENT_JOINT53|ACCENT_ALWAYS),
    SimType("joint532","Accents (joint532):                                        ", ACCENTS2,_VOID_,ACCENT_JOINT53|ACCENT_ALWAYS),
    SimType("joint533","Accents (joint533):                                        ", ACCENTS3,_VOID_,ACCENT_JOINT53|ACCENT_ALWAYS),
    SimType("joint534","Accents (joint534):                                        ", ACCENTS4,_VOID_,ACCENT_JOINT53|ACCENT_ALWAYS),
    SimType("joint535","Accents (joint535):                                        ", ACCENTS5,_VOID_,ACCENT_JOINT53|ACCENT_ALWAYS),

    SimType("joint54", "Accents (joint54):                                         ", ACCENTS0,_VOID_,ACCENT_JOINT54|ACCENT_ALWAYS),
    SimType("joint541","Accents (joint541):                                        ", ACCENTS1,_VOID_,ACCENT_JOINT54|ACCENT_ALWAYS),
    SimType("joint542","Accents (joint542):                                        ", ACCENTS2,_VOID_,ACCENT_JOINT54|ACCENT_ALWAYS),
    SimType("joint543","Accents (joint543):                                        ", ACCENTS3,_VOID_,ACCENT_JOINT54|ACCENT_ALWAYS),
    SimType("joint544","Accents (joint544):                                        ", ACCENTS4,_VOID_,ACCENT_JOINT54|ACCENT_ALWAYS),
    SimType("joint545","Accents (joint545):                                        ", ACCENTS5,_VOID_,ACCENT_JOINT54|ACCENT_ALWAYS),

    SimType("joint55", "Accents (joint55):                                         ", ACCENTS0,_VOID_,ACCENT_JOINT55|ACCENT_ALWAYS),
    SimType("joint551","Accents (joint551):                                        ", ACCENTS1,_VOID_,ACCENT_JOINT55|ACCENT_ALWAYS),
    SimType("joint552","Accents (joint552):                                        ", ACCENTS2,_VOID_,ACCENT_JOINT55|ACCENT_ALWAYS),
    SimType("joint553","Accents (joint553):                                        ", ACCENTS3,_VOID_,ACCENT_JOINT55|ACCENT_ALWAYS),
    SimType("joint554","Accents (joint554):                                        ", ACCENTS4,_VOID_,ACCENT_JOINT55|ACCENT_ALWAYS),
    SimType("joint555","Accents (joint555):                                        ", ACCENTS5,_VOID_,ACCENT_JOINT55|ACCENT_ALWAYS),

    SimType("joint56", "Accents (joint56):                                         ", ACCENTS0,_VOID_,ACCENT_JOINT56|ACCENT_ALWAYS),
    SimType("joint561","Accents (joint561):                                        ", ACCENTS1,_VOID_,ACCENT_JOINT56|ACCENT_ALWAYS),
    SimType("joint562","Accents (joint562):                                        ", ACCENTS2,_VOID_,ACCENT_JOINT56|ACCENT_ALWAYS),
    SimType("joint563","Accents (joint563):                                        ", ACCENTS3,_VOID_,ACCENT_JOINT56|ACCENT_ALWAYS),
    SimType("joint564","Accents (joint564):                                        ", ACCENTS4,_VOID_,ACCENT_JOINT56|ACCENT_ALWAYS),
    SimType("joint565","Accents (joint565):                                        ", ACCENTS5,_VOID_,ACCENT_JOINT56|ACCENT_ALWAYS),

    SimType("joint57", "Accents (joint57):                                         ", ACCENTS0,_VOID_,ACCENT_JOINT57|ACCENT_ALWAYS),
    SimType("joint571","Accents (joint571):                                        ", ACCENTS1,_VOID_,ACCENT_JOINT57|ACCENT_ALWAYS),
    SimType("joint572","Accents (joint572):                                        ", ACCENTS2,_VOID_,ACCENT_JOINT57|ACCENT_ALWAYS),
    SimType("joint573","Accents (joint573):                                        ", ACCENTS3,_VOID_,ACCENT_JOINT57|ACCENT_ALWAYS),
    SimType("joint574","Accents (joint574):                                        ", ACCENTS4,_VOID_,ACCENT_JOINT57|ACCENT_ALWAYS),
    SimType("joint575","Accents (joint575):                                        ", ACCENTS5,_VOID_,ACCENT_JOINT57|ACCENT_ALWAYS),

    SimType("joint58", "Accents (joint58):                                         ", ACCENTS0,_VOID_,ACCENT_JOINT58|ACCENT_ALWAYS),
    SimType("joint581","Accents (joint581):                                        ", ACCENTS1,_VOID_,ACCENT_JOINT58|ACCENT_ALWAYS),
    SimType("joint582","Accents (joint582):                                        ", ACCENTS2,_VOID_,ACCENT_JOINT58|ACCENT_ALWAYS),
    SimType("joint583","Accents (joint583):                                        ", ACCENTS3,_VOID_,ACCENT_JOINT58|ACCENT_ALWAYS),
    SimType("joint584","Accents (joint584):                                        ", ACCENTS4,_VOID_,ACCENT_JOINT58|ACCENT_ALWAYS),
    SimType("joint585","Accents (joint585):                                        ", ACCENTS5,_VOID_,ACCENT_JOINT58|ACCENT_ALWAYS),

    SimType("joint61", "Accents (joint61):                                         ", ACCENTS0,_VOID_,ACCENT_JOINT61|ACCENT_ALWAYS),
    SimType("joint611","Accents (joint611):                                        ", ACCENTS1,_VOID_,ACCENT_JOINT61|ACCENT_ALWAYS),
    SimType("joint612","Accents (joint612):                                        ", ACCENTS2,_VOID_,ACCENT_JOINT61|ACCENT_ALWAYS),
    SimType("joint613","Accents (joint613):                                        ", ACCENTS3,_VOID_,ACCENT_JOINT61|ACCENT_ALWAYS),
    SimType("joint614","Accents (joint614):                                        ", ACCENTS4,_VOID_,ACCENT_JOINT61|ACCENT_ALWAYS),
    SimType("joint615","Accents (joint615):                                        ", ACCENTS5,_VOID_,ACCENT_JOINT61|ACCENT_ALWAYS),

    SimType("joint62", "Accents (joint62):                                         ", ACCENTS0,_VOID_,ACCENT_JOINT62|ACCENT_ALWAYS),
    SimType("joint621","Accents (joint621):                                        ", ACCENTS1,_VOID_,ACCENT_JOINT62|ACCENT_ALWAYS),
    SimType("joint622","Accents (joint622):                                        ", ACCENTS2,_VOID_,ACCENT_JOINT62|ACCENT_ALWAYS),
    SimType("joint623","Accents (joint623):                                        ", ACCENTS3,_VOID_,ACCENT_JOINT62|ACCENT_ALWAYS),
    SimType("joint624","Accents (joint624):                                        ", ACCENTS4,_VOID_,ACCENT_JOINT62|ACCENT_ALWAYS),
    SimType("joint625","Accents (joint625):                                        ", ACCENTS5,_VOID_,ACCENT_JOINT62|ACCENT_ALWAYS),

    SimType("joint63", "Accents (joint63):                                         ", ACCENTS0,_VOID_,ACCENT_JOINT63|ACCENT_ALWAYS),
    SimType("joint631","Accents (joint631):                                        ", ACCENTS1,_VOID_,ACCENT_JOINT63|ACCENT_ALWAYS),
    SimType("joint632","Accents (joint632):                                        ", ACCENTS2,_VOID_,ACCENT_JOINT63|ACCENT_ALWAYS),
    SimType("joint633","Accents (joint633):                                        ", ACCENTS3,_VOID_,ACCENT_JOINT63|ACCENT_ALWAYS),
    SimType("joint634","Accents (joint634):                                        ", ACCENTS4,_VOID_,ACCENT_JOINT63|ACCENT_ALWAYS),
    SimType("joint635","Accents (joint635):                                        ", ACCENTS5,_VOID_,ACCENT_JOINT63|ACCENT_ALWAYS),

    SimType("joint64", "Accents (joint64):                                         ", ACCENTS0,_VOID_,ACCENT_JOINT64|ACCENT_ALWAYS),
    SimType("joint641","Accents (joint641):                                        ", ACCENTS1,_VOID_,ACCENT_JOINT64|ACCENT_ALWAYS),

    SimType("joint642","Accents (joint642):                                        ", ACCENTS2,_VOID_,ACCENT_JOINT64|ACCENT_ALWAYS),
    SimType("joint643","Accents (joint643):                                        ", ACCENTS3,_VOID_,ACCENT_JOINT64|ACCENT_ALWAYS),
    SimType("joint644","Accents (joint644):                                        ", ACCENTS4,_VOID_,ACCENT_JOINT64|ACCENT_ALWAYS),
    SimType("joint645","Accents (joint645):                                        ", ACCENTS5,_VOID_,ACCENT_JOINT64|ACCENT_ALWAYS),
    */

};


static int compareNoCase(const char* s1, const char *s2)
{
   uint i = 0;
   while( s1[i] != 0 && s2[i] !=0){
      char c1 = s1[i]>'a' ? s1[i]-'a' + 'A' : s1[i];
      char c2 = s2[i]>'a' ? s2[i]-'a' + 'A' : s2[i];
      if(c1<c2) return -1;
      if(c1>c2) return  1;
      ++i;
   }
   if(s1[i] == 0){
       if(s2[i] != 0 ) return -1;
   }
   if(s2[i] == 0){
       if(s1[i] != 0 ) return +1;
   }
   return 0;
}

static int getSimTypeIdx(const string& type)
{
   uint len = sizeof(File::SimTypes)/sizeof(File::SimTypes[0]);
   for(uint i = 0; i<len; ++i){
      if(compareNoCase(File::SimTypes[i].m_sName.c_str(), type.c_str())==0) return i;
   }
   return -1;
}

static int getFeatureIdx(const string& feature)
{
   uint len = sizeof(File::FeatureDefs)/sizeof(File::FeatureDefs[0]);
   for(uint i = 0; i<len; ++i){
      if(compareNoCase(File::FeatureDefs[i].getName().c_str(), feature.c_str())==0) return i;
   }
   return -1;
}
FeatureDef *File::getFeature(const string& feature)
{
   int idx = getFeatureIdx(feature);
   if(idx == -1) return 0;
   return &File::FeatureDefs[idx];
}

bool File::getFeaturesFromString(const string& str, FeatureList& fl)
{
   fl.clear();
   for(uint i = 1; ;++i){
      string feature = getToken(str.c_str(), i, ',');
      if(feature.empty()){
         feature = getToken(str.c_str(), i, ';');
         if(feature.empty()) break;
      }
      int idx = getFeatureIdx(feature);
      if(idx == -1) continue;
      fl.push_back(&File::FeatureDefs[idx]);
   }
   return !fl.empty();
}

void File::printFeatures(bool bExplanation)
{
   uint len = sizeof(File::FeatureDefs)/sizeof(File::FeatureDefs[0]);
   for(uint i = 0; i<len; ++i){
      if(bExplanation){
         cout<<File::FeatureDefs[i].getName().c_str()<<" ("<<File::FeatureDefs[i].getDisplayName().c_str()<<")"<<endl;
      }
      else{
         cout<<File::FeatureDefs[i].getName().c_str()<<endl;
      }
   }
}

void File::printSimTypes()
{
   uint len = sizeof(File::SimTypes)/sizeof(File::SimTypes[0]);
   for(uint i = 0; i<len; ++i){
      cout<<File::SimTypes[i].m_sName.c_str()<<endl;
   }
}


string File::getToken(const char *str, uint which, const char delim)
{
   uint i = 0;
   char *tmp;
   char *start = 0, *end = 0;
   string szRet("");
   if(!str || !which) return szRet;

   tmp = new char[strlen(str)+1];
   if(!tmp) return szRet;
   strcpy(tmp, str);

   start = tmp;
   end   = strchr(start, delim);

   if(!end){
      if(which != 1){
         goto out;
      }
      else{
         szRet = str;
         goto out;
      }
   }

   for(i = 0; i<which - 1; ++i){
      end = strchr(start, delim);
      if(!end){
         if(i == which-1){
            end = start + strlen(start);
            break;
         }
         else goto out;
      }
      start = end+1;
   }
   end = strchr(start, delim);
   if(end)*end = '\0';
   szRet = string(start);

out:
   delete []tmp;
   return szRet;
}

void File::getAllTypes(SimTypeList &typeList, string& header, bool &bNeedGauss)
{

   typeList.clear();
   header = "file1" + m_sFieldSeparator + "file2" + m_sFieldSeparator +"trans" + m_sFieldSeparator;
   uint len = sizeof(SimTypes)/sizeof(SimTypes[0]);
   CombiType   tmpType;
   
   for(uint i = 0; i<len; ++i){
      CombiTypeElement tmpCT(SimTypes[i].m_sName, 1.0);
      tmpCT.push_back(&SimTypes[i]); 
      tmpType.push_back(tmpCT);
      typeList.push_back(tmpType);
      header += SimTypes[i].m_sName + m_sFieldSeparator;
   }
   header= header.substr(0, header.length()-1);
   bNeedGauss= true;
}

bool File::getMultSimList(const string &sMultType, CombiTypeElement &combiType)
{
   uint i = 0;
   string sType;
   combiType.clear();
   if(sMultType.find("*") == string::npos){
      int type = getSimTypeIdx(sMultType);
      if(type == -1){
         cerr<<"Unrecognized similarity type \""<<sType.c_str()<<"\" in combi type "<<sMultType<<". Skipping."<<endl;
         return false;
      }
      combiType.push_back(&File::SimTypes[type]);
      return true;             
   }

   for(i = 1; ;++i){
      sType= getToken(sMultType.c_str(), i, '*');
      if(sType.length() == 0) break;
      int type = getSimTypeIdx(sType);
      if(type == -1){
         cerr<<"Unrecognized similarity type \""<<sType.c_str()<<"\" in combi type "<<sMultType<<". Skipping."<<endl;
         return false;
      }
      cerr<<"Added "<<sType.c_str()<<endl;
      combiType.push_back(&File::SimTypes[type]);
   }
   return true;   
}

bool File::getCombiType(const char *buf, CombiType& combiType, string& combiDisplay, bool &bNeedGauss)
{
   CombiTypeElement tmpCT;
   string sType, sWeight, combiName;

   combiType.clear();
   bNeedGauss = false;

   sType          = getToken(buf, 1, ' ');
   combiName      = getToken(sType.c_str(), 1, ':');

   if(buf[0] == '#') return false;
   if(combiName != string("combi")){//single
      int type = getSimTypeIdx(sType);
      if(type == -1){
         cerr<<"Skipping unrecognized similarity type \""<<sType.c_str()<<"\""<<endl;
         return false;
      }
      if(sType == "rhytGaus") bNeedGauss = true;
      tmpCT.set(File::SimTypes[type].m_sDisplay, 1.0);
      tmpCT.push_back(&File::SimTypes[type]); 
      combiDisplay = sType;
      combiType.m_sCombiName = sType;
      combiType.push_back(tmpCT);
      return true;
   }

   combiDisplay   = getToken(sType.c_str(), 2, ':');
   if(!combiDisplay.length()){
      combiDisplay = "combi";
   }
   combiType.m_sCombiName     = combiDisplay;
   combiType.m_sCombiDisplay  = combiDisplay;
   if(m_verbLevel>silent)
      cerr<<"Found "<<combiDisplay.c_str()<<endl;

   for(uint i = 0;; i += 2){
      sType = getToken(buf, 2+i, ' ');
      if(sType.length()==0) break;
      if(sType.find("rhytGaus") != string::npos) bNeedGauss = true;
      sWeight = getToken(buf, 2+i+1, ' ');
      if(sWeight.length() == 0){
         cerr<<"Missing weight in combi type "<<combiDisplay<<". Skipping."<<endl;
         return false;
      }
      if(!getMultSimList(sType, tmpCT)) return false;
      if(m_verbLevel>silent)
         cerr<<sType.c_str()<<" with weight: "<<sWeight.c_str()<<endl;
      tmpCT.set(combiDisplay, atof(sWeight.c_str()));
      combiType.push_back(tmpCT);
   }
   if(combiType.empty()){
      cerr<<"Missing types for combi type "<<combiDisplay<<". Skipping."<<endl;
      return false;

   }
   return true;
}

void File::getDefaultSimTypes(SimTypeList &typeList, string &header, bool &bNeedGauss)
{
   static char *simTypeDefaults[] = {
      "combi:opt3 nGrUkkon 0.505 rhytFuzz 0.417 harmCorE 0.24 const -0.146",
      "diffEd",
      "nGrUkkon",
      "conSEd",
      "rhytFuz2",
      "harmCorE",
      "joint52"
   };
   bNeedGauss =false;
   typeList.clear();
   header = "file1" + m_sFieldSeparator + "file2" + m_sFieldSeparator;

   string combiDisplay;
   CombiType   tmpCT; 
   for(uint i = 0; i<sizeof(simTypeDefaults)/sizeof(simTypeDefaults[0]); ++i){
      char *ptr = simTypeDefaults[i];
      if(!getCombiType(ptr, tmpCT, combiDisplay, bNeedGauss)) continue;
      typeList.push_back(tmpCT);
      header +=combiDisplay + m_sFieldSeparator;
      if(m_verbLevel>silent)
         cerr<<"Added similarity type \""<<combiDisplay.c_str()<<"\"."<<endl;
   }
}

bool File::readTypesFile(const char* file, SimTypeList &typeList, string &header, bool &bNeedGauss)
{
   bool bRet = false;
   FILE *fp;
   char buf[1024] ="";
   string line;
   string sType, sWeight, combiName, combiDisplay;
   CombiType   tmpCT, tmpCT1;
   bool bGauss = false;
   if(!file)
      return bRet;

   if((fp = fopen(file, "r")) == 0){
      cerr<<"Could not open "<<file<<endl;
      return bRet;
   }
   
   typeList.clear();
   header = "file1" + m_sFieldSeparator + "file2" + m_sFieldSeparator;
   while(!feof(fp)){
      if(fgets(buf, sizeof(buf), fp) == NULL){
         if(ferror(fp)){
            cerr<<"Error reading "<<file<<endl;
            goto out;
         }
         else break;

      }
      if(buf[0] ==';' || buf[0] == '\n') continue;
      string sBuf = stripWhiteSpace(string(buf), false, true);

      if(!getCombiType(sBuf.c_str(), tmpCT, combiDisplay, bGauss))
         continue;
      if(bGauss) bNeedGauss = true;
      typeList.push_back(tmpCT);
      header +=combiDisplay + m_sFieldSeparator;
      if(m_verbLevel>silent)
         cerr<<"Added similarity type \""<<combiDisplay.c_str()<<"\"."<<endl;
   }
   bRet = true;
   

out:

   fclose(fp);
   return bRet;
}

bool File::readFeatureFile(const char* file, FeatureList &featureList)
{
   bool bRet = false;
   FILE *fp;

   if(!file)
      return bRet;

   if((fp = fopen(file, "r")) == 0){
      cerr<<"Could not open "<<file<<endl;
      return bRet;
   }
   
   featureList.clear();

   char buf[1024] ="";

   while(!feof(fp)){
      if(fgets(buf, sizeof(buf), fp) == NULL){
         if(ferror(fp)){
            cerr<<"Error reading "<<file<<endl;
            goto out;
         }
         else break;

      }
      if(buf[0] ==';' || buf[0] == '\n') continue;
      string sBuf = stripWhiteSpace(string(buf), false, true);

      int idx = getFeatureIdx(sBuf.c_str());
      if(idx == -1){
         cerr<<"Skipping unrecognized feature \""<<sBuf.c_str()<<"\""<<endl;
         continue;
      }
      FeatureDef* tmp = &File::FeatureDefs[idx];
      featureList.push_back(tmp);
      cerr<<"Added feature \""<<tmp->getName().c_str()<<"\"."<<endl;
   }
   bRet = true;
   

out:

   fclose(fp);
   return bRet;
}


bool File::readFilesFile(const char* file, vector<string> &fileList)
{
   bool bRet = false;
   FILE *fp;
   char buf[1024] ="";
   string line;

   if(!file)
      return bRet;

   if((fp = fopen(file, "r")) == 0){
      cerr<<"Could not open "<<file<<endl;
      return bRet;
   }
   
   fileList.clear();

   while(!feof(fp)){
      if(fgets(buf, sizeof(buf), fp) == NULL){
         if(ferror(fp)){
            cerr<<"Error reading "<<file<<endl;
            goto out;
         }
         else break;

      }
      if(buf[0] ==';' || buf[0] == '\n') continue;
      string sBuf = stripWhiteSpace(string(buf), false, true);
      fileList.push_back(sBuf);
   }

   bRet = true;
   
out:
   fclose(fp);
   return bRet;
}

bool File::parseCSVHeader(const char * buf, Signature& sig, uint &key)
{
   string str(buf);
   int ndx = -1;
   uint count = 0;
   int i  = 0;
   key = 12;
   if((ndx = str.find("/")) == -1){
      return false;
   }
   
   for(i = ndx-1; i>=0 ; --i){
      if(atoi(str.substr(i).c_str()) == 0 ) break;
      count = atoi(str.substr(i).c_str());      
   }
   if(count == 0) return false;
   sig.m_nCount = count;
   sig.m_nDenom = atoi( str.substr(ndx+1).c_str());

   if((ndx = str.find("Ticks")) == -1){
      return false;
   }
   count = 0;

   for(i = ndx + 5; i<(int)str.length() ; ++i){
      if((count = atoi(str.substr(i).c_str())) != 0 ) break;

   }
   if(count == 0) return false;
   sig.m_nTicks = count;
   sig.setFraction();

   if((ndx = str.find("Key")) != -1){
      key = atoi(str.substr(ndx+5).c_str());
   }
   else{
      key = 0;
   }
   return true;
}

BarPosition File::getBarPosition(const char * buf, const Signature* pSig)
{
   BarPosition barPos(pSig);
   
   barPos.setBar(atoi(getToken(buf, 3, ';').c_str()));
   barPos.setBeat(atoi(getToken(buf, 4, ';').c_str()));
   barPos.setTicks(atoi(getToken(buf, 5, ';').c_str()));
   //barPos.dumpBar();

   return barPos;
}

bool File::readCSVFile(const char* file, Melody &melody)
{
   bool bRet = false;
   char buf[1024] = "";
   char onset[32] = "";
   string tmp;
   FILE *fp;
   uint sum = 0, sz = 0;
   MIDIPitch low = 0, high = 0;
   /*static*/ Signature sig;
   uint key = 0;
   BarPosition tmpBar;
   uint        quantLevel  = melody.getQuantLevel();
   indizes tmpIdz;
   uint dur = 0;
   unsigned char pitch     = 0;
   unsigned char lastPitch = 0;
   vector<uint> durTicks;
   melody.clear();
   
   if(( fp = fopen(file, "r")) == NULL){
       return bRet;
   }
   if(m_verbLevel>silent)
      melody.out()<<"Reading: "<<file<<endl;
   //read first 2 lines;
   for(uint i = 0; i<2; ++i){
      if(fgets(buf,sizeof(buf), fp) == NULL){
         cerr<<file<<": I/O Error"<<endl;
         goto out;
      }
      if(i == 0) {
         if(parseCSVHeader(buf, sig, key)){
            melody.setSignature(sig);
            melody.setAnnotatedKey(key);
         }
         else{
            cerr<<file<<": Bad data format!"<<endl;         
            goto out;
         }
      }
   }

   //read lines
   while(!feof(fp)){
      if(fgets(buf,sizeof(buf), fp) == NULL){
         if(ferror(fp)){
            cerr<<file<<": I/O Error"<<endl;
            goto out;
         }
         break;
      }
      //override \n
      buf[strlen(buf)-1] = '\0';

      //get pitch
      tmp = getToken(buf, 6, ';');
      if(tmp.length() == 0) {
         cerr<<file<<": Bad data format!"<<endl;
         goto out;
      }
      lastPitch = pitch;
      pitch = (unsigned char)atoi(tmp.c_str());
      if(pitch == 128 || pitch == 150 || pitch ==200 ){
         continue; //ignore
      }
      if(pitch>128){
         if(pitch != 250) {
            cerr<<"Found undefined pitch!"<<endl;
            goto out;
         }
         else{
            pitch = lastPitch<128? lastPitch : 0;
         }
      }
      if(pitch == 0) continue;
      melody.m_pitches.push_back(pitch);

      //getOnsets
      tmp = getToken(buf, 1, ';');
      strncpy(onset, tmp.c_str(), sizeof(onset)-1);
      onset[sizeof(onset)-1] = '\0';
      subchr(onset, ',', '.');      
      melody.m_onsets.push_back(atof(onset));

      //get durations
      tmp = getToken(buf, 9, ';');
      if(tmp.length() == 0) {
         cerr<<file<<": Bad data format!"<<endl;
         goto out;
      }
      dur = (uint)atoi(tmp.c_str());
      sum += dur;
      if (dur == 0){
         dur = (sum/16+1)*16-sum;
         if(dur>4) dur = 4;
         sum +=dur;
         //cerr<<file<<": Found duration 0. Adjusting to "<<dur<<endl; 
      }
      //cerr<<"Pitch: "<<(uint) pitch<<" dur16: "<<dur<<endl;
      
      melody.m_durations.push_back(dur);
      tmpBar = getBarPosition(buf, &melody.m_signature);
      //tmpBar.dump();
      melody.m_timeLine.push_back(tmpBar);
      //get durtics
      tmp = getToken(buf, 8, ';');
      if(tmp.length() == 0) {
         cerr<<file<<": Bad data format!"<<endl;
         goto out;
      }
      uint durtic = (uint)atoi(tmp.c_str());
      durTicks.push_back(durtic);
      //cerr<<"Pitch: "<<(uint) pitch<<" durTicks: "<<durtic<<endl;

   }
   //a valid melody should have at least two tones!
   if(melody.m_pitches.size()<2 || melody.m_durations.size()<2 || melody.m_timeLine.size()<2){
      bRet = false;      
      cerr<<"Warning: "<<melody.m_pitches.size()<<"  pitches in melody "<<file<<endl;
      goto out;
   }
   if(quantLevel>sig.m_nTicks/2){
      cerr<<"Warning: Quantization level ("<<quantLevel<<") suspiciously high. Using 24 instead."<<endl;
      quantLevel = 24;
      melody.setQuantLevel(quantLevel);
   }
   if(quantLevel>1 && quantLevel<=sig.m_nTicks && sig.m_nTicks % quantLevel){
      uint kgv = kgV(sig.m_nTicks, quantLevel);
      melody.m_timeLine.rescaleTicks(kgv/sig.m_nTicks);
      sig.m_nTicks = kgv;
      //cerr<<"Scaling to "<<kgv<<" ticks per beat"<<endl;
      sig.setFraction();
      melody.setSignature(sig);
   }
   melody.setName(file);
   
   if(!melody.m_timeLine.isQuantized(quantLevel)){
      melody.m_timeLine = melody.m_timeLine.quantize(quantLevel, tmpIdz);
      melody.out()<<"Quantizing melody "<<file<<" at level "<<quantLevel<<" ...";
      if(!tmpIdz.empty()){
         cerr<<" Failure."<<endl;
         goto out;
      }
      cerr<<" Success."<<endl;
   }
   
   melody.m_timeLine.setTimebase();
   sz = melody.m_timeLine.getTimebase();
   if(sz==0) sz = sig.m_nTicks;
   melody.m_durations = invScaleVector<uint>(melody.m_timeLine.getTickDurations(), sz);
   tmpBar.quantize(quantLevel);
   dur = durTicks[durTicks.size()-1]/sz;
   if( dur == 0){
      dur = tmpBar.getTicksToNextBeat()/sz;
   }  
   melody.m_durations.push_back(dur);
   melody.m_timeLine.setBeatDivisions();
   //dumpData("New durations", melody.m_durations, melody.out());
   //dumpData("Dur Ticks", melody.m_timeLine.getTickDurations(), melody.out());
   
   bRet = true;
   melody.setPhraseBoundaries();

out:
   if(!bRet){
      melody.clear();
   }
   fclose(fp);
   return bRet;
}

bool File::readMelodies(Melody **ppMelody, const vector<string>& fileList, const uint quantLevel)
{
   uint nSize = fileList.size();
   uint errCount = 0;
   *ppMelody = 0;
   errorString = "";
   if(!nSize) return true;

   *ppMelody = new Melody[nSize];
   if(!*ppMelody){
      cerr<<"Out of memory!"<<endl;
      return false;
   }
   
   for(uint i = 0; i<nSize; ++i){
      (*ppMelody)[i].setOStream(&cerr);
      (*ppMelody)[i].setQuantLevel(quantLevel);
      if(!readCSVFile(fileList[i].c_str(), (*ppMelody)[i])){
         errCount++;
         cerr<<"Error reading "<<fileList[i].c_str()<<endl;
         perror(fileList[i].c_str());
         errorString = fileList[i]; 
      }
   }
   if(errCount == nSize) return false;
   return true;
}

bool File::printCSV(const char *filename, const uint mode, const char* line)
{
   bool bRet = false;
   FILE *fp = NULL;

   if(mode == FILE_MODE_APPEND){
      fp = fopen(filename, "a");
   }
   else {
      fp = fopen(filename, "w");
   }
   
   if( fp == NULL ){
      cerr<<"Could not open "<<filename<<endl;
      perror(filename);
      errorString = filename;
      return false;
   }

   if(!fputs(line, fp) && ferror(fp)){
      goto out;
   }
   if(!fputs("\n", fp) && ferror(fp)){
      goto out;
   }
   bRet = true;
out:  
   fclose(fp);
   return bRet;
}

class Compare
{
   public:
  bool operator()(pair<string, double> val1, pair<string, double> val2)
  {
     return val1.second>val2.second;
  }
};
string stripExtension(const string str)
{
   string ret = str;
   int pos = str.find_last_of(".");
   if(pos == string::npos){
      return ret;
   }
   return ret.substr(0, pos);
}

bool 
File::writeQueryResultFile(const string &sResultFile, vector<string> fileList1, vector<string> fileList2, 
                           dataVec& totVals, const string &sPath, const int idx, const SimTypeList& simTypes)
{
   uint i = 0, j = 0;
   list<pair<string, double> > results;
   list<pair<string, double> >::iterator iter;
   data vec;
   //sanity
   if(idx>0 && idx>=(int)totVals[0].size()){
      cerr<<"Invalid index requested."<<endl;
      return false;
   }
   FILE *fp = 0;
   if(sResultFile.length() == 0){
      fp = stdout;
   }
   else{
      fp = fopen(sResultFile.c_str(), "w");
   }
   if( fp == NULL ){
      cerr<<"Could not open "<<sResultFile<<endl;
      return false;
   }
   if(totVals.size()<fileList2.size()* fileList2.size()) {
      cerr<<"Invalid data matrix (too small)"<<endl;
      return false;
   }
   uint start = 0;
   uint end = simTypes.size()-1;
   if(idx>=0){
      start = idx; end = idx;
   }
   for(uint k = start; k<=end; ++k){
      for(j = 0; j<fileList2.size(); ++j){
         stringstream buf;
         results.clear();
         for(i = 0; i<fileList1.size(); ++i){
            results.push_back(pair<string, double> (fileList1[i], (totVals[i*fileList2.size()+j])[k]));
         }
         Compare cmp;
         results.sort<Compare>(cmp);
         string tmpPath = sPath; 
         if(!tmpPath.empty() && tmpPath[tmpPath.size()-1] != '\\'){
            tmpPath += "\\";
         }
         string query   = tmpPath.empty() ? stripExtension(fileList2[j]) : tmpPath  + fileList2[j];
         string result  = query;
         
#ifndef MIREX
         buf<<"Query "<<fileList2[j].c_str()<<"  using '"<<simTypes[k].m_sCombiName<<"'"<<endl;
#endif            
         uint i = 1;
         uint maxLen = 0;
         for(iter = results.begin(); iter != results.end(); ++iter, ++i) {
            string rankFile = sPath.empty() ? stripExtension(iter->first) :sPath  + iter->first;
            result += rankFile ;
#ifdef MIREX
            if(i>0)buf<<stripExtension(iter->first.c_str()).c_str()<<endl;
            if(i==10) break;
#else
            buf<<i<<". "<<iter->first.c_str()<<" ("<<iter->second<<")"<<endl;
#endif            
         }
         result[result.size()-1] = '\n';
         fprintf(fp, "%s", buf.str().c_str());
         //printf("%s", result.c_str());
         if(ferror(fp)){
            cerr<<"File I/O error"<<endl;
            fclose(fp);
            return false;
         }
      }
   }
   fclose(fp);   
   return true;
}
