Example #1
0
FiffCov FiffCov::pick_channels(const QStringList &p_include, const QStringList &p_exclude)
{
    RowVectorXi sel = FiffInfoBase::pick_channels(this->names, p_include, p_exclude);
    FiffCov res;//No deep copy here - since almost everything else is adapted anyway

    res.kind = this->kind;
    res.diag = this->diag;
    res.dim = sel.size();

    for(qint32 k = 0; k < sel.size(); ++k)
        res.names << this->names[sel(k)];

    res.data.resize(res.dim, res.dim);
    for(qint32 i = 0; i < res.dim; ++i)
        for(qint32 j = 0; j < res.dim; ++j)
            res.data(i, j) = this->data(sel(i), sel(j));
    res.projs = this->projs;

    for(qint32 k = 0; k < this->bads.size(); ++k)
        if(res.names.contains(this->bads[k]))
            res.bads << this->bads[k];
    res.nfree = this->nfree;

    return res;
}
Example #2
0
FiffEvoked FiffEvoked::pick_channels(const QStringList& include, const QStringList& exclude) const
{
    if(include.size() == 0 && exclude.size() == 0)
        return FiffEvoked(*this);

    RowVectorXi sel = FiffInfo::pick_channels(this->info.ch_names, include, exclude);
    if (sel.cols() == 0)
    {
        qWarning("Warning : No channels match the selection.\n");
        return FiffEvoked(*this);
    }

    FiffEvoked res(*this);
    //
    //   Modify the measurement info
    //
    res.info = FiffInfo(res.info.pick_info(sel));
    //
    //   Create the reduced data set
    //
    MatrixXd selBlock(1,1);

    if(selBlock.rows() != sel.cols() || selBlock.cols() != res.data.cols())
        selBlock.resize(sel.cols(), res.data.cols());
    for(qint32 l = 0; l < sel.cols(); ++l)
    {
        selBlock.block(l,0,1,selBlock.cols()) = res.data.block(sel(0,l),0,1,selBlock.cols());
    }
    res.data.resize(sel.cols(), res.data.cols());
    res.data = selBlock;

    return res;
}
Example #3
0
RowVectorXi FiffInfoBase::pick_channels(const QStringList& ch_names, const QStringList& include, const QStringList& exclude)
{
    RowVectorXi sel = RowVectorXi::Zero(ch_names.size());

    QStringList t_includedSelection;

    qint32 count = 0;
    for(qint32 k = 0; k < ch_names.size(); ++k)
    {
        if( (include.size() == 0 || include.contains(ch_names[k])) && !exclude.contains(ch_names[k]))
        {
            //make sure channel is unique
            if(!t_includedSelection.contains(ch_names[k]))
            {
                sel[count] = k;
                ++count;
                t_includedSelection << ch_names[k];
            }
        }
    }
    sel.conservativeResize(count);
    return sel;
}
Example #4
0
/**
* The function main marks the entry point of the program.
* By default, main has the storage class extern.
*
* @param [in] argc (argument count) is an integer that indicates how many arguments were entered on the command line when the program was started.
* @param [in] argv (argument vector) is an array of pointers to arrays of character objects. The array objects are null-terminated strings, representing the arguments that were entered on the command line when the program was started.
* @return the value that was set to exit() (which is 0 if exit() is called via quit()).
*/
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    //############################# Data location and configs - Change if necessary ############################################

    //source localization type
    QString method("MNE"); //"MNE" | "dSPM" | "sLORETA"

    //Choose which epoch to take - i.e. for every 4th epoch set to 4
    int averageIterator = 1;

    bool doRawTrialLocalization = false;

    //measurement data location (data location must always has same directory structure - see dropbox folder for more information)
    //QString data_location("D:/Dropbox/Masterarbeit DB/Messdaten/EEG/2013_12_05_Lorenz_Esch_001");
    //QString data_location("D:/Dropbox/Masterarbeit DB/Messdaten/EEG/2014_01_10_Lorenz_Esch_002");
    //QString data_location("D:/Dropbox/Masterarbeit DB/Messdaten/EEG/2014_01_14_Lorenz_Esch_003");
    //QString data_location("D:/Dropbox/Masterarbeit DB/Messdaten/EEG/2014_01_28_Lorenz_Esch_004");
    //QString data_location("D:/Dropbox/Masterarbeit DB/Messdaten/EEG/2014_02_04_Lorenz_Esch_005");
    //QString data_location("D:/Dropbox/Masterarbeit DB/Messdaten/EEG/2014_02_05_Uwe_Graichen_006");
    QString data_location("D:/Dropbox/Masterarbeit DB/Messdaten/EEG/2014_02_07_Lorenz_Esch_007");
    //QString data_location("D:/Dropbox/Masterarbeit DB/Messdaten/EEG/2014_02_24_Lorenz_Esch_008");
    //QString data_location("D:/Dropbox/Masterarbeit DB/Messdaten/EEG/2014_02_25_Christoph_Dinh_009");
    //QString data_location("D:/Dropbox/Masterarbeit DB/Messdaten/EEG/2014_03_17_Lorenz_Esch_010");

    //Forward solution
    //QFile t_fileFwd("D:/Dropbox/Masterarbeit DB/Messdaten/Forward solutions/Lorenz-131212-Duke128-fwd.fif");
    //QFile t_fileFwd("D:/Dropbox/Masterarbeit DB/Messdaten/Forward solutions/Lorenz-140112-Duke128-fwd.fif");
    //QFile t_fileFwd("D:/Dropbox/Masterarbeit DB/Messdaten/Forward solutions/Lorenz-140114-Duke128-fwd.fif");
    //QFile t_fileFwd("D:/Dropbox/Masterarbeit DB/Messdaten/Forward solutions/Lorenz-140123-Duke128-fwd.fif");
    QFile t_fileFwd("D:/Dropbox/Masterarbeit DB/Messdaten/Forward solutions/Lorenz-140128-Duke128-fwd.fif");


    //Surface generated by freesurfer
    SurfaceSet t_surfSet("D:/Dropbox/Masterarbeit DB/Messdaten/Forward solutions/surface/lh.white", "D:/Dropbox/Masterarbeit DB/Messdaten/Forward solutions/surface/rh.white");

    //AnnotationSet (See Destrieux paper)
    AnnotationSet t_annotationSet("D:/Dropbox/Masterarbeit DB/Messdaten/Forward solutions/atlas/lh.aparc.a2009s.annot", "D:/Dropbox/Masterarbeit DB/Messdaten/Forward solutions/atlas/rh.aparc.a2009s.annot");

    //////////////////////////////////////////// Interesting start ////////////////////////////////////////////////////////////////////
    //********************************** Involuntary Tapping ***********************************//
    //time read around events - note: trigger point is the pressing of the button, not the atual
//    float tmin = -2.0f;
//    float tmax = 2.0f;

//    //Filtered 7-14Hz left tapping
//    QString t_sRawFileNameRel  ("/Processed/filtered/EEG_data_001_involuntary_left_tapping_filtered_7_14_raw.fif");
//    QString t_sCovFileNameRel  ("/Processed/covariance/EEG_data_001_base_filtered_7_14_raw-cov.fif");
//    QString t_sEventFileNameRel("/Processed/events/EEG_data_001_involuntary_left_tapping_131_raw-eve.fif");
//    QString t_sStcFileNameRel  ("/Processed/stc/SourceLoc_involuntary_left_tapping_filtered_7_14_Averaged_");
//    QString t_sAvrFileNameRel  ("/Processed/averaged/EEG_data_001_involuntary_left_tapping_filtered_7_14_Averaged_");

//    //Filtered 7-14Hz right tapping
//    QString t_sRawFileNameRel  ("/Processed/filtered/EEG_data_001_involuntary_right_tapping_filtered_7_14_raw.fif");
//    QString t_sCovFileNameRel  ("/Processed/covariance/EEEG_data_001_base_filtered_7_14_raw-cov.fif");
//    QString t_sEventFileNameRel("/Processed/events/EEG_data_001_involuntary_right_tapping_136_raw-eve.fif");
//    QString t_sStcFileNameRel  ("/Processed/stc/SourceLoc_involuntary_right_tapping_filtered_7_14_Averaged_");
//    QString t_sAvrFileNameRel  ("/Processed/averaged/EEG_data_001_involuntary_right_tapping_filtered_7_14_Averaged_");

//    //Filtered 0.7-40Hz left tapping
//    QString t_sRawFileNameRel  ("/Processed/filtered/EEG_data_001_involuntary_left_tapping_filtered_07_40_raw.fif");
//    QString t_sCovFileNameRel  ("/Processed/covariance/EEG_data_001_base_filtered_07_40_raw-cov.fif");
//    QString t_sEventFileNameRel("/Processed/events/EEG_data_001_involuntary_left_tapping_131_raw-eve.fif");
//    QString t_sStcFileNameRel  ("/Processed/stc/SourceLoc_involuntary_left_tapping_filtered_07_40_Averaged_");
//    QString t_sAvrFileNameRel  ("/Processed/averaged/EEG_data_001_involuntary_left_tapping_filtered_07_40_Averaged_");

//    //Filtered 0.7-40Hz right tapping
//    QString t_sRawFileNameRel  ("/Processed/filtered/EEG_data_001_involuntary_right_tapping_filtered_07_40_raw.fif");
//    QString t_sCovFileNameRel  ("/Processed/covariance/EEG_data_001_base_filtered_07_40_raw-cov.fif");
//    QString t_sEventFileNameRel("/Processed/events/EEG_data_001_involuntary_right_tapping_136_raw-eve.fif");
//    QString t_sStcFileNameRel  ("/Processed/stc/SourceLoc_involuntary_right_tapping_filtered_07_40_Averaged_");
//    QString t_sAvrFileNameRel  ("/Processed/averaged/EEG_data_001_involuntary_right_tapping_filtered_07_40_Averaged_");

    //////////////////////////////////////////// Interesting end ////////////////////////////////////////////////////////////////////

    //********************************** Voluntary Tapping ***********************************//

//    //time read around events - note: trigger point is the pressing of the button, not the atual
//    float tmin = -1.0f;
//    float tmax = 1.0f;

//    //Original left tapping - no filtering DC still present
//    QString t_sRawFileNameRel  ("/Original/EEG_data_001_right_tapping_raw.fif");
//    QString t_sCovFileNameRel  ("/Processed/covariance/EEG_data_001_base_raw-cov.fif");
//    QString t_sEventFileNameRel("/Processed/events/EEG_data_001_right_tapping_raw-eve.fif");
//    QString t_sStcFileNameRel  ("/Processed/stc/SourceLoc_right_tapping_Averaged_");
//    QString t_sAvrFileNameRel  ("/Processed/averaged/EEG_data_001_right_tapping_Averaged_");

//    //Filtered 0.6-40Hz left tapping
//    QString t_sRawFileNameRel  ("/Processed/filtered/EEG_data_001_left_tapping_filtered_06_40_raw.fif");
//    QString t_sCovFileNameRel  ("/Processed/covariance/EEG_data_001_left_tapping_filtered_06_40_raw-cov.fif");
//    QString t_sEventFileNameRel("/Processed/events/EEG_data_001_left_tapping_raw-eve.fif");
//    QString t_sStcFileNameRel  ("/Processed/stc/SourceLoc_left_tapping_filtered_06_40_Averaged_");
//    QString t_sAvrFileNameRel  ("/Processed/averaged/EEG_data_001_left_tapping_filtered_06_40_Averaged_");

//    //Filtered 0.6-40Hz right tapping
//    QString t_sRawFileNameRel  ("/Processed/filtered/EEG_data_001_right_tapping_filtered_06_40_raw.fif");
//    QString t_sCovFileNameRel  ("/Processed/covariance/EEG_data_001_right_tapping_filtered_06_40_raw-cov.fif");
//    QString t_sEventFileNameRel("/Processed/events/EEG_data_001_right_tapping_raw-eve.fif");
//    QString t_sStcFileNameRel  ("/Processed/stc/SourceLoc_right_tapping_filtered_06_40_Averaged_");
//    QString t_sAvrFileNameRel  ("/Processed/averaged/EEG_data_001_right_tapping_filtered_06_40_Averaged_");

//    //Filtered 7-14Hz left tapping
//    QString t_sRawFileNameRel  ("/Processed/filtered/EEG_data_002_voluntary_left_tapping_filtered_7_14_raw.fif");
//    QString t_sCovFileNameRel  ("/Processed/covariance/EEG_data_voluntary_tapping_base_filtered_7_14_raw-cov.fif");
//    QString t_sEventFileNameRel("/Processed/events/EEG_data_002_voluntary_left_tapping_artefact_reduction_-1_1_0.002_71_raw-eve.fif");
//    QString t_sStcFileNameRel  ("/Processed/stc/SourceLoc_voluntary_left_tapping_filtered_7_14_Averaged_");
//    QString t_sAvrFileNameRel  ("/Processed/averaged/EEG_data_002_voluntary_left_tapping_filtered_7_14_Averaged_");

//    //Filtered 7-14Hz right tapping
//    QString t_sRawFileNameRel  ("/Processed/filtered/EEG_data_002_voluntary_right_tapping_filtered_7_14_raw.fif");
//    QString t_sCovFileNameRel  ("/Processed/covariance/EEG_data_voluntary_tapping_base_filtered_7_14_raw-cov.fif");
//    QString t_sEventFileNameRel("/Processed/events/EEG_data_002_voluntary_right_tapping_artefact_reduction_-1_1_0.003_69_raw-eve.fif");
//    QString t_sStcFileNameRel  ("/Processed/stc/SourceLoc_voluntary_right_tapping_filtered_7_14_Averaged_");
//    QString t_sAvrFileNameRel  ("/Processed/averaged/EEG_data_002_voluntary_right_tapping_filtered_7_14_Averaged_");

//    //Filtered 0.7-40Hz left tapping
//    QString t_sRawFileNameRel  ("/Processed/filtered/EEG_data_002_voluntary_left_tapping_filtered_07_40_raw.fif");
//    QString t_sCovFileNameRel  ("/Processed/covariance/EEG_data_voluntary_tapping_base_filtered_07_40_raw-cov.fif");
//    QString t_sEventFileNameRel("/Processed/events/EEG_data_002_voluntary_left_tapping_222_raw-eve.fif");
//    QString t_sStcFileNameRel  ("/Processed/stc/SourceLoc_voluntary_left_tapping_filtered_07_40_Averaged_");
//    QString t_sAvrFileNameRel  ("/Processed/averaged/EEG_data_002_voluntary_left_tapping_filtered_07_40_Averaged_");

//    //Filtered 0.7-40Hz right tapping
//    QString t_sRawFileNameRel  ("/Processed/filtered/EEG_data_002_voluntary_right_tapping_filtered_07_40_raw.fif");
//    QString t_sCovFileNameRel  ("/Processed/covariance/EEG_data_voluntary_tapping_base_filtered_07_40_raw-cov.fif");
//    QString t_sEventFileNameRel("/Processed/events/EEG_data_002_voluntary_right_tapping_184_raw-eve.fif");
//    QString t_sStcFileNameRel  ("/Processed/stc/SourceLoc_voluntary_right_tapping_filtered_07_40_Averaged_");
//    QString t_sAvrFileNameRel  ("/Processed/averaged/EEG_data_002_voluntary_right_tapping_filtered_07_40_Averaged_");

    //********************************** Medianus stimulation **********************************//

//    //time read around events - note: trigger point is the pressing of the button, not the atual
//    float tmin = -1.0f;
//    float tmax = 1.0f;

//    //Original left medianus stimulation - no filtering DC still present
//    QString t_sRawFileNameRel  ("/Original/EEG_data_002_medianus_left_raw.fif");
//    QString t_sCovFileNameRel  ("/Processed/covariance/EEG_data_medianus_base_raw-cov.fif");
//    QString t_sEventFileNameRel("/Processed/events/EEG_data_002_medianus_left_240_raw-eve.fif");
//    QString t_sStcFileNameRel  ("/Processed/stc/SourceLoc_medianus_left_Averaged_");
//    QString t_sAvrFileNameRel  ("/Processed/averaged/EEG_data_002_medianus_left_Averaged_");

//    //Original right medianus stimulation - no filtering DC still present
//    QString t_sRawFileNameRel  ("/Original/EEG_data_002_medianus_right_raw.fif");
//    QString t_sCovFileNameRel  ("/Processed/covariance/EEG_data_medianus_base_raw-cov.fif");
//    QString t_sEventFileNameRel("/Processed/events/EEG_data_002_medianus_right_295_raw-eve.fif");
//    QString t_sStcFileNameRel  ("/Processed/stc/SourceLoc_medianus_right_Averaged_");
//    QString t_sAvrFileNameRel  ("/Processed/averaged/EEG_data_002_medianus_right_Averaged_");

//    //Filtered 0.7-40Hz left medianus stimulation
//    QString t_sRawFileNameRel  ("/Processed/filtered/EEG_data_002_medianus_left_filtered_07_40_raw.fif");
//    QString t_sCovFileNameRel  ("/Processed/covariance/EEG_data_medianus_base_filtered_07_40_raw-cov.fif");
//    QString t_sEventFileNameRel("/Processed/events/EEG_data_002_medianus_left_artefact_reduction_-1_1_0.002_80_raw-eve.fif"); // ("EEG_data_002_medianus_left_raw-eve")
//    QString t_sStcFileNameRel  ("/Processed/stc/SourceLoc_medianus_left_filtered_07_40_Averaged_");
//    QString t_sAvrFileNameRel  ("/Processed/averaged/EEG_data_002_medianus_left_filtered_07_40_Averaged_");

//    //Filtered 0.7-40Hz right medianus stimulation
//    QString t_sRawFileNameRel  ("/Processed/filtered/EEG_data_002_medianus_right_filtered_07_40_raw.fif");
//    QString t_sCovFileNameRel  ("/Processed/covariance/EEG_data_medianus_base_filtered_07_40_raw-cov.fif");
//    QString t_sEventFileNameRel("/Processed/events/EEG_data_002_medianus_right_artefact_reduction_-1_1_0.0025_93_raw-eve.fif");    // ("EEG_data_002_medianus_right_raw-eve")
//    QString t_sStcFileNameRel  ("/Processed/stc/SourceLoc_medianus_right_filtered_07_40_Averaged_");
//    QString t_sAvrFileNameRel  ("/Processed/averaged/EEG_data_002_medianus_right_filtered_07_40_Averaged_");

//    //Filtered 7-14Hz left medianus stimulation
//    QString t_sRawFileNameRel  ("/Processed/filtered/EEG_data_002_medianus_left_filtered_7_14_raw.fif");
//    QString t_sCovFileNameRel  ("/Processed/covariance/EEG_data_medianus_base_filtered_7_14_raw-cov.fif");
//    QString t_sEventFileNameRel("/Processed/events/EEG_data_002_medianus_left_artefact_reduction_-1_1_0.002_80_raw-eve.fif");
//    QString t_sStcFileNameRel  ("/Processed/stc/SourceLoc_medianus_left_filtered_7_14_Averaged_");
//    QString t_sAvrFileNameRel  ("/Processed/averaged/EEG_data_002_medianus_left_filtered_7_14_Averaged_");

//    //Filtered 7-14Hz right medianus stimulation
//    QString t_sRawFileNameRel  ("/Processed/filtered/EEG_data_002_medianus_right_filtered_7_14_raw.fif");
//    QString t_sCovFileNameRel  ("/Processed/covariance/EEG_data_medianus_base_filtered_7_14_raw-cov.fif");
//    QString t_sEventFileNameRel("/Processed/events/EEG_data_002_medianus_right_artefact_reduction_-1_1_0.0025_93_raw-eve.fif");
//    QString t_sStcFileNameRel  ("/Processed/stc/SourceLoc_medianus_right_filtered_7_14_Averaged_");
//    QString t_sAvrFileNameRel  ("/Processed/averaged/EEG_data_002_medianus_right_filtered_7_14_Averaged_");

    //*************************** Voluntary opposing finger movement **************************//

//    //time read around events - note: trigger point is the pressing of the button, not the atual
//    float tmin = -0.3f;
//    float tmax = 0.1f;

//    //Original left opposing finger movement - no filtering DC still present
//    QString t_sRawFileNameRel  ("/Original/EEG_data_001_voluntary_left_opposing_raw.fif");
//    QString t_sCovFileNameRel  ("/Processed/covariance/EEG_data_voluntary_base_raw-cov.fif");
//    QString t_sEventFileNameRel("/Processed/events/EEG_data_001_voluntary_left_opposing_89_raw-eve.fif");
//    QString t_sStcFileNameRel  ("/Processed/stc/SourceLoc_voluntary_left_Averaged_");
//    QString t_sAvrFileNameRel  ("/Processed/averaged/EEG_data_001_voluntary_left_Averaged_");

//    //Original right opposing finger movement - no filtering DC still present
//    QString t_sRawFileNameRel  ("/Original/EEG_data_001_voluntary_right_opposing_raw.fif");
//    QString t_sCovFileNameRel  ("/Processed/covariance/EEG_data_voluntary_base_raw-cov.fif");
//    QString t_sEventFileNameRel("/Processed/events/EEG_data_001_voluntary_right_opposing_90_raw-eve.fif");
//    QString t_sStcFileNameRel  ("/Processed/stc/SourceLoc_voluntary_right_Averaged_");
//    QString t_sAvrFileNameRel  ("/Processed/averaged/EEG_data_001_voluntary_right_Averaged_");

//    //Filtered 7-14Hz left voluntary finger opposing
//    QString t_sRawFileNameRel  ("/Processed/filtered/EEG_data_001_voluntary_left_opposing_filtered_7_14_raw.fif");
//    QString t_sCovFileNameRel  ("/Processed/covariance/EEG_data_voluntary_opposing_base_filtered_7_14_raw-cov.fif");
//    QString t_sEventFileNameRel("/Processed/events/EEG_data_001_voluntary_left_opposing_154_raw-eve.fif");
//    QString t_sStcFileNameRel  ("/Processed/stc/SourceLoc_voluntary_left_opposing_filtered_7_14_Averaged_");
//    QString t_sAvrFileNameRel  ("/Processed/averaged/EEG_data_001_voluntary_left_opposing_filtered_7_14_Averaged_");

//    //Filtered 7-14Hz right voluntary finger opposing
//    QString t_sRawFileNameRel  ("/Processed/filtered/EEG_data_001_voluntary_right_opposing_filtered_7_14_raw.fif");
//    QString t_sCovFileNameRel  ("/Processed/covariance/EEG_data_voluntary_opposing_base_filtered_7_14_raw-cov.fif");
//    QString t_sEventFileNameRel("/Processed/events/EEG_data_001_voluntary_right_opposing_135_raw-eve.fif");
//    QString t_sStcFileNameRel  ("/Processed/stc/SourceLoc_voluntary_right_opposing_filtered_7_14_Averaged_");
//    QString t_sAvrFileNameRel  ("/Processed/averaged/EEG_data_001_voluntary_right_opposing_filtered_7_14_Averaged_");

//    //Filtered 0.7-40Hz left voluntary finger opposing
//    QString t_sRawFileNameRel  ("/Processed/filtered/EEG_data_001_voluntary_left_opposing_filtered_07_40_raw.fif");
//    QString t_sCovFileNameRel  ("/Processed/covariance/EEG_data_voluntary_opposing_base_filtered_07_40_raw-cov.fif");
//    QString t_sEventFileNameRel("/Processed/events/EEG_data_001_voluntary_left_opposing_137_raw-eve.fif");
//    QString t_sStcFileNameRel  ("/Processed/stc/SourceLoc_voluntary_left_opposing_filtered_07_40_Averaged_");
//    QString t_sAvrFileNameRel  ("/Processed/averaged/EEG_data_001_voluntary_left_opposing_filtered_07_40_Averaged_");

//    //Filtered 0.7-40Hz right voluntary finger opposing
//    QString t_sRawFileNameRel  ("/Processed/filtered/EEG_data_001_voluntary_right_opposing_filtered_07_40_raw.fif");
//    QString t_sCovFileNameRel  ("/Processed/covariance/EEG_data_voluntary_opposing_base_filtered_07_40_raw-cov.fif");
//    QString t_sEventFileNameRel("/Processed/events/EEG_data_001_voluntary_right_opposing_135_raw-eve.fif");
//    QString t_sStcFileNameRel  ("/Processed/stc/SourceLoc_voluntary_right_opposing_filtered_07_40_Averaged_");
//    QString t_sAvrFileNameRel  ("/Processed/averaged/EEG_data_001_voluntary_right_opposing_filtered_07_40_Averaged_");


    //*************************** Involuntary opposing finger movement **************************//

    //time read around events - note: trigger point is the pressing of the button
    float tmin = -1.0f;
    float tmax = 1.0f;

//    //Filtered 7-14Hz left involuntary finger opposing
//    QString t_sRawFileNameRel  ("/Processed/filtered/EEG_data_001_involuntary_left_opposing_filtered_7_14_raw.fif");
//    QString t_sCovFileNameRel  ("/Processed/covariance/EEG_data_001_base_filtered_7_14_raw-cov.fif");
//    QString t_sEventFileNameRel("/Processed/events/EEG_data_001_involuntary_left_opposing_137_raw-eve.fif");
//    QString t_sStcFileNameRel  ("/Processed/stc/SourceLoc_involuntary_left_opposing_filtered_7_14_Averaged_");
//    QString t_sAvrFileNameRel  ("/Processed/averaged/EEG_data_001_involuntary_left_opposing_filtered_7_14_Averaged_");

//    //Filtered 7-14Hz right involuntary finger opposing
//    QString t_sRawFileNameRel  ("/Processed/filtered/EEG_data_001_involuntary_right_opposing_filtered_7_14_raw.fif");
//    QString t_sCovFileNameRel  ("/Processed/covariance/EEG_data_001_base_filtered_7_14_raw-cov.fif");
//    QString t_sEventFileNameRel("/Processed/events/EEG_data_001_involuntary_right_opposing_150_raw-eve.fif");
//    QString t_sStcFileNameRel  ("/Processed/stc/SourceLoc_involuntary_right_opposing_filtered_7_14_Averaged_");
//    QString t_sAvrFileNameRel  ("/Processed/averaged/EEG_data_001_involuntary_right_opposing_filtered_7_14_Averaged_");

//    //Filtered 0.7-40Hz left involuntary finger opposing
//    QString t_sRawFileNameRel  ("/Processed/filtered/EEG_data_001_involuntary_left_opposing_filtered_07_40_raw.fif");
//    QString t_sCovFileNameRel  ("/Processed/covariance/EEG_data_001_base_filtered_07_40_raw-cov.fif");
//    QString t_sEventFileNameRel("/Processed/events/EEG_data_001_involuntary_left_opposing_137_raw-eve.fif");
//    QString t_sStcFileNameRel  ("/Processed/stc/SourceLoc_involuntary_left_opposing_filtered_07_40_Averaged_");
//    QString t_sAvrFileNameRel  ("/Processed/averaged/EEG_data_001_involuntary_left_opposing_filtered_07_40_Averaged_");

    //Filtered 0.7-40Hz right involuntary finger opposing
    QString t_sRawFileNameRel  ("/Processed/filtered/EEG_data_001_involuntary_right_opposing_filtered_07_40_raw.fif");
    QString t_sCovFileNameRel  ("/Processed/covariance/EEG_data_001_base_filtered_07_40_raw-cov.fif");
    QString t_sEventFileNameRel("/Processed/events/EEG_data_001_involuntary_right_opposing_150_raw-eve.fif");
    QString t_sStcFileNameRel  ("/Processed/stc/SourceLoc_involuntary_right_opposing_filtered_07_40_Averaged_");
    QString t_sAvrFileNameRel  ("/Processed/averaged/EEG_data_001_involuntary_right_opposing_filtered_07_40_Averaged_");

    //*************************** Motor imagery **************************//

//    //time read around events - note: trigger point is the pressing of the button, not the atual
//    float tmin = -1.0f;
//    float tmax = 6.0f;

//    //Filtered 7-14Hz left MI
//    QString t_sRawFileNameRel  ("/Processed/filtered/EEG_data_002_left_MI_filtered_7_14_raw.fif");
//    QString t_sCovFileNameRel  ("/Processed/covariance/EEG_data_002_base_filtered_7_14_raw-cov.fif");
//    QString t_sEventFileNameRel("/Processed/events/EEG_data_002_left_MI_filtered_100_raw-eve.fif");
//    QString t_sStcFileNameRel  ("/Processed/stc/SourceLoc_left_MI_filtered_7_14_Averaged_");
//    QString t_sAvrFileNameRel  ("/Processed/averaged/EEG_data_002_left_MI_filtered_7_14_Averaged_");

//    //Filtered 7-14Hz right MI
//    QString t_sRawFileNameRel  ("/Processed/filtered/EEG_data_002_right_MI_filtered_7_14_raw.fif");
//    QString t_sCovFileNameRel  ("/Processed/covariance/EEG_data_002_base_filtered_7_14_raw-cov.fif");
//    QString t_sEventFileNameRel("/Processed/events/EEG_data_002_right_MI_filtered_105_raw-eve.fif");
//    QString t_sStcFileNameRel  ("/Processed/stc/SourceLoc_right_MI_filtered_7_14_Averaged_");
//    QString t_sAvrFileNameRel  ("/Processed/averaged/EEG_data_002_right_MI_filtered_7_14_Averaged_");

//    //Filtered 0.7-40Hz left MI
//    QString t_sRawFileNameRel  ("/Processed/filtered/EEG_data_002_left_MI_filtered_07_40_raw.fif");
//    QString t_sCovFileNameRel  ("/Processed/covariance/EEG_data_002_base_filtered_07_40_raw-cov.fif");
//    QString t_sEventFileNameRel("/Processed/events/EEG_data_002_left_MI_filtered_100_raw-eve.fif");
//    QString t_sStcFileNameRel  ("/Processed/stc/SourceLoc_left_MI_filtered_07_40_Averaged_");
//    QString t_sAvrFileNameRel  ("/Processed/averaged/EEG_data_002_left_MI_filtered_07_40_Averaged_");

//    //Filtered 0.7-40Hz right MI
//    QString t_sRawFileNameRel  ("/Processed/filtered/EEG_data_002_right_MI_filtered_07_40_raw.fif");
//    QString t_sCovFileNameRel  ("/Processed/covariance/EEG_data_002_base_filtered_07_40_raw-cov.fif");
//    QString t_sEventFileNameRel("/Processed/events/EEG_data_002_right_MI_filtered_105_raw-eve.fif");
//    QString t_sStcFileNameRel  ("/Processed/stc/SourceLoc_right_MI_filtered_07_40_Averaged_");
//    QString t_sAvrFileNameRel  ("/Processed/averaged/EEG_data_002_right_MI_filtered_07_40_Averaged_");

    //*************************** BCI lefti right in one file finger tapping **************************//

//    //time read around events - note: trigger point is the pressing of the button, not the atual
//    float tmin = -1.0f;
//    float tmax = 1.0f;

//    //Filtered 7-14Hz left MI
//    QString t_sRawFileNameRel  ("/Original/EEG_data_001_voluntary_left_right_tapping_raw.fif");
//    QString t_sCovFileNameRel  ("/Processed/covariance/EEG_data_002_base_filtered_7_14_raw-cov.fif");
//    QString t_sEventFileNameRel("/Processed/events/EEG_data_001_voluntary_left_right_tapping_234_raw-eve.fif");
//    QString t_sStcFileNameRel  ("/Processed/stc/SourceLoc_left_MI_filtered_7_14_Averaged_");
//    QString t_sAvrFileNameRel  ("/Processed/averaged/EEG_data_001_voluntary_right_tapping_raw_Averaged_");

    //##########################################################################################################################

    //Create final location dirs and files
    QFile t_fileRaw(t_sRawFileNameRel.prepend(data_location));
    QFile t_fileCov(t_sCovFileNameRel.prepend(data_location));
    QString t_sEventName = t_sEventFileNameRel.prepend(data_location);

    qint32 event = 1; //254-right trigger | 253-left trigger | 252-beep | 1-old eventfile value for trigger

    qint32 k, p;
    fiff_int_t dest_comp = 0;
    bool keep_comp = false;
    bool pick_all  = false;

    //
    //   Setup for reading the raw data
    //
    FiffRawData raw(t_fileRaw);

    RowVectorXi picks;
    if (pick_all)
    {
        //
        // Pick all
        //
        picks.resize(raw.info.nchan);

        for(k = 0; k < raw.info.nchan; ++k)
            picks(k) = k;
        //
    }
    else
    {
        QStringList include;
        //include << "STI 014";
        bool want_meg   = false;
        bool want_eeg   = true;
        bool want_stim  = false;

        picks = raw.info.pick_types(want_meg, want_eeg, want_stim, include, raw.info.bads);//prefer member function
    }

    QStringList ch_names;
    for(k = 0; k < picks.cols(); ++k)
        ch_names << raw.info.ch_names[picks(0,k)];

    //
    //   Set up projection
    //
    if (raw.info.projs.size() == 0)
        printf("No projector specified for these data\n");
    else
    {
        //
        //   Activate the projection items
        //
        for (k = 0; k < raw.info.projs.size(); ++k)
            raw.info.projs[k].active = true;

        printf("%d projection items activated\n",raw.info.projs.size());

        //
        //   Create the projector
        //
        fiff_int_t nproj = raw.info.make_projector(raw.proj);

        if (nproj == 0)
        {
            printf("The projection vectors do not apply to these channels\n");
        }
        else
        {
            printf("Created an SSP operator (subspace dimension = %d)\n",nproj);
        }
    }

    //
    //   Set up the CTF compensator
    //
    qint32 current_comp = raw.info.get_current_comp();
    if (current_comp > 0)
        printf("Current compensation grade : %d\n",current_comp);

    if (keep_comp)
        dest_comp = current_comp;

    if (current_comp != dest_comp)
    {
        qDebug() << "This part needs to be debugged";
        if(MNE::make_compensator(raw.info, current_comp, dest_comp, raw.comp))
        {
            raw.info.set_current_comp(dest_comp);
            printf("Appropriate compensator added to change to grade %d.\n",dest_comp);
        }
        else
        {
            printf("Could not make the compensator\n");
            return 0;
        }
    }

    //
    //  Read the events
    //
    QFile t_EventFile;
    MatrixXi events;
    if (t_sEventName.size() == 0)
    {
        p = t_fileRaw.fileName().indexOf(".fif");
        if (p > 0)
        {
            t_sEventName = t_fileRaw.fileName().replace(p, 4, "-eve.fif");
        }
        else
        {
            printf("Raw file name does not end properly\n");
            return 0;
        }

        t_EventFile.setFileName(t_sEventName);
        MNE::read_events(t_EventFile, events);
        printf("Events read from %s\n",t_sEventName.toUtf8().constData());
    }
    else
    {
        //
        //   Binary file
        //
        p = t_fileRaw.fileName().indexOf(".fif");
        if (p > 0)
        {
            t_EventFile.setFileName(t_sEventName);
            if(!MNE::read_events(t_EventFile, events))
            {
                printf("Error while read events.\n");
                return 0;
            }
            printf("Binary event file %s read\n",t_sEventName.toUtf8().constData());
        }
        else
        {
            //
            //   Text file
            //
            printf("Text file %s is not supported jet.\n",t_sEventName.toUtf8().constData());
        }
    }

    //
    //    Select the desired events
    //
    qint32 count = 0;
    MatrixXi selected = MatrixXi::Zero(1, events.rows());
    for (p = 0; p < events.rows(); ++p)
    {
        if (events(p,1) == 0 && events(p,2) == event)
        {
            selected(0,count) = p;
            ++count;
        }
    }
    selected.conservativeResize(1, count);
    if (count > 0)
        printf("%d matching events found\n",count);
    else
    {
        printf("No desired events found.\n");
        return 0;
    }

    fiff_int_t event_samp, from, to;
    MatrixXd timesDummy;

    MNEEpochDataList data;

    MNEEpochData* epoch = NULL;

    MatrixXd times;

    for (p = 0; p < count; ++p)
    {
        //
        //       Read a data segment
        //
        event_samp = events(selected(p),0);
        from = event_samp + tmin*raw.info.sfreq;
        to   = event_samp + floor(tmax*raw.info.sfreq + 0.5);

        epoch = new MNEEpochData();

        if(raw.read_raw_segment(epoch->epoch, timesDummy, from, to, picks))
        {
            if (p == 0)
            {
                times.resize(1, to-from+1);
                for (qint32 i = 0; i < times.cols(); ++i)
                    times(0, i) = ((float)(from-event_samp+i)) / raw.info.sfreq;
            }

            epoch->event = event;
            epoch->tmin = ((float)(from)-(float)(raw.first_samp))/raw.info.sfreq;
            epoch->tmax = ((float)(to)-(float)(raw.first_samp))/raw.info.sfreq;

            data.append(MNEEpochData::SPtr(epoch)); //List takes ownwership of the pointer - no delete need
        }
        else
        {
            printf("Can't read the event data segments");
            return 0;
        }
    }

    if(data.size() > 0)
    {
        printf("Read %d epochs, %d samples each.\n",data.size(),(qint32)data[0]->epoch.cols());

        //DEBUG
        std::cout << data[0]->epoch.block(0,0,10,10) << std::endl;
        qDebug() << data[0]->epoch.rows() << " x " << data[0]->epoch.cols();

        std::cout << times.block(0,0,1,10) << std::endl;
        qDebug() << times.rows() << " x " << times.cols();
    }

    //
    // calculate the average
    //

    //Only take first finger movement of each tapping session (each tapping session consists of 4 seperate finger movement)
//    VectorXi vecSel(1);
//    vecSel << 60;

    if(count<averageIterator)
        averageIterator = count;

    VectorXi vecSel(count/averageIterator);

    int i;
    for(i=0; i<count/averageIterator; i++)
        vecSel[i] = i*averageIterator;

    // Add number of averages read from the eventfile to the file name
    t_sAvrFileNameRel.append(t_sAvrFileNameRel.number(tmin));
    t_sAvrFileNameRel.append("_");
    t_sAvrFileNameRel.append(t_sAvrFileNameRel.number(tmax));
    t_sAvrFileNameRel.append("_");
    t_sAvrFileNameRel.append(t_sAvrFileNameRel.number(i));
    t_sAvrFileNameRel.append(".fif");
    QString t_sAvrFileName = t_sAvrFileNameRel.prepend(data_location);

    t_sStcFileNameRel.append(t_sStcFileNameRel.number(tmin));
    t_sStcFileNameRel.append("_");
    t_sStcFileNameRel.append(t_sStcFileNameRel.number(tmax));
    t_sStcFileNameRel.append("_");
    t_sStcFileNameRel.append(t_sStcFileNameRel.number(i));
    t_sStcFileNameRel.append("_");
    t_sStcFileNameRel.append(method.append(".stc"));
    QString t_sFileNameStc = t_sStcFileNameRel.prepend(data_location);

    std::cout << "Select following epochs to average:\n" << vecSel << std::endl;
    raw.info.filename = QString(""); //this need to be done in order to write a new file. otherwise some of the info contents are not getting copied correctly from raw.info (i.e. digitizer data)
    FiffEvoked evoked = data.average(raw.info, tmin*raw.info.sfreq, floor(tmax*raw.info.sfreq + 0.5), vecSel);

    //Write averaged data to file
    QFile m_fileOut(t_sAvrFileName);
    RowVectorXd m_cals;

    FiffStream::SPtr m_pOutfid = Fiff::start_writing_raw(m_fileOut, raw.info, m_cals);
    fiff_int_t first = 0;
    m_pOutfid->write_int(FIFF_FIRST_SAMPLE, &first);
    //m_pOutfid->finish_writing_raw();

    Eigen::MatrixXd eData = evoked.data;
    Eigen::MatrixXd matValue = MatrixXd::Zero(eData.rows()+10, eData.cols());

    matValue.block(0,0,128,matValue.cols()) = evoked.data;

    m_pOutfid->write_raw_buffer(matValue, m_cals);

    m_pOutfid->finish_writing_raw();

    //################################# Source Estimate start ##########################################

    double snr = 0.1f;//1.0f;//3.0f;//0.1f;//3.0f;

    QString t_sFileNameClusteredInv("");

    // Parse command line parameters
    for(qint32 i = 0; i < argc; ++i)
    {
        if(strcmp(argv[i], "-snr") == 0 || strcmp(argv[i], "--snr") == 0)
        {
            if(i + 1 < argc)
                snr = atof(argv[i+1]);
        }
        else if(strcmp(argv[i], "-method") == 0 || strcmp(argv[i], "--method") == 0)
        {
            if(i + 1 < argc)
                method = QString::fromUtf8(argv[i+1]);
        }
        else if(strcmp(argv[i], "-inv") == 0 || strcmp(argv[i], "--inv") == 0)
        {
            if(i + 1 < argc)
                t_sFileNameClusteredInv = QString::fromUtf8(argv[i+1]);
        }
        else if(strcmp(argv[i], "-stc") == 0 || strcmp(argv[i], "--stc") == 0)
        {
            if(i + 1 < argc)
                t_sFileNameStc = QString::fromUtf8(argv[i+1]);
        }
    }

    double lambda2 = 1.0 / pow(snr, 2);


    qDebug() << "Start calculation with: SNR" << snr << "; Lambda" << lambda2 << "; Method" << method << "; stc:" << t_sFileNameStc;

    MNEForwardSolution t_Fwd(t_fileFwd);
    if(t_Fwd.isEmpty())
        return 1;

    FiffCov noise_cov(t_fileCov);

    // regularize noise covariance
    noise_cov = noise_cov.regularize(evoked.info, 0.05, 0.05, 0.1, true);

    //
    // Cluster forward solution;
    //
    MNEForwardSolution t_clusteredFwd = t_Fwd.cluster_forward_solution(t_annotationSet, 20);//40); % Use multithreading
    //MNEForwardSolution t_clusteredFwd = t_Fwd.cluster_forward_solution(t_annotationSet, 10);//40);

    //MNEForwardSolution t_clusteredFwd = t_Fwd;

    //
    // Find rows of interest in stc files
    //

    QFile wrtFWD ("./mne_x_plugins/resources/tmsi/fwd_clustered.txt");
    wrtFWD.open(QIODevice::WriteOnly | QIODevice::Text);
    QTextStream out(&wrtFWD);

    //Read vertnos
    VectorXi vertno_left = t_clusteredFwd.src[0].vertno;
    VectorXi vertno_right = t_clusteredFwd.src[1].vertno;

    out<<"Vertno Left Hemi:"<<endl<<endl;
    for(int i=0; i<vertno_left.rows(); i++)
        out<<vertno_left[i]<<endl;

    out<<endl<<"Vertno right Hemi:"<<endl<<endl;
    for(int i=0; i<vertno_right.rows(); i++)
        out<<vertno_right[i]<<endl;

    //Read corresponding labels
    VectorXi labelIds_left = t_annotationSet[0].getLabelIds();
    out<<endl<<endl<<"labelIds_left:"<<endl<<endl;
    for(int i=0; i<labelIds_left.rows(); i++)
        out<<labelIds_left[i]<<endl;

    VectorXi labelIds_right = t_annotationSet[1].getLabelIds();
    out<<endl<<endl<<"labelIds_right:"<<endl<<endl;
    for(int i=0; i<labelIds_right.rows(); i++)
        out<<labelIds_right[i]<<endl;

    //Find interesting rows in stc files
    // Left hemisphere
    QFile wrtFWD_28_left ("./mne_x_plugins/resources/tmsi/fwd_clustered_postcentral_28_Left.txt");
    wrtFWD_28_left.open(QIODevice::WriteOnly | QIODevice::Text);
    QTextStream out_28_left(&wrtFWD_28_left);

    QFile wrtFWD_29_left ("./mne_x_plugins/resources/tmsi/fwd_clustered_precentral_29_Left.txt");
    wrtFWD_29_left.open(QIODevice::WriteOnly | QIODevice::Text);
    QTextStream out_29_left(&wrtFWD_29_left);

    QFile wrtFWD_45_left ("./mne_x_plugins/resources/tmsi/fwd_clustered_central_45_Left.txt");
    wrtFWD_45_left.open(QIODevice::WriteOnly | QIODevice::Text);
    QTextStream out_45_left(&wrtFWD_45_left);

    QVector<int> interestingRows_Left;
    out<<endl<<endl<<"interestingRows_Left (matlab syntax):"<<endl<<endl;
    for(int i=0; i<vertno_left.rows() ; i++)
    {
        //G_postcentral
        if(labelIds_left[vertno_left[i]] == 9221140)
        {
            interestingRows_Left.push_back(i);
            out<<"Region 28 - G_postcentral: "<<i+1<<endl;
            out_28_left<<i+1<<endl;
        }

        //G_precentral
        if(labelIds_left[vertno_left[i]] == 11832380)
        {
            interestingRows_Left.push_back(i);
            out<<"Region 29 - G_precentral: "<<i+1<<endl;
            out_29_left<<i+1<<endl;
        }

        //S_central
        if(labelIds_left[vertno_left[i]] == 660701)
        {
            interestingRows_Left.push_back(i);
            out<<"Region 45 - S_central: "<<i+1<<endl;
            out_45_left<<i+1<<endl;
        }
    }

    // Right hemisphere
    QFile wrtFWD_28_right ("./mne_x_plugins/resources/tmsi/fwd_clustered_postcentral_28_Right.txt");
    wrtFWD_28_right.open(QIODevice::WriteOnly | QIODevice::Text);
    QTextStream out_28_right(&wrtFWD_28_right);

    QFile wrtFWD_29_right ("./mne_x_plugins/resources/tmsi/fwd_clustered_precentral_29_Right.txt");
    wrtFWD_29_right.open(QIODevice::WriteOnly | QIODevice::Text);
    QTextStream out_29_right(&wrtFWD_29_right);

    QFile wrtFWD_45_right ("./mne_x_plugins/resources/tmsi/fwd_clustered_central_45_Right.txt");
    wrtFWD_45_right.open(QIODevice::WriteOnly | QIODevice::Text);
    QTextStream out_45_right(&wrtFWD_45_right);

    QVector<int> interestingRows_Right;
    out<<endl<<endl<<"interestingRows_Right (matlab syntax):"<<endl<<endl;
    for(int i=0; i<vertno_right.rows() ; i++)
    {
        //G_postcentral
        if(labelIds_right[vertno_right[i]] == 9221140)
        {
            interestingRows_Right.push_back(i);
            out<<"Region 28 - G_postcentral: "<<i+1+vertno_left.rows()<<endl;
            out_28_right<<i+1<<endl;
        }

        //G_precentral
        if(labelIds_right[vertno_right[i]] == 11832380)
        {
            interestingRows_Right.push_back(i);
            out<<"Region 29 - G_precentral: "<<i+1+vertno_left.rows()<<endl;
            out_29_right<<i+1<<endl;
        }

        //S_central
        if(labelIds_right[vertno_right[i]] == 660701)
        {
            interestingRows_Right.push_back(i);
            out<<"Region 45 - S_central: "<<i+1+vertno_left.rows()<<endl;
            out_45_right<<i+1<<endl;
        }
    }

    wrtFWD_28_left.close();
    wrtFWD_29_left.close();
    wrtFWD_45_left.close();
    wrtFWD_28_right.close();
    wrtFWD_29_right.close();
    wrtFWD_45_right.close();
    wrtFWD.close();

    //
    // make an inverse operators
    //
    FiffInfo info = evoked.info;

    MNEInverseOperator inverse_operator(info, t_clusteredFwd, noise_cov, 0.2f, 0.8f);

//    QFile t_fileInv("D:/Dropbox/Masterarbeit DB/Messdaten/EEG/2014_02_07_Lorenz_Esch_007/Processed/inverse operators/Lorenz-140128-Duke128-eeg-inv.fif");
//    MNEInverseOperator inverse_operator(t_fileInv);

    //
    // save clustered inverse
    //
    if(!t_sFileNameClusteredInv.isEmpty())
    {
        QFile t_fileClusteredInverse(t_sFileNameClusteredInv);
        inverse_operator.write(t_fileClusteredInverse);
    }

    //
    // Compute inverse solution
    //
    // Calculate stc for averaged data
    MinimumNorm minimumNorm(inverse_operator, lambda2, method);

    MNESourceEstimate sourceEstimate = minimumNorm.calculateInverse(evoked);

    if(sourceEstimate.isEmpty())
        return 1;

    // Calculate stc for all trials and write to file - dirty
    if(doRawTrialLocalization)
    {
        MNESourceEstimate sourceEstimate_trial;

        for(int i = 0; i<data.size(); i++)
        {
            QString file_trial_stc_orig = t_sFileNameStc;

            QString file_trial_stc_tmp = t_sFileNameStc;
            QString stc_trial_sub_folder = file_trial_stc_tmp.remove(0,t_sFileNameStc.indexOf("/So")+1);

            stc_trial_sub_folder.remove(".stc");
            stc_trial_sub_folder.append("-raw-trials/");

            QString dirCheck = data_location;
            dirCheck.append("/Processed/stc/");
            dirCheck.append(stc_trial_sub_folder);

            if(QDir(dirCheck).exists() == false)
                QDir().mkdir(dirCheck);

            stc_trial_sub_folder.prepend("stc/");

            file_trial_stc_orig.replace("stc/", stc_trial_sub_folder);

            QString temp;
            temp.append("_");
            temp.append(temp.number(i));
            temp.append(".stc");

            file_trial_stc_orig.replace(".stc",temp);

            sourceEstimate_trial = minimumNorm.calculateInverse(data[i]->epoch,0,1/info.sfreq);

            if(sourceEstimate_trial.isEmpty())
                return 1;

            if(!t_sFileNameStc.isEmpty())
            {
                QFile t_fileTrialStc(file_trial_stc_orig);
                sourceEstimate_trial.write(t_fileTrialStc);
            }
        }
    }

    // View activation time-series
    std::cout << "\nsourceEstimate:\n" << sourceEstimate.data.block(0,0,10,10) << std::endl;
    std::cout << "time\n" << sourceEstimate.times.block(0,0,1,10) << std::endl;
    std::cout << "timeMin\n" << sourceEstimate.times[0] << std::endl;
    std::cout << "timeMax\n" << sourceEstimate.times[sourceEstimate.times.size()-1] << std::endl;
    std::cout << "time step\n" << sourceEstimate.tstep << std::endl;

    VectorXd s;

    //double t_dConditionNumber = MNEMath::getConditionNumber(t_Fwd.sol->data, s);
    //double t_dConditionNumberClustered = MNEMath::getConditionNumber(t_clusteredFwd.sol->data, s);

//    std::cout << "Condition Number:\n" << t_dConditionNumber << std::endl;
//    std::cout << "Clustered Condition Number:\n" << t_dConditionNumberClustered << std::endl;

//    std::cout << "ForwardSolution" << t_Fwd.sol->data.block(0,0,10,10) << std::endl;

    std::cout << "Clustered ForwardSolution" << t_clusteredFwd.sol->data.block(0,0,10,10) << std::endl;

    // Write stc to file
    if(!t_sFileNameStc.isEmpty())
    {
        QFile t_fileClusteredStc(t_sFileNameStc);
        sourceEstimate.write(t_fileClusteredStc);
    }

    //############################### Source Estimate end #########################################

    //only one time point - P100
//    qint32 sample = 0;
//    for(qint32 i = 0; i < sourceEstimate.times.size(); ++i)
//    {
//        if(sourceEstimate.times(i) >= 0)
//        {
//            sample = i;
//            break;
//        }
//    }
//    sample += (qint32)ceil(0.106/sourceEstimate.tstep); //100ms
//    sourceEstimate = sourceEstimate.reduce(sample, 1);

//   sourceEstimate = sourceEstimate.reduce(253, 1); //1731

    View3D::SPtr testWindow = View3D::SPtr(new View3D());
    testWindow->addBrainData("Subject01", "HemiLRSet", t_surfSet, t_annotationSet);

    QList<BrainRTSourceLocDataTreeItem*> rtItemList = testWindow->addRtBrainData("Subject01", "HemiLRSet", sourceEstimate, t_clusteredFwd);

    testWindow->show();

    Control3DWidget::SPtr control3DWidget = Control3DWidget::SPtr(new Control3DWidget());
    control3DWidget->setView3D(testWindow);
    control3DWidget->show();

    return a.exec();//1;//a.exec();
}
Example #5
0
FiffCov FiffCov::regularize(const FiffInfo& p_info, double p_fRegMag, double p_fRegGrad, double p_fRegEeg, bool p_bProj, QStringList p_exclude) const
{
    FiffCov cov(*this);

    if(p_exclude.size() == 0)
    {
        p_exclude = p_info.bads;
        for(qint32 i = 0; i < cov.bads.size(); ++i)
            if(!p_exclude.contains(cov.bads[i]))
                p_exclude << cov.bads[i];
    }

    RowVectorXi sel_eeg = p_info.pick_types(false, true, false, defaultQStringList, p_exclude);
    RowVectorXi sel_mag = p_info.pick_types(QString("mag"), false, false, defaultQStringList, p_exclude);
    RowVectorXi sel_grad = p_info.pick_types(QString("grad"), false, false, defaultQStringList, p_exclude);

    QStringList info_ch_names = p_info.ch_names;
    QStringList ch_names_eeg, ch_names_mag, ch_names_grad;
    for(qint32 i = 0; i < sel_eeg.size(); ++i)
        ch_names_eeg << info_ch_names[sel_eeg(i)];
    for(qint32 i = 0; i < sel_mag.size(); ++i)
        ch_names_mag << info_ch_names[sel_mag(i)];
    for(qint32 i = 0; i < sel_grad.size(); ++i)
        ch_names_grad << info_ch_names[sel_grad(i)];

    // This actually removes bad channels from the cov, which is not backward
    // compatible, so let's leave all channels in
    FiffCov cov_good = cov.pick_channels(info_ch_names, p_exclude);
    QStringList ch_names = cov_good.names;

    std::vector<qint32> idx_eeg, idx_mag, idx_grad;
    for(qint32 i = 0; i < ch_names.size(); ++i)
    {
        if(ch_names_eeg.contains(ch_names[i]))
            idx_eeg.push_back(i);
        else if(ch_names_mag.contains(ch_names[i]))
            idx_mag.push_back(i);
        else if(ch_names_grad.contains(ch_names[i]))
            idx_grad.push_back(i);
    }

    MatrixXd C(cov_good.data);

    if((unsigned) C.rows() != idx_eeg.size() + idx_mag.size() + idx_grad.size())
        printf("Error in FiffCov::regularize: Channel dimensions do not fit.\n");//ToDo Throw

    QList<FiffProj> t_listProjs;
    if(p_bProj)
    {
        t_listProjs = p_info.projs + cov_good.projs;
        FiffProj::activate_projs(t_listProjs);
    }

    //Build regularization MAP
    QMap<QString, QPair<double, std::vector<qint32> > > regData;
    regData.insert("EEG", QPair<double, std::vector<qint32> >(p_fRegEeg, idx_eeg));
    regData.insert("MAG", QPair<double, std::vector<qint32> >(p_fRegMag, idx_mag));
    regData.insert("GRAD", QPair<double, std::vector<qint32> >(p_fRegGrad, idx_grad));

    //
    //Regularize
    //
    QMap<QString, QPair<double, std::vector<qint32> > >::Iterator it;
    for(it = regData.begin(); it != regData.end(); ++it)
    {
        QString desc(it.key());
        double reg = it.value().first;
        std::vector<qint32> idx = it.value().second;

        if(idx.size() == 0 || reg == 0.0)
            printf("\tNothing to regularize within %s data.\n", desc.toLatin1().constData());
        else
        {
            printf("\tRegularize %s: %f\n", desc.toLatin1().constData(), reg);
            MatrixXd this_C(idx.size(), idx.size());
            for(quint32 i = 0; i < idx.size(); ++i)
                for(quint32 j = 0; j < idx.size(); ++j)
                    this_C(i,j) = cov_good.data(idx[i], idx[j]);

            MatrixXd U;
            qint32 ncomp;
            if(p_bProj)
            {
                QStringList this_ch_names;
                for(quint32 k = 0; k < idx.size(); ++k)
                    this_ch_names << ch_names[idx[k]];

                MatrixXd P;
                ncomp = FiffProj::make_projector(t_listProjs, this_ch_names, P); //ToDo: Synchronize with mne-python and debug

                JacobiSVD<MatrixXd> svd(P, ComputeFullU);
                //Sort singular values and singular vectors
                VectorXd t_s = svd.singularValues();
                MatrixXd t_U = svd.matrixU();
                MNEMath::sort<double>(t_s, t_U);

                U = t_U.block(0,0, t_U.rows(), t_U.cols()-ncomp);

                if (ncomp > 0)
                {
                    printf("\tCreated an SSP operator for %s (dimension = %d).\n", desc.toLatin1().constData(), ncomp);
                    this_C = U.transpose() * (this_C * U);
                }
            }

            double sigma = this_C.diagonal().mean();
            this_C.diagonal() = this_C.diagonal().array() + reg * sigma;  // modify diag inplace
            if(p_bProj && ncomp > 0)
                this_C = U * (this_C * U.transpose());

            for(qint32 i = 0; i < this_C.rows(); ++i)
                for(qint32 j = 0; j < this_C.cols(); ++j)
                    C(idx[i],idx[j]) = this_C(i,j);
        }
    }

    // Put data back in correct locations
    RowVectorXi idx = FiffInfo::pick_channels(cov.names, info_ch_names, p_exclude);
    for(qint32 i = 0; i < idx.size(); ++i)
        for(qint32 j = 0; j < idx.size(); ++j)
            cov.data(idx[i], idx[j]) = C(i, j);

    return cov;
}
Example #6
0
void RtSss::run()
{
//    QList<MatrixXd> lineqn;
    MatrixXd lineqn;

    m_bIsRunning = true;

    // start receiving data
    //
    m_bReceiveData = true;

    // Read Fiff Info
    //
    while(!m_pFiffInfo)
        msleep(10);// Wait for fiff Info

    //Find index vector for wanted meg channels
    QStringList exclude;
    for(int i = 0; i < m_pFiffInfo->chs.size(); i++) {
        if(m_pFiffInfo->chs.at(i).chpos.coil_type != FIFFV_COIL_BABY_MAG)
            exclude<<m_pFiffInfo->chs.at(i).ch_name;
    }

    exclude<<m_pFiffInfo->bads;

//    qDebug()<< exclude ;

    QString chType("mag");
    RowVectorXi pickedChannels = m_pFiffInfo->pick_types(chType,false, false, QStringList(),exclude);
    qDebug()<< "finished pickedChannels";
    qint32 nmegchanused = pickedChannels.cols();

//    for(int i = 0; i < nmegchanused; i++)
//        std::cout << " pickedID= " << pickedChannels(i) <<", ";

//    qDebug()<< "number of picked channels for rtSSS= " << nmegchanused;

    // Initialize output
    m_pRTMSAOutput->data()->initFromFiffInfo(m_pFiffInfo);
    m_pRTMSAOutput->data()->setMultiArraySize(1);
    // m_pRTMSAOutput->data()->setSamplingRate(m_pFiffInfo->sfreq);
    m_pRTMSAOutput->data()->setVisibility(true);

    // Set MEG channel infomation to rtSSS
//    rsss.setMEGInfo(m_pFiffInfo);
//    std::cout << "****** coil trans ****** " << std::endl;
//    std::cout <<  m_pFiffInfo->chs[pickedChannels(1)].coil_trans << std::endl;
//    return;
    rsss.setMEGInfo(m_pFiffInfo, pickedChannels);
//    qDebug() << " setMEGInfo finished";

    // Get channel information
    qint32 nmegchan = rsss.getNumMEGChan();
    //qint32 nmegchanused = rsss.getNumMEGChanUsed();
    //qDebug() << "number of meg channels(run): " << nmegchan;
    VectorXi badch = rsss.getBadChan();

    // Load and set the number of spherical harmonics expansion
    //qDebug() << "LinRR (run): " << LinRR << ", LoutRR (run): " << LoutRR <<", Lin (run): " << Lin <<", Lout (run): " << Lout;
    QList<int> expOrder;
    expOrder << LinRR << LoutRR << Lin << Lout;
    rsss.setSSSParameter(expOrder);

//    // Find out if coils are all gradiometers, all magnetometers, or both.
//    // When both gradiometers and magnetometers are used,
//    //      MagScale facor of 100 must be appiled to magnetomters.
//    float MagScale;
//    if ((0 < CoilGrad.sum()) && (CoilGrad.sum() < NumCoil))  MagScale = 100;
//    else MagScale = 1;

//    VectorXd CoilScale;
//    CoilScale.setOnes(NumCoil);
//    for(int i=0; i<NumCoil; i++)
//    {
//        if (CoilGrad(i) == 0) CoilScale(i) = MagScale;
////        std::cout <<  "i=" << i << "CoilGrad: " << CoilGrad(i) << ",  CoilScale: " << CoilScale(i) << std::endl;
//    }

    // Find a starting MEG channel index fiff
    // When the MEG recording of the first channel is saved starting from the first row in the signal matrix, the startID_MEGch will be 0.
    // When the MEG recording of the first channel is saved starting not from the first row and being followed by others like EEG,
    //   the startID_MEGch will be the first encounter of MEG channel other than zero.
    //
//    qint32 startID_MEGch = 0;
//    for(qint32 i = 0; i < m_pFiffInfo->nchan; ++i)
//        if(m_pFiffInfo->chs[i].kind == FIFFV_MEG_CH)
//        {
//            startID_MEGch = i;
//            break;
//        }
    //qDebug() << "strat id: " << startID_MEGch;

    //  Build linear equation
    qDebug() << "building an initial SSS linear equation .....";
    lineqn = rsss.buildLinearEqn();

    //qDebug() << "..finished !!";

    // start processing data
    m_bProcessData = true;
    qint32 HEADMOV_COR_cnt = 15 ;
    qint32 cnt=0;
    //qDebug() << "rtSSS started.....";

    bool m_bIsHeadMov = true;

    while(m_bIsRunning)
    {
//        if (m_bIsHeadMov)
//        {
//            lineqn = rsss.buildLinearEqn();
            //qDebug() << "rebuilt SSS linear equation .....";
//            m_bIsHeadMov = false;
//        }
//        else
//        {
//            m_bIsHeadMov = true;
//        }

        qint16 nrows = m_pRtSssBuffer->rows();

        if(nrows > 0) // check if init
        {
            // * Dispatch the inputs * //
            MatrixXd in_mat = m_pRtSssBuffer->pop();
//            qDebug() << "size of in_mat (run): " << in_mat.rows() << " x " << in_mat.cols();

            //Generate new matrix from picked channels
            MatrixXd in_mat_used(pickedChannels.cols(), in_mat.cols());

            for(qint32 i = 0; i < in_mat_used.rows(); ++i)
                in_mat_used.row(i) = in_mat.row(pickedChannels(i));

//            //  Remove bad channel signals
//            MatrixXd in_mat_used(nmegchanused, in_mat.cols());
////            qDebug() << "size of in_mat_used (run): " << in_mat_used.rows() << " x " << in_mat_used.cols();
//            for(qint32 i = 0, k = 0; i < nmegchan; ++i)
//                if (badch(i) == 0)
//                {
//                    in_mat_used.row(k) = in_mat.row(i);
//                    k++;
//                }
//            in_mat_used = in_mat.block(0,0,nmegchanused,in_mat.cols());

           in_mat_used = rt_sss(in_mat_used);

            // Implement Concurrent mapreduced for parallel processing
            // divide the in_mat_used into 2 or 4 matrices, which renders 50ms or 25ms data
//            QList<MatrixXd> list_in_mat;
//            qint32 nSubSample = 20;
//            qint32 nThread = in_mat_used.cols() / nSubSample;

//            for(qint32 ith = 0; ith < nThread; ++ ith) {
//                if(ith*nSubSample+nSubSample < in_mat_used.cols())
//                    list_in_mat.append(in_mat_used.block(0,ith*nSubSample,nmegchanused,in_mat_used.cols()-(ith*nSubSample)));
//                else
//                    list_in_mat.append(in_mat_used.block(0,ith*nSubSample,nmegchanused,nSubSample));
//            }
//            qDebug() << "rtSSS split up done!";

//            QFuture<MatrixXd> res = QtConcurrent::mapped(list_in_mat, rt_sss);
//            res.waitForFinished();

//            qDebug() << "rtSSS mapped done!";

//            for(qint32 ith = 0; ith < nThread; ++ ith)
//                in_mat_used.block(0,ith*nSubSample,nmegchanused,nSubSample)= res.resultAt(ith);

            // Replace raw signal by SSS signal
            for(qint32 i = 0; i < in_mat_used.rows(); ++i) {
                in_mat.row(pickedChannels(i)) = in_mat_used.row(i);
//                qDebug() <<    in_mat.row(pickedChannels(i));
            }

            // Output to display
            m_pRTMSAOutput->data()->setValue(0.01* in_mat);

//            cnt++;
//            qDebug() << cnt << "   " ;
        }
    }

    m_bProcessData = false;
    m_bReceiveData = false;
    //qDebug() << "rtSSS stopped.";
}
Example #7
0
/**
* The function main marks the entry point of the program.
* By default, main has the storage class extern.
*
* @param [in] argc (argument count) is an integer that indicates how many arguments were entered on the command line when the program was started.
* @param [in] argv (argument vector) is an array of pointers to arrays of character objects. The array objects are null-terminated strings, representing the arguments that were entered on the command line when the program was started.
* @return the value that was set to exit() (which is 0 if exit() is called via quit()).
*/
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    // Command Line Parser
    QCommandLineParser parser;
    parser.setApplicationDescription("Clustered Inverse Raw Example");
    parser.addHelpOption();

    QCommandLineOption inputOption("fileIn", "The input file <in>.", "in", "./MNE-sample-data/MEG/sample/sample_audvis_raw.fif");
    QCommandLineOption surfOption("surfType", "Surface type <type>.", "type", "inflated");
    QCommandLineOption annotOption("annotType", "Annotation type <type>.", "type", "aparc.a2009s");
    QCommandLineOption subjectOption("subject", "Selected subject <subject>.", "subject", "sample");
    QCommandLineOption subjectPathOption("subjectPath", "Selected subject path <subjectPath>.", "subjectPath", "./MNE-sample-data/subjects");
    QCommandLineOption fwdOption("fwd", "Path to forwad solution <file>.", "file", "./MNE-sample-data/MEG/sample/sample_audvis-meg-eeg-oct-6-fwd.fif");
    QCommandLineOption covFileOption("cov", "Path to the covariance <file>.", "file", "./MNE-sample-data/MEG/sample/sample_audvis-cov.fif");
    QCommandLineOption evokedIndexOption("aveIdx", "The average <index> to choose from the average file.", "index", "1");
    QCommandLineOption eventsFileOption("eve", "Path to the event <file>.", "file", "./MNE-sample-data/MEG/sample/sample_audvis_raw-eve.fif");
    QCommandLineOption hemiOption("hemi", "Selected hemisphere <hemi>.", "hemi", "2");
    QCommandLineOption methodOption("method", "Inverse estimation <method>, i.e., 'MNE', 'dSPM' or 'sLORETA'.", "method", "dSPM");//"MNE" | "dSPM" | "sLORETA"
    QCommandLineOption snrOption("snr", "The SNR value used for computation <snr>.", "snr", "1.0");//3.0;//0.1;//3.0;
    QCommandLineOption invFileOutOption("invOut", "Path to inverse <file>, which is to be written.", "file", "");
    QCommandLineOption stcFileOutOption("stcOut", "Path to stc <file>, which is to be written.", "file", "");
    QCommandLineOption keepCompOption("keepComp", "Keep compensators.", "keepComp", "false");
    QCommandLineOption pickAllOption("pickAll", "Pick all channels.", "pickAll", "true");
    QCommandLineOption destCompsOption("destComps", "<Destination> of the compensator which is to be calculated.", "destination", "0");

    parser.addOption(inputOption);
    parser.addOption(surfOption);
    parser.addOption(annotOption);
    parser.addOption(subjectOption);
    parser.addOption(subjectPathOption);
    parser.addOption(fwdOption);
    parser.addOption(covFileOption);
    parser.addOption(evokedIndexOption);
    parser.addOption(eventsFileOption);
    parser.addOption(hemiOption);
    parser.addOption(methodOption);
    parser.addOption(snrOption);
    parser.addOption(invFileOutOption);
    parser.addOption(stcFileOutOption);
    parser.addOption(keepCompOption);
    parser.addOption(pickAllOption);
    parser.addOption(destCompsOption);

    parser.process(a);

    // Load files
    QFile t_fileFwd(parser.value(fwdOption));
    QFile t_fileCov(parser.value(covFileOption));
    QFile t_fileRaw(parser.value(inputOption));
    QString t_sEventName = parser.value(eventsFileOption);

    SurfaceSet t_surfSet (parser.value(subjectOption), parser.value(hemiOption).toInt(), parser.value(surfOption), parser.value(subjectPathOption));
    AnnotationSet t_annotationSet (parser.value(subjectOption), parser.value(hemiOption).toInt(), parser.value(annotOption), parser.value(subjectPathOption));

    qint32 event = parser.value(evokedIndexOption).toInt();

    float tmin = -0.2f;
    float tmax = 0.4f;

    bool keep_comp = false;
    if(parser.value(keepCompOption) == "false" || parser.value(keepCompOption) == "0") {
        keep_comp = false;
    } else if(parser.value(keepCompOption) == "true" || parser.value(keepCompOption) == "1") {
        keep_comp = true;
    }

    fiff_int_t dest_comp = parser.value(destCompsOption).toInt();

    bool pick_all = false;
    if(parser.value(pickAllOption) == "false" || parser.value(pickAllOption) == "0") {
        pick_all = false;
    } else if(parser.value(pickAllOption) == "true" || parser.value(pickAllOption) == "1") {
        pick_all = true;
    }

    qint32 k, p;

    //
    //   Setup for reading the raw data
    //
    FiffRawData raw(t_fileRaw);

    RowVectorXi picks;
    if (pick_all)
    {
        //
        // Pick all
        //
        picks.resize(raw.info.nchan);

        for(k = 0; k < raw.info.nchan; ++k)
            picks(k) = k;
        //
    }
    else
    {
        QStringList include;
        include << "STI 014";
        bool want_meg   = true;
        bool want_eeg   = false;
        bool want_stim  = false;

//        picks = Fiff::pick_types(raw.info, want_meg, want_eeg, want_stim, include, raw.info.bads);
        picks = raw.info.pick_types(want_meg, want_eeg, want_stim, include, raw.info.bads);//prefer member function
    }

    QStringList ch_names;
    for(k = 0; k < picks.cols(); ++k)
        ch_names << raw.info.ch_names[picks(0,k)];

    //
    //   Set up projection
    //
    if (raw.info.projs.size() == 0)
        printf("No projector specified for these data\n");
    else
    {
        //
        //   Activate the projection items
        //
        for (k = 0; k < raw.info.projs.size(); ++k)
            raw.info.projs[k].active = true;

        printf("%d projection items activated\n",raw.info.projs.size());
        //
        //   Create the projector
        //
//        fiff_int_t nproj = MNE::make_projector_info(raw.info, raw.proj); Using the member function instead
        fiff_int_t nproj = raw.info.make_projector(raw.proj);

        if (nproj == 0)
        {
            printf("The projection vectors do not apply to these channels\n");
        }
        else
        {
            printf("Created an SSP operator (subspace dimension = %d)\n",nproj);
        }
    }

    //
    //   Set up the CTF compensator
    //
//    qint32 current_comp = MNE::get_current_comp(raw.info);
    qint32 current_comp = raw.info.get_current_comp();
    if (current_comp > 0)
        printf("Current compensation grade : %d\n",current_comp);

    if (keep_comp)
        dest_comp = current_comp;

    if (current_comp != dest_comp)
    {
        qDebug() << "This part needs to be debugged";
        if(MNE::make_compensator(raw.info, current_comp, dest_comp, raw.comp))
        {
//            raw.info.chs = MNE::set_current_comp(raw.info.chs,dest_comp);
            raw.info.set_current_comp(dest_comp);
            printf("Appropriate compensator added to change to grade %d.\n",dest_comp);
        }
        else
        {
            printf("Could not make the compensator\n");
            return 0;
        }
    }
    //
    //  Read the events
    //
    QFile t_EventFile;
    MatrixXi events;
    if (t_sEventName.size() == 0)
    {
        p = t_fileRaw.fileName().indexOf(".fif");
        if (p > 0)
        {
            t_sEventName = t_fileRaw.fileName().replace(p, 4, "-eve.fif");
        }
        else
        {
            printf("Raw file name does not end properly\n");
            return 0;
        }
//        events = mne_read_events(t_sEventName);

        t_EventFile.setFileName(t_sEventName);
        MNE::read_events(t_EventFile, events);
        printf("Events read from %s\n",t_sEventName.toUtf8().constData());
    }
    else
    {
        //
        //   Binary file
        //
        p = t_fileRaw.fileName().indexOf(".fif");
        if (p > 0)
        {
            t_EventFile.setFileName(t_sEventName);
            if(!MNE::read_events(t_EventFile, events))
            {
                printf("Error while read events.\n");
                return 0;
            }
            printf("Binary event file %s read\n",t_sEventName.toUtf8().constData());
        }
        else
        {
            //
            //   Text file
            //
            printf("Text file %s is not supported jet.\n",t_sEventName.toUtf8().constData());
//            try
//                events = load(eventname);
//            catch
//                error(me,mne_omit_first_line(lasterr));
//            end
//            if size(events,1) < 1
//                error(me,'No data in the event file');
//            end
//            //
//            //   Convert time to samples if sample number is negative
//            //
//            for p = 1:size(events,1)
//                if events(p,1) < 0
//                    events(p,1) = events(p,2)*raw.info.sfreq;
//                end
//            end
//            //
//            //    Select the columns of interest (convert to integers)
//            //
//            events = int32(events(:,[1 3 4]));
//            //
//            //    New format?
//            //
//            if events(1,2) == 0 && events(1,3) == 0
//                fprintf(1,'The text event file %s is in the new format\n',eventname);
//                if events(1,1) ~= raw.first_samp
//                    error(me,'This new format event file is not compatible with the raw data');
//                end
//            else
//                fprintf(1,'The text event file %s is in the old format\n',eventname);
//                //
//                //   Offset with first sample
//                //
//                events(:,1) = events(:,1) + raw.first_samp;
//            end
        }
    }

    //
    //    Select the desired events
    //
    qint32 count = 0;
    MatrixXi selected = MatrixXi::Zero(1, events.rows());
    for (p = 0; p < events.rows(); ++p)
    {
        if (events(p,1) == 0 && events(p,2) == event)
        {
            selected(0,count) = p;
            ++count;
        }
    }
    selected.conservativeResize(1, count);
    if (count > 0)
        printf("%d matching events found\n",count);
    else
    {
        printf("No desired events found.\n");
        return 0;
    }


    fiff_int_t event_samp, from, to;
    MatrixXd timesDummy;

    MNEEpochDataList data;

    MNEEpochData* epoch = NULL;

    MatrixXd times;

    for (p = 0; p < count; ++p)
    {
        //
        //       Read a data segment
        //
        event_samp = events(selected(p),0);
        from = event_samp + tmin*raw.info.sfreq;
        to   = event_samp + floor(tmax*raw.info.sfreq + 0.5);

        epoch = new MNEEpochData();

        if(raw.read_raw_segment(epoch->epoch, timesDummy, from, to, picks))
        {
            if (p == 0)
            {
                times.resize(1, to-from+1);
                for (qint32 i = 0; i < times.cols(); ++i)
                    times(0, i) = ((float)(from-event_samp+i)) / raw.info.sfreq;
            }

            epoch->event = event;
            epoch->tmin = ((float)(from)-(float)(raw.first_samp))/raw.info.sfreq;
            epoch->tmax = ((float)(to)-(float)(raw.first_samp))/raw.info.sfreq;

            data.append(MNEEpochData::SPtr(epoch));//List takes ownwership of the pointer - no delete need
        }
        else
        {
            printf("Can't read the event data segments");
            return 0;
        }
    }

    if(data.size() > 0)
    {
        printf("Read %d epochs, %d samples each.\n",data.size(),(qint32)data[0]->epoch.cols());

        //DEBUG
        std::cout << data[0]->epoch.block(0,0,10,10) << std::endl;
        qDebug() << data[0]->epoch.rows() << " x " << data[0]->epoch.cols();

        std::cout << times.block(0,0,1,10) << std::endl;
        qDebug() << times.rows() << " x " << times.cols();
    }

    // Calculate the average
    // Option 1 - Random selection
    VectorXi vecSel(50);
    srand (time(NULL)); // initialize random seed

    for(qint32 i = 0; i < vecSel.size(); ++i)
    {
        qint32 val = rand() % count;
        vecSel(i) = val;
    }

//    //Option 3 - Take all epochs
//    VectorXi vecSel(data.size());

//    for(qint32 i = 0; i < vecSel.size(); ++i)
//    {
//        vecSel(i) = i;
//    }

//    //Option 3 - Manual selection
//    VectorXi vecSel(20);

//    vecSel << 76, 74, 13, 61, 97, 94, 75, 71, 60, 56, 26, 57, 56, 0, 52, 72, 33, 86, 96, 67;

    std::cout << "Select following epochs to average:\n" << vecSel << std::endl;

    FiffEvoked evoked = data.average(raw.info, tmin*raw.info.sfreq, floor(tmax*raw.info.sfreq + 0.5), vecSel);

    //########################################################################################
    // Source Estimate

    //
    // Settings
    //
    double snr = parser.value(snrOption).toDouble();
    QString method(parser.value(methodOption));

    QString t_sFileNameClusteredInv(parser.value(invFileOutOption));
    QString t_sFileNameStc(parser.value(stcFileOutOption));

    double lambda2 = 1.0 / pow(snr, 2);
    qDebug() << "Start calculation with: SNR" << snr << "; Lambda" << lambda2 << "; Method" << method << "; stc:" << t_sFileNameStc;

    //
    // Load data
    //
    MNEForwardSolution t_Fwd(t_fileFwd);
    if(t_Fwd.isEmpty())
        return 1;

    FiffCov noise_cov(t_fileCov);

    //
    // regularize noise covariance
    //
    noise_cov = noise_cov.regularize(evoked.info, 0.05, 0.05, 0.1, true);

    //
    // Cluster forward solution;
    //
    MatrixXd D;
    MNEForwardSolution t_clusteredFwd = t_Fwd.cluster_forward_solution(t_annotationSet, 20, D, noise_cov, evoked.info);

    //
    // make an inverse operators
    //
    FiffInfo info = evoked.info;

    MNEInverseOperator inverse_operator(info, t_clusteredFwd, noise_cov, 0.2f, 0.8f);

    //
    // save clustered inverse
    //
    if(!t_sFileNameClusteredInv.isEmpty())
    {
        QFile t_fileClusteredInverse(t_sFileNameClusteredInv);
        inverse_operator.write(t_fileClusteredInverse);
    }

    //
    // Compute inverse solution
    //
    MinimumNorm minimumNorm(inverse_operator, lambda2, method);

#ifdef BENCHMARK
    //
    //   Set up the inverse according to the parameters
    //
    minimumNorm.doInverseSetup(vecSel.size(),false);

    MNESourceEstimate sourceEstimate;
    QList<qint64> qVecElapsedTime;
    for(qint32 i = 0; i < 100; ++i)
    {
        //Benchmark time
        QElapsedTimer timer;
        timer.start();
        sourceEstimate = minimumNorm.calculateInverse(evoked.data, evoked.times(0), evoked.times(1)-evoked.times(0));
        qVecElapsedTime.append(timer.elapsed());
    }

    double meanTime = 0.0;
    qint32 offset = 19;
    qint32 c = 0;
    for(qint32 i = offset; i < qVecElapsedTime.size(); ++i)
    {
        meanTime += qVecElapsedTime[i];
        ++c;
    }

    meanTime /= (double)c;

    double varTime = 0;
    for(qint32 i = offset; i < qVecElapsedTime.size(); ++i)
        varTime += pow(qVecElapsedTime[i] - meanTime,2);

    varTime /= (double)c - 1.0f;
    varTime = sqrt(varTime);

    qDebug() << "MNE calculation took" << meanTime << "+-" << varTime << "ms in average";

#else
    MNESourceEstimate sourceEstimate = minimumNorm.calculateInverse(evoked);
#endif

    if(sourceEstimate.isEmpty())
        return 1;

    // View activation time-series
    std::cout << "\nsourceEstimate:\n" << sourceEstimate.data.block(0,0,10,10) << std::endl;
    std::cout << "time\n" << sourceEstimate.times.block(0,0,1,10) << std::endl;
    std::cout << "timeMin\n" << sourceEstimate.times[0] << std::endl;
    std::cout << "timeMax\n" << sourceEstimate.times[sourceEstimate.times.size()-1] << std::endl;
    std::cout << "time step\n" << sourceEstimate.tstep << std::endl;

    //Condition Numbers
//    MatrixXd mags(102, t_Fwd.sol->data.cols());
//    qint32 count = 0;
//    for(qint32 i = 2; i < 306; i += 3)
//    {
//        mags.row(count) = t_Fwd.sol->data.row(i);
//        ++count;
//    }
//    MatrixXd magsClustered(102, t_clusteredFwd.sol->data.cols());
//    count = 0;
//    for(qint32 i = 2; i < 306; i += 3)
//    {
//        magsClustered.row(count) = t_clusteredFwd.sol->data.row(i);
//        ++count;
//    }

//    MatrixXd grads(204, t_Fwd.sol->data.cols());
//    count = 0;
//    for(qint32 i = 0; i < 306; i += 3)
//    {
//        grads.row(count) = t_Fwd.sol->data.row(i);
//        ++count;
//        grads.row(count) = t_Fwd.sol->data.row(i+1);
//        ++count;
//    }
//    MatrixXd gradsClustered(204, t_clusteredFwd.sol->data.cols());
//    count = 0;
//    for(qint32 i = 0; i < 306; i += 3)
//    {
//        gradsClustered.row(count) = t_clusteredFwd.sol->data.row(i);
//        ++count;
//        gradsClustered.row(count) = t_clusteredFwd.sol->data.row(i+1);
//        ++count;
//    }

    VectorXd s;

    double t_dConditionNumber = MNEMath::getConditionNumber(t_Fwd.sol->data, s);
    double t_dConditionNumberClustered = MNEMath::getConditionNumber(t_clusteredFwd.sol->data, s);

    std::cout << "Condition Number:\n" << t_dConditionNumber << std::endl;
    std::cout << "Clustered Condition Number:\n" << t_dConditionNumberClustered << std::endl;

    std::cout << "ForwardSolution" << t_Fwd.sol->data.block(0,0,10,10) << std::endl;

    std::cout << "Clustered ForwardSolution" << t_clusteredFwd.sol->data.block(0,0,10,10) << std::endl;


//    double t_dConditionNumberMags = MNEMath::getConditionNumber(mags, s);
//    double t_dConditionNumberMagsClustered = MNEMath::getConditionNumber(magsClustered, s);

//    std::cout << "Condition Number Magnetometers:\n" << t_dConditionNumberMags << std::endl;
//    std::cout << "Clustered Condition Number Magnetometers:\n" << t_dConditionNumberMagsClustered << std::endl;

//    double t_dConditionNumberGrads = MNEMath::getConditionNumber(grads, s);
//    double t_dConditionNumberGradsClustered = MNEMath::getConditionNumber(gradsClustered, s);

//    std::cout << "Condition Number Gradiometers:\n" << t_dConditionNumberGrads << std::endl;
//    std::cout << "Clustered Condition Number Gradiometers:\n" << t_dConditionNumberGradsClustered << std::endl;


    //Source Estimate end
    //########################################################################################

//    //only one time point - P100
//    qint32 sample = 0;
//    for(qint32 i = 0; i < sourceEstimate.times.size(); ++i)
//    {
//        if(sourceEstimate.times(i) >= 0)
//        {
//            sample = i;
//            break;
//        }
//    }
//    sample += (qint32)ceil(0.106/sourceEstimate.tstep); //100ms
//    sourceEstimate = sourceEstimate.reduce(sample, 1);

    View3D::SPtr testWindow = View3D::SPtr(new View3D());
    Data3DTreeModel::SPtr p3DDataModel = Data3DTreeModel::SPtr(new Data3DTreeModel());
    testWindow->setModel(p3DDataModel);

    p3DDataModel->addSurfaceSet(parser.value(subjectOption), "MRI", t_surfSet, t_annotationSet);

    if(MneEstimateTreeItem* pRTDataItem = p3DDataModel->addSourceData(parser.value(subjectOption), evoked.comment, sourceEstimate, t_clusteredFwd)) {
        pRTDataItem->setLoopState(true);
        pRTDataItem->setTimeInterval(17);
        pRTDataItem->setNumberAverages(1);
        pRTDataItem->setStreamingActive(true);
        pRTDataItem->setNormalization(QVector3D(0.0,0.5,20.0));
        pRTDataItem->setVisualizationType("Smoothing based");
        pRTDataItem->setColortable("Hot");
    }

    testWindow->show();

    Control3DWidget::SPtr control3DWidget = Control3DWidget::SPtr(new Control3DWidget());
    control3DWidget->init(p3DDataModel, testWindow);
    control3DWidget->show();

    if(!t_sFileNameStc.isEmpty())
    {
        QFile t_fileClusteredStc(t_sFileNameStc);
        sourceEstimate.write(t_fileClusteredStc);
    }

    return a.exec();
}
Example #8
0
bool MNEForwardSolution::read_forward_solution(QIODevice& p_IODevice, MNEForwardSolution& fwd, bool force_fixed, bool surf_ori, QStringList& include, QStringList& exclude)
{
    FiffStream* t_pStream = new FiffStream(&p_IODevice);
    FiffDirTree t_Tree;
    QList<FiffDirEntry> t_Dir;

    printf("Reading forward solution from %s...\n", t_pStream->streamName().toUtf8().constData());
    if(!t_pStream->open(t_Tree, t_Dir))
        return false;
    //
    //   Find all forward solutions
    //
    QList<FiffDirTree> fwds = t_Tree.dir_tree_find(FIFFB_MNE_FORWARD_SOLUTION);

    if (fwds.size() == 0)
    {
        t_pStream->device()->close();
        std::cout << "No forward solutions in " << t_pStream->streamName().toUtf8().constData(); // ToDo throw error
        //garbage collecting
        if(t_pStream)
            delete t_pStream;
        return false;
    }
    //
    //   Parent MRI data
    //
    QList<FiffDirTree> parent_mri = t_Tree.dir_tree_find(FIFFB_MNE_PARENT_MRI_FILE);
    if (parent_mri.size() == 0)
    {
        t_pStream->device()->close();
        std::cout << "No parent MRI information in " << t_pStream->streamName().toUtf8().constData(); // ToDo throw error
        //garbage collecting
        if(t_pStream)
            delete t_pStream;
        return false;
    }

    MNESourceSpace t_SourceSpace;// = NULL;
    if(!MNESourceSpace::read_source_spaces(t_pStream, true, t_Tree, t_SourceSpace))
    {
        t_pStream->device()->close();
        std::cout << "Could not read the source spaces\n"; // ToDo throw error
        //ToDo error(me,'Could not read the source spaces (%s)',mne_omit_first_line(lasterr));
        //garbage collecting
        if(t_pStream)
            delete t_pStream;
        return false;
    }

    for(int k = 0; k < t_SourceSpace.hemispheres.size(); ++k)
        t_SourceSpace.hemispheres[k].id = MNESourceSpace::find_source_space_hemi(t_SourceSpace.hemispheres[k]);

    //
    //   Bad channel list
    //
    QStringList bads = Fiff::read_bad_channels(t_pStream,t_Tree);
    printf("\t%d bad channels read\n",bads.size());
    qDebug() << bads;

    //
    //   Locate and read the forward solutions
    //
    FIFFLIB::FiffTag* t_pTag = NULL;
    FiffDirTree megnode;
    FiffDirTree eegnode;
    for(int k = 0; k < fwds.size(); ++k)
    {
        if(!fwds[k].find_tag(t_pStream, FIFF_MNE_INCLUDED_METHODS, t_pTag))
        {
            t_pStream->device()->close();
            std::cout << "Methods not listed for one of the forward solutions\n"; // ToDo throw error
            //garbage collecting
            if(t_pStream)
                delete t_pStream;
            return false;
        }
        if (*t_pTag->toInt() == FIFFV_MNE_MEG)
        {
            printf("MEG solution found\n");
            megnode = fwds[k];
        }
        else if(*t_pTag->toInt() == FIFFV_MNE_EEG)
        {
            printf("EEG solution found\n");
            eegnode = fwds.at(k);
        }
    }

    MNEForwardSolution megfwd;
    QString ori;
    if (read_one(t_pStream, megnode, megfwd))
    {
        if (megfwd.source_ori == FIFFV_MNE_FIXED_ORI)
            ori = QString("fixed");
        else
            ori = QString("free");
        printf("\tRead MEG forward solution (%d sources, %d channels, %s orientations)\n", megfwd.nsource,megfwd.nchan,ori.toUtf8().constData());
    }
    MNEForwardSolution eegfwd;
    if (read_one(t_pStream, eegnode, eegfwd))
    {
        if (eegfwd.source_ori == FIFFV_MNE_FIXED_ORI)
            ori = QString("fixed");
        else
            ori = QString("free");
        printf("\tRead EEG forward solution (%d sources, %d channels, %s orientations)\n", eegfwd.nsource,eegfwd.nchan,ori.toUtf8().constData());
    }

    //
    //   Merge the MEG and EEG solutions together
    //
    fwd.clear();

    if (!megfwd.isEmpty() && !eegfwd.isEmpty())
    {
        if (megfwd.sol->data.cols() != eegfwd.sol->data.cols() ||
                megfwd.source_ori != eegfwd.source_ori ||
                megfwd.nsource != eegfwd.nsource ||
                megfwd.coord_frame != eegfwd.coord_frame)
        {
            t_pStream->device()->close();
            std::cout << "The MEG and EEG forward solutions do not match\n"; // ToDo throw error
            //garbage collecting
            if(t_pStream)
                delete t_pStream;
            return false;
        }

        fwd = MNEForwardSolution(megfwd);
        fwd.sol->data = MatrixXd(megfwd.sol->nrow + eegfwd.sol->nrow, megfwd.sol->ncol);

        fwd.sol->data.block(0,0,megfwd.sol->nrow,megfwd.sol->ncol) = megfwd.sol->data;
        fwd.sol->data.block(megfwd.sol->nrow,0,eegfwd.sol->nrow,eegfwd.sol->ncol) = eegfwd.sol->data;
        fwd.sol->nrow = megfwd.sol->nrow + eegfwd.sol->nrow;
        fwd.sol->row_names.append(eegfwd.sol->row_names);

        if (!fwd.sol_grad->isEmpty())
        {
            fwd.sol_grad->data.resize(megfwd.sol_grad->data.rows() + eegfwd.sol_grad->data.rows(), megfwd.sol_grad->data.cols());

            fwd.sol->data.block(0,0,megfwd.sol_grad->data.rows(),megfwd.sol_grad->data.cols()) = megfwd.sol_grad->data;
            fwd.sol->data.block(megfwd.sol_grad->data.rows(),0,eegfwd.sol_grad->data.rows(),eegfwd.sol_grad->data.cols()) = eegfwd.sol_grad->data;

            fwd.sol_grad->nrow      = megfwd.sol_grad->nrow + eegfwd.sol_grad->nrow;
            fwd.sol_grad->row_names.append(eegfwd.sol_grad->row_names);
        }
        fwd.nchan  = megfwd.nchan + eegfwd.nchan;
        printf("\tMEG and EEG forward solutions combined\n");
    }
    else if (!megfwd.isEmpty())
        fwd = megfwd; //new MNEForwardSolution(megfwd);//not copied for the sake of speed
    else
        fwd = eegfwd; //new MNEForwardSolution(eegfwd);//not copied for the sake of speed

    //
    //   Get the MRI <-> head coordinate transformation
    //
    if(!parent_mri[0].find_tag(t_pStream, FIFF_COORD_TRANS, t_pTag))
    {
        t_pStream->device()->close();
        std::cout << "MRI/head coordinate transformation not found\n"; // ToDo throw error
        //garbage collecting
        if(t_pStream)
            delete t_pStream;
        if(t_pTag)
            delete t_pTag;
        return false;
    }
    else
    {
//        if(fwd.mri_head_t)
//            delete fwd.mri_head_t;
        fwd.mri_head_t = t_pTag->toCoordTrans();
//            std::cout << "Transformation\n" << fwd.mri_head_t.trans << std::endl;
//            std::cout << "from " << fwd.mri_head_t.from << " to " << fwd.mri_head_t.to << std::endl;

//            std::cout << "inverse Transformation\n" << fwd.mri_head_t.invtrans << std::endl;
//            std::cout << "size " << sizeof(FiffCoordTrans) << std::endl;
//            std::cout << "size " << sizeof(fiffCoordTransRec) << std::endl;

        if (fwd.mri_head_t.from != FIFFV_COORD_MRI || fwd.mri_head_t.to != FIFFV_COORD_HEAD)
        {
            fwd.mri_head_t.invert_transform();
            if (fwd.mri_head_t.from != FIFFV_COORD_MRI || fwd.mri_head_t.to != FIFFV_COORD_HEAD)
            {
                t_pStream->device()->close();
                std::cout << "MRI/head coordinate transformation not found\n"; // ToDo throw error
                //garbage collecting
                if(t_pStream)
                    delete t_pStream;
                if(t_pTag)
                    delete t_pTag;
                return false;
            }
        }
    }
    t_pStream->device()->close();

    //
    //   Transform the source spaces to the correct coordinate frame
    //   if necessary
    //
    if (fwd.coord_frame != FIFFV_COORD_MRI && fwd.coord_frame != FIFFV_COORD_HEAD)
    {
        std::cout << "Only forward solutions computed in MRI or head coordinates are acceptable";
        return false;
    }

    //
    qint32 nuse = 0;
    t_SourceSpace.transform_source_space_to(fwd.coord_frame,fwd.mri_head_t);
    for(int k = 0; k < t_SourceSpace.hemispheres.size(); ++k)
        nuse += t_SourceSpace.hemispheres[k].nuse;

    if (nuse != fwd.nsource)
        throw("Source spaces do not match the forward solution.\n");

    printf("\tSource spaces transformed to the forward solution coordinate frame\n");
    fwd.src = t_SourceSpace; //not new MNESourceSpace(t_SourceSpace); for sake of speed
    //
    //   Handle the source locations and orientations
    //
    if (fwd.source_ori == FIFFV_MNE_FIXED_ORI || force_fixed == true)
    {
        nuse = 0;
        fwd.source_rr = MatrixXd::Zero(fwd.nsource,3);
        fwd.source_nn = MatrixXd::Zero(fwd.nsource,3);
        for(qint32 k = 0; k < t_SourceSpace.hemispheres.size();++k)
        {
            for(qint32 q = 0; q < t_SourceSpace.hemispheres[k].nuse; ++q)
            {
                fwd.source_rr.block(q,0,1,3) = t_SourceSpace.hemispheres[k].rr.block(t_SourceSpace.hemispheres[k].vertno(q),0,1,3);
                fwd.source_nn.block(q,0,1,3) = t_SourceSpace.hemispheres[k].nn.block(t_SourceSpace.hemispheres[k].vertno(q),0,1,3);
            }
            nuse += t_SourceSpace.hemispheres[k].nuse;
        }
        //
        //   Modify the forward solution for fixed source orientations
        //
        if (fwd.source_ori != FIFFV_MNE_FIXED_ORI)
        {
            printf("\tChanging to fixed-orientation forward solution...");

            MatrixXd tmp = fwd.source_nn.transpose();
            SparseMatrix<double>* fix_rot = MNEMath::make_block_diag(&tmp,1);
            fwd.sol->data *= (*fix_rot);
            fwd.sol->ncol  = fwd.nsource;
            fwd.source_ori = FIFFV_MNE_FIXED_ORI;

            if (!fwd.sol_grad->isEmpty())
            {
                SparseMatrix<double> t_matKron;
                SparseMatrix<double> t_eye(3,3);
                for (qint32 i = 0; i < 3; ++i)
                    t_eye.insert(i,i) = 1.0f;
                kroneckerProduct(*fix_rot,t_eye,t_matKron);//kron(fix_rot,eye(3));
                fwd.sol_grad->data *= t_matKron;
                fwd.sol_grad->ncol   = 3*fwd.nsource;
            }
            delete fix_rot;
            printf("[done]\n");
        }
    }
    else
    {
        if (surf_ori)
        {
            //
            //   Rotate the local source coordinate systems
            //
            printf("\tConverting to surface-based source orientations...");
            nuse = 0;
            qint32 pp = 0;
            fwd.source_rr = MatrixXd::Zero(fwd.nsource,3);
            fwd.source_nn = MatrixXd::Zero(fwd.nsource*3,3);

            printf(" (Warning: Rotating the source coordinate system haven't been verified --> Singular Vectors U are different from MATLAB!) ");

            for(qint32 k = 0; k < t_SourceSpace.hemispheres.size();++k)
            {

                for (qint32 q = 0; q < t_SourceSpace.hemispheres[k].nuse; ++q)
                    fwd.source_rr.block(q+nuse,0,1,3) = t_SourceSpace.hemispheres[k].rr.block(t_SourceSpace.hemispheres[k].vertno(q),0,1,3);

                for (qint32 p = 0; p < t_SourceSpace.hemispheres[k].nuse; ++p)
                {
                    //
                    //  Project out the surface normal and compute SVD
                    //
                    Vector3d nn = t_SourceSpace.hemispheres[k].nn.block(t_SourceSpace.hemispheres[k].vertno(p),0,1,3).transpose();

                    Matrix3d tmp = Matrix3d::Identity() - nn*nn.transpose();

                    JacobiSVD<MatrixXd> t_svd(tmp, Eigen::ComputeThinU);

                    MatrixXd U(t_svd.matrixU());

                    //
                    //  Make sure that ez is in the direction of nn
                    //
                    if ((nn.transpose() * U.block(0,2,3,1))(0,0) < 0)
                    {
                        U *= -1;
                    }

                    fwd.source_nn.block(pp, 0, 3, 3) = U.transpose();

                    pp += 3;
                }
                nuse += t_SourceSpace.hemispheres[k].nuse;
            }
            MatrixXd tmp = fwd.source_nn.transpose();
            SparseMatrix<double>* surf_rot = MNEMath::make_block_diag(&tmp,3);

            fwd.sol->data *= *surf_rot;

            if (!fwd.sol_grad->isEmpty())
            {
                SparseMatrix<double> t_matKron;
                SparseMatrix<double> t_eye(3,3);
                for (qint32 i = 0; i < 3; ++i)
                    t_eye.insert(i,i) = 1.0f;
                kroneckerProduct(*surf_rot,t_eye,t_matKron);//kron(surf_rot,eye(3));
                fwd.sol_grad->data *= t_matKron;
            }
            delete surf_rot;
            printf("[done]\n");
        }
        else
        {
            printf("\tCartesian source orientations...");
            nuse = 0;
            fwd.source_rr = MatrixXd::Zero(fwd.nsource,3);
            for(int k = 0; k < t_SourceSpace.hemispheres.size(); ++k)
            {
                for (qint32 q = 0; q < t_SourceSpace.hemispheres[k].nuse; ++q)
                    fwd.source_rr.block(q+nuse,0,1,3) = t_SourceSpace.hemispheres[k].rr.block(t_SourceSpace.hemispheres[k].vertno(q),0,1,3);

                nuse += t_SourceSpace.hemispheres[k].nuse;
            }

            MatrixXd t_ones = MatrixXd::Ones(fwd.nsource,1);
            Matrix3d t_eye = Matrix3d::Identity();
            kroneckerProduct(t_ones,t_eye,fwd.source_nn);

            printf("[done]\n");
        }
    }

    //
    //   Do the channel selection
    //
    if (include.size() > 0 || exclude.size() > 0 || bads.size() > 0)
    {
        //
        //   First do the channels to be included
        //
        RowVectorXi pick;
        if (include.size() == 0)
            pick = RowVectorXi::Ones(fwd.nchan);
        else
        {
            pick = RowVectorXi::Zero(fwd.nchan);
            for(qint32 k = 0; k < include.size(); ++k)
            {
                QList<int> c;
                for(qint32 l = 0; l < fwd.sol->row_names.size(); ++l)
                    if(fwd.sol->row_names.at(l).contains(include.at(k),Qt::CaseInsensitive))
                        pick(l) = 1;

//                    c = strmatch(include{k},fwd.sol->row_names,'exact');
//                    for p = 1:length(c)
//                        pick(c(p)) = 1;
//                    end
            }
        }
        //
        //   Then exclude what needs to be excluded
        //
        if (exclude.size() > 0)
        {
            for(qint32 k = 0; k < exclude.size(); ++k)
            {
                QList<int> c;
                for(qint32 l = 0; l < fwd.sol->row_names.size(); ++l)
                    if(fwd.sol->row_names.at(l).contains(exclude.at(k),Qt::CaseInsensitive))
                        pick(l) = 0;

//                    c = strmatch(exclude{k},fwd.sol->row_names,'exact');
//                    for p = 1:length(c)
//                        pick(c(p)) = 0;
//                    end
            }
        }
        if (bads.size() > 0)
        {
            for(qint32 k = 0; k < bads.size(); ++k)
            {
                QList<int> c;
                for(qint32 l = 0; l < fwd.sol->row_names.size(); ++l)
                    if(fwd.sol->row_names.at(l).contains(bads.at(k),Qt::CaseInsensitive))
                        pick(l) = 0;

//                    c = strmatch(bads{k},fwd.sol->row_names,'exact');
//                    for p = 1:length(c)
//                        pick(c(p)) = 0;
//                    end
            }
        }
        //
        //   Do we have something?
        //
        nuse = pick.sum();
        if (nuse == 0)
            throw("Nothing remains after picking");
        //
        //   Create the selector
        //
        qint32 p = 0;
        MatrixXd t_solData(nuse,fwd.sol->data.cols());
        QStringList t_solRowNames;

        MatrixXd t_solGradData;// = NULL;
        QStringList t_solGradRowNames;

        if (!fwd.sol_grad->isEmpty())
            t_solGradData.resize(nuse, fwd.sol_grad->data.cols());

        for(qint32 k = 0; k < fwd.nchan; ++k)
        {
            if(pick(k) > 0)
            {
                t_solData.block(p, 0, 1, fwd.sol->data.cols()) = fwd.sol->data.block(k, 0, 1, fwd.sol->data.cols());
                t_solRowNames.append(fwd.sol->row_names.at(k));

                if (!fwd.sol_grad->isEmpty())
                {
                    t_solGradData.block(p, 0, 1, fwd.sol_grad->data.cols()) = fwd.sol_grad->data.block(k, 0, 1, fwd.sol_grad->data.cols());
                    t_solGradRowNames.append(fwd.sol_grad->row_names.at(k));
                }

                ++p;
            }
        }
        printf("\t%d out of %d channels remain after picking\n",nuse,fwd.nchan);
        //
        //   Pick the correct rows of the forward operator
        //
        fwd.nchan          = nuse;
//        if(fwd.sol->data)
//            delete fwd.sol->data;
        fwd.sol->data      = t_solData;
        fwd.sol->nrow      = nuse;
        fwd.sol->row_names = t_solRowNames;

        if (!fwd.sol_grad->isEmpty())
        {
            fwd.sol_grad->data      = t_solGradData;
            fwd.sol_grad->nrow      = nuse;
            fwd.sol_grad->row_names = t_solGradRowNames;
        }
    }

    //garbage collecting
    t_pStream->device()->close();
    if(t_pStream)
        delete t_pStream;
    if(t_pTag)
        delete t_pTag;

    return true;
}
Example #9
0
/**
* The function main marks the entry point of the program.
* By default, main has the storage class extern.
*
* @param [in] argc (argument count) is an integer that indicates how many arguments were entered on the command line when the program was started.
* @param [in] argv (argument vector) is an array of pointers to arrays of character objects. The array objects are null-terminated strings, representing the arguments that were entered on the command line when the program was started.
* @return the value that was set to exit() (which is 0 if exit() is called via quit()).
*/
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QFile t_fileRaw("./MNE-sample-data/MEG/sample/sample_audvis_raw.fif");
    QString t_sEventName = "./MNE-sample-data/MEG/sample/sample_audvis_raw-eve.fif";
    QFile t_fileFwd("./MNE-sample-data/MEG/sample/sample_audvis-meg-eeg-oct-6-fwd.fif");
    AnnotationSet t_annotationSet("./MNE-sample-data/subjects/sample/label/lh.aparc.a2009s.annot", "./MNE-sample-data/subjects/sample/label/rh.aparc.a2009s.annot");
    SurfaceSet t_surfSet("./MNE-sample-data/subjects/sample/surf/lh.white", "./MNE-sample-data/subjects/sample/surf/rh.white");

//    QFile t_fileRaw("E:/Data/sl_data/MEG/mind006/mind006_051209_auditory01_raw.fif");
//    QString t_sEventName = "E:/Data/sl_data/MEG/mind006/mind006_051209_auditory01_raw-eve.fif";
//    QFile t_fileFwd("E:/Data/sl_data/MEG/mind006/mind006_051209_auditory01_raw-oct-6p-fwd.fif");
//    AnnotationSet t_annotationSet("E:/Data/sl_data/subjects/mind006/label/lh.aparc.a2009s.annot", "E:/Data/sl_data/subjects/mind006/label/rh.aparc.a2009s.annot");
//    SurfaceSet t_surfSet("E:/Data/sl_data/subjects/mind006/surf/lh.white", "E:/Data/sl_data/subjects/mind006/surf/rh.white");

//    QFile t_fileRaw("E:/Data/sl_data/MEG/mind006/mind006_051209_median01_raw.fif");
//    QString t_sEventName = "E:/Data/sl_data/MEG/mind006/mind006_051209_median01_raw-eve.fif";
//    QFile t_fileFwd("E:/Data/sl_data/MEG/mind006/mind006_051209_median01_raw-oct-6-fwd.fif");
//    AnnotationSet t_annotationSet("E:/Data/sl_data/subjects/mind006/label/lh.aparc.a2009s.annot", "E:/Data/sl_data/subjects/mind006/label/rh.aparc.a2009s.annot");
//    SurfaceSet t_surfSet("E:/Data/sl_data/subjects/mind006/surf/lh.white", "E:/Data/sl_data/subjects/mind006/surf/rh.white");

    QString t_sFileNameStc("");//("mind006_051209_auditory01.stc");


    bool doMovie = false;//true;

    qint32 numDipolePairs = 7;

    qint32 event = 1;

    float tmin = -0.2f;
    float tmax = 0.4f;

    bool keep_comp = false;
    fiff_int_t dest_comp = 0;
    bool pick_all  = true;

    qint32 k, p;


    // Parse command line parameters
    for(qint32 i = 0; i < argc; ++i)
    {
        if(strcmp(argv[i], "-stc") == 0 || strcmp(argv[i], "--stc") == 0)
        {
            if(i + 1 < argc)
                t_sFileNameStc = QString::fromUtf8(argv[i+1]);
        }
    }

    //
    // Load data
    //
    MNEForwardSolution t_Fwd(t_fileFwd);
    if(t_Fwd.isEmpty())
        return 1;

    //
    //   Setup for reading the raw data
    //
    FiffRawData raw(t_fileRaw);

    RowVectorXi picks;
    if (pick_all)
    {
        //
        // Pick all
        //
        picks.resize(raw.info.nchan);

        for(k = 0; k < raw.info.nchan; ++k)
            picks(k) = k;
        //
    }
    else
    {
        QStringList include;
        include << "STI 014";
        bool want_meg   = true;
        bool want_eeg   = false;
        bool want_stim  = false;

        picks = raw.info.pick_types(want_meg, want_eeg, want_stim, include, raw.info.bads);//prefer member function
    }

    QStringList ch_names;
    for(k = 0; k < picks.cols(); ++k)
        ch_names << raw.info.ch_names[picks(0,k)];

    //
    //   Set up projection
    //
    if (raw.info.projs.size() == 0)
        printf("No projector specified for these data\n");
    else
    {
        //
        //   Activate the projection items
        //
        for (k = 0; k < raw.info.projs.size(); ++k)
            raw.info.projs[k].active = true;

        printf("%d projection items activated\n",raw.info.projs.size());
        //
        //   Create the projector
        //
//        fiff_int_t nproj = MNE::make_projector_info(raw.info, raw.proj); Using the member function instead
        fiff_int_t nproj = raw.info.make_projector(raw.proj);

        if (nproj == 0)
        {
            printf("The projection vectors do not apply to these channels\n");
        }
        else
        {
            printf("Created an SSP operator (subspace dimension = %d)\n",nproj);
        }
    }

    //
    //   Set up the CTF compensator
    //
    qint32 current_comp = raw.info.get_current_comp();
    if (current_comp > 0)
        printf("Current compensation grade : %d\n",current_comp);

    if (keep_comp)
        dest_comp = current_comp;

    if (current_comp != dest_comp)
    {
        qDebug() << "This part needs to be debugged";
        if(MNE::make_compensator(raw.info, current_comp, dest_comp, raw.comp))
        {
            raw.info.set_current_comp(dest_comp);
            printf("Appropriate compensator added to change to grade %d.\n",dest_comp);
        }
        else
        {
            printf("Could not make the compensator\n");
            return 0;
        }
    }
    //
    //  Read the events
    //
    QFile t_EventFile;
    MatrixXi events;
    if (t_sEventName.size() == 0)
    {
        p = t_fileRaw.fileName().indexOf(".fif");
        if (p > 0)
        {
            t_sEventName = t_fileRaw.fileName().replace(p, 4, "-eve.fif");
        }
        else
        {
            printf("Raw file name does not end properly\n");
            return 0;
        }
//        events = mne_read_events(t_sEventName);

        t_EventFile.setFileName(t_sEventName);
        MNE::read_events(t_EventFile, events);
        printf("Events read from %s\n",t_sEventName.toUtf8().constData());
    }
    else
    {
        //
        //   Binary file
        //
        p = t_fileRaw.fileName().indexOf(".fif");
        if (p > 0)
        {
            t_EventFile.setFileName(t_sEventName);
            if(!MNE::read_events(t_EventFile, events))
            {
                printf("Error while read events.\n");
                return 0;
            }
            printf("Binary event file %s read\n",t_sEventName.toUtf8().constData());
        }
        else
        {
            //
            //   Text file
            //
            printf("Text file %s is not supported jet.\n",t_sEventName.toUtf8().constData());
//            try
//                events = load(eventname);
//            catch
//                error(me,mne_omit_first_line(lasterr));
//            end
//            if size(events,1) < 1
//                error(me,'No data in the event file');
//            end
//            //
//            //   Convert time to samples if sample number is negative
//            //
//            for p = 1:size(events,1)
//                if events(p,1) < 0
//                    events(p,1) = events(p,2)*raw.info.sfreq;
//                end
//            end
//            //
//            //    Select the columns of interest (convert to integers)
//            //
//            events = int32(events(:,[1 3 4]));
//            //
//            //    New format?
//            //
//            if events(1,2) == 0 && events(1,3) == 0
//                fprintf(1,'The text event file %s is in the new format\n',eventname);
//                if events(1,1) ~= raw.first_samp
//                    error(me,'This new format event file is not compatible with the raw data');
//                end
//            else
//                fprintf(1,'The text event file %s is in the old format\n',eventname);
//                //
//                //   Offset with first sample
//                //
//                events(:,1) = events(:,1) + raw.first_samp;
//            end
        }
    }

    //
    //    Select the desired events
    //
    qint32 count = 0;
    MatrixXi selected = MatrixXi::Zero(1, events.rows());
    for (p = 0; p < events.rows(); ++p)
    {
        if (events(p,1) == 0 && events(p,2) == event)
        {
            selected(0,count) = p;
            ++count;
        }
    }
    selected.conservativeResize(1, count);
    if (count > 0)
        printf("%d matching events found\n",count);
    else
    {
        printf("No desired events found.\n");
        return 0;
    }


    fiff_int_t event_samp, from, to;
    MatrixXd timesDummy;

    MNEEpochDataList data;

    MNEEpochData* epoch = NULL;

    MatrixXd times;

    for (p = 0; p < count; ++p)
    {
        //
        //       Read a data segment
        //
        event_samp = events(selected(p),0);
        from = event_samp + tmin*raw.info.sfreq;
        to   = event_samp + floor(tmax*raw.info.sfreq + 0.5);

        epoch = new MNEEpochData();

        if(raw.read_raw_segment(epoch->epoch, timesDummy, from, to, picks))
        {
            if (p == 0)
            {
                times.resize(1, to-from+1);
                for (qint32 i = 0; i < times.cols(); ++i)
                    times(0, i) = ((float)(from-event_samp+i)) / raw.info.sfreq;
            }

            epoch->event = event;
            epoch->tmin = ((float)(from)-(float)(raw.first_samp))/raw.info.sfreq;
            epoch->tmax = ((float)(to)-(float)(raw.first_samp))/raw.info.sfreq;

            data.append(MNEEpochData::SPtr(epoch));//List takes ownwership of the pointer - no delete need
        }
        else
        {
            printf("Can't read the event data segments");
            return 0;
        }
    }

    if(data.size() > 0)
    {
        printf("Read %d epochs, %d samples each.\n",data.size(),(qint32)data[0]->epoch.cols());

        //DEBUG
        std::cout << data[0]->epoch.block(0,0,10,10) << std::endl;
        qDebug() << data[0]->epoch.rows() << " x " << data[0]->epoch.cols();

        std::cout << times.block(0,0,1,10) << std::endl;
        qDebug() << times.rows() << " x " << times.cols();
    }

    //
    // calculate the average
    //
//    //Option 1
//    qint32 numAverages = 99;
//    VectorXi vecSel(numAverages);
//    srand (time(NULL)); // initialize random seed

//    for(qint32 i = 0; i < vecSel.size(); ++i)
//    {
//        qint32 val = rand() % data.size();
//        vecSel(i) = val;
//    }

    //Option 2
//    VectorXi vecSel(20);

////    vecSel << 76, 74, 13, 61, 97, 94, 75, 71, 60, 56, 26, 57, 56, 0, 52, 72, 33, 86, 96, 67;

//    vecSel << 65, 22, 47, 55, 16, 29, 14, 36, 57, 97, 89, 46, 9, 93, 83, 52, 71, 52, 3, 96;

    //Option 3 Newest
//    VectorXi vecSel(10);

//    vecSel << 0, 96, 80, 55, 66, 25, 26, 2, 55, 58, 6, 88;


    VectorXi vecSel(1);

    vecSel << 0;


    std::cout << "Select following epochs to average:\n" << vecSel << std::endl;

    FiffEvoked evoked = data.average(raw.info, tmin*raw.info.sfreq, floor(tmax*raw.info.sfreq + 0.5), vecSel);

    QStringList ch_sel_names = t_Fwd.info.ch_names;
    FiffEvoked pickedEvoked = evoked.pick_channels(ch_sel_names);



    //########################################################################################
    // RAP MUSIC Source Estimate

    //
    // Cluster forward solution;
    //
    MNEForwardSolution t_clusteredFwd = t_Fwd.cluster_forward_solution(t_annotationSet, 20);//40);

    //
    // Compute inverse solution
    //
    RapMusic t_rapMusic(t_clusteredFwd, false, numDipolePairs);

    if(doMovie)
        t_rapMusic.setStcAttr(200,0.5);

    MNESourceEstimate sourceEstimate = t_rapMusic.calculateInverse(pickedEvoked);

    if(sourceEstimate.isEmpty())
        return 1;

//    // View activation time-series
//    std::cout << "\nsourceEstimate:\n" << sourceEstimate.data.block(0,0,10,10) << std::endl;
//    std::cout << "time\n" << sourceEstimate.times.block(0,0,1,10) << std::endl;
//    std::cout << "timeMin\n" << sourceEstimate.times[0] << std::endl;
//    std::cout << "timeMax\n" << sourceEstimate.times[sourceEstimate.times.size()-1] << std::endl;
//    std::cout << "time step\n" << sourceEstimate.tstep << std::endl;

    //Source Estimate end
    //########################################################################################

//    //only one time point - P100
//    qint32 sample = 0;
//    for(qint32 i = 0; i < sourceEstimate.times.size(); ++i)
//    {
//        if(sourceEstimate.times(i) >= 0)
//        {
//            sample = i;
//            break;
//        }
//    }
//    sample += (qint32)ceil(0.106/sourceEstimate.tstep); //100ms
//    sourceEstimate = sourceEstimate.reduce(sample, 1);

    View3D::SPtr testWindow = View3D::SPtr(new View3D());
    testWindow->addBrainData("Subject01", "HemiLRSet", t_surfSet, t_annotationSet);

    QList<BrainRTSourceLocDataTreeItem*> rtItemList = testWindow->addRtBrainData("Subject01", "HemiLRSet", sourceEstimate, t_clusteredFwd);

    testWindow->show();

    Control3DWidget::SPtr control3DWidget = Control3DWidget::SPtr(new Control3DWidget());
    control3DWidget->setView3D(testWindow);
    control3DWidget->show();

    if(!t_sFileNameStc.isEmpty())
    {
        QFile t_fileClusteredStc(t_sFileNameStc);
        sourceEstimate.write(t_fileClusteredStc);
    }

    return a.exec();//1;//a.exec();
}
Example #10
0
/**
* The function main marks the entry point of the program.
* By default, main has the storage class extern.
*
* @param [in] argc (argument count) is an integer that indicates how many arguments were entered on the command line when the program was started.
* @param [in] argv (argument vector) is an array of pointers to arrays of character objects. The array objects are null-terminated strings, representing the arguments that were entered on the command line when the program was started.
* @return the value that was set to exit() (which is 0 if exit() is called via quit()).
*/
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    // Command Line Parser
    QCommandLineParser parser;
    parser.setApplicationDescription("Clustered Inverse Powell Rap Music Raw Example");
    parser.addHelpOption();

    QCommandLineOption inputOption("fileIn", "The input file <in>.", "in", QCoreApplication::applicationDirPath() + "/MNE-sample-data/MEG/sample/sample_audvis_raw.fif");
    QCommandLineOption eventsFileOption("eve", "Path to the event <file>.", "file", QCoreApplication::applicationDirPath() + "/MNE-sample-data/MEG/sample/sample_audvis_raw-eve.fif");
    QCommandLineOption fwdOption("fwd", "Path to forwad solution <file>.", "file", QCoreApplication::applicationDirPath() + "/MNE-sample-data/MEG/sample/sample_audvis-meg-eeg-oct-6-fwd.fif");
    QCommandLineOption surfOption("surfType", "Surface type <type>.", "type", "orig");
    QCommandLineOption annotOption("annotType", "Annotation type <type>.", "type", "aparc.a2009s");
    QCommandLineOption subjectOption("subject", "Selected subject <subject>.", "subject", "sample");
    QCommandLineOption subjectPathOption("subjectPath", "Selected subject path <subjectPath>.", "subjectPath", QCoreApplication::applicationDirPath() + "/MNE-sample-data/subjects");
    QCommandLineOption stcFileOption("stcOut", "Path to stc <file>, which is to be written.", "file", "");
    QCommandLineOption numDipolePairsOption("numDip", "<number> of dipole pairs to localize.", "number", "7");
    QCommandLineOption evokedIdxOption("aveIdx", "The average <index> to choose from the average file.", "index", "1");
    QCommandLineOption hemiOption("hemi", "Selected hemisphere <hemi>.", "hemi", "2");
    QCommandLineOption doMovieOption("doMovie", "Create overlapping movie.", "doMovie", "false");
    QCommandLineOption keepCompOption("keepComp", "Keep compensators.", "keepComp", "false");
    QCommandLineOption pickAllOption("pickAll", "Pick all channels.", "pickAll", "true");
    QCommandLineOption destCompsOption("destComps", "<Destination> of the compensator which is to be calculated.", "destination", "0");

    parser.addOption(inputOption);
    parser.addOption(eventsFileOption);
    parser.addOption(fwdOption);
    parser.addOption(surfOption);
    parser.addOption(annotOption);
    parser.addOption(subjectOption);
    parser.addOption(subjectPathOption);
    parser.addOption(stcFileOption);
    parser.addOption(numDipolePairsOption);
    parser.addOption(evokedIdxOption);
    parser.addOption(hemiOption);
    parser.addOption(doMovieOption);
    parser.addOption(keepCompOption);
    parser.addOption(pickAllOption);
    parser.addOption(destCompsOption);

    parser.process(a);

    //Load data
    QFile t_fileRaw(parser.value(inputOption));
    QString t_sEventName = parser.value(eventsFileOption);
    QFile t_fileFwd(parser.value(fwdOption));

    SurfaceSet t_surfSet (parser.value(subjectOption), parser.value(hemiOption).toInt(), parser.value(surfOption), parser.value(subjectPathOption));
    AnnotationSet t_annotationSet (parser.value(subjectOption), parser.value(hemiOption).toInt(), parser.value(annotOption), parser.value(subjectPathOption));

    QString t_sFileNameStc(parser.value(stcFileOption));

    qint32 numDipolePairs = parser.value(numDipolePairsOption).toInt();

    //Choose average
    qint32 event = parser.value(evokedIdxOption).toInt();

    float tmin = 0.1f;
    float tmax = 0.2f;

    bool keep_comp = false;
    if(parser.value(keepCompOption) == "false" || parser.value(keepCompOption) == "0") {
        keep_comp = false;
    } else if(parser.value(keepCompOption) == "true" || parser.value(keepCompOption) == "1") {
        keep_comp = true;
    }

    fiff_int_t dest_comp = parser.value(destCompsOption).toInt();

    bool pick_all = false;
    if(parser.value(pickAllOption) == "false" || parser.value(pickAllOption) == "0") {
        pick_all = false;
    } else if(parser.value(pickAllOption) == "true" || parser.value(pickAllOption) == "1") {
        pick_all = true;
    }

    qint32 k, p;

    bool doMovie = false;
    if(parser.value(doMovieOption) == "false" || parser.value(doMovieOption) == "0") {
        pick_all = false;
    } else if(parser.value(doMovieOption) == "true" || parser.value(doMovieOption) == "1") {
        pick_all = true;
    }

    //
    // Load data
    //
    MNEForwardSolution t_Fwd(t_fileFwd);
    if(t_Fwd.isEmpty())
        return 1;

    //
    //   Setup for reading the raw data
    //
    FiffRawData raw(t_fileRaw);

    RowVectorXi picks;
    if (pick_all)
    {
        //
        // Pick all
        //
        picks.resize(raw.info.nchan);

        for(k = 0; k < raw.info.nchan; ++k)
            picks(k) = k;
        //
    }
    else
    {
        QStringList include;
        include << "STI 014";
        bool want_meg   = true;
        bool want_eeg   = false;
        bool want_stim  = false;

        picks = raw.info.pick_types(want_meg, want_eeg, want_stim, include, raw.info.bads);//prefer member function
    }

    QStringList ch_names;
    for(k = 0; k < picks.cols(); ++k)
        ch_names << raw.info.ch_names[picks(0,k)];

    //
    //   Set up projection
    //
    if (raw.info.projs.size() == 0)
        printf("No projector specified for these data\n");
    else
    {
        //
        //   Activate the projection items
        //
        for (k = 0; k < raw.info.projs.size(); ++k)
            raw.info.projs[k].active = true;

        printf("%d projection items activated\n",raw.info.projs.size());
        //
        //   Create the projector
        //
//        fiff_int_t nproj = MNE::make_projector_info(raw.info, raw.proj); Using the member function instead
        fiff_int_t nproj = raw.info.make_projector(raw.proj);

        if (nproj == 0)
        {
            printf("The projection vectors do not apply to these channels\n");
        }
        else
        {
            printf("Created an SSP operator (subspace dimension = %d)\n",nproj);
        }
    }

    //
    //   Set up the CTF compensator
    //
    qint32 current_comp = raw.info.get_current_comp();
    if (current_comp > 0)
        printf("Current compensation grade : %d\n",current_comp);

    if (keep_comp)
        dest_comp = current_comp;

    if (current_comp != dest_comp)
    {
        qDebug() << "This part needs to be debugged";
        if(MNE::make_compensator(raw.info, current_comp, dest_comp, raw.comp))
        {
            raw.info.set_current_comp(dest_comp);
            printf("Appropriate compensator added to change to grade %d.\n",dest_comp);
        }
        else
        {
            printf("Could not make the compensator\n");
            return 0;
        }
    }
    //
    //  Read the events
    //
    QFile t_EventFile;
    MatrixXi events;
    if (t_sEventName.size() == 0)
    {
        p = t_fileRaw.fileName().indexOf(".fif");
        if (p > 0)
        {
            t_sEventName = t_fileRaw.fileName().replace(p, 4, "-eve.fif");
        }
        else
        {
            printf("Raw file name does not end properly\n");
            return 0;
        }
//        events = mne_read_events(t_sEventName);

        t_EventFile.setFileName(t_sEventName);
        MNE::read_events(t_EventFile, events);
        printf("Events read from %s\n",t_sEventName.toUtf8().constData());
    }
    else
    {
        //
        //   Binary file
        //
        p = t_fileRaw.fileName().indexOf(".fif");
        if (p > 0)
        {
            t_EventFile.setFileName(t_sEventName);
            if(!MNE::read_events(t_EventFile, events))
            {
                printf("Error while read events.\n");
                return 0;
            }
            printf("Binary event file %s read\n",t_sEventName.toUtf8().constData());
        }
        else
        {
            //
            //   Text file
            //
            printf("Text file %s is not supported jet.\n",t_sEventName.toUtf8().constData());
//            try
//                events = load(eventname);
//            catch
//                error(me,mne_omit_first_line(lasterr));
//            end
//            if size(events,1) < 1
//                error(me,'No data in the event file');
//            end
//            //
//            //   Convert time to samples if sample number is negative
//            //
//            for p = 1:size(events,1)
//                if events(p,1) < 0
//                    events(p,1) = events(p,2)*raw.info.sfreq;
//                end
//            end
//            //
//            //    Select the columns of interest (convert to integers)
//            //
//            events = int32(events(:,[1 3 4]));
//            //
//            //    New format?
//            //
//            if events(1,2) == 0 && events(1,3) == 0
//                fprintf(1,'The text event file %s is in the new format\n',eventname);
//                if events(1,1) ~= raw.first_samp
//                    error(me,'This new format event file is not compatible with the raw data');
//                end
//            else
//                fprintf(1,'The text event file %s is in the old format\n',eventname);
//                //
//                //   Offset with first sample
//                //
//                events(:,1) = events(:,1) + raw.first_samp;
//            end
        }
    }

    //
    //    Select the desired events
    //
    qint32 count = 0;
    MatrixXi selected = MatrixXi::Zero(1, events.rows());
    for (p = 0; p < events.rows(); ++p)
    {
        if (events(p,1) == 0 && events(p,2) == event)
        {
            selected(0,count) = p;
            ++count;
        }
    }
    selected.conservativeResize(1, count);
    if (count > 0)
        printf("%d matching events found\n",count);
    else
    {
        printf("No desired events found.\n");
        return 0;
    }


    fiff_int_t event_samp, from, to;
    MatrixXd timesDummy;

    MNEEpochDataList data;

    MNEEpochData* epoch = NULL;

    MatrixXd times;

    for (p = 0; p < count; ++p)
    {
        //
        //       Read a data segment
        //
        event_samp = events(selected(p),0);
        from = event_samp + tmin*raw.info.sfreq;
        to   = event_samp + floor(tmax*raw.info.sfreq + 0.5);

        epoch = new MNEEpochData();

        if(raw.read_raw_segment(epoch->epoch, timesDummy, from, to, picks))
        {
            if (p == 0)
            {
                times.resize(1, to-from+1);
                for (qint32 i = 0; i < times.cols(); ++i)
                    times(0, i) = ((float)(from-event_samp+i)) / raw.info.sfreq;
            }

            epoch->event = event;
            epoch->tmin = ((float)(from)-(float)(raw.first_samp))/raw.info.sfreq;
            epoch->tmax = ((float)(to)-(float)(raw.first_samp))/raw.info.sfreq;

            data.append(MNEEpochData::SPtr(epoch));//List takes ownwership of the pointer - no delete need
        }
        else
        {
            printf("Can't read the event data segments");
            return 0;
        }
    }

    if(data.size() > 0)
    {
        printf("Read %d epochs, %d samples each.\n",data.size(),(qint32)data[0]->epoch.cols());

//        //DEBUG
//        std::cout << data[0]->epoch.block(0,0,10,10) << std::endl;
//        qDebug() << data[0]->epoch.rows() << " x " << data[0]->epoch.cols();

//        std::cout << times.block(0,0,1,10) << std::endl;
//        qDebug() << times.rows() << " x " << times.cols();
    }


    // Calculate the average
    // Option 1 - Random selection
    VectorXi vecSel(2);    
    srand (time(NULL)); // initialize random seed

    for(qint32 i = 0; i < vecSel.size(); ++i)
    {
        qint32 val = rand() % count;
        vecSel(i) = val;
    }

//    //Option 3 - Take all epochs
//    VectorXi vecSel(data.size());

//    for(qint32 i = 0; i < vecSel.size(); ++i)
//    {
//        vecSel(i) = i;
//    }

//    //Option 3 - Manual selection
//    VectorXi vecSel(20);

//    vecSel << 76, 74, 13, 61, 97, 94, 75, 71, 60, 56, 26, 57, 56, 0, 52, 72, 33, 86, 96, 67;


    std::cout << "Select following epochs to average:\n" << vecSel << std::endl;

    FiffEvoked evoked = data.average(raw.info, tmin*raw.info.sfreq, floor(tmax*raw.info.sfreq + 0.5), vecSel);

    QStringList ch_sel_names = t_Fwd.info.ch_names;
    FiffEvoked pickedEvoked = evoked.pick_channels(ch_sel_names);

    //########################################################################################
    // RAP MUSIC Source Estimate

    //
    // Cluster forward solution;
    //
    MNEForwardSolution t_clusteredFwd = t_Fwd.cluster_forward_solution(t_annotationSet, 20);//40);

    //
    // Compute inverse solution
    //
    PwlRapMusic t_pwlRapMusic(t_clusteredFwd, false, numDipolePairs);

#ifdef BENCHMARK
    MNESourceEstimate sourceEstimate;
    QList<qint64> qVecElapsedTime;
    for(qint32 i = 0; i < 100; ++i)
    {
        //Benchmark time
        QElapsedTimer timer;
        timer.start();
        sourceEstimate = t_pwlRapMusic.calculateInverse(pickedEvoked);
        qVecElapsedTime.append(timer.elapsed());
    }

    double meanTime = 0.0;
    qint32 offset = 19;
    qint32 c = 0;
    for(qint32 i = offset; i < qVecElapsedTime.size(); ++i)
    {
        meanTime += qVecElapsedTime[i];
        ++c;
    }

    meanTime /= (double)c;

    double varTime = 0;
    for(qint32 i = offset; i < qVecElapsedTime.size(); ++i)
        varTime += pow(qVecElapsedTime[i] - meanTime,2);

    varTime /= (double)c - 1.0f;
    varTime = sqrt(varTime);

    qDebug() << "RAP-MUSIC calculation took" << meanTime << "+-" << varTime << "ms in average";

#else
    int iWinSize = 200;
    if(doMovie) {
        t_pwlRapMusic.setStcAttr(iWinSize, 0.6f);
    }

    MNESourceEstimate sourceEstimate = t_pwlRapMusic.calculateInverse(pickedEvoked);

    if(doMovie) {
        //Select only the activations once
        MatrixXd dataPicked(sourceEstimate.data.rows(), int(std::floor(sourceEstimate.data.cols()/iWinSize)));

        for(int i = 0; i < dataPicked.cols(); ++i) {
            dataPicked.col(i) = sourceEstimate.data.col(i*iWinSize);
        }

        sourceEstimate.data = dataPicked;
    }

    if(sourceEstimate.isEmpty()) {
        return 1;
    }

#endif

    if(sourceEstimate.isEmpty())
        return 1;

//    // View activation time-series
//    std::cout << "\nsourceEstimate:\n" << sourceEstimate.data.block(0,0,10,10) << std::endl;
//    std::cout << "time\n" << sourceEstimate.times.block(0,0,1,10) << std::endl;
//    std::cout << "timeMin\n" << sourceEstimate.times[0] << std::endl;
//    std::cout << "timeMax\n" << sourceEstimate.times[sourceEstimate.times.size()-1] << std::endl;
//    std::cout << "time step\n" << sourceEstimate.tstep << std::endl;

    //Source Estimate end
    //########################################################################################

//    //only one time point - P100
//    qint32 sample = 0;
//    for(qint32 i = 0; i < sourceEstimate.times.size(); ++i)
//    {
//        if(sourceEstimate.times(i) >= 0)
//        {
//            sample = i;
//            break;
//        }
//    }
//    sample += (qint32)ceil(0.106/sourceEstimate.tstep); //100ms
//    sourceEstimate = sourceEstimate.reduce(sample, 1);

    AbstractView::SPtr p3DAbstractView = AbstractView::SPtr(new AbstractView());
    Data3DTreeModel::SPtr p3DDataModel = p3DAbstractView->getTreeModel();

    p3DDataModel->addSurfaceSet(parser.value(subjectOption), evoked.comment, t_surfSet, t_annotationSet);

    //Add rt source loc data and init some visualization values
    if(MneEstimateTreeItem* pRTDataItem = p3DDataModel->addSourceData(parser.value(subjectOption),
                                                                      evoked.comment,
                                                                      sourceEstimate,
                                                                      t_clusteredFwd,
                                                                      t_surfSet,
                                                                      t_annotationSet)) {
        pRTDataItem->setLoopState(true);
        pRTDataItem->setTimeInterval(17);
        pRTDataItem->setNumberAverages(1);
        pRTDataItem->setStreamingState(true);
        pRTDataItem->setThresholds(QVector3D(0.01f,0.5f,1.0f));
        pRTDataItem->setVisualizationType("Annotation based");
        pRTDataItem->setColormapType("Hot");
    }

    p3DAbstractView->show();

    QList<Label> t_qListLabels;
    QList<RowVector4i> t_qListRGBAs;

    //ToDo overload toLabels using instead of t_surfSet rr of MNESourceSpace
    t_annotationSet.toLabels(t_surfSet, t_qListLabels, t_qListRGBAs);

    if(!t_sFileNameStc.isEmpty())
    {
        QFile t_fileClusteredStc(t_sFileNameStc);
        sourceEstimate.write(t_fileClusteredStc);
    }

    return a.exec();//1;//a.exec();
}
Example #11
0
/**
* The function main marks the entry point of the program.
* By default, main has the storage class extern.
*
* @param [in] argc (argument count) is an integer that indicates how many arguments were entered on the command line when the program was started.
* @param [in] argv (argument vector) is an array of pointers to arrays of character objects. The array objects are null-terminated strings, representing the arguments that were entered on the command line when the program was started.
* @return the value that was set to exit() (which is 0 if exit() is called via quit()).
*/
int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);
    QGuiApplication::setApplicationName("RTC Evaluation");
    QGuiApplication::setApplicationVersion("Revision 1");

    ///////////////////////////////////// #1 CLI Parser /////////////////////////////////////
    QCommandLineParser parser;
    parser.setApplicationDescription("RTC Evaluation");
    parser.addHelpOption();
    parser.addVersionOption();

    // MEG Source Directory
    QCommandLineOption srcDirectoryOption(QStringList() << "s" << "meg-source-directory",
            QCoreApplication::translate("main", "Read MEG (fwd, cov, raw, eve) source files from <directory>."),
            QCoreApplication::translate("main", "directory"),
            "./MNE-sample-data/MEG/sample/");
    parser.addOption(srcDirectoryOption);

    // Forward Solution File
    QCommandLineOption fwdFileOption(QStringList() << "fwd" << "forward-solution",
            QCoreApplication::translate("main", "The forward solution <file>."),
            QCoreApplication::translate("main", "file"),
            "sample_audvis-meg-eeg-oct-6-fwd.fif");
    parser.addOption(fwdFileOption);

    // Raw MEG File
    QCommandLineOption rawFileOption(QStringList() << "raw" << "raw-file",
            QCoreApplication::translate("main", "The raw MEG data <file>."),
            QCoreApplication::translate("main", "file"),
            "sample_audvis_raw.fif");
    parser.addOption(rawFileOption);

    // Event File
    QCommandLineOption eveFileOption(QStringList() << "eve" << "event-file",
            QCoreApplication::translate("main", "The event <file>."),
            QCoreApplication::translate("main", "file"),
            "sample_audvis_raw-eve.fif");
    parser.addOption(eveFileOption);

    // Event Num
    QCommandLineOption evenNumOption(QStringList() << "evenum" << "event-number",
            QCoreApplication::translate("main", "The <event number>."),
            QCoreApplication::translate("main", "event"),
            "1");//2;//3;//4;
    parser.addOption(evenNumOption);

    // FS Subject Directory
    QCommandLineOption subjDirectoryOption(QStringList() << "subjdir" << "subject-directory",
            QCoreApplication::translate("main", "The FreeSurfer <subjects directory>."),
            QCoreApplication::translate("main", "directory"),
            "./MNE-sample-data/subjects");
    parser.addOption(subjDirectoryOption);

    // FS Subject
    QCommandLineOption subjIdOption(QStringList() << "subjid" << "subject-id",
            QCoreApplication::translate("main", "The FreeSurfer <subject id>."),
            QCoreApplication::translate("main", "subject id"),
            "sample");
    parser.addOption(subjIdOption);

    // Target Directory
    QCommandLineOption targetDirectoryOption(QStringList() << "t" << "target-directory",
            QCoreApplication::translate("main", "Copy all result files into <directory>."),
            QCoreApplication::translate("main", "directory"));
    parser.addOption(targetDirectoryOption);

    // Target Prefix
    QCommandLineOption targetPrefixOption(QStringList() << "p" << "prefix",
            QCoreApplication::translate("main", "The result file's <prefix>."),
            QCoreApplication::translate("main", "prefix"));
    parser.addOption(targetPrefixOption);

    // tmin
    QCommandLineOption tMinOption(QStringList() << "tmin" << "t-min",
            QCoreApplication::translate("main", "The starting time point <tmin>."),
            QCoreApplication::translate("main", "tmin"),
            "0.1");
    parser.addOption(tMinOption);

    // tmax
    QCommandLineOption tMaxOption(QStringList() << "tmax" << "t-max",
            QCoreApplication::translate("main", "The end time point <tmax>."),
            QCoreApplication::translate("main", "tmax"),
            "0.2");
    parser.addOption(tMaxOption);

    // Process the actual command line arguments given by the user
    parser.process(app);


    //////////////////////////////// #2 get parsed values /////////////////////////////////

    //Sources
    QString sFwdName = parser.value(srcDirectoryOption)+parser.value(fwdFileOption);
    qDebug() << "Forward Solution" << sFwdName;

    QString sRawName = parser.value(srcDirectoryOption)+parser.value(rawFileOption);
    qDebug() << "Raw data" << sRawName;

    QString t_sEventName = parser.value(srcDirectoryOption)+parser.value(eveFileOption);
    qDebug() << "Events" << t_sEventName;

    qint32 eveNum = (qint32)parser.value(evenNumOption).toInt();
    qDebug() << "Event Number" << eveNum;

    QString t_sSubjectsDir = parser.value(subjDirectoryOption);
    qDebug() << "Subjects Directory" << t_sSubjectsDir;

    QString t_sSubject = parser.value(subjIdOption);
    qDebug() << "Subject" << t_sSubject;

    //Targets
    QString sTargetDir = parser.value(targetDirectoryOption);
    qDebug() << "Target Directory" << sTargetDir;

    QString sTargetPrefix = parser.value(targetPrefixOption);
    qDebug() << "Target Prefix" << sTargetPrefix;

    //Parameters
    float tmin = (float)parser.value(tMinOption).toFloat();
    qDebug() << "tMin" << tmin;

    float tmax = (float)parser.value(tMaxOption).toFloat();
    qDebug() << "tMax" << tmax;

    QFile t_fileFwd(sFwdName);
    //
    // Load data
    //
    MNEForwardSolution t_Fwd(t_fileFwd);
    if(t_Fwd.isEmpty())
        return 1;


    AnnotationSet t_annotationSet(t_sSubject, 2, "aparc.a2009s", t_sSubjectsDir);

//    std::cout << "LabelIDs:\n" << t_annotationSet[0].getColortable().getLabelIds() << std::endl;

    //
    // Cluster forward solution;
    //
    MNEForwardSolution t_clusteredFwd = t_Fwd.cluster_forward_solution(t_annotationSet, 20);//40);

    QFile t_fileRaw(sRawName);


//    bool doMovie = false;//true;

    qint32 numDipolePairs = 1;

    bool keep_comp = false;
    fiff_int_t dest_comp = 0;
    bool pick_all  = true;

    qint32 k, p;

    //
    //   Setup for reading the raw data
    //
    FiffRawData raw(t_fileRaw);

    RowVectorXi picks;
    if (pick_all)
    {
        //
        // Pick all
        //
        picks.resize(raw.info.nchan);

        for(k = 0; k < raw.info.nchan; ++k)
            picks(k) = k;
        //
    }
    else
    {
        QStringList include;
        include << "STI 014";
        bool want_meg   = true;
        bool want_eeg   = false;
        bool want_stim  = false;

        picks = raw.info.pick_types(want_meg, want_eeg, want_stim, include, raw.info.bads);//prefer member function
    }

    QStringList ch_names;
    for(k = 0; k < picks.cols(); ++k)
        ch_names << raw.info.ch_names[picks(0,k)];

    //
    //   Set up projection
    //
    if (raw.info.projs.size() == 0)
        printf("No projector specified for these data\n");
    else
    {
        //
        //   Activate the projection items
        //
        for (k = 0; k < raw.info.projs.size(); ++k)
            raw.info.projs[k].active = true;

        printf("%d projection items activated\n",raw.info.projs.size());
        //
        //   Create the projector
        //
//        fiff_int_t nproj = MNE::make_projector_info(raw.info, raw.proj); Using the member function instead
        fiff_int_t nproj = raw.info.make_projector(raw.proj);

        if (nproj == 0)
        {
            printf("The projection vectors do not apply to these channels\n");
        }
        else
        {
            printf("Created an SSP operator (subspace dimension = %d)\n",nproj);
        }
    }

    //
    //   Set up the CTF compensator
    //
    qint32 current_comp = raw.info.get_current_comp();
    if (current_comp > 0)
        printf("Current compensation grade : %d\n",current_comp);

    if (keep_comp)
        dest_comp = current_comp;

    if (current_comp != dest_comp)
    {
        qDebug() << "This part needs to be debugged";
        if(MNE::make_compensator(raw.info, current_comp, dest_comp, raw.comp))
        {
            raw.info.set_current_comp(dest_comp);
            printf("Appropriate compensator added to change to grade %d.\n",dest_comp);
        }
        else
        {
            printf("Could not make the compensator\n");
            return 0;
        }
    }
    //
    //  Read the events
    //
    QFile t_EventFile;
    MatrixXi events;
    if (t_sEventName.size() == 0)
    {
        p = t_fileRaw.fileName().indexOf(".fif");
        if (p > 0)
        {
            t_sEventName = t_fileRaw.fileName().replace(p, 4, "-eve.fif");
        }
        else
        {
            printf("Raw file name does not end properly\n");
            return 0;
        }
//        events = mne_read_events(t_sEventName);

        t_EventFile.setFileName(t_sEventName);
        MNE::read_events(t_EventFile, events);
        printf("Events read from %s\n",t_sEventName.toUtf8().constData());
    }
    else
    {
        //
        //   Binary file
        //
        p = t_fileRaw.fileName().indexOf(".fif");
        if (p > 0)
        {
            t_EventFile.setFileName(t_sEventName);
            if(!MNE::read_events(t_EventFile, events))
            {
                printf("Error while read events.\n");
                return 0;
            }
            printf("Binary event file %s read\n",t_sEventName.toUtf8().constData());
        }
        else
        {
            //
            //   Text file
            //
            printf("Text file %s is not supported jet.\n",t_sEventName.toUtf8().constData());
//            try
//                events = load(eventname);
//            catch
//                error(me,mne_omit_first_line(lasterr));
//            end
//            if size(events,1) < 1
//                error(me,'No data in the event file');
//            end
//            //
//            //   Convert time to samples if sample number is negative
//            //
//            for p = 1:size(events,1)
//                if events(p,1) < 0
//                    events(p,1) = events(p,2)*raw.info.sfreq;
//                end
//            end
//            //
//            //    Select the columns of interest (convert to integers)
//            //
//            events = int32(events(:,[1 3 4]));
//            //
//            //    New format?
//            //
//            if events(1,2) == 0 && events(1,3) == 0
//                fprintf(1,'The text event file %s is in the new format\n',eventname);
//                if events(1,1) ~= raw.first_samp
//                    error(me,'This new format event file is not compatible with the raw data');
//                end
//            else
//                fprintf(1,'The text event file %s is in the old format\n',eventname);
//                //
//                //   Offset with first sample
//                //
//                events(:,1) = events(:,1) + raw.first_samp;
//            end
        }
    }

//    std::cout << "Events:\n" << events << std::endl;

    //
    //    Select the desired events
    //
    qint32 count = 0;
    MatrixXi selected = MatrixXi::Zero(1, events.rows());
    for (p = 0; p < events.rows(); ++p)
    {
        if (events(p,1) == 0 && events(p,2) == eveNum)
        {
            selected(0,count) = p;
            ++count;
        }
    }
    selected.conservativeResize(1, count);
    if (count > 0)
        printf("%d matching events found\n",count);
    else
    {
        printf("No desired events found.\n");
        return 0;
    }


    fiff_int_t event_samp, from, to;
    MatrixXd timesDummy;

    MNEEpochDataList data;

    MNEEpochData* epoch = NULL;

    MatrixXd times;

    for (p = 0; p < count; ++p)
    {
        //
        //       Read a data segment
        //
        event_samp = events(selected(p),0);
        from = event_samp + tmin*raw.info.sfreq;
        to   = event_samp + floor(tmax*raw.info.sfreq + 0.5);

        epoch = new MNEEpochData();

        if(raw.read_raw_segment(epoch->epoch, timesDummy, from, to, picks))
        {
            if (p == 0)
            {
                times.resize(1, to-from+1);
                for (qint32 i = 0; i < times.cols(); ++i)
                    times(0, i) = ((float)(from-event_samp+i)) / raw.info.sfreq;
            }

            epoch->event = eveNum;
            epoch->tmin = ((float)(from)-(float)(raw.first_samp))/raw.info.sfreq;
            epoch->tmax = ((float)(to)-(float)(raw.first_samp))/raw.info.sfreq;

            data.append(MNEEpochData::SPtr(epoch));//List takes ownwership of the pointer - no delete need
        }
        else
        {
            printf("Can't read the event data segments");
            return 0;
        }
    }

    if(data.size() > 0)
    {
        printf("Read %d epochs, %d samples each.\n",data.size(),(qint32)data[0]->epoch.cols());

//        //DEBUG
//        std::cout << data[0]->epoch.block(0,0,10,10) << std::endl;
//        qDebug() << data[0]->epoch.rows() << " x " << data[0]->epoch.cols();

//        std::cout << times.block(0,0,1,10) << std::endl;
//        qDebug() << times.rows() << " x " << times.cols();
    }




    //
    // Init RAP-MUSIC
    //
    RapMusic t_rapMusic(t_clusteredFwd, false, numDipolePairs);




    //
    // calculate the average
    //
    for(qint32 numAverages = 1; numAverages <= 20; numAverages += 1)
    {
        for(qint32 it = 0; it <= 30; ++it)
        {
            //
            // calculate the average
            //
            VectorXi vecSel(numAverages);
            srand (time(NULL)); // initialize random seed

            for(qint32 i = 0; i < vecSel.size(); ++i)
            {
                qint32 val = rand() % data.size();
                vecSel(i) = val;
            }

//            std::cout << "Select following epochs to average:\n" << vecSel << std::endl;

//            QString sSelFile = QString("aveInfo_%1_%2.txt").arg(numAverages).arg(it);
//            std::ofstream selFile(sSelFile.toLatin1().constData());
//            if (selFile.is_open())
//            {
//              selFile << vecSel << '\n';
//            }


            FiffEvoked evoked = data.average(raw.info, tmin*raw.info.sfreq, floor(tmax*raw.info.sfreq + 0.5), vecSel);



            QStringList ch_sel_names = t_Fwd.info.ch_names;
            FiffEvoked pickedEvoked = evoked.pick_channels(ch_sel_names);


            //########################################################################################
            // RAP MUSIC Source Estimate

//            if(doMovie)
//                t_pwlRapMusic.setStcAttr(200,0.5);

            MNESourceEstimate sourceEstimate = t_rapMusic.calculateInverse(pickedEvoked);

//            std::cout << "Source Estimate:\n" << sourceEstimate.data << std::endl;

//            std::cout << "Source Estimate vertices:\n" << sourceEstimate.vertices << std::endl;



            if(!sourceEstimate.isEmpty())
            {
                QString t_sFileNameStc = sTargetDir+QString("%1_%2_ave_it_%3.stc").arg(sTargetPrefix).arg(numAverages).arg(it);

                qDebug() << "Write to:" << t_sFileNameStc;


                QDir dir(sTargetDir);
                if (!dir.exists()) {
                    dir.mkpath(".");
                }

                if(!t_sFileNameStc.isEmpty())
                {
                    QFile t_fileClusteredStc(t_sFileNameStc);
                    sourceEstimate.write(t_fileClusteredStc);
                }
            }
        }
    }

    return 0;//app.exec();
}
Example #12
0
/**
* The function main marks the entry point of the program.
* By default, main has the storage class extern.
*
* @param [in] argc (argument count) is an integer that indicates how many arguments were entered on the command line when the program was started.
* @param [in] argv (argument vector) is an array of pointers to arrays of character objects. The array objects are null-terminated strings, representing the arguments that were entered on the command line when the program was started.
* @return the value that was set to exit() (which is 0 if exit() is called via quit()).
*/
int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);
    QGuiApplication::setApplicationName("MNE ROI Cluster Evaluation");
    QGuiApplication::setApplicationVersion("Revision 2");

    ///////////////////////////////////// #1 CLI Parser /////////////////////////////////////
    QCommandLineParser parser;
    parser.setApplicationDescription("MNE ROI Cluster Evaluation");
    parser.addHelpOption();
    parser.addVersionOption();

    // MEG Source Directory
    QCommandLineOption srcDirectoryOption(QStringList() << "s" << "meg-source-directory",
            QCoreApplication::translate("main", "Read MEG (fwd, cov, raw, eve) source files from <directory>."),
            QCoreApplication::translate("main", "directory"),
            "./MNE-sample-data/MEG/sample/");
    parser.addOption(srcDirectoryOption);

    // Forward Solution File
    QCommandLineOption fwdFileOption(QStringList() << "fwd" << "forward-solution",
            QCoreApplication::translate("main", "The forward solution <file>."),
            QCoreApplication::translate("main", "file"),
            "sample_audvis-meg-eeg-oct-6-fwd.fif");
    parser.addOption(fwdFileOption);

    // Fixed Forward Solution File
    QCommandLineOption xfwdFileOption(QStringList() << "xfwd" << "fixed-forward-solution",
            QCoreApplication::translate("main", "The fixed forward solution <file>."),
            QCoreApplication::translate("main", "file"),
            "sample_audvis-meg-eeg-oct-6-fwd-fixed.fif");//"D:/Data/MEG/mind006/mind006_051209_auditory01_raw-oct-6-fwd-fixed.fif");
    parser.addOption(xfwdFileOption);

    // Covariance File
    QCommandLineOption covFileOption(QStringList() << "cov" << "covariance",
            QCoreApplication::translate("main", "The covariance <file>."),
            QCoreApplication::translate("main", "file"),
            "sample_audvis-cov.fif");
    parser.addOption(covFileOption);

    // Raw MEG File
    QCommandLineOption rawFileOption(QStringList() << "raw" << "raw-file",
            QCoreApplication::translate("main", "The raw MEG data <file>."),
            QCoreApplication::translate("main", "file"),
            "sample_audvis_raw.fif");
    parser.addOption(rawFileOption);

    // Event File
    QCommandLineOption eveFileOption(QStringList() << "eve" << "event-file",
            QCoreApplication::translate("main", "The event <file>."),
            QCoreApplication::translate("main", "file"),
            "sample_audvis_raw-eve.fif");
    parser.addOption(eveFileOption);

    // Event Num
    QCommandLineOption evenNumOption(QStringList() << "evenum" << "event-number",
            QCoreApplication::translate("main", "The <event number>."),
            QCoreApplication::translate("main", "event"),
            "1");//2;//3;//4;
    parser.addOption(evenNumOption);

    // FS Subject Directory
    QCommandLineOption subjDirectoryOption(QStringList() << "subjdir" << "subject-directory",
            QCoreApplication::translate("main", "The FreeSurfer <subjects directory>."),
            QCoreApplication::translate("main", "directory"),
            "./MNE-sample-data/subjects");
    parser.addOption(subjDirectoryOption);

    // FS Subject
    QCommandLineOption subjIdOption(QStringList() << "subjid" << "subject-id",
            QCoreApplication::translate("main", "The FreeSurfer <subject id>."),
            QCoreApplication::translate("main", "subject id"),
            "sample");
    parser.addOption(subjIdOption);

    // Target Directory
    QCommandLineOption targetDirectoryOption(QStringList() << "t" << "target-directory",
            QCoreApplication::translate("main", "Copy all result files into <directory>."),
            QCoreApplication::translate("main", "directory"));
    parser.addOption(targetDirectoryOption);

    // Target Prefix
    QCommandLineOption targetPrefixOption(QStringList() << "p" << "prefix",
            QCoreApplication::translate("main", "The result file's <prefix>."),
            QCoreApplication::translate("main", "prefix"));
    parser.addOption(targetPrefixOption);

    //// Source estimate parameters ////
    // SNR
    QCommandLineOption snrOption(QStringList() << "snr" << "signal-to-noise-ratio",
            QCoreApplication::translate("main", "The <snr> estimation for the given data file."),
            QCoreApplication::translate("main", "snr"),
            "1.0");//0.1f;//1.0f;//3.0f;
    parser.addOption(snrOption);

    // METHOD
    QCommandLineOption methodOption(QStringList() << "m" << "method",
            QCoreApplication::translate("main", "The estimation <method>."),
            QCoreApplication::translate("main", "method"),
            "dSPM");//"MNE" | "dSPM" | "sLORETA"
    parser.addOption(methodOption);

    // File Name Clustered Inverse Operator
    QCommandLineOption clustInvFileOption(QStringList() << "icf" << "inverse-clustered-file",
            QCoreApplication::translate("main", "Target <file> to store clustered inverse operator to."),
            QCoreApplication::translate("main", "file"));
    parser.addOption(clustInvFileOption);

    // File Name of the Source Estimate
    QCommandLineOption stcFileOption(QStringList() << "stcf" << "stc-file",
            QCoreApplication::translate("main", "Target <stcfile> to store stc to."),
            QCoreApplication::translate("main", "file"));//"mind006_051209_auditory01.stc"
    parser.addOption(stcFileOption);


    // Process the actual command line arguments given by the user
    parser.process(app);


    //////////////////////////////// #2 get parsed values /////////////////////////////////

    //Sources
    QString sFwdName = parser.value(srcDirectoryOption)+parser.value(fwdFileOption);
    qDebug() << "Forward Solution" << sFwdName;

    QString sXFwdName = parser.value(srcDirectoryOption)+parser.value(xfwdFileOption);
    qDebug() << "Fixed Forward Solution" << sXFwdName;
//    QFile t_fileXFwd(sXFwdName);

    QString sCovName = parser.value(srcDirectoryOption)+parser.value(covFileOption);
    qDebug() << "Covariance matrix" << sCovName;

    QString sRawName = parser.value(srcDirectoryOption)+parser.value(rawFileOption);
    qDebug() << "Raw data" << sRawName;

    QString t_sEventName = parser.value(srcDirectoryOption)+parser.value(eveFileOption);
    qDebug() << "Events" << t_sEventName;

    qint32 eveNum = (qint32)parser.value(evenNumOption).toInt();
    qDebug() << "Event Number" << eveNum;

    QString t_sSubjectsDir = parser.value(subjDirectoryOption);
    qDebug() << "Subjects Directory" << t_sSubjectsDir;

    QString t_sSubject = parser.value(subjIdOption);
    qDebug() << "Subject" << t_sSubject;

    AnnotationSet t_annotationSet(t_sSubject, 2, "aparc.a2009s", t_sSubjectsDir);
    SurfaceSet t_surfSet(t_sSubject, 2, "white", t_sSubjectsDir);

    //Targets
    QString sTargetDir = parser.value(targetDirectoryOption);
    qDebug() << "Target Directory" << sTargetDir;

    QString sTargetPrefix = parser.value(targetPrefixOption);
    qDebug() << "Target Prefix" << sTargetPrefix;

    //// Source estimate parameters ////
    double snr = parser.value(snrOption).toFloat();
    qDebug() << "SNR" << snr;

    QString method = parser.value(methodOption);
    qDebug() << "Method" << method;

    QString t_sFileNameClusteredInv = parser.value(clustInvFileOption);
    qDebug() << "Store clustered inverse operator to:" << t_sFileNameClusteredInv;

    QString t_sFileNameStc = parser.value(stcFileOption);
    qDebug() << "Store stc to:" << t_sFileNameStc;




    //OLD
//    QFile t_fileFwd("./MNE-sample-data/MEG/sample/sample_audvis-meg-eeg-oct-6-fwd.fif");
//    QFile t_fileCov("./MNE-sample-data/MEG/sample/sample_audvis-cov.fif");
//    QFile t_fileRaw("./MNE-sample-data/MEG/sample/sample_audvis_raw.fif");
//    QString t_sEventName = "./MNE-sample-data/MEG/sample/sample_audvis_raw-eve.fif";
//    AnnotationSet t_annotationSet("sample", 2, "aparc.a2009s", "./MNE-sample-data/subjects");
//    SurfaceSet t_surfSet("sample", 2, "white", "./MNE-sample-data/subjects");

//    QFile t_fileFwd("D:/Data/MEG/mind006/mind006_051209_auditory01_raw-oct-6p-fwd.fif");
//    QFile t_fileCov("D:/Data/MEG/mind006/mind006_051209_auditory01_raw-cov.fif");
//    QFile t_fileRaw("D:/Data/MEG/mind006/mind006_051209_auditory01_raw.fif");
//    QString t_sEventName = "D:/Data/MEG/mind006/mind006_051209_auditory01_raw-eve.fif";
//    AnnotationSet t_annotationSet("mind006", 2, "aparc.a2009s", "D:/Data/subjects");
//    SurfaceSet t_surfSet("mind006", 2, "white", "D:/Data/subjects");


    ///////////////////////////////////// #3 read data //////////////////////////////////////
    qint32 event = eveNum;//1;

    float tmin = -0.2f;
    float tmax = 0.4f;

    bool keep_comp = false;
    fiff_int_t dest_comp = 0;
    bool pick_all  = true;

    qint32 k, p;

    //
    //   Setup for reading the raw data
    //
    QFile t_fileRaw(sRawName);
    FiffRawData raw(t_fileRaw);

    RowVectorXi picks;
    if (pick_all)
    {
        //
        // Pick all
        //
        picks.resize(raw.info.nchan);

        for(k = 0; k < raw.info.nchan; ++k)
            picks(k) = k;
        //
    }
    else
    {
        QStringList include;
        include << "STI 014";
        bool want_meg   = true;
        bool want_eeg   = false;
        bool want_stim  = false;

        picks = raw.info.pick_types(want_meg, want_eeg, want_stim, include, raw.info.bads);
    }

    QStringList ch_names;
    for(k = 0; k < picks.cols(); ++k)
        ch_names << raw.info.ch_names[picks(0,k)];

    //
    //   Set up projection
    //
    if (raw.info.projs.size() == 0)
        printf("No projector specified for these data\n");
    else
    {
        //
        //   Activate the projection items
        //
        for (k = 0; k < raw.info.projs.size(); ++k)
            raw.info.projs[k].active = true;

        printf("%d projection items activated\n",raw.info.projs.size());
        //
        //   Create the projector
        //
        fiff_int_t nproj = raw.info.make_projector(raw.proj);

        if (nproj == 0)
        {
            printf("The projection vectors do not apply to these channels\n");
        }
        else
        {
            printf("Created an SSP operator (subspace dimension = %d)\n",nproj);
        }
    }

    //
    //   Set up the CTF compensator
    //
    qint32 current_comp = raw.info.get_current_comp();
    if (current_comp > 0)
        printf("Current compensation grade : %d\n",current_comp);

    if (keep_comp)
        dest_comp = current_comp;

    if (current_comp != dest_comp)
    {
        qDebug() << "This part needs to be debugged";
        if(MNE::make_compensator(raw.info, current_comp, dest_comp, raw.comp))
        {
            raw.info.set_current_comp(dest_comp);
            printf("Appropriate compensator added to change to grade %d.\n",dest_comp);
        }
        else
        {
            printf("Could not make the compensator\n");
            return 0;
        }
    }
    //
    //  Read the events
    //
    QFile t_EventFile;
    MatrixXi events;
    if (t_sEventName.size() == 0)
    {
        p = t_fileRaw.fileName().indexOf(".fif");
        if (p > 0)
        {
            t_sEventName = t_fileRaw.fileName().replace(p, 4, "-eve.fif");
        }
        else
        {
            printf("Raw file name does not end properly\n");
            return 0;
        }
        t_EventFile.setFileName(t_sEventName);
        MNE::read_events(t_EventFile, events);
        printf("Events read from %s\n",t_sEventName.toUtf8().constData());
    }
    else
    {
        //
        //   Binary file
        //
        p = t_fileRaw.fileName().indexOf(".fif");
        if (p > 0)
        {
            t_EventFile.setFileName(t_sEventName);
            if(!MNE::read_events(t_EventFile, events))
            {
                printf("Error while read events.\n");
                return 0;
            }
            printf("Binary event file %s read\n",t_sEventName.toUtf8().constData());
        }
        else
        {
            //
            //   Text file
            //
            printf("Text file %s is not supported jet.\n",t_sEventName.toUtf8().constData());
//            try
//                events = load(eventname);
//            catch
//                error(me,mne_omit_first_line(lasterr));
//            end
//            if size(events,1) < 1
//                error(me,'No data in the event file');
//            end
//            //
//            //   Convert time to samples if sample number is negative
//            //
//            for p = 1:size(events,1)
//                if events(p,1) < 0
//                    events(p,1) = events(p,2)*raw.info.sfreq;
//                end
//            end
//            //
//            //    Select the columns of interest (convert to integers)
//            //
//            events = int32(events(:,[1 3 4]));
//            //
//            //    New format?
//            //
//            if events(1,2) == 0 && events(1,3) == 0
//                fprintf(1,'The text event file %s is in the new format\n',eventname);
//                if events(1,1) ~= raw.first_samp
//                    error(me,'This new format event file is not compatible with the raw data');
//                end
//            else
//                fprintf(1,'The text event file %s is in the old format\n',eventname);
//                //
//                //   Offset with first sample
//                //
//                events(:,1) = events(:,1) + raw.first_samp;
//            end
        }
    }

    //
    //    Select the desired events
    //
    qint32 count = 0;
    MatrixXi selected = MatrixXi::Zero(1, events.rows());
//    std::cout << "Events:\n" << events << std::endl;
    for (p = 0; p < events.rows(); ++p)
    {
        if (events(p,1) == 0 && events(p,2) == event)
        {
            selected(0,count) = p;
            ++count;
        }
    }
    selected.conservativeResize(1, count);
    if (count > 0)
        printf("%d matching events found\n",count);
    else
    {
        printf("No desired events found.\n");
        return 0;
    }


    fiff_int_t event_samp, from, to;
    MatrixXd timesDummy;

    MNEEpochDataList data;

    MNEEpochData* epoch = NULL;

    MatrixXd times;

    for (p = 0; p < count; ++p)
    {
        //
        //       Read a data segment
        //
        event_samp = events(selected(p),0);
        from = event_samp + tmin*raw.info.sfreq;
        to   = event_samp + floor(tmax*raw.info.sfreq + 0.5);

        epoch = new MNEEpochData();

        if(raw.read_raw_segment(epoch->epoch, timesDummy, from, to, picks))
        {
            if (p == 0)
            {
                times.resize(1, to-from+1);
                for (qint32 i = 0; i < times.cols(); ++i)
                    times(0, i) = ((float)(from-event_samp+i)) / raw.info.sfreq;
            }

            epoch->event = event;
            epoch->tmin = ((float)(from)-(float)(raw.first_samp))/raw.info.sfreq;
            epoch->tmax = ((float)(to)-(float)(raw.first_samp))/raw.info.sfreq;

            data.append(MNEEpochData::SPtr(epoch));//List takes ownwership of the pointer - no delete need
        }
        else
        {
            printf("Can't read the event data segments");
            return 0;
        }
    }

    //DEBUG Output
    if(data.size() > 0)
    {
        printf("Sampling frequency, %f\n", raw.info.sfreq);

        printf("Read %d epochs, %d samples each.\n",data.size(),(qint32)data[0]->epoch.cols());
//        //DEBUG
//        std::cout << data[0]->epoch.block(0,0,10,10) << std::endl;
//        qDebug() << data[0]->epoch.rows() << " x " << data[0]->epoch.cols();

//        std::cout << times.block(0,0,1,10) << std::endl;
//        qDebug() << times.rows() << " x " << times.cols();
    }

    /////////////////////////////////// #4 process data /////////////////////////////////////

    //
    // calculate the average
    //
    FiffEvoked evoked = data.average(raw.info, tmin*raw.info.sfreq, floor(tmax*raw.info.sfreq + 0.5));


    //########################################################################################
    // Source Estimate

    double lambda2 = 1.0 / pow(snr, 2);
    qDebug() << "Start calculation with: SNR" << snr << "; Lambda" << lambda2 << "; Method" << method << "; stc:" << t_sFileNameStc;

//    // Load data
//    fiff_int_t setno = 1;
//    QPair<QVariant, QVariant> baseline(QVariant(), 0);
//    FiffEvoked evoked(t_fileEvoked, setno, baseline);
//    if(evoked.isEmpty())
//        return 1;

    QFile t_fileFwd(sFwdName);
    MNEForwardSolution t_Fwd(t_fileFwd);
    if(t_Fwd.isEmpty())
        return 1;

    QFile t_fileFwdFixed(sXFwdName);
    MNEForwardSolution t_FwdFixed(t_fileFwdFixed);
    if(t_FwdFixed.isEmpty())
        return 1;

    QFile t_fileCov(sCovName);
    FiffCov noise_cov(t_fileCov);

    // regularize noise covariance
    noise_cov = noise_cov.regularize(evoked.info, 0.05, 0.05, 0.1, true);


    qDebug() << ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 1. t_Fwd <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<";

    QString sG = sTargetDir + sTargetPrefix + QString("G.txt");
    std::ofstream ofs_G(sG.toUtf8().constData(), std::ofstream::out);
    if (ofs_G.is_open())
    {
        printf("writing to %s\n",sG.toUtf8().constData());
        ofs_G << t_Fwd.sol->data << '\n';
    }
    else
        printf("Not writing to %s\n",sG.toUtf8().constData());
    ofs_G.close();

//    qDebug() << ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 1. t_Fwd_whitened <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<";
//    //
//    // Whiten L1 gain matrix
//    //
//    MatrixXd t_Fwd_whitened(0,0);

//    //
//    // Whiten gain matrix before clustering -> cause diffenerent units Magnetometer, Gradiometer and EEG
//    //
//    if(!noise_cov.isEmpty() && !evoked.info.isEmpty())
//    {
//        FiffInfo p_outFwdInfo;
//        FiffCov p_outNoiseCov;
//        MatrixXd p_outWhitener;
//        qint32 p_outNumNonZero;
//        //do whitening with noise cov
//        t_Fwd.prepare_forward(evoked.info, noise_cov, false, p_outFwdInfo, t_Fwd_whitened, p_outNoiseCov, p_outWhitener, p_outNumNonZero);
//        printf("\tWhitening the forward solution.\n");

//        t_Fwd_whitened = p_outWhitener*t_Fwd_whitened;
//    }

//    QString sG_Whitened = sTargetDir + sTargetPrefix + QString("G_whitened.txt");
//    std::ofstream ofs_G_Whitened(sG_Whitened.toUtf8().constData(), std::ofstream::out);//"G_whitened.txt", std::ofstream::out);
//    if (ofs_G_Whitened.is_open())
//    {
//        printf("writing to %s\n",sG_Whitened.toUtf8().constData());
//        ofs_G_Whitened << t_Fwd_whitened << '\n';
//    }
//    else
//        printf("Not writing to %s\n",sG_Whitened.toUtf8().constData());
//    ofs_G_Whitened.close();

//    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


    //
    // Cluster forward solution;
    //
    MatrixXd D_L1;

    std::cout << "t_Fwd " << t_Fwd.sol->data.rows() << " x " << t_Fwd.sol->data.cols() << std::endl;

    MNEForwardSolution t_clusteredFwd_L1 = t_Fwd.cluster_forward_solution(t_annotationSet, 20, D_L1, noise_cov, evoked.info, "cityblock");
    QString sCILHL1 = sTargetDir + sTargetPrefix + QString("ClusterInfoLH_L1.txt");
    t_clusteredFwd_L1.src[0].cluster_info.write(sCILHL1);
    QString sCIRHL1 = sTargetDir + sTargetPrefix + QString("ClusterInfoRH_L1.txt");
    t_clusteredFwd_L1.src[1].cluster_info.write(sCIRHL1);


    qDebug() << ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 2. t_clusteredFwd_L1 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<";

    QString sG_L1 = sTargetDir + sTargetPrefix + QString("G_L1.txt");
    std::ofstream ofs_G_L1(sG_L1.toUtf8().constData(), std::ofstream::out);
    if (ofs_G_L1.is_open())
    {
        printf("writing to %s\n",sG_L1.toUtf8().constData());
        ofs_G_L1 << t_clusteredFwd_L1.sol->data << '\n';
    }
    else
        printf("Not writing to %s\n",sG_L1.toUtf8().constData());
    ofs_G_L1.close();


//    qDebug() << ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 2. t_clusteredFwd_L1_whitened <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<";
//    //
//    // Whiten L1 gain matrix
//    //
//    MatrixXd t_clusteredFwd_L1_whitened(0,0);

//    //
//    // Whiten gain matrix before clustering -> cause diffenerent units Magnetometer, Gradiometer and EEG
//    //
//    if(!noise_cov.isEmpty() && !evoked.info.isEmpty())
//    {
//        FiffInfo p_outFwdInfo;
//        FiffCov p_outNoiseCov;
//        MatrixXd p_outWhitener;
//        qint32 p_outNumNonZero;
//        //do whitening with noise cov
//        t_clusteredFwd_L1.prepare_forward(evoked.info, noise_cov, false, p_outFwdInfo, t_clusteredFwd_L1_whitened, p_outNoiseCov, p_outWhitener, p_outNumNonZero);
//        printf("\tWhitening the forward solution.\n");

//        t_clusteredFwd_L1_whitened = p_outWhitener*t_clusteredFwd_L1_whitened;
//    }

//    QString sG_L1_Whitened = sTargetDir + sTargetPrefix + QString("G_L1_whitened.txt");
//    std::ofstream ofs_G_L1_Whitened(sG_L1_Whitened.toUtf8().constData(), std::ofstream::out);//"G_L1_whitened.txt", std::ofstream::out);
//    if (ofs_G_L1_Whitened.is_open())
//    {
//        printf("writing to %s\n",sG_L1_Whitened.toUtf8().constData());
//        ofs_G_L1_Whitened << t_clusteredFwd_L1_whitened << '\n';
//    }
//    else
//        printf("Not writing to %s\n",sG_L1_Whitened.toUtf8().constData());
//    ofs_G_L1_Whitened.close();

//    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


    std::cout << "D_L1 " << D_L1.rows() << " x " << D_L1.cols() << std::endl;
    std::cout << "t_clusteredFwd_L1 " << t_clusteredFwd_L1.sol->data.rows() << " x " << t_clusteredFwd_L1.sol->data.cols() << std::endl;

    MatrixXd D_L2;

    MNEForwardSolution t_clusteredFwd_L2 = t_Fwd.cluster_forward_solution(t_annotationSet, 20, D_L2, noise_cov, evoked.info, "sqeuclidean");
    QString sCILH_L2 = sTargetDir + sTargetPrefix + QString("ClusterInfoLH_L2.txt");
    t_clusteredFwd_L2.src[0].cluster_info.write(sCILH_L2);
    QString sCIRH_L2 = sTargetDir + sTargetPrefix + QString("ClusterInfoRH_L2.txt");
    t_clusteredFwd_L2.src[1].cluster_info.write(sCIRH_L2);

    std::cout << "D_L2 " << D_L2.rows() << " x " << D_L2.cols() << std::endl;
    std::cout << "t_clusteredFwd_L2 " << t_clusteredFwd_L2.sol->data.rows() << " x " << t_clusteredFwd_L2.sol->data.cols() << std::endl;


    qDebug() << ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 3. t_clusteredFwd_L2 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<";

    QString sG_L2 = sTargetDir + sTargetPrefix + QString("G_L2.txt");
    std::ofstream ofs_G_L2(sG_L2.toUtf8().constData(), std::ofstream::out);
    if (ofs_G_L2.is_open())
    {
        printf("writing to %s\n",sG_L2.toUtf8().constData());
        ofs_G_L2 << t_clusteredFwd_L2.sol->data << '\n';
    }
    else
        printf("Not writing to %s\n",sG_L2.toUtf8().constData());
    ofs_G_L2.close();

//    qDebug() << ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 3. t_clusteredFwd_L2_whitened <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<";
//    //
//    // Whiten L1 gain matrix
//    //
//    MatrixXd t_clusteredFwd_L2_whitened(0,0);

//    //
//    // Whiten gain matrix before clustering -> cause diffenerent units Magnetometer, Gradiometer and EEG
//    //
//    if(!noise_cov.isEmpty() && !evoked.info.isEmpty())
//    {
//        FiffInfo p_outFwdInfo;
//        FiffCov p_outNoiseCov;
//        MatrixXd p_outWhitener;
//        qint32 p_outNumNonZero;
//        //do whitening with noise cov
//        t_clusteredFwd_L2.prepare_forward(evoked.info, noise_cov, false, p_outFwdInfo, t_clusteredFwd_L2_whitened, p_outNoiseCov, p_outWhitener, p_outNumNonZero);
//        printf("\tWhitening the forward solution.\n");

//        t_clusteredFwd_L2_whitened = p_outWhitener*t_clusteredFwd_L2_whitened;
//    }

//    QString sG_L2_Whitened = sTargetDir + sTargetPrefix + QString("G_L2_whitened.txt");
//    std::ofstream ofs_G_L2_Whitened(sG_L2_Whitened.toUtf8().constData(), std::ofstream::out);//"G_L2_whitened.txt", std::ofstream::out);
//    if (ofs_G_L2_Whitened.is_open())
//    {
//        printf("writing to %s\n",sG_L2_Whitened.toUtf8().constData());
//        ofs_G_L2_Whitened << t_clusteredFwd_L2_whitened << '\n';
//    }
//    else
//        printf("Not writing to %s\n",sG_L2_Whitened.toUtf8().constData());
//    ofs_G_L2_Whitened.close();

    return CommandLineOk;

//    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


    //
    // make an inverse operators
    //
    FiffInfo info = evoked.info;

    QFile t_fileSelectedFwd(sFwdName);


//    QFile t_fileFwd("D:/Data/MEG/mind006/mind006_051209_auditory01_raw-oct-6p-fwd.fif");
//    QFile t_fileCov("D:/Data/MEG/mind006/mind006_051209_auditory01_raw-cov.fif");
//    QFile t_fileRaw("D:/Data/MEG/mind006/mind006_051209_auditory01_raw.fif");
//    QString t_sEventName = "D:/Data/MEG/mind006/mind006_051209_auditory01_raw-eve.fif";
//    AnnotationSet t_annotationSet("mind006", 2, "aparc.a2009s", "D:/Data/subjects");
//    SurfaceSet t_surfSet("mind006", 2, "white", "D:/Data/subjects");


    MNEForwardSolution t_selectedRawFwd(t_fileSelectedFwd);
    if(t_selectedRawFwd.isEmpty())
        return 1;

    MatrixXd D_selected;
    MNEForwardSolution t_selectedFwd = t_selectedRawFwd.reduce_forward_solution(t_clusteredFwd_L2.isFixedOrient() ? t_clusteredFwd_L2.sol->data.cols() : t_clusteredFwd_L2.sol->data.cols()/3, D_selected);

//    qDebug() << "#### t_selectedFwd" << t_selectedFwd.sol->data.rows() << "x" << t_selectedFwd.sol->data.cols();

    MNEInverseOperator inverse_operator_selected(info, t_selectedFwd, noise_cov, 0.2f, 0.8f);

    MNEInverseOperator inverse_operator_clustered_L1(info, t_clusteredFwd_L1, noise_cov, 0.2f, 0.8f);

    MNEInverseOperator inverse_operator_clustered_L2(info, t_clusteredFwd_L2, noise_cov, 0.2f, 0.8f);

    MNEInverseOperator inverse_operator(info, t_Fwd, noise_cov, 0.2f, 0.8f);

//    //
//    // save clustered inverse
//    //
//    if(!t_sFileNameClusteredInv.isEmpty())
//    {
//        QFile t_fileClusteredInverse(t_sFileNameClusteredInv);
//        inverse_operator_clustered_L2.write(t_fileClusteredInverse);
//    }


    //
    // Compute inverse solution
    //
    MinimumNorm minimumNormSelected(inverse_operator_selected, lambda2, method);

    MinimumNorm minimumNormClustered_L1(inverse_operator_clustered_L1, lambda2, method);

    MinimumNorm minimumNormClustered_L2(inverse_operator_clustered_L2, lambda2, method);

    MinimumNorm minimumNorm(inverse_operator, lambda2, method);


//#ifdef BENCHMARK
//    //
//    //   Set up the inverse according to the parameters
//    //
//    minimumNormClustered.doInverseSetup(vecSel.size(),false);

//    MNESourceEstimate sourceEstimate;
//    QList<qint64> qVecElapsedTime;
//    for(qint32 i = 0; i < 100; ++i)
//    {
//        //Benchmark time
//        QElapsedTimer timer;
//        timer.start();
//        sourceEstimate = minimumNormClustered.calculateInverse(evoked.data, evoked.times(0), evoked.times(1)-evoked.times(0));
//        qVecElapsedTime.append(timer.elapsed());
//    }

//    double meanTime = 0.0;
//    qint32 offset = 19;
//    qint32 c = 0;
//    for(qint32 i = offset; i < qVecElapsedTime.size(); ++i)
//    {
//        meanTime += qVecElapsedTime[i];
//        ++c;
//    }

//    meanTime /= (double)c;

//    double varTime = 0;
//    for(qint32 i = offset; i < qVecElapsedTime.size(); ++i)
//        varTime += pow(qVecElapsedTime[i] - meanTime,2);

//    varTime /= (double)c - 1.0f;
//    varTime = sqrt(varTime);

//    qDebug() << "MNE calculation took" << meanTime << "+-" << varTime << "ms in average";

//#else
//    MNESourceEstimate sourceEstimateSelected =

    minimumNormSelected.calculateInverse(evoked);

//    MNESourceEstimate sourceEstimateClustered_L1 =

    minimumNormClustered_L1.calculateInverse(evoked);

//    MNESourceEstimate sourceEstimateClustered_L2 =

    minimumNormClustered_L2.calculateInverse(evoked);

//    MNESourceEstimate sourceEstimate =

    minimumNorm.calculateInverse(evoked);
//#endif


//    ////////////////////////////////// original
//    // #### R calculation ####
//    printf("R original calculation\n");
//    MatrixXd M_orig = minimumNorm.getKernel();

//    MatrixXd R_orig = M_orig * t_FwdFixed.sol->data;

//    QString sROrig = sTargetDir + sTargetPrefix + QString("R_orig.txt");
//    std::ofstream ofs_R_orig(sROrig.toUtf8().constData(), std::ofstream::out);//, std::ofstream::out);
//    if (ofs_R_orig.is_open())
//    {
//        printf("writing to %s\n", sROrig.toUtf8().constData());
//        ofs_R_orig << R_orig << '\n';
//    }
//    else
//        printf("Not writing to %s\n", sROrig.toUtf8().constData());
//    ofs_R_orig.close();

//    R_orig.resize(0,0);


//    //ToDo:just original
//    return CommandLineOk;


    ////////////////////////////////// L1 calculations

    MatrixXd D_MT_L1;
    MatrixXd MT_clustered_L1 = minimumNorm.getPreparedInverseOperator().cluster_kernel(t_annotationSet, 20, D_MT_L1, "cityblock");

    // #### R calculation ####
    //// Option II_L1
    //Cluster Inverse operator
    MatrixXd M_L1 = D_L1.transpose() * minimumNorm.getKernel();

    MatrixXd R_L1 = M_L1 * t_FwdFixed.sol->data;


//    QString sTargetDir = parser.value(targetDirectoryOption);
//    qDebug() << "Target Directory" << sTargetDir;

//    QString sTargetPrefix = parser.value(targetPrefixOption);
//    qDebug() << "Target Prefix" << sTargetPrefix;


    QString sR_L1 = sTargetDir + sTargetPrefix + QString("R_L1.txt");

    std::ofstream ofs_R_L1(sR_L1.toUtf8().constData(), std::ofstream::out);//"R_L1.txt", std::ofstream::out);
    if (ofs_R_L1.is_open())
    {
        printf("writing to %s\n",sR_L1.toUtf8().constData());

        ofs_R_L1 << R_L1 << '\n';
    }
    else
        printf("Not writing to %s\n",sR_L1.toUtf8().constData());
    ofs_R_L1.close();

    M_L1.resize(0,0);
    R_L1.resize(0,0);

    //// Option I_L1
    printf("[3]\n");
    MatrixXd M_clusterd_L1 = minimumNormClustered_L1.getKernel();

    printf("[4]\n");
    MatrixXd R_clustered_L1 = M_clusterd_L1 * t_FwdFixed.sol->data;

    QString sRClustered_L1 = sTargetDir + sTargetPrefix + QString("R_clustered_L1.txt");
    std::ofstream ofs_R_clustered_L1(sRClustered_L1.toUtf8().constData(), std::ofstream::out);//, std::ofstream::out);
    if (ofs_R_clustered_L1.is_open())
    {
        printf("writing to %s\n", sRClustered_L1.toUtf8().constData());
        ofs_R_clustered_L1 << R_clustered_L1 << '\n';
    }
    else
        printf("Not writing to %s\n", sRClustered_L1.toUtf8().constData());
    ofs_R_clustered_L1.close();

    M_clusterd_L1.resize(0,0);
    R_clustered_L1.resize(0,0);

//Cluster Operator D_L1
    QString sD_L1 = sTargetDir + sTargetPrefix + QString("D_L1.txt");
    std::ofstream ofs_D_L1(sD_L1.toUtf8().constData(), std::ofstream::out);//"D_L1.txt", std::ofstream::out);
    if (ofs_D_L1.is_open())
    {
        printf("writing to %s\n",sD_L1.toUtf8().constData());
        ofs_D_L1 << D_L1 << '\n';
    }
    else
        printf("Not writing to %s\n",sD_L1.toUtf8().constData());
    ofs_D_L1.close();


    //// Option III_L1
    printf("[5]\n");
    MatrixXd R_MT_clustered_L1 = MT_clustered_L1.transpose() * t_FwdFixed.sol->data;

    QString sRMTClust_L1 = sTargetDir + sTargetPrefix + QString("R_MT_clustered_L1.txt");
    std::ofstream ofs_R_MT_clustered_L1(sRMTClust_L1.toUtf8().constData(), std::ofstream::out);
    if (ofs_R_MT_clustered_L1.is_open())
    {
        printf("writing to %s\n",sRMTClust_L1.toUtf8().constData());
        ofs_R_MT_clustered_L1 << R_MT_clustered_L1 << '\n';
    }
    else
        printf("Not writing to %s\n",sRMTClust_L1.toUtf8().constData());
    ofs_R_MT_clustered_L1.close();

    R_MT_clustered_L1.resize(0,0);

    //Cluster Operator D
    QString sDMT_L1 = sTargetDir + sTargetPrefix + QString("D_MT_L1.txt");
    std::ofstream ofs_D_MT_L1(sDMT_L1.toUtf8().constData(), std::ofstream::out);
    if (ofs_D_MT_L1.is_open())
    {
        printf("writing to %s\n",sDMT_L1.toUtf8().constData());
        ofs_D_MT_L1 << D_MT_L1 << '\n';
    }
    else
        printf("Not writing to %s\n",sDMT_L1.toUtf8().constData());
    ofs_D_MT_L1.close();





    ////////////////////////////////// L2 calculations

    MatrixXd D_MT_L2;
    MatrixXd MT_clustered_L2 = minimumNorm.getPreparedInverseOperator().cluster_kernel(t_annotationSet, 20, D_MT_L2, "sqeuclidean");

    // #### R calculation ####

    //// Option II_L2
    MatrixXd M_L2 = D_L2.transpose() * minimumNorm.getKernel();

    MatrixXd R_L2 = M_L2 * t_FwdFixed.sol->data;


//    QString sTargetDir = parser.value(targetDirectoryOption);
//    qDebug() << "Target Directory" << sTargetDir;

//    QString sTargetPrefix = parser.value(targetPrefixOption);
//    qDebug() << "Target Prefix" << sTargetPrefix;


    QString sR_L2 = sTargetDir + sTargetPrefix + QString("R_L2.txt");

    std::ofstream ofs_R_L2(sR_L2.toUtf8().constData(), std::ofstream::out);//"R_L2.txt", std::ofstream::out);
    if (ofs_R_L2.is_open())
    {
        printf("writing to %s\n",sR_L2.toUtf8().constData());

        ofs_R_L2 << R_L2 << '\n';
    }
    else
        printf("Not writing to %s\n",sR_L2.toUtf8().constData());
    ofs_R_L2.close();

    M_L2.resize(0,0);
    R_L2.resize(0,0);


    //// Option I_L2
    printf("[3]\n");
    MatrixXd M_clusterd_L2 = minimumNormClustered_L2.getKernel();

    printf("[4]\n");
    MatrixXd R_clustered_L2 = M_clusterd_L2 * t_FwdFixed.sol->data;

    QString sRClustered_L2 = sTargetDir + sTargetPrefix + QString("R_clustered_L2.txt");
    std::ofstream ofs_R_clustered_L2(sRClustered_L2.toUtf8().constData(), std::ofstream::out);//, std::ofstream::out);
    if (ofs_R_clustered_L2.is_open())
    {
        printf("writing to %s\n", sRClustered_L2.toUtf8().constData());
        ofs_R_clustered_L2 << R_clustered_L2 << '\n';
    }
    else
        printf("Not writing to %s\n", sRClustered_L2.toUtf8().constData());
    ofs_R_clustered_L2.close();

    M_clusterd_L2.resize(0,0);
    R_clustered_L2.resize(0,0);

//Cluster Operator D_L2
    QString sD_L2 = sTargetDir + sTargetPrefix + QString("D_L2.txt");
    std::ofstream ofs_D_L2(sD_L2.toUtf8().constData(), std::ofstream::out);//"D_L2.txt", std::ofstream::out);
    if (ofs_D_L2.is_open())
    {
        printf("writing to %s\n",sD_L2.toUtf8().constData());
        ofs_D_L2 << D_L2 << '\n';
    }
    else
        printf("Not writing to %s\n",sD_L2.toUtf8().constData());
    ofs_D_L2.close();


    //// Option III_L2
    printf("[5]\n");
    MatrixXd R_MT_clustered_L2 = MT_clustered_L2.transpose() * t_FwdFixed.sol->data;

    QString sRMTClust_L2 = sTargetDir + sTargetPrefix + QString("R_MT_clustered_L2.txt");
    std::ofstream ofs_R_MT_clustered_L2(sRMTClust_L2.toUtf8().constData(), std::ofstream::out);
    if (ofs_R_MT_clustered_L2.is_open())
    {
        printf("writing to %s\n",sRMTClust_L2.toUtf8().constData());
        ofs_R_MT_clustered_L2 << R_MT_clustered_L2 << '\n';
    }
    else
        printf("Not writing to %s\n",sRMTClust_L2.toUtf8().constData());
    ofs_R_MT_clustered_L2.close();

    R_MT_clustered_L2.resize(0,0);

    //Cluster Operator D
    QString sDMT_L2 = sTargetDir + sTargetPrefix + QString("D_MT_L2.txt");
    std::ofstream ofs_D_MT_L2(sDMT_L2.toUtf8().constData(), std::ofstream::out);
    if (ofs_D_MT_L2.is_open())
    {
        printf("writing to %s\n",sDMT_L2.toUtf8().constData());
        ofs_D_MT_L2 << D_MT_L2 << '\n';
    }
    else
        printf("Not writing to %s\n",sDMT_L2.toUtf8().constData());
    ofs_D_MT_L2.close();





    ////////////////////////////////// Selection calculation

    //option d)
    MatrixXd M_selected = minimumNormSelected.getKernel();

//    qDebug() << "M_selected: " << M_selected.rows() << "x" << M_selected.cols();


    printf("[7]\n");
    MatrixXd R_selected= M_selected * t_FwdFixed.sol->data;

    QString sRselected = sTargetDir + sTargetPrefix + QString("R_selected.txt");
    std::ofstream ofs_R_selected(sRselected.toUtf8().constData(), std::ofstream::out);//"R_selected.txt", std::ofstream::out);
    if (ofs_R_selected.is_open())
    {
        printf("writing to %s\n",sRselected.toUtf8().constData());
        ofs_R_selected << R_selected << '\n';
    }
    else
        printf("Not writing to %s\n",sRselected.toUtf8().constData());
    ofs_R_selected.close();

    R_selected.resize(0,0);

    //Cluster Operator D
    QString sDselected = sTargetDir + sTargetPrefix + QString("D_selected.txt");
    std::ofstream ofs_D_selected(sDselected.toUtf8().constData(), std::ofstream::out);//"D_selected.txt", std::ofstream::out);
    if (ofs_D_selected.is_open())
    {
        printf("writing to %s\n",sDselected.toUtf8().constData());
        ofs_D_selected << D_selected << '\n';
    }
    else
        printf("Not writing to %s\n",sDselected.toUtf8().constData());
    ofs_D_selected.close();

    // #### R calculation end ####















    /////////////////////////////////// #5 METHOD I /////////////////////////////////////
    // I) M_D -> I_L1
//    {
//        qDebug() << "METHOD I_L1";
//    }


    /////////////////////////////////// #6 METHOD II /////////////////////////////////////
    // II) D_G^T M -> II_L1
//    {
//        qDebug() << "METHOD II_L1";
//    }


    /////////////////////////////////// #7 METHOD III /////////////////////////////////////
    // III) D^T_{M^T} M -> III_L1
//    {
//        qDebug() << "METHOD III_L1";
//    }


    /////////////////////////////////// #8 METHOD IV /////////////////////////////////////
    // IV) M_D -> I_L2
//    {
//        qDebug() << "METHOD I_L2";
//    }


    /////////////////////////////////// #9 METHOD V /////////////////////////////////////
    // V) D^T_G M -> II_L2
//    {
//        qDebug() << "METHOD II_L2";
//    }


    /////////////////////////////////// #10 METHOD VI /////////////////////////////////////
    // VI) D^T_{M^T} M -> III_L2
//    {
//        qDebug() << "METHOD III_L2";
//    }


    /////////////////////////////////// #11 METHOD VII /////////////////////////////////////
    // VII) M -> IV
//    {
//        qDebug() << "METHOD IV";
//    }






















//    //Condition Numbers Attention - Condition only with fixed orientation!!!!!!!!!
//    VectorXd s;

//    double t_dConditionNumber = MNEMath::getConditionNumber(t_Fwd.sol->data, s);
//    std::cout << "Condition Number:\n" << t_dConditionNumber << std::endl;

//    //
//    QString sKappa = sTargetDir + sTargetPrefix + QString("Kappa.txt");
//    std::ofstream ofs_Kappa(sKappa.toUtf8().constData(), std::ofstream::out);
//    if (ofs_Kappa.is_open())
//    {
//        printf("writing to %s\n",sKappa.toUtf8().constData());
//        ofs_Kappa << t_dConditionNumber << '\n';
//    }
//    else
//        printf("Not writing to %s\n",sKappa.toUtf8().constData());
//    ofs_Kappa.close();

//    // s
//    QString sS = sTargetDir + sTargetPrefix + QString("S.txt");
//    std::ofstream ofs_sS(sS.toUtf8().constData(), std::ofstream::out);
//    if (ofs_sS.is_open())
//    {
//        printf("writing to %s\n",sS.toUtf8().constData());
//        ofs_sS << s << '\n';
//    }
//    else
//        printf("Not writing to %s\n",sS.toUtf8().constData());
//    ofs_sS.close();



//    double t_dConditionNumberClustered_L1 = MNEMath::getConditionNumber(t_clusteredFwd_L1.sol->data, s);
//    std::cout << "Clustered L1 Condition Number:\n" << t_dConditionNumberClustered_L1 << std::endl;

//    //
//    QString sKappaL1 = sTargetDir + sTargetPrefix + QString("Kappa_L1.txt");
//    std::ofstream ofs_KappaL1(sKappaL1.toUtf8().constData(), std::ofstream::out);
//    if (ofs_KappaL1.is_open())
//    {
//        printf("writing to %s\n",sKappaL1.toUtf8().constData());
//        ofs_KappaL1 << t_dConditionNumberClustered_L1 << '\n';
//    }
//    else
//        printf("Not writing to %s\n",sKappaL1.toUtf8().constData());
//    ofs_KappaL1.close();

//    // s
//    QString sSL1 = sTargetDir + sTargetPrefix + QString("S_L1.txt");
//    std::ofstream ofs_SL1(sSL1.toUtf8().constData(), std::ofstream::out);
//    if (ofs_SL1.is_open())
//    {
//        printf("writing to %s\n",sSL1.toUtf8().constData());
//        ofs_SL1 << s << '\n';
//    }
//    else
//        printf("Not writing to %s\n",sSL1.toUtf8().constData());
//    ofs_SL1.close();



//    double t_dConditionNumberClustered_L2 = MNEMath::getConditionNumber(t_clusteredFwd_L2.sol->data, s);
//    std::cout << "Clustered L2 Condition Number:\n" << t_dConditionNumberClustered_L2 << std::endl;

//    // Kappa
//    QString sKappaL2 = sTargetDir + sTargetPrefix + QString("Kappa_L2.txt");
//    std::ofstream ofs_KappaL2(sKappaL2.toUtf8().constData(), std::ofstream::out);
//    if (ofs_KappaL2.is_open())
//    {
//        printf("writing to %s\n",sKappaL2.toUtf8().constData());
//        ofs_KappaL2 << t_dConditionNumberClustered_L2 << '\n';
//    }
//    else
//        printf("Not writing to %s\n",sKappaL2.toUtf8().constData());
//    ofs_KappaL2.close();

//    // s
//    QString sSL2 = sTargetDir + sTargetPrefix + QString("S_L2.txt");
//    std::ofstream ofs_SL2(sSL2.toUtf8().constData(), std::ofstream::out);
//    if (ofs_SL2.is_open())
//    {
//        printf("writing to %s\n",sSL2.toUtf8().constData());
//        ofs_SL2 << s << '\n';
//    }
//    else
//        printf("Not writing to %s\n",sSL2.toUtf8().constData());
//    ofs_SL2.close();


//    double t_dConditionNumberMags = MNEMath::getConditionNumber(mags, s);
//    double t_dConditionNumberMagsClustered = MNEMath::getConditionNumber(magsClustered, s);

//    std::cout << "Condition Number Magnetometers:\n" << t_dConditionNumberMags << std::endl;
//    std::cout << "Clustered Condition Number Magnetometers:\n" << t_dConditionNumberMagsClustered << std::endl;

//    double t_dConditionNumberGrads = MNEMath::getConditionNumber(grads, s);
//    double t_dConditionNumberGradsClustered = MNEMath::getConditionNumber(gradsClustered, s);

//    std::cout << "Condition Number Gradiometers:\n" << t_dConditionNumberGrads << std::endl;
//    std::cout << "Clustered Condition Number Gradiometers:\n" << t_dConditionNumberGradsClustered << std::endl;


    return CommandLineOk;
}
Example #13
0
/**
* The function main marks the entry point of the program.
* By default, main has the storage class extern.
*
* @param [in] argc (argument count) is an integer that indicates how many arguments were entered on the command line when the program was started.
* @param [in] argv (argument vector) is an array of pointers to arrays of character objects. The array objects are null-terminated strings, representing the arguments that were entered on the command line when the program was started.
* @return the value that was set to exit() (which is 0 if exit() is called via quit()).
*/
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    // Command Line Parser
    QCommandLineParser parser;
    parser.setApplicationDescription("Read Epochs Example");
    parser.addHelpOption();

    QCommandLineOption inputOption("fileIn", "The input file <in>.", "in", QCoreApplication::applicationDirPath() + "/MNE-sample-data/MEG/sample/sample_audvis_raw.fif");
    QCommandLineOption eventsFileOption("eve", "Path to the event <file>.", "file", QCoreApplication::applicationDirPath() + "/MNE-sample-data/MEG/sample/sample_audvis_raw-eve.fif");
    QCommandLineOption evokedIdxOption("aveIdx", "The average <index> to choose from the average file.", "index", "3");
    QCommandLineOption pickAllOption("pickAll", "Pick all channels.", "pickAll", "true");
    QCommandLineOption keepCompOption("keepComp", "Keep compensators.", "keepComp", "false");
    QCommandLineOption destCompsOption("destComps", "<Destination> of the compensator which is to be calculated.", "destination", "0");

    parser.addOption(inputOption);
    parser.addOption(eventsFileOption);
    parser.addOption(evokedIdxOption);
    parser.addOption(pickAllOption);
    parser.addOption(keepCompOption);
    parser.addOption(destCompsOption);

    parser.process(a);

    //Load data
    QString t_fileRawName = parser.value(inputOption);
    QFile t_fileRaw(t_fileRawName);

    qint32 event = parser.value(evokedIdxOption).toInt();
    QString t_sEventName = parser.value(eventsFileOption);
    float fTMin = -1.5f;
    float fTMax = 1.5f;

    bool keep_comp = false;
    if(parser.value(keepCompOption) == "false" || parser.value(keepCompOption) == "0") {
        keep_comp = false;
    } else if(parser.value(keepCompOption) == "true" || parser.value(keepCompOption) == "1") {
        keep_comp = true;
    }

    fiff_int_t dest_comp = parser.value(destCompsOption).toInt();

    bool pick_all = false;
    if(parser.value(pickAllOption) == "false" || parser.value(pickAllOption) == "0") {
        pick_all = false;
    } else if(parser.value(pickAllOption) == "true" || parser.value(pickAllOption) == "1") {
        pick_all = true;
    }

    // Setup for reading the raw data
    FiffRawData raw(t_fileRaw);
    MNE::setup_compensators(raw, dest_comp, keep_comp);

    RowVectorXi picks;
    if (pick_all) {
        // Pick all
        picks.resize(raw.info.nchan);

        for(qint32 k = 0; k < raw.info.nchan; ++k) {
            picks(k) = k;
        }
    } else {
        QStringList include;
        include << "STI 014";
        bool want_meg   = true;
        bool want_eeg   = false;
        bool want_stim  = false;

        picks = raw.info.pick_types(want_meg,
                                    want_eeg,
                                    want_stim,
                                    include,
                                    raw.info.bads);
    }

    // Read the events
    MatrixXi events;    
    MNE::read_events(t_sEventName,
                     t_fileRawName,
                     events);

    // Read the epochs and reject epochs with EOG higher than 250e-06
    MNEEpochDataList data = MNEEpochDataList::readEpochs(raw,
                                                         events,
                                                         fTMin,
                                                         fTMax,
                                                         event,
                                                         250.0*0.0000010,
                                                         "eog",
                                                         picks);

    // Drop rejected epochs
    data.dropRejected();

    // Generate a evoked from the epochs
    FiffEvoked evoked = data.average(raw.info,
                                     raw.first_samp,
                                     raw.last_samp);

    return a.exec();
}
Example #14
0
/**
* The function main marks the entry point of the program.
* By default, main has the storage class extern.
*
* @param [in] argc (argument count) is an integer that indicates how many arguments were entered on the command line when the program was started.
* @param [in] argv (argument vector) is an array of pointers to arrays of character objects. The array objects are null-terminated strings, representing the arguments that were entered on the command line when the program was started.
* @return the value that was set to exit() (which is 0 if exit() is called via quit()).
*/
int main(int argc, char *argv[])
{
    QGuiApplication a(argc, argv);




//    QFile t_fileFwd("./MNE-sample-data/MEG/sample/sample_audvis-meg-eeg-oct-6-fwd.fif");
//    QFile t_fileCov("./MNE-sample-data/MEG/sample/sample_audvis-cov.fif");
//    QFile t_fileRaw("./MNE-sample-data/MEG/sample/sample_audvis_raw.fif");
//    QString t_sEventName = "./MNE-sample-data/MEG/sample/sample_audvis_raw-eve.fif";
//    AnnotationSet t_annotationSet("./MNE-sample-data/subjects/sample/label/lh.aparc.a2009s.annot", "./MNE-sample-data/subjects/sample/label/rh.aparc.a2009s.annot");
//    SurfaceSet t_surfSet("./MNE-sample-data/subjects/sample/surf/lh.white", "./MNE-sample-data/subjects/sample/surf/rh.white");

    QFile t_fileFwd("E:/Data/sl_data/MEG/mind006/mind006_051209_auditory01_raw-oct-6p-fwd.fif");
    QFile t_fileCov("E:/Data/sl_data/MEG/mind006/mind006_051209_auditory01_raw-cov.fif");
    QFile t_fileRaw("E:/Data/sl_data/MEG/mind006/mind006_051209_auditory01_raw.fif");
    QString t_sEventName = "E:/Data/sl_data/MEG/mind006/mind006_051209_auditory01_raw-eve.fif";
    AnnotationSet t_annotationSet("E:/Data/sl_data/subjects/mind006/label/lh.aparc.a2009s.annot", "E:/Data/sl_data/subjects/mind006/label/rh.aparc.a2009s.annot");
    SurfaceSet t_surfSet("E:/Data/sl_data/subjects/mind006/surf/lh.white", "E:/Data/sl_data/subjects/mind006/surf/rh.white");


    qint32 event = 1;

    float tmin = -0.2f;
    float tmax = 0.4f;

    bool keep_comp = false;
    fiff_int_t dest_comp = 0;
    bool pick_all  = true;

    qint32 k, p;

    //
    //   Setup for reading the raw data
    //
    FiffRawData raw(t_fileRaw);

    RowVectorXi picks;
    if (pick_all)
    {
        //
        // Pick all
        //
        picks.resize(raw.info.nchan);

        for(k = 0; k < raw.info.nchan; ++k)
            picks(k) = k;
        //
    }
    else
    {
        QStringList include;
        include << "STI 014";
        bool want_meg   = true;
        bool want_eeg   = false;
        bool want_stim  = false;

//        picks = Fiff::pick_types(raw.info, want_meg, want_eeg, want_stim, include, raw.info.bads);
        picks = raw.info.pick_types(want_meg, want_eeg, want_stim, include, raw.info.bads);//prefer member function
    }

    QStringList ch_names;
    for(k = 0; k < picks.cols(); ++k)
        ch_names << raw.info.ch_names[picks(0,k)];

    //
    //   Set up projection
    //
    if (raw.info.projs.size() == 0)
        printf("No projector specified for these data\n");
    else
    {
        //
        //   Activate the projection items
        //
        for (k = 0; k < raw.info.projs.size(); ++k)
            raw.info.projs[k].active = true;

        printf("%d projection items activated\n",raw.info.projs.size());
        //
        //   Create the projector
        //
//        fiff_int_t nproj = MNE::make_projector_info(raw.info, raw.proj); Using the member function instead
        fiff_int_t nproj = raw.info.make_projector(raw.proj);

        if (nproj == 0)
        {
            printf("The projection vectors do not apply to these channels\n");
        }
        else
        {
            printf("Created an SSP operator (subspace dimension = %d)\n",nproj);
        }
    }

    //
    //   Set up the CTF compensator
    //
//    qint32 current_comp = MNE::get_current_comp(raw.info);
    qint32 current_comp = raw.info.get_current_comp();
    if (current_comp > 0)
        printf("Current compensation grade : %d\n",current_comp);

    if (keep_comp)
        dest_comp = current_comp;

    if (current_comp != dest_comp)
    {
        qDebug() << "This part needs to be debugged";
        if(MNE::make_compensator(raw.info, current_comp, dest_comp, raw.comp))
        {
//            raw.info.chs = MNE::set_current_comp(raw.info.chs,dest_comp);
            raw.info.set_current_comp(dest_comp);
            printf("Appropriate compensator added to change to grade %d.\n",dest_comp);
        }
        else
        {
            printf("Could not make the compensator\n");
            return 0;
        }
    }
    //
    //  Read the events
    //
    QFile t_EventFile;
    MatrixXi events;
    if (t_sEventName.size() == 0)
    {
        p = t_fileRaw.fileName().indexOf(".fif");
        if (p > 0)
        {
            t_sEventName = t_fileRaw.fileName().replace(p, 4, "-eve.fif");
        }
        else
        {
            printf("Raw file name does not end properly\n");
            return 0;
        }
//        events = mne_read_events(t_sEventName);

        t_EventFile.setFileName(t_sEventName);
        MNE::read_events(t_EventFile, events);
        printf("Events read from %s\n",t_sEventName.toUtf8().constData());
    }
    else
    {
        //
        //   Binary file
        //
        p = t_fileRaw.fileName().indexOf(".fif");
        if (p > 0)
        {
            t_EventFile.setFileName(t_sEventName);
            if(!MNE::read_events(t_EventFile, events))
            {
                printf("Error while read events.\n");
                return 0;
            }
            printf("Binary event file %s read\n",t_sEventName.toUtf8().constData());
        }
        else
        {
            //
            //   Text file
            //
            printf("Text file %s is not supported jet.\n",t_sEventName.toUtf8().constData());
//            try
//                events = load(eventname);
//            catch
//                error(me,mne_omit_first_line(lasterr));
//            end
//            if size(events,1) < 1
//                error(me,'No data in the event file');
//            end
//            //
//            //   Convert time to samples if sample number is negative
//            //
//            for p = 1:size(events,1)
//                if events(p,1) < 0
//                    events(p,1) = events(p,2)*raw.info.sfreq;
//                end
//            end
//            //
//            //    Select the columns of interest (convert to integers)
//            //
//            events = int32(events(:,[1 3 4]));
//            //
//            //    New format?
//            //
//            if events(1,2) == 0 && events(1,3) == 0
//                fprintf(1,'The text event file %s is in the new format\n',eventname);
//                if events(1,1) ~= raw.first_samp
//                    error(me,'This new format event file is not compatible with the raw data');
//                end
//            else
//                fprintf(1,'The text event file %s is in the old format\n',eventname);
//                //
//                //   Offset with first sample
//                //
//                events(:,1) = events(:,1) + raw.first_samp;
//            end
        }
    }

    //
    //    Select the desired events
    //
    qint32 count = 0;
    MatrixXi selected = MatrixXi::Zero(1, events.rows());
    for (p = 0; p < events.rows(); ++p)
    {
        if (events(p,1) == 0 && events(p,2) == event)
        {
            selected(0,count) = p;
            ++count;
        }
    }
    selected.conservativeResize(1, count);
    if (count > 0)
        printf("%d matching events found\n",count);
    else
    {
        printf("No desired events found.\n");
        return 0;
    }


    fiff_int_t event_samp, from, to;
    MatrixXd timesDummy;

    MNEEpochDataList data;

    MNEEpochData* epoch = NULL;

    MatrixXd times;

    for (p = 0; p < count; ++p)
    {
        //
        //       Read a data segment
        //
        event_samp = events(selected(p),0);
        from = event_samp + tmin*raw.info.sfreq;
        to   = event_samp + floor(tmax*raw.info.sfreq + 0.5);

        epoch = new MNEEpochData();

        if(raw.read_raw_segment(epoch->epoch, timesDummy, from, to, picks))
        {
            if (p == 0)
            {
                times.resize(1, to-from+1);
                for (qint32 i = 0; i < times.cols(); ++i)
                    times(0, i) = ((float)(from-event_samp+i)) / raw.info.sfreq;
            }

            epoch->event = event;
            epoch->tmin = ((float)(from)-(float)(raw.first_samp))/raw.info.sfreq;
            epoch->tmax = ((float)(to)-(float)(raw.first_samp))/raw.info.sfreq;

            data.append(MNEEpochData::SPtr(epoch));//List takes ownwership of the pointer - no delete need
        }
        else
        {
            printf("Can't read the event data segments");
            return 0;
        }
    }

    if(data.size() > 0)
    {
        printf("Read %d epochs, %d samples each.\n",data.size(),(qint32)data[0]->epoch.cols());

        //DEBUG
        std::cout << data[0]->epoch.block(0,0,10,10) << std::endl;
        qDebug() << data[0]->epoch.rows() << " x " << data[0]->epoch.cols();

        std::cout << times.block(0,0,1,10) << std::endl;
        qDebug() << times.rows() << " x " << times.cols();
    }

    //
    // calculate the average
    //
//    //Option 1
//    qint32 numAverages = 99;
//    VectorXi vecSel(numAverages);
//    srand (time(NULL)); // initialize random seed

//    for(qint32 i = 0; i < vecSel.size(); ++i)
//    {
//        qint32 val = rand() % data.size();
//        vecSel(i) = val;
//    }

//    //Option 2
//    VectorXi vecSel(20);

////    vecSel << 76, 74, 13, 61, 97, 94, 75, 71, 60, 56, 26, 57, 56, 0, 52, 72, 33, 86, 96, 67;

//    vecSel << 65, 22, 47, 55, 16, 29, 14, 36, 57, 97, 89, 46, 9, 93, 83, 52, 71, 52, 3, 96;

    //Option 3 Newest
    VectorXi vecSel(10);

    vecSel << 0, 96, 80, 55, 66, 25, 26, 2, 55, 58, 6, 88;


    std::cout << "Select following epochs to average:\n" << vecSel << std::endl;

    FiffEvoked evoked = data.average(raw.info, tmin*raw.info.sfreq, floor(tmax*raw.info.sfreq + 0.5), vecSel);










    //########################################################################################
    // Source Estimate

    double snr = 1.0f;//0.1f;//1.0f;//3.0f;//0.1f;//3.0f;
    QString method("dSPM"); //"MNE" | "dSPM" | "sLORETA"

    QString t_sFileNameClusteredInv("");
    QString t_sFileNameStc("mind006_051209_auditory01.stc");

    // Parse command line parameters
    for(qint32 i = 0; i < argc; ++i)
    {
        if(strcmp(argv[i], "-snr") == 0 || strcmp(argv[i], "--snr") == 0)
        {
            if(i + 1 < argc)
                snr = atof(argv[i+1]);
        }
        else if(strcmp(argv[i], "-method") == 0 || strcmp(argv[i], "--method") == 0)
        {
            if(i + 1 < argc)
                method = QString::fromUtf8(argv[i+1]);
        }
        else if(strcmp(argv[i], "-inv") == 0 || strcmp(argv[i], "--inv") == 0)
        {
            if(i + 1 < argc)
                t_sFileNameClusteredInv = QString::fromUtf8(argv[i+1]);
        }
        else if(strcmp(argv[i], "-stc") == 0 || strcmp(argv[i], "--stc") == 0)
        {
            if(i + 1 < argc)
                t_sFileNameStc = QString::fromUtf8(argv[i+1]);
        }
    }

    double lambda2 = 1.0 / pow(snr, 2);
    qDebug() << "Start calculation with: SNR" << snr << "; Lambda" << lambda2 << "; Method" << method << "; stc:" << t_sFileNameStc;

//    // Load data
//    fiff_int_t setno = 1;
//    QPair<QVariant, QVariant> baseline(QVariant(), 0);
//    FiffEvoked evoked(t_fileEvoked, setno, baseline);
//    if(evoked.isEmpty())
//        return 1;

    MNEForwardSolution t_Fwd(t_fileFwd);
    if(t_Fwd.isEmpty())
        return 1;


    FiffCov noise_cov(t_fileCov);

    // regularize noise covariance
    noise_cov = noise_cov.regularize(evoked.info, 0.05, 0.05, 0.1, true);

    //
    // Cluster forward solution;
    //
    MNEForwardSolution t_clusteredFwd = t_Fwd.cluster_forward_solution_ccr(t_annotationSet, 20);//40);

    //
    // make an inverse operators
    //
    FiffInfo info = evoked.info;

    MNEInverseOperator inverse_operator(info, t_clusteredFwd, noise_cov, 0.2f, 0.8f);

    //
    // save clustered inverse
    //
    if(!t_sFileNameClusteredInv.isEmpty())
    {
        QFile t_fileClusteredInverse(t_sFileNameClusteredInv);
        inverse_operator.write(t_fileClusteredInverse);
    }

    //
    // Compute inverse solution
    //
    MinimumNorm minimumNorm(inverse_operator, lambda2, method);

#ifdef BENCHMARK
    MNESourceEstimate sourceEstimate;
    QList<qint64> qVecElapsedTime;
    for(qint32 i = 0; i < 20; ++i)
    {
        //Benchmark time
        QElapsedTimer timer;
        timer.start();
        sourceEstimate = minimumNorm.calculateInverse(evoked);
        qVecElapsedTime.append(timer.elapsed());
    }

    double meanTime = 0.0;
    for(qint32 i = 0; i < qVecElapsedTime.size(); ++i)
        meanTime += qVecElapsedTime[i];

    meanTime /= qVecElapsedTime.size();
    qDebug() << "MNE calculation took" << meanTime << "ms in average";

#else
    MNESourceEstimate sourceEstimate = minimumNorm.calculateInverse(evoked);
#endif

    if(sourceEstimate.isEmpty())
        return 1;

    // View activation time-series
    std::cout << "\nsourceEstimate:\n" << sourceEstimate.data.block(0,0,10,10) << std::endl;
    std::cout << "time\n" << sourceEstimate.times.block(0,0,1,10) << std::endl;
    std::cout << "timeMin\n" << sourceEstimate.times[0] << std::endl;
    std::cout << "timeMax\n" << sourceEstimate.times[sourceEstimate.times.size()-1] << std::endl;
    std::cout << "time step\n" << sourceEstimate.tstep << std::endl;

    //Condition Numbers
//    MatrixXd mags(102, t_Fwd.sol->data.cols());
//    qint32 count = 0;
//    for(qint32 i = 2; i < 306; i += 3)
//    {
//        mags.row(count) = t_Fwd.sol->data.row(i);
//        ++count;
//    }
//    MatrixXd magsClustered(102, t_clusteredFwd.sol->data.cols());
//    count = 0;
//    for(qint32 i = 2; i < 306; i += 3)
//    {
//        magsClustered.row(count) = t_clusteredFwd.sol->data.row(i);
//        ++count;
//    }

//    MatrixXd grads(204, t_Fwd.sol->data.cols());
//    count = 0;
//    for(qint32 i = 0; i < 306; i += 3)
//    {
//        grads.row(count) = t_Fwd.sol->data.row(i);
//        ++count;
//        grads.row(count) = t_Fwd.sol->data.row(i+1);
//        ++count;
//    }
//    MatrixXd gradsClustered(204, t_clusteredFwd.sol->data.cols());
//    count = 0;
//    for(qint32 i = 0; i < 306; i += 3)
//    {
//        gradsClustered.row(count) = t_clusteredFwd.sol->data.row(i);
//        ++count;
//        gradsClustered.row(count) = t_clusteredFwd.sol->data.row(i+1);
//        ++count;
//    }

    VectorXd s;

    double t_dConditionNumber = MNEMath::getConditionNumber(t_Fwd.sol->data, s);
    double t_dConditionNumberClustered = MNEMath::getConditionNumber(t_clusteredFwd.sol->data, s);


    std::cout << "Condition Number:\n" << t_dConditionNumber << std::endl;
    std::cout << "Clustered Condition Number:\n" << t_dConditionNumberClustered << std::endl;

    std::cout << "ForwardSolution" << t_Fwd.sol->data.block(0,0,10,10) << std::endl;

    std::cout << "Clustered ForwardSolution" << t_clusteredFwd.sol->data.block(0,0,10,10) << std::endl;


//    double t_dConditionNumberMags = MNEMath::getConditionNumber(mags, s);
//    double t_dConditionNumberMagsClustered = MNEMath::getConditionNumber(magsClustered, s);

//    std::cout << "Condition Number Magnetometers:\n" << t_dConditionNumberMags << std::endl;
//    std::cout << "Clustered Condition Number Magnetometers:\n" << t_dConditionNumberMagsClustered << std::endl;

//    double t_dConditionNumberGrads = MNEMath::getConditionNumber(grads, s);
//    double t_dConditionNumberGradsClustered = MNEMath::getConditionNumber(gradsClustered, s);

//    std::cout << "Condition Number Gradiometers:\n" << t_dConditionNumberGrads << std::endl;
//    std::cout << "Clustered Condition Number Gradiometers:\n" << t_dConditionNumberGradsClustered << std::endl;


    //Source Estimate end
    //########################################################################################

//    //only one time point - P100
//    qint32 sample = 0;
//    for(qint32 i = 0; i < sourceEstimate.times.size(); ++i)
//    {
//        if(sourceEstimate.times(i) >= 0)
//        {
//            sample = i;
//            break;
//        }
//    }
//    sample += (qint32)ceil(0.106/sourceEstimate.tstep); //100ms
//    sourceEstimate = sourceEstimate.reduce(sample, 1);

    QList<Label> t_qListLabels;
    QList<RowVector4i> t_qListRGBAs;

    //ToDo overload toLabels using instead of t_surfSet rr of MNESourceSpace
    t_annotationSet.toLabels(t_surfSet, t_qListLabels, t_qListRGBAs);

    InverseView view(minimumNorm.getSourceSpace(), t_qListLabels, t_qListRGBAs, 24, true, false, true);

    if (view.stereoType() != QGLView::RedCyanAnaglyph)
        view.camera()->setEyeSeparation(0.3f);
    QStringList args = QCoreApplication::arguments();
    int w_pos = args.indexOf("-width");
    int h_pos = args.indexOf("-height");
    if (w_pos >= 0 && h_pos >= 0)
    {
        bool ok = true;
        int w = args.at(w_pos + 1).toInt(&ok);
        if (!ok)
        {
            qWarning() << "Could not parse width argument:" << args;
            return 1;
        }
        int h = args.at(h_pos + 1).toInt(&ok);
        if (!ok)
        {
            qWarning() << "Could not parse height argument:" << args;
            return 1;
        }
        view.resize(w, h);
    }
    else
    {
        view.resize(800, 600);
    }
    view.show();

    //Push Estimate
    view.pushSourceEstimate(sourceEstimate);

    if(!t_sFileNameStc.isEmpty())
    {
        QFile t_fileClusteredStc(t_sFileNameStc);
        sourceEstimate.write(t_fileClusteredStc);
    }

//*/
    return a.exec();//1;//a.exec();
}