<commit_before>// @(#)root/roostats:$Id:  cranmer $
// Author: Kyle Cranmer, Akira Shibata
/*************************************************************************
 * Copyright (C) 1995-2008, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//_________________________________________________
/*
BEGIN_HTML

This is a package that creates a RooFit probability density function from ROOT histograms
of expected distributions and histograms that represent the +/- 1 sigma variations
from systematic effects. The resulting probability density function can then be used
with any of the statistical tools provided within RooStats, such as the profile
likelihood ratio, Feldman-Cousins, etc.  In this version, the model is directly
fed to a likelihodo ratio test, but it needs to be further factorized.

The user needs to provide histograms (in picobarns per bin) and configure the job
with XML.  The configuration XML is defined in the file config/Config.dtd, but essentially
it is organized as follows (see config/Combination.xml and config/ee.xml for examples)

 - a top level 'Combination' that is composed of:

- several 'Channels' (eg. ee, emu, mumu), which are composed of:

- several 'Samples' (eg. signal, bkg1, bkg2, ...), each of which has:

 - a name

 - if the sample is normalized by theory (eg N = L*sigma) or not (eg. data driven)

 - a nominal expectation histogram

 - a named 'Normalization Factor' (which can be fixed or allowed to float in a fit)

 - several 'Overall Systematics' in normalization with:

 - a name

 - +/- 1 sigma variations (eg. 1.05 and 0.95 for a 5% uncertainty)

- several 'Histogram Systematics' in shape with:

- a name (which can be shared with the OverallSyst if correlated)

- +/- 1 sigma variational histograms

- several 'Measurements' (corresponding to a full fit of the model) each of which specifies

- a name for this fit to be used in tables and files

      - what is the luminosity associated to the measurement in picobarns

      - which bins of the histogram should be used

      - what is the relative uncertainty on the luminosity

      - what is (are) the parameter(s) of interest that will be measured

      - which parameters should be fixed/floating (eg. nuisance parameters)

END_HTML
*/
//

// from std
#include <string>
#include <vector>
#include <map>
#include <iostream>
#include <sstream>

// from root
#include "TFile.h"
#include "TH1F.h"
#include "TDOMParser.h"
#include "TXMLAttr.h"
#include "TString.h"

// from roofit
#include "RooStats/ModelConfig.h"

// from this package
#include "Helper.h"
#include "ConfigParser.h"
#include "RooStats/HistFactory/EstimateSummary.h"
#include "RooStats/HistFactory/HistoToWorkspaceFactory.h"

using namespace RooFit;
using namespace RooStats;
using namespace HistFactory;

void topDriver(string input);
void fastDriver(string input); // in MakeModelAndMeasurementsFast

//_____________________________batch only_____________________
#ifndef __CINT__

int main(int argc, char** argv) {

  if(! (argc>1)) {
    cerr << "need input file" << endl;
    exit(1);
  }

  if(argc==2){
    string input(argv[1]);
    try {
      fastDriver(input);
    }
    catch (std::string str) {
      cerr << "caught exception: " << str << endl ;
    }
  }

  if(argc==3){
    string flag(argv[1]);
    string input(argv[2]);
    if(flag=="-standard_form")
      try {
	fastDriver(input);
      }
      catch (std::string str) {
	cerr << "caught exception: " << str << endl ;
      }
    else if(flag=="-number_counting_form")
      topDriver(input);
    else
      cerr <<"unrecognized flag.  Options are -standard_form or -number_counting_form"<<endl;

  }
  return 0;
}

#endif

void topDriver(string input ){

  // TO DO:
  // would like to fully factorize the XML parsing.
  // No clear need to have some here and some in ConfigParser

  /*** read in the input xml ***/
  TDOMParser xmlparser;
  Int_t parseError = xmlparser.ParseFile( input.c_str() );
  if( parseError ) {
    std::cerr << "Loading of xml document \"" << input
          << "\" failed" << std::endl;
  }

  cout << "reading input : " << input << endl;
  TXMLDocument* xmldoc = xmlparser.GetXMLDocument();
  TXMLNode* rootNode = xmldoc->GetRootNode();

  if( rootNode->GetNodeName() == TString( "Combination" ) ){
    string outputFileName, outputFileNamePrefix;
    vector<string> xml_input;

    TListIter attribIt = rootNode->GetAttributes();
    TXMLAttr* curAttr = 0;
    while( ( curAttr = dynamic_cast< TXMLAttr* >( attribIt() ) ) != 0 ) {
      if( curAttr->GetName() == TString( "OutputFilePrefix" ) ) {
        outputFileNamePrefix=string(curAttr->GetValue());
        cout << "output file is : " << outputFileName << endl;
      }
    }
    TXMLNode* node = rootNode->GetChildren();
    while( node != 0 ) {
      if( node->GetNodeName() == TString( "Input" ) ) {
        xml_input.push_back(node->GetText());
      }
      node = node->GetNextNode();
    }
    node = rootNode->GetChildren();
    while( node != 0 ) {
      if( node->GetNodeName() == TString( "Measurement" ) ) {

        Double_t nominalLumi=0, lumiRelError=0, lumiError=0;
        Int_t lowBin=0, highBin=0;
        string rowTitle, POI, mode;
        vector<string> systToFix;
        map<string,double> gammaSyst;
        map<string,double> uniformSyst;
        map<string,double> logNormSyst;
	bool exportOnly = false;

	//        TListIter attribIt = node->GetAttributes();
	//        TXMLAttr* curAttr = 0;
        attribIt = node->GetAttributes();
        curAttr = 0;
        while( ( curAttr = dynamic_cast< TXMLAttr* >( attribIt() ) ) != 0 ) {
          if( curAttr->GetName() == TString( "Lumi" ) ) {
            nominalLumi=atof(curAttr->GetValue());
          }
          if( curAttr->GetName() == TString( "LumiRelErr" ) ) {
            lumiRelError=atof(curAttr->GetValue());
          }
          if( curAttr->GetName() == TString( "BinLow" ) ) {
            lowBin=atoi(curAttr->GetValue());
          }
          if( curAttr->GetName() == TString( "BinHigh" ) ) {
            highBin=atoi(curAttr->GetValue());
          }
          if( curAttr->GetName() == TString( "Name" ) ) {
            rowTitle=curAttr->GetValue();
            outputFileName=outputFileNamePrefix+"_"+rowTitle+".root";
          }
          if( curAttr->GetName() == TString( "Mode" ) ) {
            mode=curAttr->GetValue();
          }
          if( curAttr->GetName() == TString( "ExportOnly" ) ) {
            if(curAttr->GetValue() == TString( "True" ) )
	      exportOnly = true;
	    else
	      exportOnly = false;
          }
        }
        lumiError=nominalLumi*lumiRelError;

        TXMLNode* mnode = node->GetChildren();
        while( mnode != 0 ) {
          if( mnode->GetNodeName() == TString( "POI" ) ) {
            POI=mnode->GetText();
          }
          if( mnode->GetNodeName() == TString( "ParamSetting" ) ) {
	    //            TListIter attribIt = mnode->GetAttributes();
            //TXMLAttr* curAttr = 0;
	    attribIt = mnode->GetAttributes();
	    curAttr = 0;
            while( ( curAttr = dynamic_cast< TXMLAttr* >( attribIt() ) ) != 0 ) {
              if( curAttr->GetName() == TString( "Const" ) ) {
                if(curAttr->GetValue()==TString("True")){
                  AddSubStrings(systToFix, mnode->GetText());
                }
              }
            }
          }
          if( mnode->GetNodeName() == TString( "ConstraintTerm" ) ) {
            vector<string> syst; string type = ""; double rel = 0;
            AddSubStrings(syst,mnode->GetText());
	    //            TListIter attribIt = mnode->GetAttributes();
	    //            TXMLAttr* curAttr = 0;
	    attribIt = mnode->GetAttributes();
            curAttr = 0;
            while( ( curAttr = dynamic_cast< TXMLAttr* >( attribIt() ) ) != 0 ) {
              if( curAttr->GetName() == TString( "Type" ) ) {
                type = curAttr->GetValue();
              }
              if( curAttr->GetName() == TString( "RelativeUncertainty" ) ) {
                rel = atof(curAttr->GetValue());
              }
            }
            if (type=="Gamma" && rel!=0) {
              for (vector<string>::const_iterator it=syst.begin(); it!=syst.end(); it++) gammaSyst[(*it).c_str()] = rel;
            }
            if (type=="Uniform" && rel!=0) {
              for (vector<string>::const_iterator it=syst.begin(); it!=syst.end(); it++) uniformSyst[(*it).c_str()] = rel;
            }
            if (type=="LogNormal" && rel!=0) {
              for (vector<string>::const_iterator it=syst.begin(); it!=syst.end(); it++) logNormSyst[(*it).c_str()] = rel;
            }
          }
          mnode = mnode->GetNextNode();
        }

        /* Do measurement */
        cout << "using lumi = " << nominalLumi << " and lumiError = " << lumiError
             << " including bins between " << lowBin << " and " << highBin << endl;
        cout << "fixing the following parameters:"  << endl;
        for(vector<string>::iterator itr=systToFix.begin(); itr!=systToFix.end(); ++itr){
          cout << "   " << *itr << endl;
        }

        /***
            Construction of Model. Only requirement is that they return vector<vector<EstimateSummary> >
	    This is where we use the factory.
        ***/

        vector<vector<EstimateSummary> > summaries;
        if(xml_input.empty()){
          cerr << "no input channels found" << endl;
          exit(1);
        }

        vector<RooWorkspace*> chs;
        vector<string> ch_names;
        TFile* outFile = new TFile(outputFileName.c_str(), "recreate");
        HistoToWorkspaceFactory factory(outputFileNamePrefix, rowTitle, systToFix, nominalLumi, lumiError, lowBin, highBin , outFile);

        // for results tables
        fprintf(factory.pFile, " %s &", rowTitle.c_str() );

        // read the xml for each channel and combine
        for(vector<string>::iterator itr=xml_input.begin(); itr!=xml_input.end(); ++itr){
          vector<EstimateSummary> oneChannel;
          // read xml
          ReadXmlConfig(*itr, oneChannel, nominalLumi);
          // not really needed anymore
          summaries.push_back(oneChannel);
          // use factory to create the workspace
          string ch_name=oneChannel[0].channel;
          ch_names.push_back(ch_name);
          RooWorkspace * ws = factory.MakeSingleChannelModel(oneChannel, systToFix);
          chs.push_back(ws);
          // set poi in ModelConfig
          ModelConfig * proto_config = (ModelConfig *) ws->obj("ModelConfig");
          cout << "Setting Parameter of Interest as :" << POI << endl;
          RooRealVar* poi = (RooRealVar*) ws->var(POI.c_str());
          RooArgSet * params= new RooArgSet;
          params->add(*poi);
          proto_config->SetParameters(*params);

          // Gamma/Uniform Constraints:
          // turn some Gaussian constraints into Gamma/Uniform/LogNorm constraints, rename model newSimPdf
	  if(gammaSyst.size()>0 || uniformSyst.size()>0 || logNormSyst.size()>0) {
	    factory.EditSyst(ws,("model_"+oneChannel[0].channel).c_str(),gammaSyst,uniformSyst,logNormSyst);
	    proto_config->SetPdf(*ws->pdf("newSimPdf"));
          }

	  // fill out ModelConfig and export
          RooAbsData* expData = ws->data("expData");
	  proto_config->GuessObsAndNuisance(*expData);
	  ws->writeToFile((outputFileNamePrefix+"_"+ch_name+"_"+rowTitle+"_model.root").c_str());

	  // do fit unless exportOnly requested
	  if(!exportOnly)
	    factory.FitModel(ws, ch_name, "newSimPdf", "expData", false);
          fprintf(factory.pFile, " & " );
        }

        /***
	    Make the combined model:
            If you want output histograms in root format, create and pass it to the combine routine.
            "combine" : will do the individual cross-section measurements plus combination

        ***/

        if(mode.find("comb")!=string::npos){
          RooWorkspace* ws=factory.MakeCombinedModel(ch_names,chs);
          // Gamma/Uniform Constraints:
          // turn some Gaussian constraints into Gamma/Uniform/logNormal constraints, rename model newSimPdf
	  if(gammaSyst.size()>0 || uniformSyst.size()>0 || logNormSyst.size()>0)
	    factory.EditSyst(ws,"simPdf",gammaSyst,uniformSyst,logNormSyst);
          //
          // set parameter of interest according to the configuration
          //
          ModelConfig * combined_config = (ModelConfig *) ws->obj("ModelConfig");
          cout << "Setting Parameter of Interest as :" << POI << endl;
          RooRealVar* poi = (RooRealVar*) ws->var((POI).c_str());
          //RooRealVar* poi = (RooRealVar*) ws->var((POI+"_comb").c_str());
          RooArgSet * params= new RooArgSet;
          cout << poi << endl;
          params->add(*poi);
          combined_config->SetParameters(*params);
          ws->Print();

          // Set new PDF if there are gamma/uniform constraint terms
          if(gammaSyst.size()>0 || uniformSyst.size()>0 || logNormSyst.size()>0)
	    combined_config->SetPdf(*ws->pdf("newSimPdf"));

          RooAbsData* simData = ws->data("simData");
	  combined_config->GuessObsAndNuisance(*simData);
	  //	  ws->writeToFile(("results/model_combined_edited.root").c_str());
	  ws->writeToFile((outputFileNamePrefix+"_combined_"+rowTitle+"_model.root").c_str());

	  // TO DO:
          // Totally factorize the statistical test in "fit Model" to a different area
	  if(!exportOnly)
	    factory.FitModel(ws, "combined", "simPdf", "simData", false);
        }

        fprintf(factory.pFile, " \\\\ \n");

        outFile->Close();
        delete outFile;

      }
      node = node->GetNextNode(); // next measurement
    }
  }
}

<commit_msg>fix for Coverity (23382) uncaught exception<commit_after>// @(#)root/roostats:$Id:  cranmer $
// Author: Kyle Cranmer, Akira Shibata
/*************************************************************************
 * Copyright (C) 1995-2008, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//_________________________________________________
/*
BEGIN_HTML

This is a package that creates a RooFit probability density function from ROOT histograms
of expected distributions and histograms that represent the +/- 1 sigma variations
from systematic effects. The resulting probability density function can then be used
with any of the statistical tools provided within RooStats, such as the profile
likelihood ratio, Feldman-Cousins, etc.  In this version, the model is directly
fed to a likelihodo ratio test, but it needs to be further factorized.

The user needs to provide histograms (in picobarns per bin) and configure the job
with XML.  The configuration XML is defined in the file config/Config.dtd, but essentially
it is organized as follows (see config/Combination.xml and config/ee.xml for examples)

 - a top level 'Combination' that is composed of:

- several 'Channels' (eg. ee, emu, mumu), which are composed of:

- several 'Samples' (eg. signal, bkg1, bkg2, ...), each of which has:

 - a name

 - if the sample is normalized by theory (eg N = L*sigma) or not (eg. data driven)

 - a nominal expectation histogram

 - a named 'Normalization Factor' (which can be fixed or allowed to float in a fit)

 - several 'Overall Systematics' in normalization with:

 - a name

 - +/- 1 sigma variations (eg. 1.05 and 0.95 for a 5% uncertainty)

- several 'Histogram Systematics' in shape with:

- a name (which can be shared with the OverallSyst if correlated)

- +/- 1 sigma variational histograms

- several 'Measurements' (corresponding to a full fit of the model) each of which specifies

- a name for this fit to be used in tables and files

      - what is the luminosity associated to the measurement in picobarns

      - which bins of the histogram should be used

      - what is the relative uncertainty on the luminosity

      - what is (are) the parameter(s) of interest that will be measured

      - which parameters should be fixed/floating (eg. nuisance parameters)

END_HTML
*/
//

// from std
#include <string>
#include <vector>
#include <map>
#include <iostream>
#include <sstream>

// from root
#include "TFile.h"
#include "TH1F.h"
#include "TDOMParser.h"
#include "TXMLAttr.h"
#include "TString.h"

// from roofit
#include "RooStats/ModelConfig.h"

// from this package
#include "Helper.h"
#include "ConfigParser.h"
#include "RooStats/HistFactory/EstimateSummary.h"
#include "RooStats/HistFactory/HistoToWorkspaceFactory.h"

using namespace RooFit;
using namespace RooStats;
using namespace HistFactory;

void topDriver(string input);
void fastDriver(string input); // in MakeModelAndMeasurementsFast

//_____________________________batch only_____________________
#ifndef __CINT__

int main(int argc, char** argv) {

  if(! (argc>1)) {
    cerr << "need input file" << endl;
    exit(1);
  }

  if(argc==2){
    string input(argv[1]);
    try {
      fastDriver(input);
    }
    catch (std::string str) {
      cerr << "caught exception: " << str << endl ;
    }
  }

  if(argc==3){
    string flag(argv[1]);
    string input(argv[2]);
    if(flag=="-standard_form")
      try {
	fastDriver(input);
      }
      catch (std::string str) {
	cerr << "caught exception: " << str << endl ;
      }
    else if(flag=="-number_counting_form")
      try {
         topDriver(input);
      }
      catch (std::string str) {
	cerr << "caught exception: " << str << endl ;
      }
    else
      cerr <<"unrecognized flag.  Options are -standard_form or -number_counting_form"<<endl;

  }
  return 0;
}

#endif

void topDriver(string input ){

  // TO DO:
  // would like to fully factorize the XML parsing.
  // No clear need to have some here and some in ConfigParser

  /*** read in the input xml ***/
  TDOMParser xmlparser;
  Int_t parseError = xmlparser.ParseFile( input.c_str() );
  if( parseError ) {
    std::cerr << "Loading of xml document \"" << input
          << "\" failed" << std::endl;
  }

  cout << "reading input : " << input << endl;
  TXMLDocument* xmldoc = xmlparser.GetXMLDocument();
  TXMLNode* rootNode = xmldoc->GetRootNode();

  if( rootNode->GetNodeName() == TString( "Combination" ) ){
    string outputFileName, outputFileNamePrefix;
    vector<string> xml_input;

    TListIter attribIt = rootNode->GetAttributes();
    TXMLAttr* curAttr = 0;
    while( ( curAttr = dynamic_cast< TXMLAttr* >( attribIt() ) ) != 0 ) {
      if( curAttr->GetName() == TString( "OutputFilePrefix" ) ) {
        outputFileNamePrefix=string(curAttr->GetValue());
        cout << "output file is : " << outputFileName << endl;
      }
    }
    TXMLNode* node = rootNode->GetChildren();
    while( node != 0 ) {
      if( node->GetNodeName() == TString( "Input" ) ) {
        xml_input.push_back(node->GetText());
      }
      node = node->GetNextNode();
    }
    node = rootNode->GetChildren();
    while( node != 0 ) {
      if( node->GetNodeName() == TString( "Measurement" ) ) {

        Double_t nominalLumi=0, lumiRelError=0, lumiError=0;
        Int_t lowBin=0, highBin=0;
        string rowTitle, POI, mode;
        vector<string> systToFix;
        map<string,double> gammaSyst;
        map<string,double> uniformSyst;
        map<string,double> logNormSyst;
	bool exportOnly = false;

	//        TListIter attribIt = node->GetAttributes();
	//        TXMLAttr* curAttr = 0;
        attribIt = node->GetAttributes();
        curAttr = 0;
        while( ( curAttr = dynamic_cast< TXMLAttr* >( attribIt() ) ) != 0 ) {
          if( curAttr->GetName() == TString( "Lumi" ) ) {
            nominalLumi=atof(curAttr->GetValue());
          }
          if( curAttr->GetName() == TString( "LumiRelErr" ) ) {
            lumiRelError=atof(curAttr->GetValue());
          }
          if( curAttr->GetName() == TString( "BinLow" ) ) {
            lowBin=atoi(curAttr->GetValue());
          }
          if( curAttr->GetName() == TString( "BinHigh" ) ) {
            highBin=atoi(curAttr->GetValue());
          }
          if( curAttr->GetName() == TString( "Name" ) ) {
            rowTitle=curAttr->GetValue();
            outputFileName=outputFileNamePrefix+"_"+rowTitle+".root";
          }
          if( curAttr->GetName() == TString( "Mode" ) ) {
            mode=curAttr->GetValue();
          }
          if( curAttr->GetName() == TString( "ExportOnly" ) ) {
            if(curAttr->GetValue() == TString( "True" ) )
	      exportOnly = true;
	    else
	      exportOnly = false;
          }
        }
        lumiError=nominalLumi*lumiRelError;

        TXMLNode* mnode = node->GetChildren();
        while( mnode != 0 ) {
          if( mnode->GetNodeName() == TString( "POI" ) ) {
            POI=mnode->GetText();
          }
          if( mnode->GetNodeName() == TString( "ParamSetting" ) ) {
	    //            TListIter attribIt = mnode->GetAttributes();
            //TXMLAttr* curAttr = 0;
	    attribIt = mnode->GetAttributes();
	    curAttr = 0;
            while( ( curAttr = dynamic_cast< TXMLAttr* >( attribIt() ) ) != 0 ) {
              if( curAttr->GetName() == TString( "Const" ) ) {
                if(curAttr->GetValue()==TString("True")){
                  AddSubStrings(systToFix, mnode->GetText());
                }
              }
            }
          }
          if( mnode->GetNodeName() == TString( "ConstraintTerm" ) ) {
            vector<string> syst; string type = ""; double rel = 0;
            AddSubStrings(syst,mnode->GetText());
	    //            TListIter attribIt = mnode->GetAttributes();
	    //            TXMLAttr* curAttr = 0;
	    attribIt = mnode->GetAttributes();
            curAttr = 0;
            while( ( curAttr = dynamic_cast< TXMLAttr* >( attribIt() ) ) != 0 ) {
              if( curAttr->GetName() == TString( "Type" ) ) {
                type = curAttr->GetValue();
              }
              if( curAttr->GetName() == TString( "RelativeUncertainty" ) ) {
                rel = atof(curAttr->GetValue());
              }
            }
            if (type=="Gamma" && rel!=0) {
              for (vector<string>::const_iterator it=syst.begin(); it!=syst.end(); it++) gammaSyst[(*it).c_str()] = rel;
            }
            if (type=="Uniform" && rel!=0) {
              for (vector<string>::const_iterator it=syst.begin(); it!=syst.end(); it++) uniformSyst[(*it).c_str()] = rel;
            }
            if (type=="LogNormal" && rel!=0) {
              for (vector<string>::const_iterator it=syst.begin(); it!=syst.end(); it++) logNormSyst[(*it).c_str()] = rel;
            }
          }
          mnode = mnode->GetNextNode();
        }

        /* Do measurement */
        cout << "using lumi = " << nominalLumi << " and lumiError = " << lumiError
             << " including bins between " << lowBin << " and " << highBin << endl;
        cout << "fixing the following parameters:"  << endl;
        for(vector<string>::iterator itr=systToFix.begin(); itr!=systToFix.end(); ++itr){
          cout << "   " << *itr << endl;
        }

        /***
            Construction of Model. Only requirement is that they return vector<vector<EstimateSummary> >
	    This is where we use the factory.
        ***/

        vector<vector<EstimateSummary> > summaries;
        if(xml_input.empty()){
          cerr << "no input channels found" << endl;
          exit(1);
        }

        vector<RooWorkspace*> chs;
        vector<string> ch_names;
        TFile* outFile = new TFile(outputFileName.c_str(), "recreate");
        HistoToWorkspaceFactory factory(outputFileNamePrefix, rowTitle, systToFix, nominalLumi, lumiError, lowBin, highBin , outFile);

        // for results tables
        fprintf(factory.pFile, " %s &", rowTitle.c_str() );

        // read the xml for each channel and combine
        for(vector<string>::iterator itr=xml_input.begin(); itr!=xml_input.end(); ++itr){
          vector<EstimateSummary> oneChannel;
          // read xml
          ReadXmlConfig(*itr, oneChannel, nominalLumi);
          // not really needed anymore
          summaries.push_back(oneChannel);
          // use factory to create the workspace
          string ch_name=oneChannel[0].channel;
          ch_names.push_back(ch_name);
          RooWorkspace * ws = factory.MakeSingleChannelModel(oneChannel, systToFix);
          chs.push_back(ws);
          // set poi in ModelConfig
          ModelConfig * proto_config = (ModelConfig *) ws->obj("ModelConfig");
          cout << "Setting Parameter of Interest as :" << POI << endl;
          RooRealVar* poi = (RooRealVar*) ws->var(POI.c_str());
          RooArgSet * params= new RooArgSet;
          params->add(*poi);
          proto_config->SetParameters(*params);

          // Gamma/Uniform Constraints:
          // turn some Gaussian constraints into Gamma/Uniform/LogNorm constraints, rename model newSimPdf
	  if(gammaSyst.size()>0 || uniformSyst.size()>0 || logNormSyst.size()>0) {
	    factory.EditSyst(ws,("model_"+oneChannel[0].channel).c_str(),gammaSyst,uniformSyst,logNormSyst);
	    proto_config->SetPdf(*ws->pdf("newSimPdf"));
          }

	  // fill out ModelConfig and export
          RooAbsData* expData = ws->data("expData");
	  proto_config->GuessObsAndNuisance(*expData);
	  ws->writeToFile((outputFileNamePrefix+"_"+ch_name+"_"+rowTitle+"_model.root").c_str());

	  // do fit unless exportOnly requested
	  if(!exportOnly)
	    factory.FitModel(ws, ch_name, "newSimPdf", "expData", false);
          fprintf(factory.pFile, " & " );
        }

        /***
	    Make the combined model:
            If you want output histograms in root format, create and pass it to the combine routine.
            "combine" : will do the individual cross-section measurements plus combination

        ***/

        if(mode.find("comb")!=string::npos){
          RooWorkspace* ws=factory.MakeCombinedModel(ch_names,chs);
          // Gamma/Uniform Constraints:
          // turn some Gaussian constraints into Gamma/Uniform/logNormal constraints, rename model newSimPdf
	  if(gammaSyst.size()>0 || uniformSyst.size()>0 || logNormSyst.size()>0)
	    factory.EditSyst(ws,"simPdf",gammaSyst,uniformSyst,logNormSyst);
          //
          // set parameter of interest according to the configuration
          //
          ModelConfig * combined_config = (ModelConfig *) ws->obj("ModelConfig");
          cout << "Setting Parameter of Interest as :" << POI << endl;
          RooRealVar* poi = (RooRealVar*) ws->var((POI).c_str());
          //RooRealVar* poi = (RooRealVar*) ws->var((POI+"_comb").c_str());
          RooArgSet * params= new RooArgSet;
          cout << poi << endl;
          params->add(*poi);
          combined_config->SetParameters(*params);
          ws->Print();

          // Set new PDF if there are gamma/uniform constraint terms
          if(gammaSyst.size()>0 || uniformSyst.size()>0 || logNormSyst.size()>0)
	    combined_config->SetPdf(*ws->pdf("newSimPdf"));

          RooAbsData* simData = ws->data("simData");
	  combined_config->GuessObsAndNuisance(*simData);
	  //	  ws->writeToFile(("results/model_combined_edited.root").c_str());
	  ws->writeToFile((outputFileNamePrefix+"_combined_"+rowTitle+"_model.root").c_str());

	  // TO DO:
          // Totally factorize the statistical test in "fit Model" to a different area
	  if(!exportOnly)
	    factory.FitModel(ws, "combined", "simPdf", "simData", false);
        }

        fprintf(factory.pFile, " \\\\ \n");

        outFile->Close();
        delete outFile;

      }
      node = node->GetNextNode(); // next measurement
    }
  }
}

<|endoftext|>


<commit_before>///////////////////////////////////////////////////////////////////////////////
//
// File VortexWaveInteractionSolver.cpp
//
// For more information, please see: http://www.nektar.info
//
// The MIT License
//
// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
// Department of Aeronautics, Imperial College London (UK), and Scientific
// Computing and Imaging Institute, University of Utah (USA).
//
// License for the specific language governing rights and limitations under
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// Description: Vortex Wave Interaction solver
//
///////////////////////////////////////////////////////////////////////////////

#include <Auxiliary/Driver.h>
#include <LibUtilities/BasicUtils/SessionReader.h>

using namespace Nektar;

#include<VortexWaveInteraction/VortexWaveInteraction.h>

#if defined(_MSC_VER) && BOOST_VERSION > 104700
#include <windows.h>
#undef MoveFile
#endif

void DoFixedForcingIteration(VortexWaveInteraction &vwi);
void Mvdir(string dir, NekDouble dir_ending);

int main(int argc, char *argv[])
{
    try
    {
        VortexWaveInteraction vwi(argc,argv);

        for(int i = 0; i < vwi.GetMaxWaveForceMagIter(); ++i)
        {
            DoFixedForcingIteration(vwi);

            NekDouble WaveForce = vwi.GetWaveForceMag();

            vwi.AppendEvlToFile("ConvergedSolns",WaveForce);

            vwi.SetWaveForceMag(WaveForce + vwi.GetWaveForceMagStep());
            vwi.SetAlpha(vwi.GetAlpha() + vwi.GetDAlphaDWaveForceMag()*vwi.GetWaveForceMagStep());

            // Save data directories.
            if(vwi.GetVWIIterationType() == eFixedAlphaWaveForcing)
            {
                Mvdir("Save",WaveForce);
            }
            else
            {
                Mvdir("Save_Outer",WaveForce);
                // Execute Another loop so that not same initial conditions as last iteration
                vwi.ExecuteLoop();
            }
        }
    }

    catch (const std::runtime_error&)
    {
        return 1;
    }

    catch (const std::string& eStr)
    {
        cout << "Error: " << eStr << endl;
    }
}

void Mvdir(string dir, NekDouble dir_ending)
{
    // save OuterIter.his if exists
    string saveOuterIter = "mv -f OuterIter.his "+ dir;
    if(system(saveOuterIter.c_str()))
    {
        ASSERTL0(false,saveOuterIter.c_str());
    }

    // Mv directory
    string newdir  = dir + boost::lexical_cast<std::string>(dir_ending);
    string syscall = "mv -f " + dir + " " + newdir;

    if(system(syscall.c_str()))
    {
        ASSERTL0(false,syscall.c_str());
    }

    // make new directory
    syscall = "mkdir " + dir;
    system(syscall.c_str());
}

void DoFixedForcingIteration(VortexWaveInteraction &vwi)
{

    // Reset eigenvalue checker in case used in previous iterations
    vwi.CheckEigIsStationary(true);

    switch(vwi.GetVWIIterationType())
    {
    case eFixedAlpha:
        {
            int i;
            int nouter_iter = vwi.GetNOuterIterations();
            bool exit_iteration = false;

            while(exit_iteration == false)
            {
                // Reset eigenvalue checker in case used in previous iterations
                vwi.CheckEigIsStationary(true);

                for(i = vwi.GetIterStart(); i < vwi.GetIterEnd(); ++i)
                {
                    vwi.ExecuteLoop();
                    vwi.SaveLoopDetails("Save", i);
                    vwi.AppendEvlToFile("conv.his",i);

                    if(vwi.CheckEigIsStationary())
                    {
                        vwi.SaveLoopDetails("Save_Outer", nouter_iter);
                        break;
                    }
                }

                // check to see if growth was converged.
                if(i == vwi.GetIterEnd())
                {
                    cout << "Failed to converge growth rate in" <<
                        " inner iteration after " << vwi.GetIterEnd()
                         << " loops" << endl;
                    exit(1);
                }

                vwi.AppendEvlToFile("OuterIter.his",nouter_iter++);
                exit_iteration = vwi.CheckIfAtNeutralPoint();
                if(exit_iteration == false)
                {
                    vwi.UpdateWaveForceMag(nouter_iter);
                }

                if(nouter_iter >= vwi.GetMaxOuterIterations())
                {
                    cerr << "Failed to converge after "<< vwi.GetMaxOuterIterations() << " outer iterations" << endl;
                    exit_iteration = true;
                }
            }

        }
    case eFixedWaveForcing:
    case eFixedWaveForcingPhase:
        {
            int i;
            int nouter_iter = vwi.GetNOuterIterations();
            bool exit_iteration = false;
            NekDouble alpha_init = vwi.GetAlpha();
	    NekDouble saveEigRelTol = vwi.GetEigRelTol();
	    int saveMinIters = vwi.GetMinInnerIterations();
	    int init_search = 1;

	    // initial set m_eigelTol to 1e-1 and inner iterations to 1 for
	    // quick search
	    vwi.SetEigRelTol(1e-1);
	    vwi.SetMinInnerIterations(2);

            while(exit_iteration == false)
            {
                // Reset eigenvalue checker in case used in previous iterations
                vwi.CheckEigIsStationary(true);

                for(i = vwi.GetIterStart(); i < vwi.GetIterEnd(); ++i)
                {
                    vwi.ExecuteLoop();
                    vwi.SaveLoopDetails("Save", i);
                    vwi.AppendEvlToFile("conv.his",i);
		    if(vwi.CheckEigIsStationary())
		      {
                        vwi.SaveLoopDetails("Save_Outer", nouter_iter);
                        break;
		      }
                }

                // check to see if growth was converged.
                if(i == vwi.GetIterEnd() )
                {
                    cout << "Failed to converge growth rate in" <<
                        " inner iteration after " << vwi.GetIterEnd()
                         << " loops" << endl;
                    exit(1);
                }

                vwi.AppendEvlToFile("OuterIter.his",nouter_iter++);

		exit_iteration = vwi.CheckIfAtNeutralPoint();

		// Redo iteration if at first coarse search
		if((exit_iteration == true) && (init_search == 1))
		{
		  init_search = 0;
		  vwi.SetEigRelTol(saveEigRelTol);
		  vwi.SetMinInnerIterations(saveMinIters);
		  nouter_iter = 1;
		  exit_iteration = false;
		}
		else
                {
                    vwi.UpdateAlpha(nouter_iter);
                }

                if(nouter_iter >= vwi.GetMaxOuterIterations())
                {
                    cerr << "Failed to converge after "<< vwi.GetMaxOuterIterations() << " outer iterations" << endl;
		    exit_iteration = true;
                }
            }

            vwi.UpdateDAlphaDWaveForceMag(alpha_init);

        }
        break;
    case eFixedAlphaWaveForcing:

        for(int i = vwi.GetIterStart(); i < vwi.GetIterEnd(); ++i)
        {
            vwi.ExecuteLoop();
            vwi.SaveLoopDetails("Save",i);
            vwi.AppendEvlToFile("conv.his",i);
        }
        break;
    case eFixedWaveForcingWithSubIterationOnAlpha:
        {
            int i;
            int nouter_iter = vwi.GetNOuterIterations();
            bool exit_iteration = false;

            while(exit_iteration == false)
            {
                bool exit_alphaIter = false;

                vwi.ExecuteLoop(false);

                // Sub iterate Alpha
                for(i = 0; i < vwi.GetIterEnd(); ++i)
                {
                    vwi.SaveLoopDetails("Save", i);

                    vwi.AppendEvlToFile("AlphaIter.his",i);

                    exit_alphaIter = vwi.CheckIfAtNeutralPoint();
                    if(exit_alphaIter == false)
                    {
                        vwi.UpdateAlpha(i+1);
                        vwi.ExecuteWave();
                    }
                    else
                    {
                        vwi.CalcNonLinearWaveForce();
                        break;
                    }
                }

                // check to see if growth was converged.
                if(i == vwi.GetIterEnd())
                {
                    cout << "Failed to converge growth rate in" <<
                        " inner iteration after " << vwi.GetIterEnd()
                         << " loops" << endl;
                    exit(1);
                }

                vwi.MoveFile("AlphaIter.his","Save_Outer", nouter_iter);
                vwi.SaveLoopDetails("Save_Outer", nouter_iter);
                vwi.AppendEvlToFile("OuterIter.his",nouter_iter++);

                // assume that if only previous inner loop has
                // only done one iteration then we are at neutral
                // point
                if (i == 0  && vwi.IfIterInterface()==false)
                {
                    exit_iteration = true;
                }

                if(nouter_iter >= vwi.GetMaxOuterIterations())
                {
                    cerr << "Failed to converge after "<< vwi.GetMaxOuterIterations() << " outer iterations" << endl;
                    exit_iteration = true;
                }
            }
        }
        break;
    default:
        ASSERTL0(false,"Unknown iteration type");
    }

}

<commit_msg>Hopefullly fix io issue dumping Alpha in ConvergedSolns<commit_after>///////////////////////////////////////////////////////////////////////////////
//
// File VortexWaveInteractionSolver.cpp
//
// For more information, please see: http://www.nektar.info
//
// The MIT License
//
// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
// Department of Aeronautics, Imperial College London (UK), and Scientific
// Computing and Imaging Institute, University of Utah (USA).
//
// License for the specific language governing rights and limitations under
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// Description: Vortex Wave Interaction solver
//
///////////////////////////////////////////////////////////////////////////////

#include <Auxiliary/Driver.h>
#include <LibUtilities/BasicUtils/SessionReader.h>

using namespace Nektar;

#include<VortexWaveInteraction/VortexWaveInteraction.h>

#if defined(_MSC_VER) && BOOST_VERSION > 104700
#include <windows.h>
#undef MoveFile
#endif

void DoFixedForcingIteration(VortexWaveInteraction &vwi);
void Mvdir(string dir, NekDouble dir_ending);

int main(int argc, char *argv[])
{
    try
    {
        VortexWaveInteraction vwi(argc,argv);

        for(int i = 0; i < vwi.GetMaxWaveForceMagIter(); ++i)
        {
            DoFixedForcingIteration(vwi);

            NekDouble WaveForce = vwi.GetWaveForceMag();

            vwi.AppendEvlToFile("ConvergedSolns",WaveForce);

            vwi.SetWaveForceMag(WaveForce + vwi.GetWaveForceMagStep());
            vwi.SetAlpha(vwi.GetAlpha() + vwi.GetDAlphaDWaveForceMag()*vwi.GetWaveForceMagStep());

            // Save data directories.
            if(vwi.GetVWIIterationType() == eFixedAlphaWaveForcing)
            {
                Mvdir("Save",WaveForce);
            }
            else
            {
                Mvdir("Save_Outer",WaveForce);
                // Execute Another loop so that not same initial conditions as last iteration
                vwi.ExecuteLoop();
            }
        }
    }

    catch (const std::runtime_error&)
    {
        return 1;
    }

    catch (const std::string& eStr)
    {
        cout << "Error: " << eStr << endl;
    }
}

void Mvdir(string dir, NekDouble dir_ending)
{
    // save OuterIter.his if exists
    string saveOuterIter = "mv -f OuterIter.his "+ dir;
    if(system(saveOuterIter.c_str()))
    {
        ASSERTL0(false,saveOuterIter.c_str());
    }

    // Mv directory
    string newdir  = dir + boost::lexical_cast<std::string>(dir_ending);
    string syscall = "mv -f " + dir + " " + newdir;

    if(system(syscall.c_str()))
    {
        ASSERTL0(false,syscall.c_str());
    }

    // make new directory
    syscall = "mkdir " + dir;
    system(syscall.c_str());
}

void DoFixedForcingIteration(VortexWaveInteraction &vwi)
{

    // Reset eigenvalue checker in case used in previous iterations
    vwi.CheckEigIsStationary(true);

    switch(vwi.GetVWIIterationType())
    {
    case eFixedAlpha:
        {
            int i;
            int nouter_iter = vwi.GetNOuterIterations();
            bool exit_iteration = false;

            while(exit_iteration == false)
            {
                // Reset eigenvalue checker in case used in previous iterations
                vwi.CheckEigIsStationary(true);

                for(i = vwi.GetIterStart(); i < vwi.GetIterEnd(); ++i)
                {
                    vwi.ExecuteLoop();
                    vwi.SaveLoopDetails("Save", i);
                    vwi.AppendEvlToFile("conv.his",i);

                    if(vwi.CheckEigIsStationary())
                    {
                        vwi.SaveLoopDetails("Save_Outer", nouter_iter);
                        break;
                    }
                }

                // check to see if growth was converged.
                if(i == vwi.GetIterEnd())
                {
                    cout << "Failed to converge growth rate in" <<
                        " inner iteration after " << vwi.GetIterEnd()
                         << " loops" << endl;
                    exit(1);
                }

                vwi.AppendEvlToFile("OuterIter.his",nouter_iter++);
                exit_iteration = vwi.CheckIfAtNeutralPoint();
                if(exit_iteration == false)
                {
                    vwi.UpdateWaveForceMag(nouter_iter);
                }

                if(nouter_iter >= vwi.GetMaxOuterIterations())
                {
                    cerr << "Failed to converge after "<< vwi.GetMaxOuterIterations() << " outer iterations" << endl;
                    exit_iteration = true;
                }
            }

        }
    case eFixedWaveForcing:
    case eFixedWaveForcingPhase:
        {
            int i;
            int nouter_iter = vwi.GetNOuterIterations();
            bool exit_iteration = false;
            NekDouble alpha_init = vwi.GetAlpha();
	    NekDouble saveEigRelTol = vwi.GetEigRelTol();
	    int saveMinIters = vwi.GetMinInnerIterations();
	    int init_search = 1;

	    // initial set m_eigelTol to 1e-1 and inner iterations to 1 for
	    // quick search
	    vwi.SetEigRelTol(1e-1);
	    vwi.SetMinInnerIterations(2);

            while(exit_iteration == false)
            {
                // Reset eigenvalue checker in case used in previous iterations
                vwi.CheckEigIsStationary(true);

                for(i = vwi.GetIterStart(); i < vwi.GetIterEnd(); ++i)
                {
                    vwi.ExecuteLoop();
                    vwi.SaveLoopDetails("Save", i);
                    vwi.AppendEvlToFile("conv.his",i);
		    if(vwi.CheckEigIsStationary())
		      {
                        vwi.SaveLoopDetails("Save_Outer", nouter_iter);
                        break;
		      }
                }

                // check to see if growth was converged.
                if(i == vwi.GetIterEnd() )
                {
                    cout << "Failed to converge growth rate in" <<
                        " inner iteration after " << vwi.GetIterEnd()
                         << " loops" << endl;
                    exit(1);
                }

                vwi.AppendEvlToFile("OuterIter.his",nouter_iter++);

		exit_iteration = vwi.CheckIfAtNeutralPoint();

                if(exit_iteration == false)
                {
                    vwi.UpdateAlpha(nouter_iter);
                }

		// Redo iteration if at first coarse search
		if((exit_iteration == true) && (init_search == 1))
		{
		  init_search = 0;
		  vwi.SetEigRelTol(saveEigRelTol);
		  vwi.SetMinInnerIterations(saveMinIters);
		  nouter_iter = 1;
		  exit_iteration = false;
		}

                if(nouter_iter >= vwi.GetMaxOuterIterations())
                {
                    cerr << "Failed to converge after "<< vwi.GetMaxOuterIterations() << " outer iterations" << endl;
		    exit_iteration = true;
                }
            }

            vwi.UpdateDAlphaDWaveForceMag(alpha_init);

        }
        break;
    case eFixedAlphaWaveForcing:

        for(int i = vwi.GetIterStart(); i < vwi.GetIterEnd(); ++i)
        {
            vwi.ExecuteLoop();
            vwi.SaveLoopDetails("Save",i);
            vwi.AppendEvlToFile("conv.his",i);
        }
        break;
    case eFixedWaveForcingWithSubIterationOnAlpha:
        {
            int i;
            int nouter_iter = vwi.GetNOuterIterations();
            bool exit_iteration = false;

            while(exit_iteration == false)
            {
                bool exit_alphaIter = false;

                vwi.ExecuteLoop(false);

                // Sub iterate Alpha
                for(i = 0; i < vwi.GetIterEnd(); ++i)
                {
                    vwi.SaveLoopDetails("Save", i);

                    vwi.AppendEvlToFile("AlphaIter.his",i);

                    exit_alphaIter = vwi.CheckIfAtNeutralPoint();
                    if(exit_alphaIter == false)
                    {
                        vwi.UpdateAlpha(i+1);
                        vwi.ExecuteWave();
                    }
                    else
                    {
                        vwi.CalcNonLinearWaveForce();
                        break;
                    }
                }

                // check to see if growth was converged.
                if(i == vwi.GetIterEnd())
                {
                    cout << "Failed to converge growth rate in" <<
                        " inner iteration after " << vwi.GetIterEnd()
                         << " loops" << endl;
                    exit(1);
                }

                vwi.MoveFile("AlphaIter.his","Save_Outer", nouter_iter);
                vwi.SaveLoopDetails("Save_Outer", nouter_iter);
                vwi.AppendEvlToFile("OuterIter.his",nouter_iter++);

                // assume that if only previous inner loop has
                // only done one iteration then we are at neutral
                // point
                if (i == 0  && vwi.IfIterInterface()==false)
                {
                    exit_iteration = true;
                }

                if(nouter_iter >= vwi.GetMaxOuterIterations())
                {
                    cerr << "Failed to converge after "<< vwi.GetMaxOuterIterations() << " outer iterations" << endl;
                    exit_iteration = true;
                }
            }
        }
        break;
    default:
        ASSERTL0(false,"Unknown iteration type");
    }

}

<|endoftext|>


<commit_before>#include <vector>
#include <rdomacros.h>
#include <rdotypes.h>
#include <rdodebug.h>

template<class T>
class ContainerVector
{
public:
	typedef T                                  Item;
	typedef std::vector<Item>                  Container;
	typedef typename Container::iterator       Iterator;
	typedef typename Container::const_iterator CIterator;

	Iterator  begin()       { return m_list.begin(); }
	Iterator  end  ()       { return m_list.end  (); }
	CIterator begin() const { return m_list.begin(); }
	CIterator end  () const { return m_list.end  (); }
	rbool     empty() const { return m_list.empty(); }

	REF(ContainerVector) operator() (CREF(Item) item)
	{
		m_list.push_back(item);
		return *this;
	}

private:
	Container m_list;
};

template <class Container>
class OrderFIFO
{
public:
	static typename Container::CIterator getFirst(CREF(Container) container)
	{
		return container.begin();
	}
};

template <class Container>
class OrderLIFO
{
public:
	static typename Container::CIterator getFirst(CREF(Container) container)
	{
		if (container.empty())
			return container.end();

		Container::CIterator last = container.end();
		--last;
		return last;
	}
};

template <class Container>
class OrderFIFOCashed
{
public:
	OrderFIFOCashed()
		: m_inited(false)
	{}
	typename Container::CIterator getFirst(CREF(Container) container)
	{
		m_lastItemIt = container.begin();
		m_inited     = true;
		return m_lastItemIt;
	}

private:
	rbool                         m_inited;
	typename Container::CIterator m_lastItemIt;
};

template <class Container, class Order>
class Queue
{
public:
	typename Container::CIterator getFirst(CREF(Container) container) const
	{
		return Order::getFirst(container);
	}
	typename Container::CIterator getFirst(CREF(Container) container, REF(Order) order) const
	{
		return order.getFirst(container);
	}
};

void main()
{
	typedef ruint                  Item;
	typedef ContainerVector<Item>  Container;
	Container ontainer;
	ontainer(1)(2)(4)(3);

	{
		Queue<Container, OrderFIFO<Container> > queue;
		Container::CIterator it = queue.getFirst(ontainer);
		int i = 1;
	}
	{
		Queue<Container, OrderLIFO<Container> > queue;
		Container::CIterator it = queue.getFirst(ontainer);
		int i = 1;
	}
	{
		OrderFIFOCashed<Container> order;
		Queue<Container, OrderFIFOCashed<Container> > queue;
		Container::CIterator it = queue.getFirst(ontainer, order);
		int i = 1;
	}
}
<commit_msg>* добавлен класс логики, запараметризован дисциплиной<commit_after>#include <vector>
#include <algorithm>
#include <rdomacros.h>
#include <rdotypes.h>
#include <rdodebug.h>

class MyOperation
{
public:
	MyOperation(ruint dummy)
		: m_dummy(dummy)
	{}
	rbool operator< (CREF(MyOperation) opr) const
	{
		return m_dummy < opr.m_dummy;
	}

private:
	ruint m_dummy;
};

template <class T, class C = std::vector<T> >
class Container
{
public:
	typedef T                             Item;
	typedef C                             List;
	typedef typename List::iterator       Iterator;
	typedef typename List::const_iterator CIterator;

	Iterator  begin()       { return m_list.begin(); }
	Iterator  end  ()       { return m_list.end  (); }
	CIterator begin() const { return m_list.begin(); }
	CIterator end  () const { return m_list.end  (); }
	rbool     empty() const { return m_list.empty(); }

	REF(Container) operator() (CREF(Item) item)
	{
		m_list.push_back(item);
		return *this;
	}

private:
	List m_list;
};

class OrderFIFO
{
public:
	template <class Container>
	static void sort(REF(Container) container)
	{}
};

class OrderLIFO
{
public:
	template <class Container>
	static void sort(REF(Container) container)
	{
		std::reverse(container.begin(), container.end());
	}
};

class OrderPrior
{
public:
	template <class Container>
	static void sort(REF(Container) container)
	{
		std::sort(container.begin(), container.end());
	}
};

template <class Order>
class Logic
{
public:
	Logic()
	{
		m_ontainer(1)(2)(4)(3);
	}
	rbool checkOperation()
	{
		Order::sort(m_ontainer);
		return true;
	}

private:
	typedef MyOperation              Item;
	typedef Container<Item>          Container;

	Container  m_ontainer;
};

void main()
{
	{
		Logic<OrderFIFO> logic;
		logic.checkOperation();
		int i = 1;
	}
	{
		Logic<OrderLIFO> logic;
		logic.checkOperation();
		int i = 1;
	}
	{
		Logic<OrderPrior> logic;
		logic.checkOperation();
		int i = 1;
	}
}
<|endoftext|>


<commit_before>#pragma once

#include <string>

#include "acmacs-base/sfinae.hh"
#include "acmacs-base/size.hh"
#include "acmacs-base/color.hh"
#include "acmacs-base/field.hh"
#include "acmacs-base/string.hh"

// ----------------------------------------------------------------------

namespace acmacs
{

    class FontSlant
    {
     public:
        enum Value { Normal, Italic };

        FontSlant(Value aFontSlant = Normal) : mFontSlant{aFontSlant} {}
        FontSlant(const FontSlant&) = default;
        FontSlant(std::string aFontSlant) { from(aFontSlant); }
        FontSlant(std::string_view aFontSlant) { from(aFontSlant); }
        FontSlant(const char* aFontSlant) { from(aFontSlant); }
        FontSlant& operator=(const FontSlant&) = default;
        FontSlant& operator=(std::string aFontSlant) { from(aFontSlant); return *this; }
        FontSlant& operator=(std::string_view aFontSlant) { from(aFontSlant); return *this; }

        operator std::string() const
            {
                switch (mFontSlant) {
                  case Normal:
                      return "normal";
                  case Italic:
                      return "italic";
                }
                return "normal";
            }

        operator Value() const { return mFontSlant; }

     private:
        Value mFontSlant;

        template <typename S, typename = std::enable_if_t<acmacs::sfinae::is_string_v<S>>> void from(S aFontSlant)
            {
                if (aFontSlant == "normal")
                    mFontSlant = Normal;
                else if (aFontSlant == "italic")
                    mFontSlant = Italic;
                else
                    std::runtime_error(::string::concat("Unrecognized slant: ", aFontSlant));
            }

    }; // class FontSlant

    inline std::string to_string(const FontSlant& slant) { return slant; }

// ----------------------------------------------------------------------

    class FontWeight
    {
     public:
        enum Value { Normal, Bold };

        FontWeight(Value aFontWeight = Normal) : mFontWeight{aFontWeight} {}
        FontWeight(const FontWeight&) = default;
        FontWeight(std::string aFontWeight) { from(aFontWeight); }
        FontWeight(std::string_view aFontWeight) { from(aFontWeight); }
        FontWeight(const char* aFontWeight) { from(aFontWeight); }
        FontWeight& operator=(const FontWeight&) = default;
        FontWeight& operator=(std::string aFontWeight) { from(aFontWeight); return *this; }
        FontWeight& operator=(std::string_view aFontWeight) { from(aFontWeight); return *this; }

        operator std::string() const
            {
                switch (mFontWeight) {
                  case Normal:
                      return "normal";
                  case Bold:
                      return "bold";
                }
                return "normal";
            }

        operator Value() const { return mFontWeight; }

     private:
        Value mFontWeight;

        template <typename S, typename = std::enable_if_t<acmacs::sfinae::is_string_v<S>>> void from(S aFontWeight)
            {
                if (aFontWeight == "normal")
                    mFontWeight = Normal;
                else if (aFontWeight == "bold")
                    mFontWeight = Bold;
                else
                    std::runtime_error(::string::concat("Unrecognized weight: ", aFontWeight));
            }

    }; // class FontWeight

    inline std::string to_string(const FontWeight& weight) { return weight; }

// ----------------------------------------------------------------------

    class TextStyle
    {
     public:
        template <typename T> using field = acmacs::detail::field_optional_with_default<T>;

        TextStyle() = default;
        template <typename S, typename = sfinae::string_only_t<S>> TextStyle(S font_name) : font_family{acmacs::to_string(font_name)} {}

        [[nodiscard]] bool operator==(const TextStyle& ts) const
            {
                return slant == ts.slant && weight == ts.weight && font_family == ts.font_family;
            }

        field<FontSlant> slant;
        field<FontWeight> weight;
        field<std::string> font_family;

    }; // class TextStyle

    inline std::string to_string(const TextStyle& style)
    {
        return ::string::concat("{slant:", to_string(*style.slant), " weight:", to_string(*style.weight), " familiy:", *style.font_family, '}');
    }

    inline std::ostream& operator<<(std::ostream& out, const TextStyle& ts) { return out << to_string(ts); }

// ----------------------------------------------------------------------

    class LabelStyle
    {
     public:
        template <typename T> using field = acmacs::detail::field_optional_with_default<T>;

        [[nodiscard]] bool operator==(const LabelStyle& ls) const
            {
                return shown == ls.shown && offset == ls.offset && size == ls.size && color == ls.color
                        && rotation == ls.rotation && interline == ls.interline && style == ls.style;
            }
        [[nodiscard]] bool operator!=(const LabelStyle& rhs) const { return !operator==(rhs); }

        field<bool> shown{true};
        field<Offset> offset{sOffsetDefault};
        field<Pixels> size{Pixels{10.0}};
        field<Color> color{BLACK};
        field<Rotation> rotation{NoRotation};
        field<double> interline{0.2};
        TextStyle style;

     private:
        static const Offset sOffsetDefault;

    }; // class LabelStyle

    inline std::string to_string(const LabelStyle& style)
    {
        return ::string::concat(" shown:", *style.shown, " p:", to_string(*style.offset), " s:", to_string(*style.size), " c:", to_string(*style.color), " r:", to_string(*style.rotation), " i:", to_string(*style.interline, 2), ' ', to_string(style.style));
    }

} // namespace acmacs

// ----------------------------------------------------------------------
/// Local Variables:
/// eval: (if (fboundp 'eu-rename-buffer) (eu-rename-buffer))
/// End:
<commit_msg>bug fix in string comparing<commit_after>#pragma once

#include <string>

#include "acmacs-base/sfinae.hh"
#include "acmacs-base/size.hh"
#include "acmacs-base/color.hh"
#include "acmacs-base/field.hh"
#include "acmacs-base/string.hh"

// ----------------------------------------------------------------------

namespace acmacs
{

    class FontSlant
    {
     public:
        enum Value { Normal, Italic };

        FontSlant(Value aFontSlant = Normal) : mFontSlant{aFontSlant} {}
        FontSlant(const FontSlant&) = default;
        FontSlant(std::string aFontSlant) { from(aFontSlant); }
        FontSlant(std::string_view aFontSlant) { from(aFontSlant); }
        FontSlant(const char* aFontSlant) { from(aFontSlant); }
        FontSlant& operator=(const FontSlant&) = default;
        FontSlant& operator=(std::string aFontSlant) { from(aFontSlant); return *this; }
        FontSlant& operator=(std::string_view aFontSlant) { from(aFontSlant); return *this; }

        operator std::string() const
            {
                switch (mFontSlant) {
                  case Normal:
                      return "normal";
                  case Italic:
                      return "italic";
                }
                return "normal";
            }

        operator Value() const { return mFontSlant; }

     private:
        Value mFontSlant;

        template <typename S, typename = std::enable_if_t<acmacs::sfinae::is_string_v<S>>> void from(S aFontSlant)
        {
            const auto eq = [](auto&& lh, auto&& rh) {
                if constexpr (std::is_same_v<std::decay_t<decltype(lh)>, const char*>)
                    return std::string_view(lh) == rh;
                else
                    return lh == rh;
            };

            if (eq(aFontSlant, "normal"))
                mFontSlant = Normal;
            else if (eq(aFontSlant, "italic"))
                mFontSlant = Italic;
            else
                std::runtime_error(::string::concat("Unrecognized slant: ", aFontSlant));
        }

    }; // class FontSlant

    inline std::string to_string(const FontSlant& slant) { return slant; }

// ----------------------------------------------------------------------

    class FontWeight
    {
     public:
        enum Value { Normal, Bold };

        FontWeight(Value aFontWeight = Normal) : mFontWeight{aFontWeight} {}
        FontWeight(const FontWeight&) = default;
        FontWeight(std::string aFontWeight) { from(aFontWeight); }
        FontWeight(std::string_view aFontWeight) { from(aFontWeight); }
        FontWeight(const char* aFontWeight) { from(aFontWeight); }
        FontWeight& operator=(const FontWeight&) = default;
        FontWeight& operator=(std::string aFontWeight) { from(aFontWeight); return *this; }
        FontWeight& operator=(std::string_view aFontWeight) { from(aFontWeight); return *this; }

        operator std::string() const
            {
                switch (mFontWeight) {
                  case Normal:
                      return "normal";
                  case Bold:
                      return "bold";
                }
                return "normal";
            }

        operator Value() const { return mFontWeight; }

     private:
        Value mFontWeight;

        template <typename S, typename = std::enable_if_t<acmacs::sfinae::is_string_v<S>>> void from(S aFontWeight)
        {
            const auto eq = [](auto&& lh, auto&& rh) {
                if constexpr (std::is_same_v<std::decay_t<decltype(lh)>, const char*>)
                    return std::string_view(lh) == rh;
                else
                    return lh == rh;
            };

            if (eq(aFontWeight, "normal"))
                mFontWeight = Normal;
            else if (eq(aFontWeight, "bold"))
                mFontWeight = Bold;
            else
                std::runtime_error(::string::concat("Unrecognized weight: ", aFontWeight));
        }

    }; // class FontWeight

    inline std::string to_string(const FontWeight& weight) { return weight; }

// ----------------------------------------------------------------------

    class TextStyle
    {
     public:
        template <typename T> using field = acmacs::detail::field_optional_with_default<T>;

        TextStyle() = default;
        template <typename S, typename = sfinae::string_only_t<S>> TextStyle(S font_name) : font_family{acmacs::to_string(font_name)} {}

        [[nodiscard]] bool operator==(const TextStyle& ts) const
            {
                return slant == ts.slant && weight == ts.weight && font_family == ts.font_family;
            }

        field<FontSlant> slant;
        field<FontWeight> weight;
        field<std::string> font_family;

    }; // class TextStyle

    inline std::string to_string(const TextStyle& style)
    {
        return ::string::concat("{slant:", to_string(*style.slant), " weight:", to_string(*style.weight), " familiy:", *style.font_family, '}');
    }

    inline std::ostream& operator<<(std::ostream& out, const TextStyle& ts) { return out << to_string(ts); }

// ----------------------------------------------------------------------

    class LabelStyle
    {
     public:
        template <typename T> using field = acmacs::detail::field_optional_with_default<T>;

        [[nodiscard]] bool operator==(const LabelStyle& ls) const
            {
                return shown == ls.shown && offset == ls.offset && size == ls.size && color == ls.color
                        && rotation == ls.rotation && interline == ls.interline && style == ls.style;
            }
        [[nodiscard]] bool operator!=(const LabelStyle& rhs) const { return !operator==(rhs); }

        field<bool> shown{true};
        field<Offset> offset{sOffsetDefault};
        field<Pixels> size{Pixels{10.0}};
        field<Color> color{BLACK};
        field<Rotation> rotation{NoRotation};
        field<double> interline{0.2};
        TextStyle style;

     private:
        static const Offset sOffsetDefault;

    }; // class LabelStyle

    inline std::string to_string(const LabelStyle& style)
    {
        return ::string::concat(" shown:", *style.shown, " p:", to_string(*style.offset), " s:", to_string(*style.size), " c:", to_string(*style.color), " r:", to_string(*style.rotation), " i:", to_string(*style.interline, 2), ' ', to_string(style.style));
    }

} // namespace acmacs

// ----------------------------------------------------------------------
/// Local Variables:
/// eval: (if (fboundp 'eu-rename-buffer) (eu-rename-buffer))
/// End:
<|endoftext|>


<commit_before><commit_msg>fixed ReadColour (must be independent from screen gfx format)<commit_after><|endoftext|>


<commit_before>#include "stdafx.h"

DebugRenderer debugRenderer;

static void InitVertex(MeshVertex& v, BONE_ID boneId, DWORD color)
{
	v.blendIndices.x = v.blendIndices.y = v.blendIndices.z = v.blendIndices.w = boneId;
	v.color = color;
	v.blendWeights.x = v.blendWeights.y = v.blendWeights.z = 0;
	v.normal.x = 1;
	v.normal.y = 0;
	v.normal.z = 0;
	v.uv.x = v.uv.y = 0;
	v.xyz.x = v.xyz.y = v.xyz.z = 0;
}

static inline float len(XMVECTOR v) {
	return XMVectorGetX(XMVector3Length(v));
}

void CreateCone(Block& b, XMVECTOR v1, XMVECTOR v2, BONE_ID boneId, DWORD color)
{
	float radius = 0.15f;
	XMVECTOR boneDir = XMVectorSubtract(v2, v1);
	XMVECTOR vRot0 = XMVector3Cross(boneDir, XMVectorSet(0, 0, radius, 0));
	if (len(vRot0) < 0.001f) {
		vRot0 = XMVector3Cross(boneDir, XMVectorSet(0, radius, 0, 0));
	}
	XMVECTOR vRot90 = XMVector3Cross(vRot0, XMVector3Normalize(boneDir));
	XMVECTOR vRotLast = XMVectorAdd(v1, vRot0);
	static const int div = 10;
	for (int j = 0; j < div; j++) {
		MeshVertex vert[3];
		for (auto& it : vert) {
			InitVertex(it, boneId, color);
		}
		float rad = XM_2PI / div * (j + 1);
		XMVECTOR vRot = XMVectorAdd(v1, XMVectorScale(vRot0, cosf(rad)) + XMVectorScale(vRot90, sinf(rad)));
		XMStoreFloat3(&vert[0].xyz, vRotLast);
		XMStoreFloat3(&vert[1].xyz, v2);
		XMStoreFloat3(&vert[2].xyz, vRot);
		XMVECTOR normal = XMVector3Cross(XMVectorSubtract(vRotLast, v2), XMVectorSubtract(v2, vRot));
		for (auto& it : vert) {
			XMStoreFloat3(&it.normal, normal);
			b.vertices.push_back(it);
			b.indices.push_back(b.indices.size());
		}
		vRotLast = vRot;
	}
}

void DebugRenderer::CreatePivotMesh()
{
	for (BONE_ID i = 0; (unsigned)i < BONE_MAX; i++)	{
		XMVECTOR v = XMVectorZero();
		float len = 50.0f;
		CreateCone(pivots, v, v + XMVectorSet(len, 0, 0, 0), i, 0xff0000ff);
		CreateCone(pivots, v, v + XMVectorSet(0, len, 0, 0), i, 0xff00ff00);
		CreateCone(pivots, v, v + XMVectorSet(0, 0, len, 0), i, 0xffff0000);
	}

	int sizeVertices = pivots.vertices.size() * sizeof(pivots.vertices[0]);
	int sizeIndices = pivots.indices.size() * sizeof(pivots.indices[0]);
	if (sizeVertices && sizeIndices) {
		pivotsRenderer.Init(sizeVertices, sizeIndices, &pivots.vertices[0], &pivots.indices[0]);
	}

	Material mat;
	mat.faceColor.x = 0.6f;
	mat.faceColor.y = 0.6f;
	mat.faceColor.z = 0.6f;
	mat.faceColor.w = 1.0f;
	mat.power = 1.0f;
	mat.specular.x = 1.0f;
	mat.specular.y = 1.0f;
	mat.specular.z = 1.0f;
	mat.specular.w = 1.0f;
	mat.emissive.x = 0.4f;
	mat.emissive.y = 0.4f;
	mat.emissive.z = 0.4f;
	mat.emissive.w = 1.0f;
	mat.tmid = texMan.Create("white.bmp", true);

	MaterialMap map;
	map.materialId = matMan.Create(mat);
	map.faceStartIndex = 0;
	map.faces = pivots.indices.size() / 3;
	pivots.materialMaps.push_back(map);
}

DebugRenderer::DebugRenderer()
{
}

DebugRenderer::~DebugRenderer()
{
	Destroy();
}

void DebugRenderer::Init()
{
	CreatePivotMesh();
}

void DebugRenderer::DrawPivots(const XMMATRIX mat[BONE_MAX], int num)
{
	int facesBackup = pivots.materialMaps.begin()->faces;
	pivots.materialMaps.begin()->faces = facesBackup * num / BONE_MAX;

	pivotsRenderer.Draw(mat, num, pivots);

	pivots.materialMaps.begin()->faces = facesBackup;
}

void DebugRenderer::Destroy()
{
	pivotsRenderer.Destroy();
}<commit_msg>pivots on origin<commit_after>#include "stdafx.h"

DebugRenderer debugRenderer;

static void InitVertex(MeshVertex& v, BONE_ID boneId, DWORD color)
{
	v.blendIndices.x = v.blendIndices.y = v.blendIndices.z = v.blendIndices.w = boneId;
	v.color = color;
	v.blendWeights.x = v.blendWeights.y = v.blendWeights.z = 0;
	v.normal.x = 1;
	v.normal.y = 0;
	v.normal.z = 0;
	v.uv.x = v.uv.y = 0;
	v.xyz.x = v.xyz.y = v.xyz.z = 0;
}

static inline float len(XMVECTOR v) {
	return XMVectorGetX(XMVector3Length(v));
}

void CreateCone(Block& b, XMVECTOR v1, XMVECTOR v2, BONE_ID boneId, DWORD color)
{
	float radius = 0.15f;
	XMVECTOR boneDir = XMVectorSubtract(v2, v1);
	XMVECTOR vRot0 = XMVector3Cross(boneDir, XMVectorSet(0, 0, radius, 0));
	if (len(vRot0) < 0.001f) {
		vRot0 = XMVector3Cross(boneDir, XMVectorSet(0, radius, 0, 0));
	}
	XMVECTOR vRot90 = XMVector3Cross(vRot0, XMVector3Normalize(boneDir));
	XMVECTOR vRotLast = XMVectorAdd(v1, vRot0);
	static const int div = 10;
	for (int j = 0; j < div; j++) {
		MeshVertex vert[3];
		for (auto& it : vert) {
			InitVertex(it, boneId, color);
		}
		float rad = XM_2PI / div * (j + 1);
		XMVECTOR vRot = XMVectorAdd(v1, XMVectorScale(vRot0, cosf(rad)) + XMVectorScale(vRot90, sinf(rad)));
		XMStoreFloat3(&vert[0].xyz, vRotLast);
		XMStoreFloat3(&vert[1].xyz, v2);
		XMStoreFloat3(&vert[2].xyz, vRot);
		XMVECTOR normal = XMVector3Cross(XMVectorSubtract(vRotLast, v2), XMVectorSubtract(v2, vRot));
		for (auto& it : vert) {
			XMStoreFloat3(&it.normal, normal);
			b.vertices.push_back(it);
			b.indices.push_back(b.indices.size());
		}
		vRotLast = vRot;
	}
}

void DebugRenderer::CreatePivotMesh()
{
	for (BONE_ID i = 0; (unsigned)i < BONE_MAX; i++)	{
		XMVECTOR v = XMVectorZero();
		float len = 50.0f;
		CreateCone(pivots, v, v + XMVectorSet(len, 0, 0, 0), i, 0xff0000ff);
		CreateCone(pivots, v, v + XMVectorSet(0, len, 0, 0), i, 0xff00ff00);
		CreateCone(pivots, v, v + XMVectorSet(0, 0, len, 0), i, 0xffff0000);
	}

	int sizeVertices = pivots.vertices.size() * sizeof(pivots.vertices[0]);
	int sizeIndices = pivots.indices.size() * sizeof(pivots.indices[0]);
	if (sizeVertices && sizeIndices) {
		pivotsRenderer.Init(sizeVertices, sizeIndices, &pivots.vertices[0], &pivots.indices[0]);
	}

	Material mat;
	mat.faceColor.x = 0.6f;
	mat.faceColor.y = 0.6f;
	mat.faceColor.z = 0.6f;
	mat.faceColor.w = 1.0f;
	mat.power = 1.0f;
	mat.specular.x = 1.0f;
	mat.specular.y = 1.0f;
	mat.specular.z = 1.0f;
	mat.specular.w = 1.0f;
	mat.emissive.x = 0.4f;
	mat.emissive.y = 0.4f;
	mat.emissive.z = 0.4f;
	mat.emissive.w = 1.0f;
	mat.tmid = texMan.Create("white.bmp", true);

	MaterialMap map;
	map.materialId = matMan.Create(mat);
	map.faceStartIndex = 0;
	map.faces = pivots.indices.size() / 3;
	pivots.materialMaps.push_back(map);
}

DebugRenderer::DebugRenderer()
{
}

DebugRenderer::~DebugRenderer()
{
	Destroy();
}

void DebugRenderer::Init()
{
	CreatePivotMesh();
}

void DebugRenderer::DrawPivots(const XMMATRIX mat[BONE_MAX], int num)
{
	XMMATRIX mat2[BONE_MAX];
	for (int i = 0; i < BONE_MAX; i++) {
		mat2[i] = i < num ? mat[i] : XMMatrixIdentity();
	}

	pivotsRenderer.Draw(mat2, BONE_MAX, pivots);
}

void DebugRenderer::Destroy()
{
	pivotsRenderer.Destroy();
}<|endoftext|>


<commit_before>#include <stdlib.h>
#include <unistd.h>
#include <string>
#include <cmath>
#include <wiringSerial.h>

#include "Hardware.h"

#define LENGTH_ONE 11.5
#define LENGTH_TWO 16.0

#define I_MIN_ANG -65
#define I_MAX_ANG 65
#define I_MIN_VAL 0
#define I_MAX_VAL 1023

#define J_MIN_ANG 35
#define J_MAX_ANG 180
#define J_MIN_VAL 230
#define J_MAX_VAL 850

#define K_MIN_ANG 0
#define K_MAX_ANG 270
#define K_MIN_VAL 950
#define K_MAX_VAL 20

#define SPHERE_CENTER_Z -5
#define SPHERE_RADIUS 7

Hardware::Hardware() {
    fd = serialOpen("/dev/ttyAMA0", 57600);
}

void Hardware::good() {
	system("sudo python ~/Hardware/ThingThree/Code/Dotstar/strandtest.py 0xFF0000 1 &");
}

void Hardware::bad() {
        system("sudo python ~/Hardware/ThingThree/Code/Dotstar/strandtest.py 0x00FF00  1 &");
}

void Hardware::neutral() {
	system("sudo python ~/Hardware/ThingThree/Code/Dotstar/strandtest.py 0x0000FF 1 &");
}

void Hardware::poise() {
	moveJoint(1, 512);
	moveJoint(2, 860);
	moveJoint(3, 960);
}

void Hardware::clap(int claps) {
	for (int i=0; i<1+claps*2; i++) {
		gripper(i%2);
		usleep(500000);
	}
}

int Hardware::getServoError(int id) {
	return readDxl(id,'e');
}

void Hardware::getSonars(int *sonarOne, int *sonarTwo) {
	writeCommand('R','v',128);

	std::string val;
	while (serialDataAvail(fd) > 0) val += serialGetchar(fd);

	std::string one = str.substr(0, val.find("\n"));
	std::string two = str.substr(val.find("\n"));

	*sonarOne = atoi(one.c_str());
	*sonarTwo = atoi(two.c_str());
}

int Hardware::readDxl(int id, char cmd) {
	writeCommand('R',cmd,id);

	std::string val;
	while (serialDataAvail(fd) > 0) val += serialGetchar(fd);

	return atoi(val.c_str());
}

void Hardware::writeInt(int inInt) {
	serialPutchar(fd,inInt%256);
	serialPutchar(fd,inInt>>8);
}

void Hardware::writeCommand(char readWrite, char command, int id) {
	std::string s;
	s += readWrite;
	s += command;
	s += static_cast<char>(id);
	serialPuts(fd,s.c_str());
}

void Hardware::setTorque(int id, int torque) {
	writeCommand('W','t',id);
	writeInt(torque);
}

void Hardware::setSpeed(int id, int speed) {
	writeCommand('W','s',id);
	writeInt(speed);
}

void Hardware::gripper(bool open) {
	if (open) {
		writeCommand('W','o',128);
		writeInt(500);
	} else {
		writeCommand('W','c',128);
		writeInt(500);
	}
}

bool Hardware::setJoints(double i, double j, double k) {
	double y, z;
	forwardKinematicsXY(j, k, &y, &z);

	double x = -y*sin(i*0.0174532925);
	y *= cos(i*0.0174532925);

	double radius = sqrt(x*x + y*y + pow(z-SPHERE_CENTER_Z,2));
	if (radius < SPHERE_RADIUS) return false;

	int iVal, jVal, kVal;
	scaleServos(i, j, k, &iVal, &jVal, &kVal);
	moveJoint(1,iVal);
	moveJoint(2,jVal);
	moveJoint(3,kVal);

	return true;
}

bool Hardware::setEffectorPosition(double theta, double x, double y) {
	double theta1, theta2;
	inverseKinematicsXY(x, y, &theta1, &theta2);

	return setJoints(theta,theta1,theta2);
}

void Hardware::moveJoint(int id, int position) {
	writeCommand('W','p',id);
	writeInt(position);
}

double Hardware::map(double x, double in_min, double in_max, double out_min, double out_max) {
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

void Hardware::scaleServos(double iAng, double jAng, double kAng, int *iVal, int *jVal, int *kVal) {
	*iVal = round(map(iAng,I_MIN_ANG,I_MAX_ANG,I_MIN_VAL,I_MAX_VAL));
	*jVal = round(map(jAng,J_MIN_ANG,J_MAX_ANG,J_MIN_VAL,J_MAX_VAL));
	*kVal = round(map(kAng,K_MIN_ANG,K_MAX_ANG,K_MIN_VAL,K_MAX_VAL));
}

void Hardware::forwardKinematicsXY(double theta1, double theta2, double *x, double *y) {
	double theta3 = theta2 - (180 - theta1);
	*x = LENGTH_ONE*cos(theta1*0.0174533) + LENGTH_TWO*cos(theta3*0.0174533);
	*y = LENGTH_ONE*sin(theta1*0.0174533) + LENGTH_TWO*sin(theta3*0.0174533);
}

void Hardware::inverseKinematicsXY(double x, double y, double *theta1, double *theta2) {
	double hypo = sqrt(pow(x,2) + pow(y,2));
	double q1 = atan2(y,x);
	double q2 = acos((pow(LENGTH_ONE,2) - pow(LENGTH_TWO,2) + pow(hypo,2))
					/(2.0*LENGTH_ONE*hypo));

	*theta1 = q1 + q2;
	*theta2 = acos((pow(LENGTH_ONE,2) + pow(LENGTH_TWO,2) - pow(hypo,2))
				  /(2.0*LENGTH_ONE*LENGTH_TWO));

	*theta1 *= 180.0/3.14159265;
	*theta2 *= 180.0/3.14159265;
}

Hardware::~Hardware() {
	serialClose(fd);
}
<commit_msg>fix typo<commit_after>#include <stdlib.h>
#include <unistd.h>
#include <string>
#include <cmath>
#include <wiringSerial.h>

#include "Hardware.h"

#define LENGTH_ONE 11.5
#define LENGTH_TWO 16.0

#define I_MIN_ANG -65
#define I_MAX_ANG 65
#define I_MIN_VAL 0
#define I_MAX_VAL 1023

#define J_MIN_ANG 35
#define J_MAX_ANG 180
#define J_MIN_VAL 230
#define J_MAX_VAL 850

#define K_MIN_ANG 0
#define K_MAX_ANG 270
#define K_MIN_VAL 950
#define K_MAX_VAL 20

#define SPHERE_CENTER_Z -5
#define SPHERE_RADIUS 7

Hardware::Hardware() {
    fd = serialOpen("/dev/ttyAMA0", 57600);
}

void Hardware::good() {
	system("sudo python ~/Hardware/ThingThree/Code/Dotstar/strandtest.py 0xFF0000 1 &");
}

void Hardware::bad() {
        system("sudo python ~/Hardware/ThingThree/Code/Dotstar/strandtest.py 0x00FF00  1 &");
}

void Hardware::neutral() {
	system("sudo python ~/Hardware/ThingThree/Code/Dotstar/strandtest.py 0x0000FF 1 &");
}

void Hardware::poise() {
	moveJoint(1, 512);
	moveJoint(2, 860);
	moveJoint(3, 960);
}

void Hardware::clap(int claps) {
	for (int i=0; i<1+claps*2; i++) {
		gripper(i%2);
		usleep(500000);
	}
}

int Hardware::getServoError(int id) {
	return readDxl(id,'e');
}

void Hardware::getSonars(int *sonarOne, int *sonarTwo) {
	writeCommand('R','v',128);

	std::string val;
	while (serialDataAvail(fd) > 0) val += serialGetchar(fd);

	std::string one = val.substr(0, val.find("\n"));
	std::string two = val.substr(val.find("\n"));

	*sonarOne = atoi(one.c_str());
	*sonarTwo = atoi(two.c_str());
}

int Hardware::readDxl(int id, char cmd) {
	writeCommand('R',cmd,id);

	std::string val;
	while (serialDataAvail(fd) > 0) val += serialGetchar(fd);

	return atoi(val.c_str());
}

void Hardware::writeInt(int inInt) {
	serialPutchar(fd,inInt%256);
	serialPutchar(fd,inInt>>8);
}

void Hardware::writeCommand(char readWrite, char command, int id) {
	std::string s;
	s += readWrite;
	s += command;
	s += static_cast<char>(id);
	serialPuts(fd,s.c_str());
}

void Hardware::setTorque(int id, int torque) {
	writeCommand('W','t',id);
	writeInt(torque);
}

void Hardware::setSpeed(int id, int speed) {
	writeCommand('W','s',id);
	writeInt(speed);
}

void Hardware::gripper(bool open) {
	if (open) {
		writeCommand('W','o',128);
		writeInt(500);
	} else {
		writeCommand('W','c',128);
		writeInt(500);
	}
}

bool Hardware::setJoints(double i, double j, double k) {
	double y, z;
	forwardKinematicsXY(j, k, &y, &z);

	double x = -y*sin(i*0.0174532925);
	y *= cos(i*0.0174532925);

	double radius = sqrt(x*x + y*y + pow(z-SPHERE_CENTER_Z,2));
	if (radius < SPHERE_RADIUS) return false;

	int iVal, jVal, kVal;
	scaleServos(i, j, k, &iVal, &jVal, &kVal);
	moveJoint(1,iVal);
	moveJoint(2,jVal);
	moveJoint(3,kVal);

	return true;
}

bool Hardware::setEffectorPosition(double theta, double x, double y) {
	double theta1, theta2;
	inverseKinematicsXY(x, y, &theta1, &theta2);

	return setJoints(theta,theta1,theta2);
}

void Hardware::moveJoint(int id, int position) {
	writeCommand('W','p',id);
	writeInt(position);
}

double Hardware::map(double x, double in_min, double in_max, double out_min, double out_max) {
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

void Hardware::scaleServos(double iAng, double jAng, double kAng, int *iVal, int *jVal, int *kVal) {
	*iVal = round(map(iAng,I_MIN_ANG,I_MAX_ANG,I_MIN_VAL,I_MAX_VAL));
	*jVal = round(map(jAng,J_MIN_ANG,J_MAX_ANG,J_MIN_VAL,J_MAX_VAL));
	*kVal = round(map(kAng,K_MIN_ANG,K_MAX_ANG,K_MIN_VAL,K_MAX_VAL));
}

void Hardware::forwardKinematicsXY(double theta1, double theta2, double *x, double *y) {
	double theta3 = theta2 - (180 - theta1);
	*x = LENGTH_ONE*cos(theta1*0.0174533) + LENGTH_TWO*cos(theta3*0.0174533);
	*y = LENGTH_ONE*sin(theta1*0.0174533) + LENGTH_TWO*sin(theta3*0.0174533);
}

void Hardware::inverseKinematicsXY(double x, double y, double *theta1, double *theta2) {
	double hypo = sqrt(pow(x,2) + pow(y,2));
	double q1 = atan2(y,x);
	double q2 = acos((pow(LENGTH_ONE,2) - pow(LENGTH_TWO,2) + pow(hypo,2))
					/(2.0*LENGTH_ONE*hypo));

	*theta1 = q1 + q2;
	*theta2 = acos((pow(LENGTH_ONE,2) + pow(LENGTH_TWO,2) - pow(hypo,2))
				  /(2.0*LENGTH_ONE*LENGTH_TWO));

	*theta1 *= 180.0/3.14159265;
	*theta2 *= 180.0/3.14159265;
}

Hardware::~Hardware() {
	serialClose(fd);
}
<|endoftext|>


<commit_before>
#include <cassert>
#include <type_traits>

#include <QMap>
#include <QDebug>
#include <QImage>
#include <QFile>
#include <QDataStream>
#include <QFileInfo>
#include <QStringList>

#include <QCoreApplication>

#include <version.h>

enum Format
{
    GL_RED
,   GL_RG
,   GL_RGB
,   GL_BGR
,   GL_RGBA
,   GL_BGRA
,   GL_STENCIL_INDEX
,   GL_DEPTH_COMPONENT
,   GL_DEPTH_STENCIL
};

enum Type
{
    GL_UNSIGNED_BYTE
,   GL_BYTE
,   GL_UNSIGNED_SHORT
,   GL_SHORT
,   GL_UNSIGNED_INT
,   GL_INT
,   GL_FLOAT
};

QMap<QString, Format> g_formats;
QMap<QString, Type> g_types;
QVector<QString> g_options;
QStringList g_manuals;
QStringList g_versions;

void initialize()
{
    g_formats["GL_RED"] = GL_RED;
    g_formats["GL_RG"] = GL_RG;
    g_formats["GL_RGB"] = GL_RGB;
    g_formats["GL_BGR"] = GL_BGR;
    g_formats["GL_RGBA"] = GL_RGBA;
    g_formats["GL_BGRA"] = GL_BGRA;
    //g_formats["GL_STENCIL_INDEX"] = GL_STENCIL_INDEX;
    //g_formats["GL_DEPTH_COMPONENT"] = GL_DEPTH_COMPONENT;
    //g_formats["GL_DEPTH_STENCIL"] = GL_DEPTH_STENCIL;

    g_types["GL_UNSIGNED_BYTE"] = GL_UNSIGNED_BYTE;
    g_types["GL_BYTE"] = GL_BYTE;
    g_types["GL_UNSIGNED_SHORT"] = GL_UNSIGNED_SHORT;
    g_types["GL_SHORT"] = GL_SHORT;
    g_types["GL_UNSIGNED_INT"] = GL_UNSIGNED_INT;
    g_types["GL_INT"] = GL_INT;
    g_types["GL_FLOAT"] = GL_FLOAT;

    g_options << "--mirror-horizontal"  << "-mh" ;
    g_options << "--mirror-vertical"    << "-mv" ;
    g_options << "--as-bgr"             << "-bgr";

    g_manuals  << "--help" << "-h" << "/?";
    g_versions << "--version" << "-v";
}

static const int option_mh  = 0;
static const int option_mv  = 2;
static const int option_bgr = 4;

void man()
{
    qDebug() << "";
    qDebug() << GLRAW_PROJECT_NAME << GLRAW_VERSION << "by" << GLRAW_AUTHOR_ORGANIZATION;
    qDebug() << "Converts an input image to an OpenGL compatible format.";
    qDebug() << "";
    qDebug() << "usage: glraw <Target-Format> <Target-Type> [<Options>] <Input-FilePath>";
    qDebug() << "";
    qDebug() << "<Target-Formats>:";
    qDebug().nospace() << "  " << qPrintable(QStringList(g_formats.keys()).join("\n  "));
    qDebug() << "";
    qDebug() << "<Target-Types>:";
    qDebug().nospace() << "  " << qPrintable(QStringList(g_types.keys()).join("\n  "));
    qDebug() << "";
    qDebug() << "<Options>:";
    qDebug().nospace() << "  " << qPrintable(g_options[option_mh])  << " (" << qPrintable(g_options[option_mh + 1])  << ")";
    qDebug().nospace() << "  " << qPrintable(g_options[option_mv])  << " (" << qPrintable(g_options[option_mv + 1])  << ")";
    qDebug().nospace() << "  " << qPrintable(g_options[option_bgr]) << " (" << qPrintable(g_options[option_bgr + 1]) << ")";
    qDebug() << "";
}

void version()
{
    qDebug() << GLRAW_PROJECT_NAME << GLRAW_VERSION;
    qDebug() << "";
}

template<typename T>
void write(
    QDataStream & output
,   const QImage & image
,   const Format format)
{
    const bool r = (GL_RED == format || GL_RG == format || GL_RGB == format || GL_RGBA == format || GL_BGR == format || GL_BGRA == format);
    const bool g = (GL_RG == format || GL_RGB == format || GL_RGBA == format || GL_BGR == format || GL_BGRA == format);
    const bool b = (GL_RGB == format || GL_RGBA == format || GL_BGR == format || GL_BGRA == format);
    const bool a = (GL_RGBA == format || GL_BGRA == format);

    const bool grayscale = (GL_DEPTH_COMPONENT == format || GL_DEPTH_STENCIL == format || GL_STENCIL_INDEX == format);

    const int w = image.width();
    const int h = image.height();
    const int s = w * h;

    const float scale = std::is_same<T, float>::value ? 1.f / 255.f : 1.f;

    assert(image.byteCount() == s * 4);
    for(int i = 0; i < s * 4; i += 4)
    {
        if (r)
            output << static_cast<T>(scale * image.constBits()[i + 0]);
        if (g)
            output << static_cast<T>(scale * image.constBits()[i + 1]);
        if (b)
            output << static_cast<T>(scale * image.constBits()[i + 2]);
        if (a)
            output << static_cast<T>(scale * image.constBits()[i + 3]);
    }
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    initialize();

    if (a.arguments().size() == 1 || g_manuals.contains(a.arguments()[1]))
    {
        man();
        return 0;
    }

    if (g_versions.contains(a.arguments()[1]))
    {
        version();
        return 0;
    }

    const QString farg = a.arguments()[1];
    if(!g_formats.contains(farg))
    {
        qWarning() << "Unknown Target-Format" << qPrintable(farg) << ".";
        return 0;
    }
    const Format format = g_formats[farg];

    const QString targ = a.arguments()[2];
    if(!g_types.contains(targ))
    {
        qWarning() << "Unknown Target-Type" << qPrintable(targ) << ".";
        return 0;
    }
    const Type type = g_types[targ];

    const QStringList args(a.arguments());

    const bool mh  = args.contains(g_options[option_mh])  || args.contains(g_options[option_mh + 1]);
    const bool mv  = args.contains(g_options[option_mv])  || args.contains(g_options[option_mv + 1]);
    const bool bgr = args.contains(g_options[option_bgr]) || args.contains(g_options[option_bgr + 1]);

    // catch unknown args

    QStringList unknowns;
    for (int i = 1; i < args.size() - 1; ++i)
    {
        if (!g_options.contains(args[i]) && !g_formats.contains(args[i]) && !g_types.contains(args[i]))
            unknowns << args[i];
    }
    if (!unknowns.isEmpty())
        qWarning() << "The following unknown arguments will be ignored:" << unknowns.join(", ");

    const QString iarg = a.arguments().last();

    if(!QFile::exists(iarg))
    {
        qDebug() << "Input file does not exist.";
        return 0;
    }

    QImage image(iarg);
    if(image.isNull())
    {
        qDebug() << "Loading file from input file failed.";
        return 0;
    }

    // file name

    QMap<Format, QString> formatSuffixes;
    formatSuffixes[GL_RED]  = "r";
    formatSuffixes[GL_RG]   = "rg";
    formatSuffixes[GL_RGB]  = "rgb";
    formatSuffixes[GL_BGR]  = "bgr";
    formatSuffixes[GL_RGBA] = "rgba";
    formatSuffixes[GL_BGRA] = "bgra";

    QMap<Type, QString> typeSuffixes;
    typeSuffixes[GL_UNSIGNED_BYTE]  = "ub";
    typeSuffixes[GL_BYTE]           = "b";
    typeSuffixes[GL_UNSIGNED_SHORT] = "us";
    typeSuffixes[GL_SHORT]          = "s";
    typeSuffixes[GL_UNSIGNED_INT]   = "ui";
    typeSuffixes[GL_INT]            = "i";
    typeSuffixes[GL_FLOAT]          = "f";

    const QString suffixes = QString(".%1.%2.%3.%4.raw")
            .arg(image.width())
            .arg(image.height())
            .arg(formatSuffixes[format])
            .arg(typeSuffixes[type]);

    QFileInfo fi(iarg);

    const QString target = fi.absolutePath() + "/" + fi.baseName() + suffixes;

    // prepare ?

    if (GL_BGR != format && GL_BGRA != format)
        image = image.rgbSwapped();

    image = image.mirrored(mh, !mv);

    // write

    QFile file(target);
    if(!file.open(QIODevice::WriteOnly))
    {
        qDebug() << "Opening file" << target << "failed.";
        return 0;
    }

    QDataStream output(&file);

    switch(type)
    {
    case GL_UNSIGNED_BYTE:
        write<unsigned char>(output, image, format);
        break;
    case GL_BYTE:
        write<char>(output, image, format);
        break;
    case GL_UNSIGNED_SHORT:
        write<unsigned short>(output, image, format);
        break;
    case GL_SHORT:
        write<short>(output, image, format);
        break;
    case GL_UNSIGNED_INT:
        write<unsigned int>(output, image, format);
        break;
    case GL_INT:
        write<int>(output, image, format);
        break;
    case GL_FLOAT:
        write<float>(output, image, format);
        break;
    default:
        qWarning() << "Should not happen :P.";
        break;
    }

    file.close();

    qDebug() << qPrintable(target) << "created.";
    return 1;
}

<commit_msg>add quiet option close #1<commit_after>
#include <cassert>
#include <type_traits>

#include <QMap>
#include <QDebug>
#include <QImage>
#include <QFile>
#include <QDataStream>
#include <QFileInfo>
#include <QStringList>

#include <QCoreApplication>

#include <version.h>

enum Format
{
    GL_RED
,   GL_RG
,   GL_RGB
,   GL_BGR
,   GL_RGBA
,   GL_BGRA
,   GL_STENCIL_INDEX
,   GL_DEPTH_COMPONENT
,   GL_DEPTH_STENCIL
};

enum Type
{
    GL_UNSIGNED_BYTE
,   GL_BYTE
,   GL_UNSIGNED_SHORT
,   GL_SHORT
,   GL_UNSIGNED_INT
,   GL_INT
,   GL_FLOAT
};

QMap<QString, Format> g_formats;
QMap<QString, Type> g_types;
QVector<QString> g_options;
QStringList g_manuals;
QStringList g_versions;

void initialize()
{
    g_formats["GL_RED"] = GL_RED;
    g_formats["GL_RG"] = GL_RG;
    g_formats["GL_RGB"] = GL_RGB;
    g_formats["GL_BGR"] = GL_BGR;
    g_formats["GL_RGBA"] = GL_RGBA;
    g_formats["GL_BGRA"] = GL_BGRA;
    //g_formats["GL_STENCIL_INDEX"] = GL_STENCIL_INDEX;
    //g_formats["GL_DEPTH_COMPONENT"] = GL_DEPTH_COMPONENT;
    //g_formats["GL_DEPTH_STENCIL"] = GL_DEPTH_STENCIL;

    g_types["GL_UNSIGNED_BYTE"] = GL_UNSIGNED_BYTE;
    g_types["GL_BYTE"] = GL_BYTE;
    g_types["GL_UNSIGNED_SHORT"] = GL_UNSIGNED_SHORT;
    g_types["GL_SHORT"] = GL_SHORT;
    g_types["GL_UNSIGNED_INT"] = GL_UNSIGNED_INT;
    g_types["GL_INT"] = GL_INT;
    g_types["GL_FLOAT"] = GL_FLOAT;

    g_options << "--mirror-horizontal"  << "-mh" ;
    g_options << "--mirror-vertical"    << "-mv" ;
    g_options << "--as-bgr"             << "-bgr";
    g_options << "--quiet"              << "-q";

    g_manuals  << "--help" << "-h" << "/?";
    g_versions << "--version" << "-v";
}

static const int option_mh  = 0;
static const int option_mv  = 2;
static const int option_bgr = 4;
static const int option_q   = 6;

void man()
{
    qDebug() << "";
    qDebug() << GLRAW_PROJECT_NAME << GLRAW_VERSION << "by" << GLRAW_AUTHOR_ORGANIZATION;
    qDebug() << "Converts an input image to an OpenGL compatible format.";
    qDebug() << "";
    qDebug() << "usage: glraw <Target-Format> <Target-Type> [<Options>] <Input-FilePath>";
    qDebug() << "";
    qDebug() << "<Target-Formats>:";
    qDebug().nospace() << "  " << qPrintable(QStringList(g_formats.keys()).join("\n  "));
    qDebug() << "";
    qDebug() << "<Target-Types>:";
    qDebug().nospace() << "  " << qPrintable(QStringList(g_types.keys()).join("\n  "));
    qDebug() << "";
    qDebug() << "<Options>:";
    qDebug().nospace() << "  " << qPrintable(g_options[option_mh])  << " (" << qPrintable(g_options[option_mh + 1])  << ")";
    qDebug().nospace() << "  " << qPrintable(g_options[option_mv])  << " (" << qPrintable(g_options[option_mv + 1])  << ")";
    qDebug().nospace() << "  " << qPrintable(g_options[option_bgr]) << " (" << qPrintable(g_options[option_bgr + 1]) << ")";
    qDebug().nospace() << "  " << qPrintable(g_options[option_q])   << " (" << qPrintable(g_options[option_q + 1])   << ")";
    qDebug() << "";
}

void version()
{
    qDebug() << GLRAW_PROJECT_NAME << GLRAW_VERSION;
    qDebug() << "";
}

void quietMessageHandler(QtMsgType, const QMessageLogContext &, const QString &)
{
}

template<typename T>
void write(
    QDataStream & output
,   const QImage & image
,   const Format format)
{
    const bool r = (GL_RED == format || GL_RG == format || GL_RGB == format || GL_RGBA == format || GL_BGR == format || GL_BGRA == format);
    const bool g = (GL_RG == format || GL_RGB == format || GL_RGBA == format || GL_BGR == format || GL_BGRA == format);
    const bool b = (GL_RGB == format || GL_RGBA == format || GL_BGR == format || GL_BGRA == format);
    const bool a = (GL_RGBA == format || GL_BGRA == format);

    const bool grayscale = (GL_DEPTH_COMPONENT == format || GL_DEPTH_STENCIL == format || GL_STENCIL_INDEX == format);

    const int w = image.width();
    const int h = image.height();
    const int s = w * h;

    const float scale = std::is_same<T, float>::value ? 1.f / 255.f : 1.f;

    assert(image.byteCount() == s * 4);
    for(int i = 0; i < s * 4; i += 4)
    {
        if (r)
            output << static_cast<T>(scale * image.constBits()[i + 0]);
        if (g)
            output << static_cast<T>(scale * image.constBits()[i + 1]);
        if (b)
            output << static_cast<T>(scale * image.constBits()[i + 2]);
        if (a)
            output << static_cast<T>(scale * image.constBits()[i + 3]);
    }
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    initialize();

    if (a.arguments().size() == 1 || g_manuals.contains(a.arguments()[1]))
    {
        man();
        return 0;
    }

    if (g_versions.contains(a.arguments()[1]))
    {
        version();
        return 0;
    }

    if (a.arguments().contains(g_options[option_q]) || a.arguments().contains(g_options[option_q + 1]))
        qInstallMessageHandler(quietMessageHandler);

    const QString farg = a.arguments()[1];
    if(!g_formats.contains(farg))
    {
        qWarning() << "Unknown Target-Format" << qPrintable(farg) << ".";
        return 0;
    }
    const Format format = g_formats[farg];

    const QString targ = a.arguments()[2];
    if(!g_types.contains(targ))
    {
        qWarning() << "Unknown Target-Type" << qPrintable(targ) << ".";
        return 0;
    }
    const Type type = g_types[targ];

    const QStringList args(a.arguments());

    const bool mh  = args.contains(g_options[option_mh])  || args.contains(g_options[option_mh + 1]);
    const bool mv  = args.contains(g_options[option_mv])  || args.contains(g_options[option_mv + 1]);
    const bool bgr = args.contains(g_options[option_bgr]) || args.contains(g_options[option_bgr + 1]);

    // catch unknown args

    QStringList unknowns;
    for (int i = 1; i < args.size() - 1; ++i)
    {
        if (!g_options.contains(args[i]) && !g_formats.contains(args[i]) && !g_types.contains(args[i]))
            unknowns << args[i];
    }
    if (!unknowns.isEmpty())
        qWarning() << "The following unknown arguments will be ignored:" << unknowns.join(", ");

    const QString iarg = a.arguments().last();

    if(!QFile::exists(iarg))
    {
        qDebug() << "Input file does not exist.";
        return 0;
    }

    QImage image(iarg);
    if(image.isNull())
    {
        qDebug() << "Loading file from input file failed.";
        return 0;
    }

    // file name

    QMap<Format, QString> formatSuffixes;
    formatSuffixes[GL_RED]  = "r";
    formatSuffixes[GL_RG]   = "rg";
    formatSuffixes[GL_RGB]  = "rgb";
    formatSuffixes[GL_BGR]  = "bgr";
    formatSuffixes[GL_RGBA] = "rgba";
    formatSuffixes[GL_BGRA] = "bgra";

    QMap<Type, QString> typeSuffixes;
    typeSuffixes[GL_UNSIGNED_BYTE]  = "ub";
    typeSuffixes[GL_BYTE]           = "b";
    typeSuffixes[GL_UNSIGNED_SHORT] = "us";
    typeSuffixes[GL_SHORT]          = "s";
    typeSuffixes[GL_UNSIGNED_INT]   = "ui";
    typeSuffixes[GL_INT]            = "i";
    typeSuffixes[GL_FLOAT]          = "f";

    const QString suffixes = QString(".%1.%2.%3.%4.raw")
            .arg(image.width())
            .arg(image.height())
            .arg(formatSuffixes[format])
            .arg(typeSuffixes[type]);

    QFileInfo fi(iarg);

    const QString target = fi.absolutePath() + "/" + fi.baseName() + suffixes;

    // prepare ?

    if (GL_BGR != format && GL_BGRA != format)
        image = image.rgbSwapped();

    image = image.mirrored(mh, !mv);

    // write

    QFile file(target);
    if(!file.open(QIODevice::WriteOnly))
    {
        qDebug() << "Opening file" << target << "failed.";
        return 0;
    }

    QDataStream output(&file);

    switch(type)
    {
    case GL_UNSIGNED_BYTE:
        write<unsigned char>(output, image, format);
        break;
    case GL_BYTE:
        write<char>(output, image, format);
        break;
    case GL_UNSIGNED_SHORT:
        write<unsigned short>(output, image, format);
        break;
    case GL_SHORT:
        write<short>(output, image, format);
        break;
    case GL_UNSIGNED_INT:
        write<unsigned int>(output, image, format);
        break;
    case GL_INT:
        write<int>(output, image, format);
        break;
    case GL_FLOAT:
        write<float>(output, image, format);
        break;
    default:
        qWarning() << "Should not happen :P.";
        break;
    }

    file.close();

    qDebug() << qPrintable(target) << "created.";
    return 1;
}

<|endoftext|>