<commit_before>//
// ********************************************************************
// * License and Disclaimer                                           *
// *                                                                  *
// * The  Geant4 software  is  copyright of the Copyright Holders  of *
// * the Geant4 Collaboration.  It is provided  under  the terms  and *
// * conditions of the Geant4 Software License,  included in the file *
// * LICENSE and available at  http://cern.ch/geant4/license .  These *
// * include a list of copyright holders.                             *
// *                                                                  *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work  make  any representation or  warranty, express or implied, *
// * regarding  this  software system or assume any liability for its *
// * use.  Please see the license in the file  LICENSE  and URL above *
// * for the full disclaimer and the limitation of liability.         *
// *                                                                  *
// * This  code  implementation is the result of  the  scientific and *
// * technical work of the GEANT4 collaboration.                      *
// * By using,  copying,  modifying or  distributing the software (or *
// * any work based  on the software)  you  agree  to acknowledge its *
// * use  in  resulting  scientific  publications,  and indicate your *
// * acceptance of all terms of the Geant4 Software license.          *
// ********************************************************************
//
//      ----------------------------------------------------------------
//                      K600 Spectrometer (iThemba Labs)
//      ----------------------------------------------------------------
//
//      Github repository: https://www.github.com/KevinCWLi/K600
//
//      Main Author:    K.C.W. Li
//
//      email: likevincw@gmail.com
//

#include "RunAction.hh"
#include "Analysis.hh"

#include "G4Run.hh"
#include "G4RunManager.hh"
#include "G4UnitsTable.hh"
#include "G4SystemOfUnits.hh"

//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......

RunAction::RunAction()
: G4UserRunAction()
{
    // set printing event number per each event
    G4RunManager::GetRunManager()->SetPrintProgress(1);

    // Create analysis manager
    // The choice of analysis technology is done via selectin of a namespace
    // in Analysis.hh
    G4AnalysisManager* analysisManager = G4AnalysisManager::Instance();
    G4cout << "Using " << analysisManager->GetType() << G4endl;

    // Create directories
    //analysisManager->SetHistoDirectoryName("histograms");
    //analysisManager->SetNtupleDirectoryName("ntuple");
    analysisManager->SetVerboseLevel(1);
    //analysisManager->SetFirstHistoId(1);

    // Book histograms, ntuple
    //

    // Creating 1D histograms
    /*
     ////    TIARA DETECTORS, Histograms 1-6
     analysisManager->CreateH1("CvsE_TIARA1","TIARA 1 - Counts versus Energy", 10000, 0., 10000.);
     analysisManager->CreateH1("CvsE_TIARA2","TIARA 2 - Counts versus Energy", 10000, 0., 10000.);
     analysisManager->CreateH1("CvsE_TIARA3","TIARA 3 - Counts versus Energy", 10000, 0., 10000.);
     analysisManager->CreateH1("CvsE_TIARA4","TIARA 4 - Counts versus Energy", 10000, 0., 10000.);
     analysisManager->CreateH1("CvsE_TIARA5","TIARA 5 - Counts versus Energy", 10000, 0., 10000.);
     analysisManager->CreateH1("CvsE_TIARA_EA","Entire TIARA Array - Counts versus Energy", 10000, 0., 10000.);

     ////    PADDLE DETECTORS, Histograms 7-9
     analysisManager->CreateH1("CvsE_PADDLE1","PADDLE 1 - Counts versus Energy", 1000, 0., 100.);
     analysisManager->CreateH1("CvsE_PADDLE2","PADDLE 2 - Counts versus Energy", 1000, 0., 100.);
     analysisManager->CreateH1("CvsE_PADDLE3","PADDLE 3 - Counts versus Energy", 1000, 0., 100.);

     ////    CLOVER DETECTORS, Histograms 10-19
     analysisManager->CreateH1("CvsE_CLOVER1","CLOVER 1 - Counts versus Energy", 3000, 0., 3000.);
     analysisManager->CreateH1("CvsE_CLOVER2","CLOVER 2 - Counts versus Energy", 3000, 0., 3000.);
     analysisManager->CreateH1("CvsE_CLOVER3","CLOVER 3 - Counts versus Energy", 3000, 0., 3000.);
     analysisManager->CreateH1("CvsE_CLOVER4","CLOVER 4 - Counts versus Energy", 3000, 0., 3000.);
     analysisManager->CreateH1("CvsE_CLOVER5","CLOVER 5 - Counts versus Energy", 3000, 0., 3000.);
     analysisManager->CreateH1("CvsE_CLOVER6","CLOVER 6 - Counts versus Energy", 3000, 0., 3000.);
     analysisManager->CreateH1("CvsE_CLOVER7","CLOVER 7 - Counts versus Energy", 3000, 0., 3000.);
     analysisManager->CreateH1("CvsE_CLOVER8","CLOVER 8 - Counts versus Energy", 3000, 0., 3000.);
     analysisManager->CreateH1("CvsE_CLOVER9","CLOVER 9 - Counts versus Energy", 3000, 0., 3000.);
     analysisManager->CreateH1("CvsE_CLOVER_EA","Entire CLOVER Array - Counts versus Energy", 3000, 0., 3000.);

     // Creating 2D histograms

     ////    PADDLE DETECTORS, Histograms 1-6
     analysisManager->CreateH2("PvsE_PADDLE1","PADDLE 1 - Position vs. Energy", 1400, -700., 700., 3, -3*(102/2), 3*(102/2));
     analysisManager->CreateH2("PvsE_PADDLE2","PADDLE 2 - Position vs. Energy", 1400, -700., 700., 3, -3*(102/2), 3*(102/2));
     analysisManager->CreateH2("PvsE_PADDLE3","PADDLE 3 - Position vs. Energy", 1400, -700., 700., 3, -3*(102/2), 3*(102/2));
     analysisManager->CreateH2("EvsTOF_PADDLE1","PADDLE 1 - Energy vs. Time of Flight", 300, 0., 500.*0.3, 40, 0., 40.);
     analysisManager->CreateH2("EvsTOF_PADDLE2","PADDLE 2 - Energy vs. Time of Flight", 300, 0., 500.*0.3, 40, 0., 40.);
     analysisManager->CreateH2("EvsTOF_PADDLE3","PADDLE 3 - Energy vs. Time of Flight", 300, 0., 500.*0.3, 40, 0., 40.);
     */

    ////////////////////////////////////////////////////
    //                  DataTreeSim
    ////////////////////////////////////////////////////

    // Creating ntuple
    analysisManager->CreateNtuple("DataTreeSim", "K600 Spectrometer - Coincident Events");

    /*
    ////    VDC Detectors
    analysisManager->CreateNtupleDColumn(0, "VDC1_Xpos");
    analysisManager->CreateNtupleDColumn(0, "VDC1_Y");
    analysisManager->CreateNtupleDColumn(0, "VDC1_ThetaFP");
    analysisManager->CreateNtupleDColumn(0, "VDC1_ThetaSCAT");

    analysisManager->CreateNtupleDColumn(0, "VDC2_Xpos");
    analysisManager->CreateNtupleDColumn(0, "VDC2_Y");
    analysisManager->CreateNtupleDColumn(0, "VDC2_ThetaFP");
    analysisManager->CreateNtupleDColumn(0, "VDC2_ThetaSCAT");

    ////    "True points of traversal"
    ////    VDC1
    analysisManager->CreateNtupleDColumn(0, "X1_Xpos");
    analysisManager->CreateNtupleDColumn(0, "X1_Ypos");
    analysisManager->CreateNtupleDColumn(0, "U1_Xpos");
    analysisManager->CreateNtupleDColumn(0, "U1_Ypos");
    ////    VDC2
    analysisManager->CreateNtupleDColumn(0, "X2_Xpos");
    analysisManager->CreateNtupleDColumn(0, "X2_Ypos");
    analysisManager->CreateNtupleDColumn(0, "U2_Xpos");
    analysisManager->CreateNtupleDColumn(0, "U2_Ypos");
    */

    ////    TIARA Detectors
    analysisManager->CreateNtupleIColumn(0, "TIARANo");
    analysisManager->CreateNtupleIColumn(0, "TIARA_RowNo");
    analysisManager->CreateNtupleIColumn(0, "TIARA_SectorNo");

    analysisManager->CreateNtupleDColumn(0, "TIARAE");
    analysisManager->CreateNtupleDColumn(0, "Theta");
    analysisManager->CreateNtupleDColumn(0, "Phi");

    //analysisManager->CreateNtupleDColumn("TIARANo[2]");
    //analysisManager->CreateNtupleDColumn("TIARA_RowNo[2]");
    //analysisManager->CreateNtupleDColumn("TIARA_SectorNo[2]");
    //analysisManager->CreateNtupleDColumn(0, "TIARA_t[1]");

    /*
     ////    PADDLE Detectors
     analysisManager->CreateNtupleDColumn(0, "pad1_E");
     analysisManager->CreateNtupleDColumn(0, "pad1_tof");
     analysisManager->CreateNtupleDColumn(0, "pad2_E");
     analysisManager->CreateNtupleDColumn(0, "pad2_tof");

     ////    HAGAR Detector
     analysisManager->CreateNtupleDColumn("HAGAR_E");
     //analysisManager->CreateNtupleDColumn("HAGAR_t");
     */

    analysisManager->FinishNtuple(0);

    ////////////////////////////////////////////////////////////
    //                  GeometryAnalysisTree
    ////////////////////////////////////////////////////////////

    // Creating ntuple
    analysisManager->CreateNtuple("GeometryAnalysisTree", "K600 Spectrometer - GeometryAnalysis");

    ////    TIARA Detectors
    analysisManager->CreateNtupleIColumn(1, "TIARANo");
    analysisManager->CreateNtupleIColumn(1, "TIARA_RowNo");
    analysisManager->CreateNtupleIColumn(1, "TIARA_SectorNo");
    analysisManager->CreateNtupleDColumn(1, "Theta");
    analysisManager->CreateNtupleDColumn(1, "Phi");

    analysisManager->FinishNtuple(1);

    ////////////////////////////////////////////////////////////
    //                  Input Variable Tree
    ////////////////////////////////////////////////////////////

    // Creating ntuple
    analysisManager->CreateNtuple("InputVariableTree", "K600 Spectrometer - InputVariable");

    ////    Initial Particle Angular Distributions
    analysisManager->CreateNtupleDColumn(2, "ThetaDist");
    analysisManager->CreateNtupleDColumn(2, "PhiDist");

    analysisManager->FinishNtuple(2);

}

//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......

RunAction::~RunAction()
{
    delete G4AnalysisManager::Instance();
}

//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......

void RunAction::BeginOfRunAction(const G4Run* /*run*/)
{
    //inform the runManager to save random number seed
    //G4RunManager::GetRunManager()->SetRandomNumberStore(true);

    // Get analysis manager
    G4AnalysisManager* analysisManager = G4AnalysisManager::Instance();

    // Open an output file
    //
    G4String fileName = "K600Output";
    analysisManager->OpenFile(fileName);
}

//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......

void RunAction::EndOfRunAction(const G4Run* /*run*/)
{

    G4AnalysisManager* analysisManager = G4AnalysisManager::Instance();

    /*
     // print histogram statistics
     //
     if( analysisManager->GetH1(1) ){
     G4cout << "\n ----> print histograms statistic ";
     if(isMaster) {
     G4cout << "for the entire run \n" << G4endl;
     }
     else {
     G4cout << "for the local thread \n" << G4endl;
     }

     G4cout << " EAbs : mean = "
     << G4BestUnit(analysisManager->GetH1(1)->mean(), "Energy")
     << " rms = "
     << G4BestUnit(analysisManager->GetH1(1)->rms(),  "Energy") << G4endl;

     G4cout << " EGap : mean = "
     << G4BestUnit(analysisManager->GetH1(2)->mean(), "Energy")
     << " rms = "
     << G4BestUnit(analysisManager->GetH1(2)->rms(),  "Energy") << G4endl;

     G4cout << " LAbs : mean = "
     << G4BestUnit(analysisManager->GetH1(3)->mean(), "Length")
     << " rms = "
     << G4BestUnit(analysisManager->GetH1(3)->rms(),  "Length") << G4endl;

     G4cout << " LGap : mean = "
     << G4BestUnit(analysisManager->GetH1(4)->mean(), "Length")
     << " rms = "
     << G4BestUnit(analysisManager->GetH1(4)->rms(),  "Length") << G4endl;

     }
     */

    // save histograms & ntuple
    //
    analysisManager->Write();
    analysisManager->CloseFile();

}

//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
<commit_msg>Modified Ntuple for the LEPS simulation<commit_after>//
// ********************************************************************
// * License and Disclaimer                                           *
// *                                                                  *
// * The  Geant4 software  is  copyright of the Copyright Holders  of *
// * the Geant4 Collaboration.  It is provided  under  the terms  and *
// * conditions of the Geant4 Software License,  included in the file *
// * LICENSE and available at  http://cern.ch/geant4/license .  These *
// * include a list of copyright holders.                             *
// *                                                                  *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work  make  any representation or  warranty, express or implied, *
// * regarding  this  software system or assume any liability for its *
// * use.  Please see the license in the file  LICENSE  and URL above *
// * for the full disclaimer and the limitation of liability.         *
// *                                                                  *
// * This  code  implementation is the result of  the  scientific and *
// * technical work of the GEANT4 collaboration.                      *
// * By using,  copying,  modifying or  distributing the software (or *
// * any work based  on the software)  you  agree  to acknowledge its *
// * use  in  resulting  scientific  publications,  and indicate your *
// * acceptance of all terms of the Geant4 Software license.          *
// ********************************************************************
//
//      ----------------------------------------------------------------
//                      K600 Spectrometer (iThemba Labs)
//      ----------------------------------------------------------------
//
//      Github repository: https://www.github.com/KevinCWLi/K600
//
//      Main Author:    K.C.W. Li
//
//      email: likevincw@gmail.com
//

#include "RunAction.hh"
#include "Analysis.hh"

#include "G4Run.hh"
#include "G4RunManager.hh"
#include "G4UnitsTable.hh"
#include "G4SystemOfUnits.hh"

//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......

RunAction::RunAction()
: G4UserRunAction()
{
    // set printing event number per each event
    G4RunManager::GetRunManager()->SetPrintProgress(1);

    // Create analysis manager
    // The choice of analysis technology is done via selectin of a namespace
    // in Analysis.hh
    G4AnalysisManager* analysisManager = G4AnalysisManager::Instance();
    G4cout << "Using " << analysisManager->GetType() << G4endl;

    // Create directories
    //analysisManager->SetHistoDirectoryName("histograms");
    //analysisManager->SetNtupleDirectoryName("ntuple");
    analysisManager->SetVerboseLevel(1);
    //analysisManager->SetFirstHistoId(1);

    // Book histograms, ntuple
    //

    // Creating 1D histograms
    /*
     ////    TIARA DETECTORS, Histograms 1-6
     analysisManager->CreateH1("CvsE_TIARA1","TIARA 1 - Counts versus Energy", 10000, 0., 10000.);
     analysisManager->CreateH1("CvsE_TIARA2","TIARA 2 - Counts versus Energy", 10000, 0., 10000.);
     analysisManager->CreateH1("CvsE_TIARA3","TIARA 3 - Counts versus Energy", 10000, 0., 10000.);
     analysisManager->CreateH1("CvsE_TIARA4","TIARA 4 - Counts versus Energy", 10000, 0., 10000.);
     analysisManager->CreateH1("CvsE_TIARA5","TIARA 5 - Counts versus Energy", 10000, 0., 10000.);
     analysisManager->CreateH1("CvsE_TIARA_EA","Entire TIARA Array - Counts versus Energy", 10000, 0., 10000.);

     ////    PADDLE DETECTORS, Histograms 7-9
     analysisManager->CreateH1("CvsE_PADDLE1","PADDLE 1 - Counts versus Energy", 1000, 0., 100.);
     analysisManager->CreateH1("CvsE_PADDLE2","PADDLE 2 - Counts versus Energy", 1000, 0., 100.);
     analysisManager->CreateH1("CvsE_PADDLE3","PADDLE 3 - Counts versus Energy", 1000, 0., 100.);

     ////    CLOVER DETECTORS, Histograms 10-19
     analysisManager->CreateH1("CvsE_CLOVER1","CLOVER 1 - Counts versus Energy", 3000, 0., 3000.);
     analysisManager->CreateH1("CvsE_CLOVER2","CLOVER 2 - Counts versus Energy", 3000, 0., 3000.);
     analysisManager->CreateH1("CvsE_CLOVER3","CLOVER 3 - Counts versus Energy", 3000, 0., 3000.);
     analysisManager->CreateH1("CvsE_CLOVER4","CLOVER 4 - Counts versus Energy", 3000, 0., 3000.);
     analysisManager->CreateH1("CvsE_CLOVER5","CLOVER 5 - Counts versus Energy", 3000, 0., 3000.);
     analysisManager->CreateH1("CvsE_CLOVER6","CLOVER 6 - Counts versus Energy", 3000, 0., 3000.);
     analysisManager->CreateH1("CvsE_CLOVER7","CLOVER 7 - Counts versus Energy", 3000, 0., 3000.);
     analysisManager->CreateH1("CvsE_CLOVER8","CLOVER 8 - Counts versus Energy", 3000, 0., 3000.);
     analysisManager->CreateH1("CvsE_CLOVER9","CLOVER 9 - Counts versus Energy", 3000, 0., 3000.);
     analysisManager->CreateH1("CvsE_CLOVER_EA","Entire CLOVER Array - Counts versus Energy", 3000, 0., 3000.);

     // Creating 2D histograms

     ////    PADDLE DETECTORS, Histograms 1-6
     analysisManager->CreateH2("PvsE_PADDLE1","PADDLE 1 - Position vs. Energy", 1400, -700., 700., 3, -3*(102/2), 3*(102/2));
     analysisManager->CreateH2("PvsE_PADDLE2","PADDLE 2 - Position vs. Energy", 1400, -700., 700., 3, -3*(102/2), 3*(102/2));
     analysisManager->CreateH2("PvsE_PADDLE3","PADDLE 3 - Position vs. Energy", 1400, -700., 700., 3, -3*(102/2), 3*(102/2));
     analysisManager->CreateH2("EvsTOF_PADDLE1","PADDLE 1 - Energy vs. Time of Flight", 300, 0., 500.*0.3, 40, 0., 40.);
     analysisManager->CreateH2("EvsTOF_PADDLE2","PADDLE 2 - Energy vs. Time of Flight", 300, 0., 500.*0.3, 40, 0., 40.);
     analysisManager->CreateH2("EvsTOF_PADDLE3","PADDLE 3 - Energy vs. Time of Flight", 300, 0., 500.*0.3, 40, 0., 40.);
     */

    ////////////////////////////////////////////////////
    //                  DataTreeSim
    ////////////////////////////////////////////////////

    // Creating ntuple
    analysisManager->CreateNtuple("DataTreeSim", "K600 Spectrometer - Coincident Events");

    /*
    ////    VDC Detectors
    analysisManager->CreateNtupleDColumn(0, "VDC1_Xpos");
    analysisManager->CreateNtupleDColumn(0, "VDC1_Y");
    analysisManager->CreateNtupleDColumn(0, "VDC1_ThetaFP");
    analysisManager->CreateNtupleDColumn(0, "VDC1_ThetaSCAT");

    analysisManager->CreateNtupleDColumn(0, "VDC2_Xpos");
    analysisManager->CreateNtupleDColumn(0, "VDC2_Y");
    analysisManager->CreateNtupleDColumn(0, "VDC2_ThetaFP");
    analysisManager->CreateNtupleDColumn(0, "VDC2_ThetaSCAT");

    ////    "True points of traversal"
    ////    VDC1
    analysisManager->CreateNtupleDColumn(0, "X1_Xpos");
    analysisManager->CreateNtupleDColumn(0, "X1_Ypos");
    analysisManager->CreateNtupleDColumn(0, "U1_Xpos");
    analysisManager->CreateNtupleDColumn(0, "U1_Ypos");
    ////    VDC2
    analysisManager->CreateNtupleDColumn(0, "X2_Xpos");
    analysisManager->CreateNtupleDColumn(0, "X2_Ypos");
    analysisManager->CreateNtupleDColumn(0, "U2_Xpos");
    analysisManager->CreateNtupleDColumn(0, "U2_Ypos");
    */

    ////    LEPS Detectors
    analysisManager->CreateNtupleIColumn("LEPS1_trig");
    analysisManager->CreateNtupleIColumn("LEPS2_trig");

    /*
    analysisManager->CreateNtupleIColumn(0, "LEPS3_trig");
    analysisManager->CreateNtupleIColumn(0, "LEPS4_trig");
    analysisManager->CreateNtupleIColumn(0, "LEPS5_trig");
    analysisManager->CreateNtupleIColumn(0, "LEPS6_trig");
    */

    /*
    analysisManager->CreateNtupleIColumn(0, "LEPS1_CrystalNo");
    analysisManager->CreateNtupleIColumn(0, "LEPS2_CrystalNo");
    analysisManager->CreateNtupleIColumn(0, "LEPS3_CrystalNo");
    analysisManager->CreateNtupleIColumn(0, "LEPS4_CrystalNo");
    analysisManager->CreateNtupleIColumn(0, "LEPS5_CrystalNo");
    analysisManager->CreateNtupleIColumn(0, "LEPS6_CrystalNo");
    */

    analysisManager->CreateNtupleDColumn("LEPS1_Energy");
    analysisManager->CreateNtupleDColumn("LEPS2_Energy");
    //analysisManager->CreateNtupleDColumn(0, "LEPS3_Energy");

    /*
    analysisManager->CreateNtupleDColumn(0, "LEPS3_Energy");
    analysisManager->CreateNtupleDColumn(0, "LEPS4_Energy");
    analysisManager->CreateNtupleDColumn(0, "LEPS5_Energy");
    analysisManager->CreateNtupleDColumn(0, "LEPS6_Energy");
    */

    ////    TIARA Detectors
    //analysisManager->CreateNtupleIColumn(0, "TIARANo");
    //analysisManager->CreateNtupleIColumn(0, "TIARA_RowNo");
    //analysisManager->CreateNtupleIColumn(0, "TIARA_SectorNo");

    //analysisManager->CreateNtupleDColumn(0, "TIARAE");
    //analysisManager->CreateNtupleDColumn(0, "Theta");
    //analysisManager->CreateNtupleDColumn(0, "Phi");

    //analysisManager->CreateNtupleDColumn("TIARANo[2]");
    //analysisManager->CreateNtupleDColumn("TIARA_RowNo[2]");
    //analysisManager->CreateNtupleDColumn("TIARA_SectorNo[2]");
    //analysisManager->CreateNtupleDColumn(0, "TIARA_t[1]");

    /*
     ////    PADDLE Detectors
     analysisManager->CreateNtupleDColumn(0, "pad1_E");
     analysisManager->CreateNtupleDColumn(0, "pad1_tof");
     analysisManager->CreateNtupleDColumn(0, "pad2_E");
     analysisManager->CreateNtupleDColumn(0, "pad2_tof");

     ////    HAGAR Detector
     analysisManager->CreateNtupleDColumn("HAGAR_E");
     //analysisManager->CreateNtupleDColumn("HAGAR_t");
     */

    analysisManager->FinishNtuple(0);

    ////////////////////////////////////////////////////////////
    //                  GeometryAnalysisTree
    ////////////////////////////////////////////////////////////

    // Creating ntuple

    analysisManager->CreateNtuple("GeometryAnalysisTree", "K600 Spectrometer - GeometryAnalysis");

    ////    TIARA Detectors
    analysisManager->CreateNtupleIColumn(1, "TIARANo");
    analysisManager->CreateNtupleIColumn(1, "TIARA_RowNo");
    analysisManager->CreateNtupleIColumn(1, "TIARA_SectorNo");
    analysisManager->CreateNtupleDColumn(1, "Theta");
    analysisManager->CreateNtupleDColumn(1, "Phi");

    analysisManager->FinishNtuple(1);

    ////////////////////////////////////////////////////////////
    //                  Input Variable Tree
    ////////////////////////////////////////////////////////////

    // Creating ntuple
    analysisManager->CreateNtuple("InputVariableTree", "K600 Spectrometer - InputVariable");

    ////    Initial Particle Angular Distributions
    analysisManager->CreateNtupleDColumn(2, "ThetaDist");
    analysisManager->CreateNtupleDColumn(2, "PhiDist");

    analysisManager->FinishNtuple(2);

}

//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......

RunAction::~RunAction()
{
    delete G4AnalysisManager::Instance();
}

//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......

void RunAction::BeginOfRunAction(const G4Run* /*run*/)
{
    //inform the runManager to save random number seed
    //G4RunManager::GetRunManager()->SetRandomNumberStore(true);

    // Get analysis manager
    G4AnalysisManager* analysisManager = G4AnalysisManager::Instance();

    // Open an output file
    //
    G4String fileName = "K600Output";
    analysisManager->OpenFile(fileName);
}

//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......

void RunAction::EndOfRunAction(const G4Run* /*run*/)
{

    G4AnalysisManager* analysisManager = G4AnalysisManager::Instance();

    /*
     // print histogram statistics
     //
     if( analysisManager->GetH1(1) ){
     G4cout << "\n ----> print histograms statistic ";
     if(isMaster) {
     G4cout << "for the entire run \n" << G4endl;
     }
     else {
     G4cout << "for the local thread \n" << G4endl;
     }

     G4cout << " EAbs : mean = "
     << G4BestUnit(analysisManager->GetH1(1)->mean(), "Energy")
     << " rms = "
     << G4BestUnit(analysisManager->GetH1(1)->rms(),  "Energy") << G4endl;

     G4cout << " EGap : mean = "
     << G4BestUnit(analysisManager->GetH1(2)->mean(), "Energy")
     << " rms = "
     << G4BestUnit(analysisManager->GetH1(2)->rms(),  "Energy") << G4endl;

     G4cout << " LAbs : mean = "
     << G4BestUnit(analysisManager->GetH1(3)->mean(), "Length")
     << " rms = "
     << G4BestUnit(analysisManager->GetH1(3)->rms(),  "Length") << G4endl;

     G4cout << " LGap : mean = "
     << G4BestUnit(analysisManager->GetH1(4)->mean(), "Length")
     << " rms = "
     << G4BestUnit(analysisManager->GetH1(4)->rms(),  "Length") << G4endl;

     }
     */

    // save histograms & ntuple
    //
    analysisManager->Write();
    analysisManager->CloseFile();

}

//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
<|endoftext|>


<commit_before>#include "SVGImage.h"

#define NANOSVG_IMPLEMENTATION
#include <nanosvg.h>

SVGImage::SVGImage() : _nanoSvgImage(nullptr) {
}

SVGImage::SVGImage(const boost::filesystem::path &path) : SVGImage() {
    open(path);
}

SVGImage::~SVGImage() {
    if (_nanoSvgImage) {
	::nsvgDelete(_nanoSvgImage);
    }
    _nanoSvgImage = nullptr;
}

bool SVGImage::open(const boost::filesystem::path &path) {
    _nanoSvgImage = ::nsvgParseFromFile(path.string().c_str(), "", 72.f);
    return (_nanoSvgImage->width > 0.0f && _nanoSvgImage->height > 0.0 && _nanoSvgImage->shapes);
}

void SVGImage::draw() {
}
<commit_msg>Add some headers so we can use NanoVG to render NanoSVG.<commit_after>#include "SVGImage.h"

#define NANOSVG_IMPLEMENTATION
#include <nanosvg.h>
#include <nanovg.h>
// XXX This is bad, but easy.
#define NANOVG_GL_IMPLEMENTATION
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include <GLES2/gl2platform.h>
#include <nanovg_gl.h>
#include <nanovg.c>

SVGImage::SVGImage() : _nanoSvgImage(nullptr) {
}

SVGImage::SVGImage(const boost::filesystem::path &path) : SVGImage() {
    open(path);
}

SVGImage::~SVGImage() {
    if (_nanoSvgImage) {
	::nsvgDelete(_nanoSvgImage);
    }
    _nanoSvgImage = nullptr;
}

bool SVGImage::open(const boost::filesystem::path &path) {
    _nanoSvgImage = ::nsvgParseFromFile(path.string().c_str(), "", 72.f);
    return (_nanoSvgImage->width > 0.0f && _nanoSvgImage->height > 0.0 && _nanoSvgImage->shapes);
}

void SVGImage::draw() {
}
<|endoftext|>


<commit_before>#include "Star2DControl.h"
#include "Engine.h"

using namespace MathLib;

CStar2DControl::CStar2DControl(void)
{
	m_pNormalTex = NULL;
	m_pClickTex = NULL;
	m_nEnabled = 1;
	m_nClickState = 0;
	m_fClickScale = 1.0f;
	m_vNormalColor = vec4_one;
	m_vClickColor = vec4_one;
	m_fNormalTexScale = 0.1f;
	m_fClickTexScale = 0.1f;
	Init();
}

CStar2DControl::~CStar2DControl(void)
{
	g_Engine.pGui->ReleaseTexture(m_pNormalTex);
	g_Engine.pGui->ReleaseTexture(m_pClickTex);
}

int CStar2DControl::Init()
{
	return Load(NORMAL_NAME, CLICK_NAME);
}
void CStar2DControl::Update()
{
	if (!IsEnable())
	{
		return;
	}
	m_fClickScale += m_nClickState * g_Engine.pGame->GetIFps() * 5.5f;
	if (m_fClickScale <= 0.8f)
	{
		m_nClickState = 1;
	}
	else if (m_fClickScale >= 1.0f)
	{
		m_fClickScale = 1.0f;
		m_nClickState = 0;
	}

	if (m_pNormalTex && m_pNormalTex->GetTexture())
	{
		CTexture *tex = m_pNormalTex->GetTexture();
		float width = CMathCore::Itof(tex->GetWidth());
		float height = CMathCore::Itof(tex->GetHeight());

		if (m_fNormalTexScale != 0.0f)
		{
			float aspect = height / width;
			width = g_Engine.pGui->GetWidth() * m_fNormalTexScale;
			height = width * aspect;
		}

		float CenterX = g_Engine.pGui->GetWidth() / 2.0f;
		float CenterY = g_Engine.pGui->GetHeight() / 2.0f;
		float x0 = CenterX - width / 2.0f;
		float y0 = CenterY - height / 2.0f;
		float x1 = CenterX + width / 2.0f;
		float y1 = CenterY + height / 2.0f;
		g_Engine.pGui->RenderTexture(tex, vec4(x0, y0, x1, y1), m_vNormalColor);
	}

}

<commit_msg>if (m_pClickTex && m_pClickTex->GetTexture())<commit_after>#include "Star2DControl.h"
#include "Engine.h"

using namespace MathLib;

CStar2DControl::CStar2DControl(void)
{
	m_pNormalTex = NULL;
	m_pClickTex = NULL;
	m_nEnabled = 1;
	m_nClickState = 0;
	m_fClickScale = 1.0f;
	m_vNormalColor = vec4_one;
	m_vClickColor = vec4_one;
	m_fNormalTexScale = 0.1f;
	m_fClickTexScale = 0.1f;
	Init();
}

CStar2DControl::~CStar2DControl(void)
{
	g_Engine.pGui->ReleaseTexture(m_pNormalTex);
	g_Engine.pGui->ReleaseTexture(m_pClickTex);
}

int CStar2DControl::Init()
{
	return Load(NORMAL_NAME, CLICK_NAME);
}
void CStar2DControl::Update()
{
	if (!IsEnable())
	{
		return;
	}
	m_fClickScale += m_nClickState * g_Engine.pGame->GetIFps() * 5.5f;
	if (m_fClickScale <= 0.8f)
	{
		m_nClickState = 1;
	}
	else if (m_fClickScale >= 1.0f)
	{
		m_fClickScale = 1.0f;
		m_nClickState = 0;
	}

	if (m_pNormalTex && m_pNormalTex->GetTexture())
	{
		CTexture *tex = m_pNormalTex->GetTexture();
		float width = CMathCore::Itof(tex->GetWidth());
		float height = CMathCore::Itof(tex->GetHeight());

		if (m_fNormalTexScale != 0.0f)
		{
			float aspect = height / width;
			width = g_Engine.pGui->GetWidth() * m_fNormalTexScale;
			height = width * aspect;
		}

		float CenterX = g_Engine.pGui->GetWidth() / 2.0f;
		float CenterY = g_Engine.pGui->GetHeight() / 2.0f;
		float x0 = CenterX - width / 2.0f;
		float y0 = CenterY - height / 2.0f;
		float x1 = CenterX + width / 2.0f;
		float y1 = CenterY + height / 2.0f;
		g_Engine.pGui->RenderTexture(tex, vec4(x0, y0, x1, y1), m_vNormalColor);
	}
	if (m_pClickTex && m_pClickTex->GetTexture())
	{
		CTexture *tex = m_pClickTex->GetTexture();
		float width = CMathCore::Itof(tex->GetWidth());
		float height = CMathCore::Itof(tex->GetHeight());

		if (m_fClickTexScale != 0.0f)
		{
			float aspect = height / width;
			width = g_Engine.pGui->GetWidth() * m_fClickTexScale;
			height = width * aspect;
		}

		width *= m_fClickScale;
		height *= m_fClickScale;

		float CenterX = g_Engine.pGui->GetWidth() / 2.0f;
		float CenterY = g_Engine.pGui->GetHeight() / 2.0f;
		float x0 = CenterX - width / 2.0f;
		float y0 = CenterY - height / 2.0f;
		float x1 = CenterX + width / 2.0f;
		float y1 = CenterY + height / 2.0f;
		g_Engine.pGui->RenderTexture(tex, vec4(x0, y0, x1, y1), m_vClickColor);
	}

}

<|endoftext|>


<commit_before>#include <gtest/gtest.h>
#include "utStruct.h"

//int main( int argc , char **argv )
int main( int argc , char **argv )
{
    testing :: InitGoogleTest( &argc , argv ) ;
    return RUN_ALL_TESTS( ) ;
}
<commit_msg>Delete mainStruct.cpp<commit_after><|endoftext|>


<commit_before>#ifndef REFLEXION_STRUCT2_HPP
#define REFLEXION_STRUCT2_HPP

#include <boost/preprocessor/seq/for_each.hpp>
#include <boost/preprocessor/seq/for_each_i.hpp>
#include <boost/preprocessor/variadic/to_seq.hpp>
#include <boost/preprocessor/cat.hpp>

#define RXN_GENERATE_FIELDS(r, fields, generator) generator(fields)

#define RXN_REFLECT(generators, ...) \
	BOOST_PP_SEQ_FOR_EACH(RXN_GENERATE_FIELDS, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__), generators)

#define RXN_IDENTITY(...) __VA_ARGS__

#define RXN_HEAD(head, ...) head
#define RXN_TAIL(head, ...) __VA_ARGS__

#define RXN_IGNORE(...)

#define RXN_REMOVE_PARENS(...) RXN_IDENTITY __VA_ARGS__

#define ADD_PAREN_1(...) ((__VA_ARGS__)) ADD_PAREN_2
#define ADD_PAREN_2(...) ((__VA_ARGS__)) ADD_PAREN_1
#define ADD_PAREN_1_END
#define ADD_PAREN_2_END
#define OUTPUT BOOST_PP_CAT(ADD_PAREN_1 INPUT,_END)

#define RXN_NORMALIZE_FIELD(field) BOOST_PP_CAT(ADD_PAREN_1 field, _END)

#define RXN_GENERATE_FIELD_3(generator, name_type_tuple, annotations_3) \
	generator( \
		BOOST_PP_TUPLE_ELEM(2, 0, name_type_tuple), \
		(RXN_TAIL name_type_tuple), \
		annotations_3 \
		)

#define RXN_GENERATE_FIELD_2(generator, normalized_field) \
	RXN_GENERATE_FIELD_3( \
		generator, \
		BOOST_PP_SEQ_HEAD(normalized_field), \
		BOOST_PP_SEQ_TAIL(normalized_field))

#define RXN_GENERATE_FIELD(r, generator, i, field) \
	RXN_GENERATE_FIELD_2(generator, RXN_NORMALIZE_FIELD(field))

#define RXN_MEMBER(name, type, annotations) RXN_IDENTITY type name;
#define RXN_MEMBERS(fields) BOOST_PP_SEQ_FOR_EACH_I(RXN_GENERATE_FIELD, RXN_MEMBER, fields)

#define RXN_VISIT(name, type, annotations) \
	visitor.template accept<RXN_REMOVE_PARENS(BOOST_PP_SEQ_ELEM(0, annotations))> \
						   (this->name);

#define RXN_ITERATE(fields) \
	template <class Visitor> \
	void iterate(Visitor &visitor) { \
		BOOST_PP_SEQ_FOR_EACH_I(RXN_GENERATE_FIELD, RXN_VISIT, fields) \
	} \
	template <class Visitor> \
	void iterate(Visitor &visitor) const { \
		BOOST_PP_SEQ_FOR_EACH_I(RXN_GENERATE_FIELD, RXN_VISIT, fields) \
	}

#endif
<commit_msg>clean macros up<commit_after>#ifndef REFLEXION_STRUCT2_HPP
#define REFLEXION_STRUCT2_HPP

#include <boost/preprocessor/seq/for_each.hpp>
#include <boost/preprocessor/seq/for_each_i.hpp>
#include <boost/preprocessor/variadic/to_seq.hpp>
#include <boost/preprocessor/cat.hpp>

#define RXN_GENERATE_FIELDS(r, fields, generator) generator(fields)

#define RXN_REFLECT(generators, ...) \
	BOOST_PP_SEQ_FOR_EACH(RXN_GENERATE_FIELDS, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__), generators)

#define RXN_IDENTITY(...) __VA_ARGS__

#define RXN_HEAD(head, ...) head
#define RXN_TAIL(head, ...) __VA_ARGS__

#define RXN_IGNORE(...)

#define RXN_REMOVE_PAREN(...) RXN_IDENTITY __VA_ARGS__

#define RXN_ADD_PAREN_1(...) ((__VA_ARGS__)) RXN_ADD_PAREN_2
#define RXN_ADD_PAREN_2(...) ((__VA_ARGS__)) RXN_ADD_PAREN_1
#define RXN_ADD_PAREN_1_END
#define RXN_ADD_PAREN_2_END

#define RXN_NORMALIZE_FIELD(field) BOOST_PP_CAT(RXN_ADD_PAREN_1 field, _END)

#define RXN_GENERATE_FIELD_3(generator, name_type_tuple, annotations) \
	generator( \
		BOOST_PP_TUPLE_ELEM(2, 0, name_type_tuple), \
		(RXN_TAIL name_type_tuple), \
		annotations \
		)

#define RXN_GENERATE_FIELD_2(generator, normalized_field) \
	RXN_GENERATE_FIELD_3( \
		generator, \
		BOOST_PP_SEQ_HEAD(normalized_field), \
		BOOST_PP_SEQ_TAIL(normalized_field))

#define RXN_GENERATE_FIELD(r, generator, i, field) \
	RXN_GENERATE_FIELD_2(generator, RXN_NORMALIZE_FIELD(field))

#define RXN_MEMBER(name, type, annotations) RXN_IDENTITY type name;
#define RXN_MEMBERS(fields) BOOST_PP_SEQ_FOR_EACH_I(RXN_GENERATE_FIELD, RXN_MEMBER, fields)

#define RXN_VISIT(name, type, annotations) \
	visitor.template accept<RXN_REMOVE_PAREN(BOOST_PP_SEQ_ELEM(0, annotations))> \
						   (this->name);

#define RXN_ITERATE(fields) \
	template <class Visitor> \
	void iterate(Visitor &visitor) { \
		BOOST_PP_SEQ_FOR_EACH_I(RXN_GENERATE_FIELD, RXN_VISIT, fields) \
	} \
	template <class Visitor> \
	void iterate(Visitor &visitor) const { \
		BOOST_PP_SEQ_FOR_EACH_I(RXN_GENERATE_FIELD, RXN_VISIT, fields) \
	}

#endif
<|endoftext|>


<commit_before>/*
  Copyright 2014 Sarah Wong

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
*/

#include "mainwindow.h"
#include "about.h"

#include <QPainter>

#include "config.h"

ViewerWidget::ViewerWidget(QWidget* parent)
    : QGLWidget(parent),
      m_timer(new QTimer(this)),
      m_parent(dynamic_cast<MainWindow*>(parent)),
      m_update_pending(false)
{
  QObject::connect(m_timer, SIGNAL(timeout()), this, SLOT(renderLater()));
  m_timer->setTimerType(Qt::PreciseTimer);
  m_timer->start(1000 / 120);
}

void ViewerWidget::renderLater() {
    if (!m_update_pending) {
        m_update_pending = true;
        QCoreApplication::postEvent(this, new QEvent(QEvent::UpdateRequest));
    }
}

void ViewerWidget::renderNow() {
  QPainter painter(this);

  painter.fillRect(rect(), Qt::black);

  const QPen penWhite(QColor(255, 255, 255));
  const QBrush brushWhite(QColor(255, 255, 255));

  const auto& uiConfig = m_parent->config().uiConfig;

  int m_width = uiConfig.width;
  int m_height = uiConfig.height;

  std::lock_guard<std::mutex> lockGuard(m_parent->mutex());

  auto noteToPos = [this, uiConfig, m_height](double note) {
    return m_height -
           (note - uiConfig.min_note) *
               (static_cast<double>(m_height) /
                (uiConfig.max_note - uiConfig.min_note));
  };

  const double noteWidth = uiConfig.note_width;

  double position = 0;
  for (auto f0 : m_parent->cb()) {
    if (f0 != 0) {

      double ypos = noteToPos(f0);

      painter.setPen(penWhite);
      painter.setBrush(brushWhite);

      painter.drawRect(position, ypos - 1, noteWidth, noteWidth);
    }

    position += noteWidth;
  }

  for (const auto& line : m_parent->config().uiMarkerLines.lines) {
    double ypos = noteToPos(line.frequency);
    painter.setPen(line.pen);
    painter.drawLine(0, ypos, m_width, ypos);
  }
}

bool ViewerWidget::event(QEvent* event)
{
  switch (event->type()) {
  case QEvent::UpdateRequest:
    m_update_pending = false;
    renderNow();
    return true;
  default:
    return QGLWidget::event(event);
  }
}

void ViewerWidget::paintEvent(QPaintEvent* event) {
  renderNow();
}

MainWindow::MainWindow(const config::Config& config)
    : m_cb(config.uiConfig.width / config.uiConfig.note_width), m_config(config)
{
  m_ui.setupUi(this);

  ViewerWidget* vw = new ViewerWidget(this);

  setCentralWidget(vw);
}

void MainWindow::on_action_About_triggered()
{
  About* about = new About(this);
  about->show();
}
<commit_msg>fix code to follow coding style<commit_after>/*
  Copyright 2014 Sarah Wong

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
*/

#include "mainwindow.h"
#include "about.h"

#include <QPainter>

#include "config.h"

ViewerWidget::ViewerWidget(QWidget* parent)
    : QGLWidget(parent),
      m_timer(new QTimer(this)),
      m_parent(dynamic_cast<MainWindow*>(parent)),
      m_update_pending(false)
{
  QObject::connect(m_timer, SIGNAL(timeout()), this, SLOT(renderLater()));
  m_timer->setTimerType(Qt::PreciseTimer);
  m_timer->start(1000 / 120);
}

void ViewerWidget::renderLater() {
    if (!m_update_pending) {
        m_update_pending = true;
        QCoreApplication::postEvent(this, new QEvent(QEvent::UpdateRequest));
    }
}

void ViewerWidget::renderNow() {
  QPainter painter(this);

  painter.fillRect(rect(), Qt::black);

  const QPen penWhite(QColor(255, 255, 255));
  const QBrush brushWhite(QColor(255, 255, 255));

  const auto& uiConfig = m_parent->config().uiConfig;

  int width = uiConfig.width;
  int height = uiConfig.height;

  std::lock_guard<std::mutex> lockGuard(m_parent->mutex());

  auto noteToPos = [this, uiConfig, height](double note) {
    return height -
           (note - uiConfig.min_note) *
               (static_cast<double>(height) /
                (uiConfig.max_note - uiConfig.min_note));
  };

  const double noteWidth = uiConfig.note_width;

  double position = 0;
  for (auto f0 : m_parent->cb()) {
    if (f0 != 0) {

      double ypos = noteToPos(f0);

      painter.setPen(penWhite);
      painter.setBrush(brushWhite);

      painter.drawRect(position, ypos - 1, noteWidth, noteWidth);
    }

    position += noteWidth;
  }

  for (const auto& line : m_parent->config().uiMarkerLines.lines) {
    double ypos = noteToPos(line.frequency);
    painter.setPen(line.pen);
    painter.drawLine(0, ypos, width, ypos);
  }
}

bool ViewerWidget::event(QEvent* event)
{
  switch (event->type()) {
  case QEvent::UpdateRequest:
    m_update_pending = false;
    renderNow();
    return true;
  default:
    return QGLWidget::event(event);
  }
}

void ViewerWidget::paintEvent(QPaintEvent* event) {
  renderNow();
}

MainWindow::MainWindow(const config::Config& config)
    : m_cb(config.uiConfig.width / config.uiConfig.note_width), m_config(config)
{
  m_ui.setupUi(this);

  ViewerWidget* vw = new ViewerWidget(this);

  setCentralWidget(vw);
}

void MainWindow::on_action_About_triggered()
{
  About* about = new About(this);
  about->show();
}
<|endoftext|>


<commit_before>/*++
Copyright (c) 2014 Microsoft Corporation

Module Name:

    sat_mus.cpp

Abstract:

    Faster MUS extraction based on Belov et.al. HYB (Algorithm 3, 4)

Author:

    Nikolaj Bjorner (nbjorner) 2014-20-7

Notes:

--*/

#include "sat_solver.h"
#include "sat_mus.h"
#include "sat_sls.h"

namespace sat {

    mus::mus(solver& s):s(s), m_is_active(false) {}

    mus::~mus() {}

    void mus::reset() {
        m_core.reset();
        m_mus.reset();
    }

    void mus::set_core() {
        m_core.append(m_mus);
        s.m_core.reset();
        s.m_core.append(m_core);
    }

    lbool mus::operator()() {
        flet<bool> _disable_min(s.m_config.m_minimize_core, false);
        flet<bool> _disable_opt(s.m_config.m_optimize_model, false);
        flet<bool> _is_active(m_is_active, true);
        TRACE("sat", tout << "old core: " << s.get_core() << "\n";);
        IF_VERBOSE(2, verbose_stream() << "(sat.mus " << s.get_core() << ")\n";);
        reset();
        literal_vector& core = m_core;
        literal_vector& mus = m_mus;
        core.append(s.get_core());
        for (unsigned i = 0; i < core.size(); ++i) {
            s.m_user_scope_literals.contains(core[i]);
            mus.push_back(core[i]);
            core[i] = core.back();
            core.pop_back();
            --i;
        }

        while (!core.empty()) {
            TRACE("sat",
                  tout << "core: " << core << "\n";
                  tout << "mus:  " << mus  << "\n";);

            if (s.m_cancel) {
                set_core();
                return l_undef;
            }
            literal lit = core.back();
            core.pop_back();
            unsigned sz = mus.size();
            // mus.push_back(~lit); // TBD: measure
            mus.append(core);
            lbool is_sat = s.check(mus.size(), mus.c_ptr());
            TRACE("sat", tout << "mus: " << mus << "\n";);
            mus.resize(sz);
            switch (is_sat) {
            case l_undef:
                core.push_back(lit);
                set_core();
                return l_undef;
            case l_true: {
                SASSERT(value_at(lit, s.get_model()) == l_false);
                mus.push_back(lit);
                if (!core.empty()) {
                    // mr(); // TBD: measure
                }
                break;
            }
            case l_false:
                literal_vector const& new_core = s.get_core();
                if (new_core.contains(~lit)) {
                    break;
                }
                TRACE("sat", tout << "new core: " << new_core << "\n";);
                core.reset();
                for (unsigned i = 0; i < new_core.size(); ++i) {
                    literal lit = new_core[i];
                    if (!mus.contains(lit)) {
                        core.push_back(lit);
                    }
                }
                break;
            }
        }
        TRACE("sat", tout << "new core: " << mus << "\n";);
        set_core();
        IF_VERBOSE(2, verbose_stream() << "(sat.mus.new " << core << ")\n";);
        return l_true;
    }

    void mus::mr() {
        sls sls(s);
        literal_vector tabu;
        tabu.append(m_mus);
        tabu.append(m_core);
        bool reuse_model = false;
        for (unsigned i = m_mus.size(); i < tabu.size(); ++i) {
            tabu[i] = ~tabu[i];
            lbool is_sat = sls(tabu.size(), tabu.c_ptr(), reuse_model);
            tabu[i] = ~tabu[i];
            if (is_sat == l_true) {
                m_mus.push_back(tabu[i]);
                m_core.erase(tabu[i]);
                IF_VERBOSE(2, verbose_stream() << "in core " << tabu[i] << "\n";);
                reuse_model = true;
            }
            else {
                IF_VERBOSE(2, verbose_stream() << "NOT in core " << tabu[i] << "\n";);
                reuse_model = false;
            }
        }
    }
}

<commit_msg>fix bug in unsat core finding<commit_after>/*++
Copyright (c) 2014 Microsoft Corporation

Module Name:

    sat_mus.cpp

Abstract:

    Faster MUS extraction based on Belov et.al. HYB (Algorithm 3, 4)

Author:

    Nikolaj Bjorner (nbjorner) 2014-20-7

Notes:

--*/

#include "sat_solver.h"
#include "sat_mus.h"
#include "sat_sls.h"

namespace sat {

    mus::mus(solver& s):s(s), m_is_active(false) {}

    mus::~mus() {}

    void mus::reset() {
        m_core.reset();
        m_mus.reset();
    }

    void mus::set_core() {
        m_core.append(m_mus);
        s.m_core.reset();
        s.m_core.append(m_core);
    }

    lbool mus::operator()() {
        flet<bool> _disable_min(s.m_config.m_minimize_core, false);
        flet<bool> _disable_opt(s.m_config.m_optimize_model, false);
        flet<bool> _is_active(m_is_active, true);
        TRACE("sat", tout << "old core: " << s.get_core() << "\n";);
        IF_VERBOSE(2, verbose_stream() << "(sat.mus " << s.get_core() << ")\n";);
        reset();
        literal_vector& core = m_core;
        literal_vector& mus = m_mus;
        core.append(s.get_core());
        for (unsigned i = 0; i < core.size(); ++i) {
            if (s.m_user_scope_literals.contains(core[i])) {
                mus.push_back(core[i]);
                core[i] = core.back();
                core.pop_back();
                --i;
            }
        }

        while (!core.empty()) {
            IF_VERBOSE(2, verbose_stream() << "(opt.mus reducing core: " << core.size() << " new core: " << mus.size() << ")\n";);
            TRACE("sat",
                  tout << "core: " << core << "\n";
                  tout << "mus:  " << mus  << "\n";);

            if (s.m_cancel) {
                set_core();
                return l_undef;
            }
            literal lit = core.back();
            core.pop_back();
            unsigned sz = mus.size();
            // mus.push_back(~lit); // TBD: measure
            mus.append(core);
            lbool is_sat = s.check(mus.size(), mus.c_ptr());
            TRACE("sat", tout << "mus: " << mus << "\n";);
            mus.resize(sz);
            switch (is_sat) {
            case l_undef:
                core.push_back(lit);
                set_core();
                return l_undef;
            case l_true: {
                SASSERT(value_at(lit, s.get_model()) == l_false);
                mus.push_back(lit);
                if (!core.empty()) {
                    // mr(); // TBD: measure
                }
                break;
            }
            case l_false:
                literal_vector const& new_core = s.get_core();
                if (new_core.contains(~lit)) {
                    break;
                }
                TRACE("sat", tout << "new core: " << new_core << "\n";);
                core.reset();
                for (unsigned i = 0; i < new_core.size(); ++i) {
                    literal lit = new_core[i];
                    if (!mus.contains(lit)) {
                        core.push_back(lit);
                    }
                }
                break;
            }
        }
        TRACE("sat", tout << "new core: " << mus << "\n";);
        set_core();
        IF_VERBOSE(2, verbose_stream() << "(sat.mus.new " << core << ")\n";);
        return l_true;
    }

    void mus::mr() {
        sls sls(s);
        literal_vector tabu;
        tabu.append(m_mus);
        tabu.append(m_core);
        bool reuse_model = false;
        for (unsigned i = m_mus.size(); i < tabu.size(); ++i) {
            tabu[i] = ~tabu[i];
            lbool is_sat = sls(tabu.size(), tabu.c_ptr(), reuse_model);
            tabu[i] = ~tabu[i];
            if (is_sat == l_true) {
                m_mus.push_back(tabu[i]);
                m_core.erase(tabu[i]);
                IF_VERBOSE(2, verbose_stream() << "in core " << tabu[i] << "\n";);
                reuse_model = true;
            }
            else {
                IF_VERBOSE(2, verbose_stream() << "NOT in core " << tabu[i] << "\n";);
                reuse_model = false;
            }
        }
    }
}

<|endoftext|>


<commit_before>
/*
*/
#include "defines.h"
#include "Classes/UltraDock/dcxDock.h"
#include "Dcx.h"

// [SWITCH] [OPTIONS]
mIRC(xstatusbar) {
	TString input(data);
	input.trim();
	data[0] = 0;

	const UINT numtok = input.numtok( );

	if (numtok < 1) {
		Dcx::error(TEXT("/xstatusbar"),TEXT("Invalid Parameters"));
		return 0;
	}
	const TString switches(input.getfirsttok(1));	// tok 1

	switch (switches[1]) {
		case TEXT('A'): // -A [0|1] (options)=notheme grip tooltips nodivider utf8
			{
				// check syntax
				if (numtok < 2) {
					Dcx::error(TEXT("/xstatusbar -A"),TEXT("Invalid Parameters"));
					return 0;
				}
				// Enable/Disable the Statusbar.
				// -A [0|1] [options] = notheme grip tooltips nodivider utf8
				if (input.getnexttok( ).to_int() > 0)					// tok 2
				{
					if (!DcxDock::InitStatusbar(input.getlasttoks()))	// tok 3, -1
					{
						Dcx::error(TEXT("/xstatusbar -A"),TEXT("Unable to Create Statusbar"));
						return 0;
					}
				}
				else
					DcxDock::UnInitStatusbar();

				UpdatemIRC();
			}
			break;
		case TEXT('f'): // -f [+FLAGS] [CHARSET] [SIZE] [FONTNAME] : set font
			{
				LOGFONT lf;

				// check syntax
				if (numtok < 5) {
					Dcx::error(TEXT("/xstatusbar -f"),TEXT("Invalid Parameters"));
					return 0;
				}

				if (ParseCommandToLogfont(input.getlasttoks(), &lf))	// tok 2, -1
					DcxDock::status_setFont(CreateFontIndirect(&lf));
			}
			break;
		case TEXT('k'): // -k [clr] : background colour.
			{
				// check syntax
				if (numtok != 2) {
					Dcx::error(TEXT("/xstatusbar -k"),TEXT("Invalid Parameters"));
					return 0;
				}

				const int col = input.getnexttok( ).to_int();	// tok 2

				if (col < 0)
					DcxDock::status_setBkColor((COLORREF) CLR_DEFAULT);
				else
					DcxDock::status_setBkColor((COLORREF) col);
			}
			break;
		case TEXT('l'): // -l [POS [POS POS ...]] : parts
			{
				// check syntax
				if (numtok < 2) {
					Dcx::error(TEXT("/xstatusbar -l"),TEXT("Invalid Parameters"));
					return 0;
				}

				const UINT nParts = numtok - 1;
				INT parts[256];

				int c = 0;
				TString p;
				for (UINT i = 0; i < nParts; i++ )
				{
					if (c >= 100) {
						Dcx::error(TEXT("/xstatusbar -l"),TEXT("Can't Allocate Over 100% of Statusbar!"));
						return 0;
					}

					p = input.getnexttok( );	// tok i+2

					const int t = p.to_int();

					if (p.right( 1 ) == TEXT('%')) {
						DcxDock::g_iDynamicParts[i] = t;
						c += t;
					}
					else
						DcxDock::g_iFixedParts[i] = t;

					parts[i] = t;
				}
				DcxDock::status_setParts( nParts, parts );
				DcxDock::status_updateParts();
			}
			break;
		case TEXT('t'): // -t N [+FLAGS] [#ICON] [BKGCOLOR] [TXTCOLOR] (Cell Text)([TAB]Tooltip Text) : set part
			{
				// check syntax (text can be blank)
				if (numtok < 6) {
					Dcx::error(TEXT("/xstatusbar -t"),TEXT("Invalid Parameters"));
					return 0;
				}
				const TString tsTabOne(input.getfirsttok(1, TSTAB));	// tok 1, TSTAB
				const TString tooltip(input.getnexttok(TSTAB).trim());	// tok 2, TSTAB;
				TString itemtext;

				const int nPos = (tsTabOne.getfirsttok(2).to_int() - 1);			// tok 2
				const TString flags(tsTabOne.getnexttok());							// tok 3
				const int icon = (tsTabOne.getnexttok().to_int() - 1);				// tok 4
				const COLORREF bkgClr = (COLORREF)tsTabOne.getnexttok().to_int();	// tok 5
				const COLORREF txtClr = (COLORREF)tsTabOne.getnexttok().to_int();	// tok 6
				const UINT iFlags = DcxDock::status_parseItemFlags( flags );

				if ( tsTabOne.numtok( ) > 6 )
					itemtext = tsTabOne.getlasttoks().trim();						// tok 7, -1

				DcxDock::status_deletePartInfo(nPos); // delete custom info if any.
				DestroyIcon( (HICON) DcxDock::status_getIcon( nPos ) );
				DcxDock::status_setIcon( nPos, NULL );

				if (iFlags & SBT_OWNERDRAW) {
					LPSB_PARTINFO pPart;

					try {
						pPart = new SB_PARTINFO;
					}
					catch (std::bad_alloc)
					{
						Dcx::error(TEXT("/xstatusbar -t"),TEXT("Unable to Allocate Memory"));
						return 0;
					}

					pPart->m_Child = NULL;
					pPart->m_iIcon = icon;
					pPart->m_Text = itemtext;
					pPart->m_TxtCol = CLR_INVALID;
					pPart->m_BkgCol = NULL;

					if (bkgClr != CLR_INVALID)
						pPart->m_BkgCol = CreateSolidBrush(bkgClr);
					if (txtClr != CLR_INVALID)
						pPart->m_TxtCol = txtClr;

					DcxDock::status_setTipText( nPos, tooltip.to_chr() );
					DcxDock::status_setPartInfo( nPos, iFlags, pPart );
				}
				else {
					if ( icon > -1 )
						DcxDock::status_setIcon( nPos, ImageList_GetIcon( DcxDock::status_getImageList( ), icon, ILD_TRANSPARENT ) );
					DcxDock::status_setText( nPos, iFlags, itemtext.to_chr() );
					DcxDock::status_setTipText(nPos, tooltip.to_chr());
				}
			}
			break;
		case TEXT('v'): // -v [N] [BKGCOLOR] [TXTCOLOR] (TEXT) : set parts text
			{
				// check syntax (text can be blank)
				if (numtok < 4) {
					Dcx::error(TEXT("/xstatusbar -v"),TEXT("Invalid Parameters"));
					return 0;
				}

				const int nPos = (input.getnexttok( ).to_int( ) - 1);	// tok 2

				if ( nPos > -1 && nPos < DcxDock::status_getParts( 256, 0 ) ) {

					TString itemtext;

					const COLORREF bkgClr = (COLORREF)input.getnexttok( ).to_int();	// tok 3
					const COLORREF txtClr = (COLORREF)input.getnexttok( ).to_int();	// tok 4

					if ( numtok > 4 )
						itemtext = input.getlasttoks();	// tok 5, -1

					const UINT iFlags = DcxDock::status_getPartFlags( nPos );

					if (iFlags & SBT_OWNERDRAW) {
						LPSB_PARTINFO pPart = (LPSB_PARTINFO)DcxDock::status_getText(nPos, NULL);
						if (pPart != NULL) {
							if (pPart->m_BkgCol != NULL)
								DeleteBrush(pPart->m_BkgCol);

							pPart->m_Text = itemtext;
							if (bkgClr != CLR_INVALID)
								pPart->m_BkgCol = CreateSolidBrush(bkgClr);
							pPart->m_TxtCol = txtClr;

							DcxDock::status_setPartInfo( nPos, iFlags, pPart );
						}
						else {
							Dcx::error(TEXT("/xstatusbar -v"),TEXT("Unable to set item text"));
							return 0;
						}
					}
					else {
						try {
#ifdef DCX_USE_C11
							std::unique_ptr<WCHAR> text(new WCHAR[DcxDock::status_getTextLength(nPos) + 1]);
							DcxDock::status_setText(nPos, HIWORD(DcxDock::status_getText(nPos, text.get())), itemtext.to_chr());
#else
							WCHAR *text = new WCHAR[DcxDock::status_getTextLength(nPos) + 1];
							DcxDock::status_setText(nPos, HIWORD(DcxDock::status_getText(nPos, text)), itemtext.to_chr());
							delete [] text;
#endif
						}
						catch (std::bad_alloc) {
							Dcx::error(TEXT("/xstatusbar -v"),TEXT("Unable to Allocate Memory"));
							return 0;
						}
					}
				}
			}
			break;
		case TEXT('w'): // -w [FLAGS] [INDEX] [FILENAME] : load an icon
			{
				// check syntax
				if (numtok < 4) {
					Dcx::error(TEXT("/xstatusbar -w"),TEXT("Invalid Parameters"));
					return 0;
				}

				HIMAGELIST himl = DcxDock::status_getImageList();
				const TString flags(input.getnexttok( ));			// tok 2
				const int index = input.getnexttok( ).to_int();		// tok 3
				TString filename(input.getlasttoks());				// tok 4, -1

				if (himl == NULL) {
					himl = DcxDock::status_createImageList();

					if (himl != NULL)
						DcxDock::status_setImageList(himl);
				}

				if (himl != NULL) {
					HICON icon = dcxLoadIcon(index, filename, false, flags);

					if (icon != NULL) {
						if (ImageList_AddIcon(himl, icon) == -1)
							Dcx::error(TEXT("/xstatusbar -w"),TEXT("Unable To Add Image to ImageList"));
					}
					else
						Dcx::error(TEXT("/xstatusbar -w"),TEXT("Unable To Load Icon"));
					DestroyIcon(icon);
				}
				else
					Dcx::error(TEXT("/xstatusbar -w"),TEXT("Unable To Create ImageList"));
			}
			break;
		case TEXT('y'): // destroy image list.
			{
				ImageList_Destroy( DcxDock::status_getImageList( ) );
				DcxDock::status_setImageList(NULL);
			}
			break;
		default:
			{
				Dcx::error(TEXT("/xstatusbar"),TEXT("Invalid Switch"));
				return 0;
			}
	}
	return 1;
}

// prop
mIRC(_xstatusbar)
{
	TString d(data);
	d.trim();

	data[0] = 0;

	static const TString poslist(TEXT("visible text parts tooltip"));
	const int nType = poslist.findtok(d.getfirsttok( 2 ).to_chr(),1);
	switch (nType)
	{
	case 1: // visible
		{
			//if (DcxDock::IsStatusbar())
			//	lstrcpyn(data,TEXT("$true"), MIRC_BUFFER_SIZE_CCH);
			//else
			//	lstrcpyn(data,TEXT("$false"), MIRC_BUFFER_SIZE_CCH);
			dcx_Con(DcxDock::IsStatusbar(), data);
		}
		break;
	case 2: // text
		{
			const int iPart = (d.getnexttok( ).to_int( ) -1), nParts = (int)DcxDock::status_getParts( 256, 0 );

			if ( iPart > -1 && iPart < nParts ) {
				const UINT iFlags = DcxDock::status_getPartFlags( iPart );

				if (iFlags & SBT_OWNERDRAW) {
					LPSB_PARTINFO pPart = (LPSB_PARTINFO)DcxDock::status_getText(iPart, NULL);
					if (pPart != NULL)
						dcx_strcpyn(data, pPart->m_Text.to_chr(), MIRC_BUFFER_SIZE_CCH);
				}
				else {
					const UINT len = DcxDock::status_getTextLength( iPart );
					try {
#ifdef DCX_USE_C11
						std::unique_ptr<WCHAR> text(new WCHAR[len + 1]);
						DcxDock::status_getText(iPart, text.get());
						dcx_strcpyn(data, text.get(), MIRC_BUFFER_SIZE_CCH);
#else
						WCHAR *text = new WCHAR[len + 1];
						DcxDock::status_getText(iPart, text);
						dcx_strcpyn(data, text, MIRC_BUFFER_SIZE_CCH);
						delete[] text;
#endif
					}
					catch (std::bad_alloc) {
						Dcx::error(TEXT("/xstatusbar -v"), TEXT("Unable to Allocate Memory"));
					}
				}
			}
		}
		break;
	case 3: // parts
		{
			INT parts[256] = {0};
			const int nParts = (int)DcxDock::status_getParts( 256, 0 );

			DcxDock::status_getParts( 256, parts );

			//TCHAR dd[10];
			//
			//for (int i = 0; i < nParts; i++ )
			//{
			//	wnsprintf( dd, 10, TEXT("%d"), parts[i] );
			//
			//	if ( i != 0 )
			//		lstrcat( data, TEXT(" ") );
			//	lstrcat( data, dd );
			//}

			TString tsOut((UINT)MIRC_BUFFER_SIZE_CCH);

			for (int i = 0; i < nParts; i++ )
				tsOut.addtok(parts[i]);

			dcx_strcpyn(data, tsOut.to_chr(), MIRC_BUFFER_SIZE_CCH);
		}
		break;
	case 4: // tooltip
		{
			const int iPart = d.getnexttok( ).to_int( ), nParts = (int)DcxDock::status_getParts( 256, 0 );

			if ( iPart > -1 && iPart < nParts )
				DcxDock::status_getTipText( iPart, MIRC_BUFFER_SIZE_CCH, data );
		}
		break;
	case 0: // error
	default:
		{
			wnsprintf(data, MIRC_BUFFER_SIZE_CCH, TEXT("D_ERROR Invalid prop ().%s"), d.gettok( 2 ).to_chr());
		}
		break;
	}
	return 3;
}
<commit_msg>[xstatusbar] changed code to use nullptr & auto. changed errors to exceptions<commit_after>
/*
*/
#include "defines.h"
#include "Classes/UltraDock/dcxDock.h"
#include "Dcx.h"

// [SWITCH] [OPTIONS]
mIRC(xstatusbar) {
	TString input(data);

	data[0] = 0;

	try {
		input.trim();

		const auto numtok = input.numtok();

		if (numtok < 1)
			throw std::invalid_argument("Invalid Parameters");

		const auto switches(input.getfirsttok(1));	// tok 1

		switch (switches[1]) {
		case TEXT('A'): // -A [0|1] (options)=notheme grip tooltips nodivider utf8
		{
			// check syntax
			if (numtok < 2)
				throw std::invalid_argument("Invalid Parameters");

			// Enable/Disable the Statusbar.
			// -A [0|1] [options] = notheme grip tooltips nodivider utf8
			if (input.getnexttok().to_int() > 0)					// tok 2
			{
				if (!DcxDock::InitStatusbar(input.getlasttoks()))	// tok 3, -1
					throw std::runtime_error("Unable to Create Statusbar");
			}
			else
				DcxDock::UnInitStatusbar();

			UpdatemIRC();
		}
		break;
		case TEXT('f'): // -f [+FLAGS] [CHARSET] [SIZE] [FONTNAME] : set font
		{
			LOGFONT lf;

			// check syntax
			if (numtok < 5)
				throw std::invalid_argument("Invalid Parameters");

			if (ParseCommandToLogfont(input.getlasttoks(), &lf))	// tok 2, -1
				DcxDock::status_setFont(CreateFontIndirect(&lf));
		}
		break;
		case TEXT('k'): // -k [clr] : background colour.
		{
			// check syntax
			if (numtok != 2)
				throw std::invalid_argument("Invalid Parameters");

			//const auto col = input.getnexttok().to_int();	// tok 2
			const auto col = input.getnexttok().to_<COLORREF>();	// tok 2

			if (col == CLR_INVALID)
				DcxDock::status_setBkColor(CLR_DEFAULT);
			else
				DcxDock::status_setBkColor(col);
		}
		break;
		case TEXT('l'): // -l [POS [POS POS ...]] : parts
		{
			// check syntax
			if (numtok < 2)
				throw std::invalid_argument("Invalid Parameters");

			const auto nParts = numtok - 1;
			INT parts[256];

			int c = 0;
			TString p;
			for (UINT i = 0; i < nParts; i++)
			{
				if (c >= 100)
					throw std::invalid_argument("Can't Allocate Over 100% of Statusbar!");

				p = input.getnexttok();	// tok i+2

				const auto t = p.to_int();

				if (p.right(1) == TEXT('%')) {
					DcxDock::g_iDynamicParts[i] = t;
					c += t;
				}
				else
					DcxDock::g_iFixedParts[i] = t;

				parts[i] = t;
			}
			DcxDock::status_setParts(nParts, parts);
			DcxDock::status_updateParts();
		}
		break;
		case TEXT('t'): // -t N [+FLAGS] [#ICON] [BKGCOLOR] [TXTCOLOR] (Cell Text)([TAB]Tooltip Text) : set part
		{
			// check syntax (text can be blank)
			if (numtok < 6)
				throw std::invalid_argument("Invalid Parameters");

			const auto tsTabOne(input.getfirsttok(1, TSTAB));	// tok 1, TSTAB
			const auto tooltip(input.getnexttok(TSTAB).trim());	// tok 2, TSTAB;
			TString itemtext;

			const auto nPos = (tsTabOne.getfirsttok(2).to_int() - 1);			// tok 2
			const auto flags(tsTabOne.getnexttok());							// tok 3
			const auto icon = (tsTabOne.getnexttok().to_int() - 1);				// tok 4
			//const auto bkgClr = (COLORREF)tsTabOne.getnexttok().to_int();		// tok 5
			//const auto txtClr = (COLORREF)tsTabOne.getnexttok().to_int();		// tok 6
			const auto bkgClr = tsTabOne.getnexttok().to_<COLORREF>();			// tok 5
			const auto txtClr = tsTabOne.getnexttok().to_<COLORREF>();			// tok 6
			const auto iFlags = DcxDock::status_parseItemFlags(flags);

			if (tsTabOne.numtok() > 6)
				itemtext = tsTabOne.getlasttoks().trim();						// tok 7, -1

			DcxDock::status_deletePartInfo(nPos); // delete custom info if any.
			DestroyIcon(DcxDock::status_getIcon(nPos));
			DcxDock::status_setIcon(nPos, nullptr);

			if (dcx_testflag(iFlags, SBT_OWNERDRAW)) {
				auto pPart = new SB_PARTINFOD;

				pPart->m_Child = nullptr;
				pPart->m_iIcon = icon;
				pPart->m_Text = itemtext;
				pPart->m_TxtCol = CLR_INVALID;
				pPart->m_BkgCol = nullptr;

				if (bkgClr != CLR_INVALID)
					pPart->m_BkgCol = CreateSolidBrush(bkgClr);
				if (txtClr != CLR_INVALID)
					pPart->m_TxtCol = txtClr;

				DcxDock::status_setTipText(nPos, tooltip.to_chr());
				DcxDock::status_setPartInfo(nPos, iFlags, pPart);
			}
			else {
				if (icon > -1)
					DcxDock::status_setIcon(nPos, ImageList_GetIcon(DcxDock::status_getImageList(), icon, ILD_TRANSPARENT));
				DcxDock::status_setText(nPos, iFlags, itemtext.to_chr());
				DcxDock::status_setTipText(nPos, tooltip.to_chr());
			}
		}
		break;
		case TEXT('v'): // -v [N] [BKGCOLOR] [TXTCOLOR] (TEXT) : set parts text
		{
			// check syntax (text can be blank)
			if (numtok < 4)
				throw std::invalid_argument("Invalid Parameters");

			const auto nPos = (input.getnexttok().to_int() - 1);	// tok 2

			if (nPos > -1 && nPos < DcxDock::status_getParts(256, 0)) {

				TString itemtext;

				//const COLORREF bkgClr = (COLORREF)input.getnexttok().to_int();	// tok 3
				//const COLORREF txtClr = (COLORREF)input.getnexttok().to_int();	// tok 4
				const auto bkgClr = input.getnexttok().to_<COLORREF>();	// tok 3
				const auto txtClr = input.getnexttok().to_<COLORREF>();	// tok 4

				if (numtok > 4)
					itemtext = input.getlasttoks();	// tok 5, -1

				const auto iFlags = DcxDock::status_getPartFlags(nPos);

				if (dcx_testflag(iFlags, SBT_OWNERDRAW)) {
					auto pPart = reinterpret_cast<LPSB_PARTINFOD>(DcxDock::status_getText(nPos, nullptr));
					if (pPart != NULL) {
						if (pPart->m_BkgCol != nullptr)
							DeleteBrush(pPart->m_BkgCol);

						pPart->m_Text = itemtext;
						if (bkgClr != CLR_INVALID)
							pPart->m_BkgCol = CreateSolidBrush(bkgClr);
						pPart->m_TxtCol = txtClr;

						DcxDock::status_setPartInfo(nPos, iFlags, pPart);
					}
					else
						throw std::runtime_error("Unable to set item text");
				}
				else {
					auto text = std::make_unique<WCHAR[]>(DcxDock::status_getTextLength(nPos) + 1);
					DcxDock::status_setText(nPos, HIWORD(DcxDock::status_getText(nPos, text.get())), itemtext.to_chr());
				}
			}
		}
		break;
		case TEXT('w'): // -w [FLAGS] [INDEX] [FILENAME] : load an icon
		{
			// check syntax
			if (numtok < 4)
				throw std::invalid_argument("Invalid Parameters");

			auto himl = DcxDock::status_getImageList();
			const auto flags(input.getnexttok());				// tok 2
			const auto index = input.getnexttok().to_int();		// tok 3
			auto filename(input.getlasttoks());					// tok 4, -1

			if (himl == nullptr) {
				himl = DcxDock::status_createImageList();

				if (himl != nullptr)
					DcxDock::status_setImageList(himl);
			}

			if (himl == nullptr)
				throw std::invalid_argument("Unable To Create ImageList");

			//auto icon = dcxLoadIcon(index, filename, false, flags);
			//Auto(DestroyIcon(icon));

			Dcx::dcxIcon icon(index, filename, false, flags);

			if (icon == nullptr)
				throw std::invalid_argument("Unable To Load Icon");

			if (ImageList_AddIcon(himl, icon) == -1)
				throw std::runtime_error("Unable To Add Image to ImageList");
		}
		break;
		case TEXT('y'): // destroy image list.
		{
			ImageList_Destroy(DcxDock::status_getImageList());
			DcxDock::status_setImageList(nullptr);
		}
		break;
		default:
			throw std::invalid_argument("Invalid Switch");
		}
		return 1;
	}
	catch (std::exception &e)
	{
		Dcx::errorex(TEXT("/xstatusbar"), TEXT("\"%s\" error: %S"), input.to_chr(), e.what());
		return 0;
	}
	catch (...) {
		// stop any left over exceptions...
		Dcx::errorex(TEXT("/xstatusbar"), TEXT("\"%s\" error: Unknown Exception"), input.to_chr());
		return 0;
	}
}

// prop
mIRC(_xstatusbar)
{
	TString d(data);

	data[0] = 0;

	try {
		d.trim();

		static const TString poslist(TEXT("visible text parts tooltip"));
		const auto nType = poslist.findtok(d.getfirsttok(2).to_chr(), 1);
		switch (nType)
		{
		case 1: // visible
		{
			dcx_Con(DcxDock::IsStatusbar(), data);
		}
		break;
		case 2: // text
		{
			const auto iPart = (d.getnexttok().to_int() - 1), nParts = (int)DcxDock::status_getParts(256, 0);

			if (iPart > -1 && iPart < nParts) {
				const auto iFlags = DcxDock::status_getPartFlags(iPart);

				if (dcx_testflag(iFlags, SBT_OWNERDRAW)) {
					auto pPart = reinterpret_cast<LPSB_PARTINFOD>(DcxDock::status_getText(iPart, nullptr));
					if (pPart != nullptr)
						dcx_strcpyn(data, pPart->m_Text.to_chr(), MIRC_BUFFER_SIZE_CCH);
				}
				else {
					const auto len = DcxDock::status_getTextLength(iPart);
					auto text = std::make_unique<WCHAR[]>(len + 1);

					DcxDock::status_getText(iPart, text.get());
					dcx_strcpyn(data, text.get(), MIRC_BUFFER_SIZE_CCH);
				}
			}
		}
		break;
		case 3: // parts
		{
			INT parts[256] = { 0 };
			auto nParts = DcxDock::status_getParts(256, 0);

			DcxDock::status_getParts(256, parts);

			TString tsOut((UINT)MIRC_BUFFER_SIZE_CCH);

			for (decltype(nParts) i = 0; i < nParts; i++)
				tsOut.addtok(parts[i]);

			dcx_strcpyn(data, tsOut.to_chr(), MIRC_BUFFER_SIZE_CCH);
		}
		break;
		case 4: // tooltip
		{
			const auto iPart = d.getnexttok().to_int(), nParts = (int)DcxDock::status_getParts(256, 0);

			if (iPart > -1 && iPart < nParts)
				DcxDock::status_getTipText(iPart, MIRC_BUFFER_SIZE_CCH, data);
		}
		break;
		case 0: // error
		default:
			throw std::invalid_argument(Dcx::dcxGetFormattedString(TEXT("Invalid prop ().%s"), d.gettok(2).to_chr()));
		}
		return 3;
	}
	catch (std::exception &e)
	{
		Dcx::errorex(TEXT("$!xstatusbar"), TEXT("\"%s\" error: %S"), d.to_chr(), e.what());
	}
	catch (...) {
		// stop any left over exceptions...
		Dcx::errorex(TEXT("$!xstatusbar"), TEXT("\"%s\" error: Unknown Exception"), d.to_chr());
	}
	return 0;
}
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2015 Marvin Sinister <marvin@sinister.io>
**
** This file is part of small-scope-qt.
**
** small-scope-qt is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** small-scope-qt is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with small-scope-qt.  If not, see <http://www.gnu.org/licenses/>.
**
****************************************************************************/

/****************************************************************************
icons:
start/stop: http://www.virtuallnk.com/
connect/disconnect: http://p.yusukekamiyamane.com/
****************************************************************************/

#include <QTimer>
#include <QTime>

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "settingsdialog.h"

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) {
    ui->setupUi(this);

    foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) {
        qDebug() << "Name        : " << info.portName();
    }

    // create settings dialog
    settings = new SettingsDialog;
    // create about window
    aboutDialog = new About;
    // create serial
    serial = new QSerialPort(this);
    // create buffer for serial communication
    buffer = new unsigned char[Settings::bufferSize];
    // clear buffer
    memset(buffer, 0, Settings::bufferSize);
    // initialize
    bufferFilled = 0;

    // time for random seed
    //QTime time = QTime::currentTime();
    // initialize random seed
    //qsrand((uint)time.msec());

    //QTimer *timer = new QTimer(this);
    //connect(timer, SIGNAL(timeout()), this, SLOT(immaginaryData()));
    //timer->start(10000);

    // initialize
    cursorPosition = 0;
    measure1Position = 0;
    measure2Position = 0;

    // set cursor values when mouse moves
    connect(ui->renderArea, SIGNAL(mouseMoved(int)), this, SLOT(setValuesCursor(int)));
    // set measure values on mouse click
    connect(ui->renderArea, SIGNAL(lPositionChanged(int)), this, SLOT(setValues1(int)));
    connect(ui->renderArea, SIGNAL(rPositionChanged(int)), this, SLOT(setValues2(int)));
    // update title with new fps value
    connect(ui->renderArea, SIGNAL(fpsChanged(float)), this, SLOT(setTitle(float)));

    // recalculate all values measured
    connect(this, SIGNAL(valuesChanged()), this, SLOT(recalculateValues()));

    // serial port error
    connect(serial, SIGNAL(error(QSerialPort::SerialPortError)), this, SLOT(handleError(QSerialPort::SerialPortError)));

    // read data from serial port when ready
    connect(serial, SIGNAL(readyRead()), this, SLOT(readData()));

    // resize renderArea to buffer size
    ui->renderArea->setMinimumSize(Settings::bufferSize,256*Settings::heightConstant);
    ui->renderArea->setMaximumSize(Settings::bufferSize,256*Settings::heightConstant);
    ui->renderArea->resize(Settings::bufferSize,256*Settings::heightConstant);

    // resize window to minimum size
    resize(minimumWidth(), minimumHeight());
}

MainWindow::~MainWindow() {
    delete ui;
}

// set the prescaler value of the scope
void MainWindow::setPrescalerValue(int value) {
    // calculate the actual value
    value = (int)pow(2, value);

    // save to global variable
    Settings::prescaler = value;

    // update form field
    ui->sbPrescaler->setValue(value);

    // send over serial
    QByteArray d;
    d = QByteArray("p",1);
    d.append(QByteArray::number(value, 10 ));
    writeData(d);
}

// set the trigger level of the scope
void MainWindow::setTriggerLevel(int value) {
    // save to global variable
    Settings::triggerLevel = value;

    // update form field
    ui->dsbThreshold->setValue(value*Settings::VPerUnit);

    // send over serial
    QByteArray d;
    d = QByteArray("t",1);
    d.append(QByteArray::number(value, 10 ));
    writeData(d);
}

// set the holdoff value of the scope
// holdoff is the time recorded after trigger
void MainWindow::setHoldoffValue (int value) {
    // save to global variable
    Settings::holdoff = value;

    // send over serial
    QByteArray d;
    d = QByteArray("w",1);
    d.append(QByteArray::number(value, 10 ));
    writeData(d);
}

// recalculate all measured values
void MainWindow::recalculateValues()
{
    // voltage at cursor
    float voltageC = buffer[cursorPosition] * 0.02;
    ui->leVoltage->setText(QString::number(voltageC,'f',2));
    // voltage at first measure
    float voltage1 = buffer[measure1Position] * 0.02;
    ui->leVoltage1->setText(QString::number(voltage1,'f',2));
    // voltage at second measure
    float voltage2 = buffer[measure2Position] * 0.02;
    ui->leVoltage2->setText(QString::number(voltage2,'f',2));
    // time at cursor
    float timeC = ((cursorPosition- Settings::bufferSize/2)/Settings::prescalerConstant)*Settings::prescaler;
    ui->leTime->setText(QString::number(timeC,'f',2));
    // time at first measure
    float time1 = ((measure1Position - Settings::bufferSize/2)/Settings::prescalerConstant)*Settings::prescaler;
    ui->leTime1->setText(QString::number(time1,'f',2));
    //time at second measure
    float time2 = ((measure2Position - Settings::bufferSize/2)/Settings::prescalerConstant)*Settings::prescaler;
    ui->leTime2->setText(QString::number(time2,'f',2));

    // absolute voltage and time difference
    ui->leDiffV21->setText(QString::number(fabs(voltage2 - voltage1),'f',2));
    ui->leDiffVc1->setText(QString::number(fabs(voltageC - voltage1),'f',2));
    ui->leDiffVc2->setText(QString::number(fabs(voltageC - voltage2),'f',2));
    ui->leDifft21->setText(QString::number(fabs(time2 - time1),'f',2));
    ui->leDifftc1->setText(QString::number(fabs(timeC - time1),'f',2));
    ui->leDifftc2->setText(QString::number(fabs(timeC - time2),'f',2));

    // holdoff time
    ui->dsbHoldoff->setValue(Settings::holdoff/Settings::prescalerConstant*Settings::prescaler);

    // threshold level
    ui->dsbThreshold->setValue(Settings::triggerLevel*Settings::VPerUnit);

}

// set trigger event to toggle
void MainWindow::setTriggerEventToggle() {
    writeData(QByteArray("e0",2));
}

// set the trigger event to falling
void MainWindow::setTriggerEventFalling() {
    writeData(QByteArray("e2",2));
}

// set the trigger event to rising
void MainWindow::setTriggerEventRising() {
    writeData(QByteArray("e3",2));
}

// ignore the trigger and run in continuous mode
void MainWindow::setTriggerEventNone() {
    writeData(QByteArray("e4",2));
}

// set the voltage refference to external refference
void MainWindow::setVRefAREF() {
    writeData(QByteArray("r0",2));
}

// set the voltage refference to internal supply refference
void MainWindow::setVRefAVCC() {
    writeData(QByteArray("r1",2));
}

// set the voltage refference to internal 1.1V refference
void MainWindow::setVRefInternal() {
    writeData(QByteArray("r3",2));
}

// set the cursor position
void MainWindow::setValuesCursor(int value) {
    cursorPosition = value;
    emit recalculateValues();
}

// set the first measure position
void MainWindow::setValues1 (int value) {
    measure1Position = value;
    emit recalculateValues();
}

// set the second measure position
void MainWindow::setValues2 (int value) {
    measure2Position = value;
    emit recalculateValues();
}

// change the window title
void MainWindow::setTitle(float fps) {
    this->setWindowTitle ("small-scope-qt - " + QString::number(fps) + "fps");
}

// show the COM port configuration window
void MainWindow::setupCOM() {
    settings->show();
}

// start the data aquisition
void MainWindow::startSampling() {
    QByteArray d;
    d = QByteArray("s", 1);
    writeData(d);
}

// stop the data aquisition
void MainWindow::stopSampling(){
    QByteArray d;
    d = QByteArray("S", 1);
    writeData(d);
    bufferFilled = 0;
}

// connect to scope over COM port wrapper
void MainWindow::connectCOM() {
    qDebug() << "Connecting to serial.";
    openSerialPort();
    if (serial->isOpen ()) {
        qDebug() << "Connected";
    }
    else {
        qDebug() << "Failed";
    }
}

// disconnect the COM port wrapper
void MainWindow::disconnectCOM() {
    closeSerialPort();
    qDebug() << "Disconnected";
}

// ask the scope for it's status
void MainWindow::status() {
    QByteArray d;
    d = QByteArray("d", 1);
    writeData(d);
}

// connect the COM port
void MainWindow::openSerialPort() {
    // read the settings
    SettingsDialog::Settings p = settings->settings();
    // set port name
    serial->setPortName(p.name);
    // try to connect
    if (serial->open(QIODevice::ReadWrite)) {
        if (serial->setBaudRate(p.baudRate)
                && serial->setDataBits(p.dataBits)
                && serial->setParity(p.parity)
                && serial->setStopBits(p.stopBits)
                && serial->setFlowControl(p.flowControl)) {        }
        else {
            serial->close();
            qDebug() << "Error" << serial->errorString();
        }
    }
    else {
        qDebug() << "Error" << serial->errorString();
    }
}

// disconnect the com port
void MainWindow::closeSerialPort() {
    serial->close();
}

// show the about window
void MainWindow::about() {

}

// write data to serial port
void MainWindow::writeData(const QByteArray &data) {
    if (serial->isOpen ()) {
        serial->write(data);
    }
    qDebug() << "Writing to serial: " << data;
}

// read data from serial port
void MainWindow::readData() {
    // read the data from serial
    QByteArray data = serial->readAll();

    // if there is more data than there is space in buffer, start from the beggining of buffer
    if ((bufferFilled + data.size()) > Settings::bufferSize) {
        bufferFilled = 0;
    }

    // read the data to buffer
    for (int i = 0; i < data.size(); ++i) {
        buffer[bufferFilled + i] = data[i];
    }

    // increase the filled amount
    bufferFilled+=data.size();

    // render the data on form
    ui->renderArea->drawData(buffer);
}

// generate random data for testing
/*void MainWindow::immaginaryData() {
    for (int i = 0; i < BUFFER_SIZE; ++i) {
        buffer[i] = (unsigned char)((qrand() % 256));
    }
    ui->renderArea->drawData(buffer);
}*/

// handle serial port error
void MainWindow::handleError(QSerialPort::SerialPortError error) {
    if (error == QSerialPort::ResourceError) {
        qDebug() << "Critical Error" << serial->errorString();
        closeSerialPort();
    }
}

// exit action
void MainWindow::on_actionExit_triggered() {
    close();
}

// about action
void MainWindow::on_actionAbout_triggered() {
    aboutDialog->show();
}

// COM settings action
void MainWindow::on_actionCOM_Port_Settings_triggered() {
    setupCOM();
}
<commit_msg>added recalculateValues() connection<commit_after>/****************************************************************************
**
** Copyright (C) 2015 Marvin Sinister <marvin@sinister.io>
**
** This file is part of small-scope-qt.
**
** small-scope-qt is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** small-scope-qt is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with small-scope-qt.  If not, see <http://www.gnu.org/licenses/>.
**
****************************************************************************/

/****************************************************************************
icons:
start/stop: http://www.virtuallnk.com/
connect/disconnect: http://p.yusukekamiyamane.com/
****************************************************************************/

#include <QTimer>
#include <QTime>

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "settingsdialog.h"

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) {
    ui->setupUi(this);

    foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) {
        qDebug() << "Name        : " << info.portName();
    }

    // create settings dialog
    settings = new SettingsDialog;
    // create about window
    aboutDialog = new About;
    // create serial
    serial = new QSerialPort(this);
    // create buffer for serial communication
    buffer = new unsigned char[Settings::bufferSize];
    // clear buffer
    memset(buffer, 0, Settings::bufferSize);
    // initialize
    bufferFilled = 0;

    // time for random seed
    //QTime time = QTime::currentTime();
    // initialize random seed
    //qsrand((uint)time.msec());

    //QTimer *timer = new QTimer(this);
    //connect(timer, SIGNAL(timeout()), this, SLOT(immaginaryData()));
    //timer->start(10000);

    // initialize
    cursorPosition = 0;
    measure1Position = 0;
    measure2Position = 0;

    // set cursor values when mouse moves
    connect(ui->renderArea, SIGNAL(mouseMoved(int)), this, SLOT(setValuesCursor(int)));
    // set measure values on mouse click
    connect(ui->renderArea, SIGNAL(lPositionChanged(int)), this, SLOT(setValues1(int)));
    connect(ui->renderArea, SIGNAL(rPositionChanged(int)), this, SLOT(setValues2(int)));
    // update title with new fps value
    connect(ui->renderArea, SIGNAL(fpsChanged(float)), this, SLOT(setTitle(float)));

    // recalculate all values measured
    connect(this, SIGNAL(valuesChanged()), this, SLOT(recalculateValues()));
    connect(ui->renderArea, SIGNAL(recalculateValues()), this, SLOT(recalculateValues()));

    // serial port error
    connect(serial, SIGNAL(error(QSerialPort::SerialPortError)), this, SLOT(handleError(QSerialPort::SerialPortError)));

    // read data from serial port when ready
    connect(serial, SIGNAL(readyRead()), this, SLOT(readData()));

    // resize renderArea to buffer size
    ui->renderArea->setMinimumSize(Settings::bufferSize,256*Settings::heightConstant);
    ui->renderArea->setMaximumSize(Settings::bufferSize,256*Settings::heightConstant);
    ui->renderArea->resize(Settings::bufferSize,256*Settings::heightConstant);

    // resize window to minimum size
    resize(minimumWidth(), minimumHeight());
}

MainWindow::~MainWindow() {
    delete ui;
}

// set the prescaler value of the scope
void MainWindow::setPrescalerValue(int value) {
    // calculate the actual value
    value = (int)pow(2, value);

    // save to global variable
    Settings::prescaler = value;

    // update form field
    ui->sbPrescaler->setValue(value);

    // send over serial
    QByteArray d;
    d = QByteArray("p",1);
    d.append(QByteArray::number(value, 10 ));
    writeData(d);
}

// set the trigger level of the scope
void MainWindow::setTriggerLevel(int value) {
    // save to global variable
    Settings::triggerLevel = value;

    // update form field
    ui->dsbThreshold->setValue(value*Settings::VPerUnit);

    // send over serial
    QByteArray d;
    d = QByteArray("t",1);
    d.append(QByteArray::number(value, 10 ));
    writeData(d);
}

// set the holdoff value of the scope
// holdoff is the time recorded after trigger
void MainWindow::setHoldoffValue (int value) {
    // save to global variable
    Settings::holdoff = value;

    // send over serial
    QByteArray d;
    d = QByteArray("w",1);
    d.append(QByteArray::number(value, 10 ));
    writeData(d);
}

// recalculate all measured values
void MainWindow::recalculateValues()
{
    // voltage at cursor
    float voltageC = buffer[cursorPosition] * 0.02;
    ui->leVoltage->setText(QString::number(voltageC,'f',2));
    // voltage at first measure
    float voltage1 = buffer[measure1Position] * 0.02;
    ui->leVoltage1->setText(QString::number(voltage1,'f',2));
    // voltage at second measure
    float voltage2 = buffer[measure2Position] * 0.02;
    ui->leVoltage2->setText(QString::number(voltage2,'f',2));
    // time at cursor
    float timeC = ((cursorPosition- Settings::bufferSize/2)/Settings::prescalerConstant)*Settings::prescaler;
    ui->leTime->setText(QString::number(timeC,'f',2));
    // time at first measure
    float time1 = ((measure1Position - Settings::bufferSize/2)/Settings::prescalerConstant)*Settings::prescaler;
    ui->leTime1->setText(QString::number(time1,'f',2));
    //time at second measure
    float time2 = ((measure2Position - Settings::bufferSize/2)/Settings::prescalerConstant)*Settings::prescaler;
    ui->leTime2->setText(QString::number(time2,'f',2));

    // absolute voltage and time difference
    ui->leDiffV21->setText(QString::number(fabs(voltage2 - voltage1),'f',2));
    ui->leDiffVc1->setText(QString::number(fabs(voltageC - voltage1),'f',2));
    ui->leDiffVc2->setText(QString::number(fabs(voltageC - voltage2),'f',2));
    ui->leDifft21->setText(QString::number(fabs(time2 - time1),'f',2));
    ui->leDifftc1->setText(QString::number(fabs(timeC - time1),'f',2));
    ui->leDifftc2->setText(QString::number(fabs(timeC - time2),'f',2));

    // holdoff time
    ui->dsbHoldoff->setValue(Settings::holdoff/Settings::prescalerConstant*Settings::prescaler);

    // threshold level
    ui->dsbThreshold->setValue(Settings::triggerLevel*Settings::VPerUnit);

}

// set trigger event to toggle
void MainWindow::setTriggerEventToggle() {
    writeData(QByteArray("e0",2));
}

// set the trigger event to falling
void MainWindow::setTriggerEventFalling() {
    writeData(QByteArray("e2",2));
}

// set the trigger event to rising
void MainWindow::setTriggerEventRising() {
    writeData(QByteArray("e3",2));
}

// ignore the trigger and run in continuous mode
void MainWindow::setTriggerEventNone() {
    writeData(QByteArray("e4",2));
}

// set the voltage refference to external refference
void MainWindow::setVRefAREF() {
    writeData(QByteArray("r0",2));
}

// set the voltage refference to internal supply refference
void MainWindow::setVRefAVCC() {
    writeData(QByteArray("r1",2));
}

// set the voltage refference to internal 1.1V refference
void MainWindow::setVRefInternal() {
    writeData(QByteArray("r3",2));
}

// set the cursor position
void MainWindow::setValuesCursor(int value) {
    cursorPosition = value;
    emit recalculateValues();
}

// set the first measure position
void MainWindow::setValues1 (int value) {
    measure1Position = value;
    emit recalculateValues();
}

// set the second measure position
void MainWindow::setValues2 (int value) {
    measure2Position = value;
    emit recalculateValues();
}

// change the window title
void MainWindow::setTitle(float fps) {
    this->setWindowTitle ("small-scope-qt - " + QString::number(fps) + "fps");
}

// show the COM port configuration window
void MainWindow::setupCOM() {
    settings->show();
}

// start the data aquisition
void MainWindow::startSampling() {
    QByteArray d;
    d = QByteArray("s", 1);
    writeData(d);
}

// stop the data aquisition
void MainWindow::stopSampling(){
    QByteArray d;
    d = QByteArray("S", 1);
    writeData(d);
    bufferFilled = 0;
}

// connect to scope over COM port wrapper
void MainWindow::connectCOM() {
    qDebug() << "Connecting to serial.";
    openSerialPort();
    if (serial->isOpen ()) {
        qDebug() << "Connected";
    }
    else {
        qDebug() << "Failed";
    }
}

// disconnect the COM port wrapper
void MainWindow::disconnectCOM() {
    closeSerialPort();
    qDebug() << "Disconnected";
}

// ask the scope for it's status
void MainWindow::status() {
    QByteArray d;
    d = QByteArray("d", 1);
    writeData(d);
}

// connect the COM port
void MainWindow::openSerialPort() {
    // read the settings
    SettingsDialog::Settings p = settings->settings();
    // set port name
    serial->setPortName(p.name);
    // try to connect
    if (serial->open(QIODevice::ReadWrite)) {
        if (serial->setBaudRate(p.baudRate)
                && serial->setDataBits(p.dataBits)
                && serial->setParity(p.parity)
                && serial->setStopBits(p.stopBits)
                && serial->setFlowControl(p.flowControl)) {        }
        else {
            serial->close();
            qDebug() << "Error" << serial->errorString();
        }
    }
    else {
        qDebug() << "Error" << serial->errorString();
    }
}

// disconnect the com port
void MainWindow::closeSerialPort() {
    serial->close();
}

// show the about window
void MainWindow::about() {

}

// write data to serial port
void MainWindow::writeData(const QByteArray &data) {
    if (serial->isOpen ()) {
        serial->write(data);
    }
    qDebug() << "Writing to serial: " << data;
}

// read data from serial port
void MainWindow::readData() {
    // read the data from serial
    QByteArray data = serial->readAll();

    // if there is more data than there is space in buffer, start from the beggining of buffer
    if ((bufferFilled + data.size()) > Settings::bufferSize) {
        bufferFilled = 0;
    }

    // read the data to buffer
    for (int i = 0; i < data.size(); ++i) {
        buffer[bufferFilled + i] = data[i];
    }

    // increase the filled amount
    bufferFilled+=data.size();

    // render the data on form
    ui->renderArea->drawData(buffer);
}

// generate random data for testing
/*void MainWindow::immaginaryData() {
    for (int i = 0; i < BUFFER_SIZE; ++i) {
        buffer[i] = (unsigned char)((qrand() % 256));
    }
    ui->renderArea->drawData(buffer);
}*/

// handle serial port error
void MainWindow::handleError(QSerialPort::SerialPortError error) {
    if (error == QSerialPort::ResourceError) {
        qDebug() << "Critical Error" << serial->errorString();
        closeSerialPort();
    }
}

// exit action
void MainWindow::on_actionExit_triggered() {
    close();
}

// about action
void MainWindow::on_actionAbout_triggered() {
    aboutDialog->show();
}

// COM settings action
void MainWindow::on_actionCOM_Port_Settings_triggered() {
    setupCOM();
}
<|endoftext|>