<commit_before>#if !defined(__CINT__) || defined(__MAKECINT__)
// ROOT includes
#include "TFile.h"
#include "TGrid.h"
#include "TString.h"
#include "TObjArray.h"
#include "TObjString.h"
#include "TSystem.h"
#include "TROOT.h"
#include "TKey.h"
#include "TTree.h"
#include "TParameter.h"

// Aliroot includes
#include "AliAnalysisManager.h"
#include "AliAnalysisAlien.h"
#include "AliESDInputHandler.h"

#define COMPILEMACRO

#endif

//_____________________________________________________________________________
void LoadLibs()
{
  gSystem->Load("libTree");
  gSystem->Load("libGeom");
  gSystem->Load("libVMC");
  gSystem->Load("libPhysics");
  gSystem->Load("libProof");

  gSystem->Load("libANALYSIS.so");
  gSystem->Load("libOADB.so");
  gSystem->Load("libANALYSISalice.so");
  gSystem->Load("libCORRFW.so");
  gSystem->Load("libPWGmuon.so");
  gSystem->Load("libPWGPPMUONlite.so");
}

//_____________________________________________________________________________
AliAnalysisAlien* CreateAlienHandler()
{
  AliAnalysisAlien *plugin = new AliAnalysisAlien();

  // Set the run mode
  plugin->SetRunMode("terminate");

  // Declare all libraries
  plugin->SetAdditionalLibs("libCORRFW.so libPWGHFbase.so libPWGmuon.so libPWGPPMUONlite.so");

  plugin->SetAdditionalRootLibs("libXMLParser.so libGui.so libProofPlayer.so");

  plugin->AddIncludePath("-I.");
  plugin->AddIncludePath("-I$ALICE_ROOT/PWGPP/MUON/lite");

  return plugin;
}

enum {
  trackQA = 1 << 0,
  trigQA  = 1 << 1
};

//_____________________________________________________________________________
void terminateQA ( TString outfilename = "QAresults.root", UInt_t force = 0, UInt_t mask = (trackQA|trigQA) )
{
  //
  // Load common libraries
  //

  LoadLibs();

  AliAnalysisAlien* alienHandler = CreateAlienHandler();

  AliAnalysisManager* mgr = new AliAnalysisManager("testAnalysis");
  mgr->SetCommonFileName(outfilename.Data());
  mgr->SetGridHandler(alienHandler);

  // Needed to the manager (but not used in terminate mode)
  AliESDInputHandler* esdH = new AliESDInputHandler();
  esdH->SetReadFriends(kFALSE);
  mgr->SetInputEventHandler(esdH);

  TString trigOutName = "trigChEff_ANY_Apt_allTrig.root";
  if ( ( force & trigQA ) == 0 ) {
    if ( gSystem->AccessPathName(trigOutName) == 0 ) {
      printf("Terminate already done for trigger. Skip\n");
      mask &= ~trigQA;
    }
  }
  if ( ( force & trackQA ) == 0 ) {
    TFile* file = TFile::Open(outfilename.Data());
    TKey* key = file->FindKeyAny("general2");
    if ( key ) {
      printf("Terminate already done for tracker. Skip\n");
      mask &= ~trackQA;
    }
    delete file;
  }

#ifndef COMPILEMACRO

  if ( mask & trigQA ) {
    gROOT->LoadMacro("$ALICE_ROOT/PWGPP/macros/AddTaskMTRchamberEfficiency.C");
    AliAnalysisTaskTrigChEff* trigChEffTask = AddTaskMTRchamberEfficiency(kFALSE);
    trigChEffTask->SetTerminateOptions("PhysSelPass","ANY","-5_105",Form("FORCEBATCH %s?PhysSelPass?ANY?-5_105?NoSelMatchAptFromTrg",trigOutName));
  }
  if ( mask & trackQA ) {
    gROOT->LoadMacro("$ALICE_ROOT/PWGPP/PilotTrain/AddTaskMuonQA.C");
    AliAnalysisTaskMuonQA* muonQATask = AddTaskMuonQA();
  }

#endif

//  // Check if terminate was already performed
//  if  ( ! force ) {
//    TObject* paramContainer = mgr->GetParamOutputs()->At(0);
//    if ( paramContainer ) {
//      TFile* file = TFile::Open(outfilename);
//      if ( file->FindObjectAny(paramContainer->GetName() ) ) {
//        printf("\nTerminate was already executed!\n");
//        printf("Nothing to be done\n");
//        file->Close();
//        return;
//      }
//      file->Close();
//    }
//  }

  if ( ! mgr->InitAnalysis()) {
    printf("Fatal: Cannot initialize analysis\n");
    return;
  }
  mgr->PrintStatus();
  mgr->StartAnalysis("grid terminate");
}

//_____________________________________________________________________________
TString GetFullPath ( TString filename )
{
  if ( filename.BeginsWith("alien://") ) return filename;
  TString dirName = gSystem->DirName(filename);
  TString baseName = gSystem->BaseName(filename);
  TString currDir = gSystem->pwd();
  gSystem->cd(dirName);
  TString fullDir = gSystem->pwd();
  gSystem->cd(currDir);
  TString fullPath = fullDir.Data();
  if ( ! fullDir.EndsWith("/") ) fullPath.Append("/");
  fullPath += baseName;
  return fullPath;
}

//_____________________________________________________________________________
TString GetBaseName ( TString filename )
{
  TString baseName = gSystem->BaseName(filename);
  Int_t idx = baseName.Index("#");
  if ( idx > 0 ) baseName.Remove(0,idx+1);
  return baseName;
}

//_____________________________________________________________________________
void CopyDir(TDirectory *source) {
  //copy all objects and subdirs of directory source as a subdir of the current directory
  TDirectory *savdir = gDirectory;
  TDirectory *adir = savdir->mkdir(source->GetName());
  adir->cd();
  //loop on all entries of this directory
  TKey *key;
  TIter nextkey(source->GetListOfKeys());
  while ((key = (TKey*)nextkey())) {
    const char *classname = key->GetClassName();
    TClass *cl = gROOT->GetClass(classname);
    if (!cl) continue;
    if (cl->InheritsFrom(TDirectory::Class())) {
      source->cd(key->GetName());
      TDirectory *subdir = gDirectory;
      adir->cd();
      CopyDir(subdir);
      adir->cd();
    } else if (cl->InheritsFrom(TTree::Class())) {
      TTree *T = (TTree*)source->Get(key->GetName());
      adir->cd();
      TTree *newT = T->CloneTree(-1,"fast");
      newT->Write();
    } else {
      source->cd();
      TObject *obj = key->ReadObj();
      adir->cd();
      obj->Write(obj->GetName(),TObject::kSingleKey);
      delete obj;
    }
  }
  adir->SaveSelf(kTRUE);
  savdir->cd();
}

//_____________________________________________________________________________
Bool_t GetQAInfo ( const char* qaFileName, TString dirNames = "MUON_QA MTR_ChamberEffMap MUON.TrigEfficiencyMap MUON.TriggerEfficiencyMap" )
{
  LoadLibs();

  TString outFilename = GetBaseName(qaFileName);
  TString inFullPath = GetFullPath(qaFileName);
  TString outFullPath = GetFullPath(outFilename);
  if ( inFullPath == outFullPath ) {
    printf("Warning: input and output are same file!\n");
    return kFALSE;
  }

  if ( inFullPath.BeginsWith("alien") && ! gGrid ) TGrid::Connect("alien://");

  TObjArray* dirList = dirNames.Tokenize(" ");
  TFile* outFile = TFile::Open(outFilename,"RECREATE");
  TFile* inFile = TFile::Open(qaFileName);
  for ( Int_t idir=0; idir<dirList->GetEntries(); idir++ ) {
    inFile->cd();
    TObject* obj = inFile->Get(dirList->At(idir)->GetName());
    if ( ! obj ) continue;
    outFile->cd();
    CopyDir(static_cast<TDirectory*>(obj));
  }
  delete outFile;
  delete inFile;
  delete dirList;

  return kTRUE;
}

//_____________________________________________________________________________
Bool_t AddTreeVariable ( TList& parList, const char* varName, char varType, Float_t val )
{
  if ( varType == 'D' ) varType = 'F';
  TString parName = Form("%s/%c",varName,varType);
  if ( varType == 'F' ) {
    parList.Add(new TParameter<float>(parName,val));
  }
  else if ( varType == 'I' ) {
    parList.Add(new TParameter<int>(parName,(Int_t)val));
  }
  else {
    printf("Error: variable type %c not accepted", varType);
    return kFALSE;
  }
  return kTRUE;
}

//_____________________________________________________________________________
void FillTree ( TTree* tree, TList &parList )
{
  Int_t nVars = parList.GetEntries();
  TArrayI varInt(nVars);
  TArrayF varFloat(nVars);
  for ( Int_t ivar=0; ivar<nVars; ivar++ ) {
    TObject* obj = parList.At(ivar);
    TString varName = obj->GetName();
    TString branchName = varName;
    branchName.Remove(varName.Length()-2);
    if ( varName.EndsWith("F") ) {
      varFloat[ivar] = ((TParameter<float>*)obj)->GetVal();
      tree->Branch(branchName.Data(),&varFloat[ivar],varName.Data());
    }
    else if ( varName.EndsWith("I") ) {
      varInt[ivar] = (Int_t)((TParameter<int>*)obj)->GetVal();
      tree->Branch(branchName.Data(),&varInt[ivar],varName.Data());
    }
  }
  tree->Fill();
}

//_____________________________________________________________________________
void AddTrigVars ( TString filename, TList &parList )
{
  TString trigOutName = "trigChEff_ANY_Apt_allTrig.root";
  if ( gSystem->AccessPathName(trigOutName.Data()) ) trigOutName = filename;
  TFile* file = TFile::Open(filename.Data());
  TList* inList = (TList*)file->FindObjectAny("triggerChamberEff");
  TString hChNames[] = {"bendPlaneCountChamber","nonBendPlaneCountChamber","allTracksCountChamber"};
  Int_t nHistos = sizeof(hChNames)/sizeof(hChNames[0]);
  for ( Int_t ihisto=0; ihisto<nHistos; ihisto++ ) {
    TH1* histo = (TH1*)inList->FindObject(hChNames[ihisto].Data());
    Double_t currVal = ( histo ) ? histo->GetBinContent(ibin) : 0.;
    for ( Int_t ibin=1; ibin<=4; ibin++ ) {
      AddTreeVariable(parList, Form("%s%i",hChNames[ihisto].Data(),ibin),'F',currVal);
    }
  }
  delete file;
}

//_____________________________________________________________________________
void MakeTrend ( const char* qaFile, Int_t runNumber, UInt_t force = trigQA, UInt_t mask = (trackQA|trigQA) )
{
  Bool_t isOk = GetQAInfo(qaFile);
  if ( ! isOk ) return;

  TString inFilename = GetBaseName(qaFile);

  terminateQA(inFilename,force,mask);

  TList parList;
  parList.SetOwner();
  AddTreeVariable(parList, "run", 'I', runNumber);

  // function for trigger
  AddTrigVars(inFilename.Data(),parList);

  TFile* outFile = TFile::Open("trending.root","RECREATE");
  TTree* tree = new TTree("trending","trending");

  FillTree(tree, parList);
  tree->Write();
  delete outFile;
}
<commit_msg>Bug fix: variable used outside loop<commit_after>#if !defined(__CINT__) || defined(__MAKECINT__)
// ROOT includes
#include "TFile.h"
#include "TGrid.h"
#include "TString.h"
#include "TObjArray.h"
#include "TObjString.h"
#include "TSystem.h"
#include "TROOT.h"
#include "TKey.h"
#include "TTree.h"
#include "TParameter.h"

// Aliroot includes
#include "AliAnalysisManager.h"
#include "AliAnalysisAlien.h"
#include "AliESDInputHandler.h"

#define COMPILEMACRO

#endif

//_____________________________________________________________________________
void LoadLibs()
{
  gSystem->Load("libTree");
  gSystem->Load("libGeom");
  gSystem->Load("libVMC");
  gSystem->Load("libPhysics");
  gSystem->Load("libProof");

  gSystem->Load("libANALYSIS.so");
  gSystem->Load("libOADB.so");
  gSystem->Load("libANALYSISalice.so");
  gSystem->Load("libCORRFW.so");
  gSystem->Load("libPWGmuon.so");
  gSystem->Load("libPWGPPMUONlite.so");
}

//_____________________________________________________________________________
AliAnalysisAlien* CreateAlienHandler()
{
  AliAnalysisAlien *plugin = new AliAnalysisAlien();

  // Set the run mode
  plugin->SetRunMode("terminate");

  // Declare all libraries
  plugin->SetAdditionalLibs("libCORRFW.so libPWGHFbase.so libPWGmuon.so libPWGPPMUONlite.so");

  plugin->SetAdditionalRootLibs("libXMLParser.so libGui.so libProofPlayer.so");

  plugin->AddIncludePath("-I.");
  plugin->AddIncludePath("-I$ALICE_ROOT/PWGPP/MUON/lite");

  return plugin;
}

enum {
  trackQA = 1 << 0,
  trigQA  = 1 << 1
};

//_____________________________________________________________________________
void terminateQA ( TString outfilename = "QAresults.root", UInt_t force = 0, UInt_t mask = (trackQA|trigQA) )
{
  //
  // Load common libraries
  //

  LoadLibs();

  AliAnalysisAlien* alienHandler = CreateAlienHandler();

  AliAnalysisManager* mgr = new AliAnalysisManager("testAnalysis");
  mgr->SetCommonFileName(outfilename.Data());
  mgr->SetGridHandler(alienHandler);

  // Needed to the manager (but not used in terminate mode)
  AliESDInputHandler* esdH = new AliESDInputHandler();
  esdH->SetReadFriends(kFALSE);
  mgr->SetInputEventHandler(esdH);

  TString trigOutName = "trigChEff_ANY_Apt_allTrig.root";
  if ( ( force & trigQA ) == 0 ) {
    if ( gSystem->AccessPathName(trigOutName) == 0 ) {
      printf("Terminate already done for trigger. Skip\n");
      mask &= ~trigQA;
    }
  }
  if ( ( force & trackQA ) == 0 ) {
    TFile* file = TFile::Open(outfilename.Data());
    TKey* key = file->FindKeyAny("general2");
    if ( key ) {
      printf("Terminate already done for tracker. Skip\n");
      mask &= ~trackQA;
    }
    delete file;
  }

#ifndef COMPILEMACRO

  if ( mask & trigQA ) {
    gROOT->LoadMacro("$ALICE_ROOT/PWGPP/macros/AddTaskMTRchamberEfficiency.C");
    AliAnalysisTaskTrigChEff* trigChEffTask = AddTaskMTRchamberEfficiency(kFALSE);
    trigChEffTask->SetTerminateOptions("PhysSelPass","ANY","-5_105",Form("FORCEBATCH %s?PhysSelPass?ANY?-5_105?NoSelMatchAptFromTrg",trigOutName));
  }
  if ( mask & trackQA ) {
    gROOT->LoadMacro("$ALICE_ROOT/PWGPP/PilotTrain/AddTaskMuonQA.C");
    AliAnalysisTaskMuonQA* muonQATask = AddTaskMuonQA();
  }

#endif

//  // Check if terminate was already performed
//  if  ( ! force ) {
//    TObject* paramContainer = mgr->GetParamOutputs()->At(0);
//    if ( paramContainer ) {
//      TFile* file = TFile::Open(outfilename);
//      if ( file->FindObjectAny(paramContainer->GetName() ) ) {
//        printf("\nTerminate was already executed!\n");
//        printf("Nothing to be done\n");
//        file->Close();
//        return;
//      }
//      file->Close();
//    }
//  }

  if ( ! mgr->InitAnalysis()) {
    printf("Fatal: Cannot initialize analysis\n");
    return;
  }
  mgr->PrintStatus();
  mgr->StartAnalysis("grid terminate");
}

//_____________________________________________________________________________
TString GetFullPath ( TString filename )
{
  if ( filename.BeginsWith("alien://") ) return filename;
  TString dirName = gSystem->DirName(filename);
  TString baseName = gSystem->BaseName(filename);
  TString currDir = gSystem->pwd();
  gSystem->cd(dirName);
  TString fullDir = gSystem->pwd();
  gSystem->cd(currDir);
  TString fullPath = fullDir.Data();
  if ( ! fullDir.EndsWith("/") ) fullPath.Append("/");
  fullPath += baseName;
  return fullPath;
}

//_____________________________________________________________________________
TString GetBaseName ( TString filename )
{
  TString baseName = gSystem->BaseName(filename);
  Int_t idx = baseName.Index("#");
  if ( idx > 0 ) baseName.Remove(0,idx+1);
  return baseName;
}

//_____________________________________________________________________________
void CopyDir(TDirectory *source) {
  //copy all objects and subdirs of directory source as a subdir of the current directory
  TDirectory *savdir = gDirectory;
  TDirectory *adir = savdir->mkdir(source->GetName());
  adir->cd();
  //loop on all entries of this directory
  TKey *key;
  TIter nextkey(source->GetListOfKeys());
  while ((key = (TKey*)nextkey())) {
    const char *classname = key->GetClassName();
    TClass *cl = gROOT->GetClass(classname);
    if (!cl) continue;
    if (cl->InheritsFrom(TDirectory::Class())) {
      source->cd(key->GetName());
      TDirectory *subdir = gDirectory;
      adir->cd();
      CopyDir(subdir);
      adir->cd();
    } else if (cl->InheritsFrom(TTree::Class())) {
      TTree *T = (TTree*)source->Get(key->GetName());
      adir->cd();
      TTree *newT = T->CloneTree(-1,"fast");
      newT->Write();
    } else {
      source->cd();
      TObject *obj = key->ReadObj();
      adir->cd();
      obj->Write(obj->GetName(),TObject::kSingleKey);
      delete obj;
    }
  }
  adir->SaveSelf(kTRUE);
  savdir->cd();
}

//_____________________________________________________________________________
Bool_t GetQAInfo ( const char* qaFileName, TString dirNames = "MUON_QA MTR_ChamberEffMap MUON.TrigEfficiencyMap MUON.TriggerEfficiencyMap" )
{
  LoadLibs();

  TString outFilename = GetBaseName(qaFileName);
  TString inFullPath = GetFullPath(qaFileName);
  TString outFullPath = GetFullPath(outFilename);
  if ( inFullPath == outFullPath ) {
    printf("Warning: input and output are same file!\n");
    return kFALSE;
  }

  if ( inFullPath.BeginsWith("alien") && ! gGrid ) TGrid::Connect("alien://");

  TObjArray* dirList = dirNames.Tokenize(" ");
  TFile* outFile = TFile::Open(outFilename,"RECREATE");
  TFile* inFile = TFile::Open(qaFileName);
  for ( Int_t idir=0; idir<dirList->GetEntries(); idir++ ) {
    inFile->cd();
    TObject* obj = inFile->Get(dirList->At(idir)->GetName());
    if ( ! obj ) continue;
    outFile->cd();
    CopyDir(static_cast<TDirectory*>(obj));
  }
  delete outFile;
  delete inFile;
  delete dirList;

  return kTRUE;
}

//_____________________________________________________________________________
Bool_t AddTreeVariable ( TList& parList, const char* varName, char varType, Float_t val )
{
  if ( varType == 'D' ) varType = 'F';
  TString parName = Form("%s/%c",varName,varType);
  if ( varType == 'F' ) {
    parList.Add(new TParameter<float>(parName,val));
  }
  else if ( varType == 'I' ) {
    parList.Add(new TParameter<int>(parName,(Int_t)val));
  }
  else {
    printf("Error: variable type %c not accepted", varType);
    return kFALSE;
  }
  return kTRUE;
}

//_____________________________________________________________________________
void FillTree ( TTree* tree, TList &parList )
{
  Int_t nVars = parList.GetEntries();
  TArrayI varInt(nVars);
  TArrayF varFloat(nVars);
  for ( Int_t ivar=0; ivar<nVars; ivar++ ) {
    TObject* obj = parList.At(ivar);
    TString varName = obj->GetName();
    TString branchName = varName;
    branchName.Remove(varName.Length()-2);
    if ( varName.EndsWith("F") ) {
      varFloat[ivar] = ((TParameter<float>*)obj)->GetVal();
      tree->Branch(branchName.Data(),&varFloat[ivar],varName.Data());
    }
    else if ( varName.EndsWith("I") ) {
      varInt[ivar] = (Int_t)((TParameter<int>*)obj)->GetVal();
      tree->Branch(branchName.Data(),&varInt[ivar],varName.Data());
    }
  }
  tree->Fill();
}

//_____________________________________________________________________________
void AddTrigVars ( TString filename, TList &parList )
{
  TString trigOutName = "trigChEff_ANY_Apt_allTrig.root";
  if ( gSystem->AccessPathName(trigOutName.Data()) ) trigOutName = filename;
  TFile* file = TFile::Open(filename.Data());
  TList* inList = (TList*)file->FindObjectAny("triggerChamberEff");
  TString hChNames[] = {"bendPlaneCountChamber","nonBendPlaneCountChamber","allTracksCountChamber"};
  Int_t nHistos = sizeof(hChNames)/sizeof(hChNames[0]);
  for ( Int_t ihisto=0; ihisto<nHistos; ihisto++ ) {
    TH1* histo = (TH1*)inList->FindObject(hChNames[ihisto].Data());
    for ( Int_t ibin=1; ibin<=4; ibin++ ) {
      Double_t currVal = ( histo ) ? histo->GetBinContent(ibin) : 0.;
      AddTreeVariable(parList, Form("%s%i",hChNames[ihisto].Data(),ibin),'F',currVal);
    }
  }
  delete file;
}

//_____________________________________________________________________________
void MakeTrend ( const char* qaFile, Int_t runNumber, UInt_t force = trigQA, UInt_t mask = (trackQA|trigQA) )
{
  Bool_t isOk = GetQAInfo(qaFile);
  if ( ! isOk ) return;

  TString inFilename = GetBaseName(qaFile);

  terminateQA(inFilename,force,mask);

  TList parList;
  parList.SetOwner();
  AddTreeVariable(parList, "run", 'I', runNumber);

  // function for trigger
  AddTrigVars(inFilename.Data(),parList);

  TFile* outFile = TFile::Open("trending.root","RECREATE");
  TTree* tree = new TTree("trending","trending");

  FillTree(tree, parList);
  tree->Write();
  delete outFile;
}
<|endoftext|>


<commit_before>/**************************************************************************
* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
*                                                                        *
* Author: The ALICE Off-line Project.                                    *
* Contributors are mentioned in the code where appropriate.              *
*                                                                        *
* Permission to use, copy, modify and distribute this software and its   *
* documentation strictly for non-commercial purposes is hereby granted   *
* without fee, provided that the above copyright notice appears in all   *
* copies and that both the copyright notice and this permission notice   *
* appear in the supporting documentation. The authors make no claims     *
* about the suitability of this software for any purpose. It is          *
* provided "as is" without express or implied warranty.                  *
**************************************************************************/

//------------------------------------------------------------------------------
// Impementation of AliMCInfoCuts class. It keeps selection cuts for MC tracks.
//
//
// Author: J.Otwinowski 04/02/2008
//------------------------------------------------------------------------------

#include <iostream>
#include <TArrayI.h>
#include <TList.h>

#include "AliLog.h"
#include "AliMCInfoCuts.h"

using namespace std;

ClassImp(AliMCInfoCuts)

//_____________________________________________________________________________
AliMCInfoCuts::AliMCInfoCuts() :
AliAnalysisCuts()
, fMinRowsWithDigits(0)
, fMaxR(0)
, fMaxVz(0)
, fMinTPCSignal(0)
, fMaxTPCSignal(0)
, fMinTrackLength(0)
, aTrackParticles(0)
{
  // default constructor
}

//_____________________________________________________________________________
AliMCInfoCuts::AliMCInfoCuts(const Char_t* name,const Char_t *title) :
  AliAnalysisCuts(name, title)
, fMinRowsWithDigits(0)
, fMaxR(0)
, fMaxVz(0)
, fMinTPCSignal(0)
, fMaxTPCSignal(0)
, fMinTrackLength(0)
, aTrackParticles(0)
{
  // default constructor

  // init data members with defaults
  InitME();
}

//_____________________________________________________________________________
AliMCInfoCuts::AliMCInfoCuts(const AliMCInfoCuts& that) :
AliAnalysisCuts(that)
, fMinRowsWithDigits(that.fMinRowsWithDigits)
, fMaxR(that.fMaxR)
, fMaxVz(that.fMaxVz)
, fMinTPCSignal(that.fMinTPCSignal)
, fMaxTPCSignal(that.fMaxTPCSignal)
, fMinTrackLength(that.fMinTrackLength)
, aTrackParticles(new TArrayI(kNParticles))
{
  *aTrackParticles = *that.aTrackParticles;
}

//_____________________________________________________________________________
AliMCInfoCuts& AliMCInfoCuts::operator=(const AliMCInfoCuts& that)
{
  fMinRowsWithDigits = that.fMinRowsWithDigits;
  fMaxR = that.fMaxR;
  fMaxVz = that.fMaxVz;
  fMinTPCSignal = that.fMinTPCSignal;
  fMaxTPCSignal = that.fMaxTPCSignal;
  fMinTrackLength = that.fMinTrackLength;
  if (!aTrackParticles) aTrackParticles = new TArrayI(1);
  aTrackParticles = that.aTrackParticles;
  return *this;
}

//_____________________________________________________________________________
AliMCInfoCuts::~AliMCInfoCuts()
{
  // destructor
  delete aTrackParticles;
}

//_____________________________________________________________________________
void AliMCInfoCuts::InitME()
{
  // set default values
  SetMinRowsWithDigits();
  SetMaxR();
  SetMaxVz();
  SetRangeTPCSignal();
  SetMinTrackLength();

  // create aTrackParticles array
  aTrackParticles = new TArrayI(kNParticles); // max nb. of particles
  aTrackParticles->Reset(0);

  // create an array of track particles: e, muons, pions, kaons, protons
  if(aTrackParticles != 0)
  {
     // keep order adding a new particles
     AddPdgParticle(0,ep);   // e+
     AddPdgParticle(1,em);   // e-
     AddPdgParticle(2,mup);  // mu+
     AddPdgParticle(3,mum);  // mu-
     AddPdgParticle(4,pip);  // pi+
     AddPdgParticle(5,pim);  // pi-
     AddPdgParticle(6,kp);   // K+
     AddPdgParticle(7,km);   // K-
     AddPdgParticle(8,prot);    // p
     AddPdgParticle(9,protbar); // p_bar
  }
}

//_____________________________________________________________________________
void AliMCInfoCuts::AddPdgParticle(Int_t idx, Int_t pdgcode) const
{
  // add particle to the array
  if(aTrackParticles != 0) aTrackParticles->AddAt(pdgcode,idx);
  else AliDebug(AliLog::kError, "ERROR: Cannot add particle to the array");
}

//_____________________________________________________________________________
Bool_t AliMCInfoCuts::IsPdgParticle(Int_t pdgcode) const
{
  // check PDG particle
  if(aTrackParticles == 0) {
    AliDebug(AliLog::kError, "ERROR: Cannot get particle array");
    return kFALSE;
  }

  Int_t size = aTrackParticles->GetSize();
  for(int i=0; i<size; ++i) {
    if(pdgcode == aTrackParticles->At(i)) return kTRUE;
  }
  return kFALSE;
}

//_____________________________________________________________________________
Bool_t AliMCInfoCuts::IsPosPdgParticle(Int_t pdgcode) const
{
  // check PDG particle (only positive charged)
  if(aTrackParticles == 0) {
    AliDebug(AliLog::kError, "ERROR: Cannot get particle array");
    return kFALSE;
  }

  Int_t size = aTrackParticles->GetSize();
  for(int i=0; i<size; ++i) {
    // leptons have oposite pdg convension from hadrons (e+/e- = -11/11)
    if(pdgcode > 0 && (pdgcode == 11 || pdgcode == 13)) return kFALSE;
    if(pdgcode < 0 && (pdgcode != -11 || pdgcode != -13) ) return kFALSE;
	//
    if(pdgcode == aTrackParticles->At(i)) return kTRUE;
  }
  return kFALSE;
}

//_____________________________________________________________________________
Long64_t AliMCInfoCuts::Merge(TCollection* list)
{
  // Merge list of objects (needed by PROOF)
  if (!list)
  return 0;

  if (list->IsEmpty())
  return 1;

  TIterator* iter = list->MakeIterator();
  TObject* obj = 0;

  Int_t count=0;
  while((obj = iter->Next()) != 0)
  {
    AliMCInfoCuts* entry = dynamic_cast<AliMCInfoCuts*>(obj);
    if (entry == 0)
      continue;

  count++;
  }

return count;
}
<commit_msg>Fix braindead mistakes<commit_after>/**************************************************************************
* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
*                                                                        *
* Author: The ALICE Off-line Project.                                    *
* Contributors are mentioned in the code where appropriate.              *
*                                                                        *
* Permission to use, copy, modify and distribute this software and its   *
* documentation strictly for non-commercial purposes is hereby granted   *
* without fee, provided that the above copyright notice appears in all   *
* copies and that both the copyright notice and this permission notice   *
* appear in the supporting documentation. The authors make no claims     *
* about the suitability of this software for any purpose. It is          *
* provided "as is" without express or implied warranty.                  *
**************************************************************************/

//------------------------------------------------------------------------------
// Impementation of AliMCInfoCuts class. It keeps selection cuts for MC tracks.
//
//
// Author: J.Otwinowski 04/02/2008
//------------------------------------------------------------------------------

#include <iostream>
#include <TArrayI.h>
#include <TList.h>

#include "AliLog.h"
#include "AliMCInfoCuts.h"

using namespace std;

ClassImp(AliMCInfoCuts)

//_____________________________________________________________________________
AliMCInfoCuts::AliMCInfoCuts() :
AliAnalysisCuts()
, fMinRowsWithDigits(0)
, fMaxR(0)
, fMaxVz(0)
, fMinTPCSignal(0)
, fMaxTPCSignal(0)
, fMinTrackLength(0)
, aTrackParticles(0)
{
  // default constructor
}

//_____________________________________________________________________________
AliMCInfoCuts::AliMCInfoCuts(const Char_t* name,const Char_t *title) :
  AliAnalysisCuts(name, title)
, fMinRowsWithDigits(0)
, fMaxR(0)
, fMaxVz(0)
, fMinTPCSignal(0)
, fMaxTPCSignal(0)
, fMinTrackLength(0)
, aTrackParticles(0)
{
  // default constructor

  // init data members with defaults
  InitME();
}

//_____________________________________________________________________________
AliMCInfoCuts::AliMCInfoCuts(const AliMCInfoCuts& that) :
AliAnalysisCuts(that)
, fMinRowsWithDigits(that.fMinRowsWithDigits)
, fMaxR(that.fMaxR)
, fMaxVz(that.fMaxVz)
, fMinTPCSignal(that.fMinTPCSignal)
, fMaxTPCSignal(that.fMaxTPCSignal)
, fMinTrackLength(that.fMinTrackLength)
, aTrackParticles(new TArrayI(*that.aTrackParticles))
{
}

//_____________________________________________________________________________
AliMCInfoCuts& AliMCInfoCuts::operator=(const AliMCInfoCuts& that)
{
  fMinRowsWithDigits = that.fMinRowsWithDigits;
  fMaxR = that.fMaxR;
  fMaxVz = that.fMaxVz;
  fMinTPCSignal = that.fMinTPCSignal;
  fMaxTPCSignal = that.fMaxTPCSignal;
  fMinTrackLength = that.fMinTrackLength;
  if (!aTrackParticles)
    aTrackParticles = new TArrayI(*that.aTrackParticles);
  else
    *aTrackParticles = *that.aTrackParticles;
  return *this;
}

//_____________________________________________________________________________
AliMCInfoCuts::~AliMCInfoCuts()
{
  // destructor
  delete aTrackParticles;
}

//_____________________________________________________________________________
void AliMCInfoCuts::InitME()
{
  // set default values
  SetMinRowsWithDigits();
  SetMaxR();
  SetMaxVz();
  SetRangeTPCSignal();
  SetMinTrackLength();

  // create aTrackParticles array
  aTrackParticles = new TArrayI(kNParticles); // max nb. of particles
  aTrackParticles->Reset(0);

  // create an array of track particles: e, muons, pions, kaons, protons
  if(aTrackParticles != 0)
  {
     // keep order adding a new particles
     AddPdgParticle(0,ep);   // e+
     AddPdgParticle(1,em);   // e-
     AddPdgParticle(2,mup);  // mu+
     AddPdgParticle(3,mum);  // mu-
     AddPdgParticle(4,pip);  // pi+
     AddPdgParticle(5,pim);  // pi-
     AddPdgParticle(6,kp);   // K+
     AddPdgParticle(7,km);   // K-
     AddPdgParticle(8,prot);    // p
     AddPdgParticle(9,protbar); // p_bar
  }
}

//_____________________________________________________________________________
void AliMCInfoCuts::AddPdgParticle(Int_t idx, Int_t pdgcode) const
{
  // add particle to the array
  if(aTrackParticles != 0) aTrackParticles->AddAt(pdgcode,idx);
  else AliDebug(AliLog::kError, "ERROR: Cannot add particle to the array");
}

//_____________________________________________________________________________
Bool_t AliMCInfoCuts::IsPdgParticle(Int_t pdgcode) const
{
  // check PDG particle
  if(aTrackParticles == 0) {
    AliDebug(AliLog::kError, "ERROR: Cannot get particle array");
    return kFALSE;
  }

  Int_t size = aTrackParticles->GetSize();
  for(int i=0; i<size; ++i) {
    if(pdgcode == aTrackParticles->At(i)) return kTRUE;
  }
  return kFALSE;
}

//_____________________________________________________________________________
Bool_t AliMCInfoCuts::IsPosPdgParticle(Int_t pdgcode) const
{
  // check PDG particle (only positive charged)
  if(aTrackParticles == 0) {
    AliDebug(AliLog::kError, "ERROR: Cannot get particle array");
    return kFALSE;
  }

  Int_t size = aTrackParticles->GetSize();
  for(int i=0; i<size; ++i) {
    // leptons have oposite pdg convension from hadrons (e+/e- = -11/11)
    if(pdgcode > 0 && (pdgcode == 11 || pdgcode == 13)) return kFALSE;
    if(pdgcode < 0 && (pdgcode != -11 || pdgcode != -13) ) return kFALSE;
	//
    if(pdgcode == aTrackParticles->At(i)) return kTRUE;
  }
  return kFALSE;
}

//_____________________________________________________________________________
Long64_t AliMCInfoCuts::Merge(TCollection* list)
{
  // Merge list of objects (needed by PROOF)
  if (!list)
  return 0;

  if (list->IsEmpty())
  return 1;

  TIterator* iter = list->MakeIterator();
  TObject* obj = 0;

  Int_t count=0;
  while((obj = iter->Next()) != 0)
  {
    AliMCInfoCuts* entry = dynamic_cast<AliMCInfoCuts*>(obj);
    if (entry == 0)
      continue;

  count++;
  }

return count;
}
<|endoftext|>


<commit_before>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/* $Id$*/

// Trigger preprocessor class.
// According to the TriggerDetectorMask read from the logbook_trigger_clusters
// DAQ table, the triggering detectors are identified, and the
// corresponding procedure is called.
// Data are stored in the OCDB, in /TRIGGER/<DET>/<level3>, where
// <DET> correspond to the triggering detector,
// and <level3> is defined in the detector procedure

#include "AliTRIPreprocessor.h"

#include "AliCDBMetaData.h"
#include "AliCDBEntry.h"
#include "AliLog.h"
#include "AliITSTriggerConditions.h"

#include <TTimeStamp.h>
#include <TObjString.h>
#include <TList.h>
#include <TROOT.h>
#include <TSystem.h>

ClassImp(AliTRIPreprocessor)

// names of detectors/systems in the DETECTORS_MAP in /date/db/detCodes.h
const char* AliTRIPreprocessor::fgkDetectorsMapName[AliTRIPreprocessor::kNDetectorsMap] = {"SPD"/*0*/, "SDD"/*1*/, "SSD"/*2*/, "TPC"/*3*/, "TRD"/*4*/,
									       "TOF"/*5*/, "HMP"/*6*/, "PHS"/*7*/, "CPV"/*8*/, "PMD"/*9*/,
									       "MCH"/*10*/,"MTR"/*11*/,"FMD"/*12*/,"T00"/*13*/,"V00"/*14*/,
									       "ZDC"/*15*/,"ACO"/*16*/,"TRI"/*17*/,"EMC"/*18*/,"TST"/*19*/,
									       ""/*20*/,   ""/*21*/,   ""/*22*/,   ""/*23*/,   ""/*24*/,
									       ""/*25*/,   ""/*26*/,   ""/*27*/,   ""/*28*/,   "GRP"/*29*/,
									       "HLT"/*30*/};

//______________________________________________________________________________________________
AliTRIPreprocessor::AliTRIPreprocessor(AliShuttleInterface* shuttle) :
  AliPreprocessor("TRI", shuttle),
  fShuttle(shuttle)

{
	//
	// constructor
	//

	AddRunType("PHYSICS");
}

//______________________________________________________________________________________________
AliTRIPreprocessor::~AliTRIPreprocessor()
{
	//
	// destructor
	//
}

//______________________________________________________________________________________________
void AliTRIPreprocessor::Initialize(Int_t run, UInt_t startTime,
	UInt_t endTime)
{

	//
	// Initialize preprocessor
	//

	AliPreprocessor::Initialize(run, startTime, endTime);

	Log(Form("\n\tRun %d \n\tStartTime %s \n\tEndTime %s", run,
		TTimeStamp(startTime).AsString(),
		TTimeStamp(endTime).AsString()));

}

//______________________________________________________________________________________________
Bool_t AliTRIPreprocessor::ProcessDCS()
{
	//
	// DCS data are never needed
	//

	return kFALSE;
}

//______________________________________________________________________________________________
UInt_t AliTRIPreprocessor::Process(TMap* /*dcsAliasMap*/)
{

	// Procees function:
	// After reading the TriggerDetectorMask, the
	// corresponding triggering detector procedures to
	// process the trigger data are called.

	typedef Short_t (AliTRIPreprocessor::*AliProcessTriggerData)();
	const AliProcessTriggerData processTriggerDataArray[AliTRIPreprocessor::kNDetectorsMap]= {
		&AliTRIPreprocessor::ProcessSPDTriggerData,
		&AliTRIPreprocessor::ProcessEmptyTriggerData,
		&AliTRIPreprocessor::ProcessEmptyTriggerData,
		&AliTRIPreprocessor::ProcessEmptyTriggerData,
		&AliTRIPreprocessor::ProcessEmptyTriggerData,
		&AliTRIPreprocessor::ProcessEmptyTriggerData,
		&AliTRIPreprocessor::ProcessEmptyTriggerData,
		&AliTRIPreprocessor::ProcessEmptyTriggerData,
		&AliTRIPreprocessor::ProcessEmptyTriggerData,
		&AliTRIPreprocessor::ProcessEmptyTriggerData,
		&AliTRIPreprocessor::ProcessEmptyTriggerData,
		&AliTRIPreprocessor::ProcessEmptyTriggerData,
		&AliTRIPreprocessor::ProcessEmptyTriggerData,
		&AliTRIPreprocessor::ProcessEmptyTriggerData,
		&AliTRIPreprocessor::ProcessEmptyTriggerData,
		&AliTRIPreprocessor::ProcessEmptyTriggerData,
		&AliTRIPreprocessor::ProcessEmptyTriggerData,
		&AliTRIPreprocessor::ProcessEmptyTriggerData,
		&AliTRIPreprocessor::ProcessEmptyTriggerData,
		&AliTRIPreprocessor::ProcessEmptyTriggerData,
		&AliTRIPreprocessor::ProcessEmptyTriggerData,
		&AliTRIPreprocessor::ProcessEmptyTriggerData,
		&AliTRIPreprocessor::ProcessEmptyTriggerData,
		&AliTRIPreprocessor::ProcessEmptyTriggerData,
		&AliTRIPreprocessor::ProcessEmptyTriggerData,
		&AliTRIPreprocessor::ProcessEmptyTriggerData,
		&AliTRIPreprocessor::ProcessEmptyTriggerData,
		&AliTRIPreprocessor::ProcessEmptyTriggerData,
		&AliTRIPreprocessor::ProcessEmptyTriggerData,
		&AliTRIPreprocessor::ProcessEmptyTriggerData,
		&AliTRIPreprocessor::ProcessEmptyTriggerData};

	// getting the list of triggering detectors from DAQ logbook

	TString triggerDetectorMask = (TString)GetTriggerDetectorMask();
	Int_t result=0;
	if (!triggerDetectorMask.IsNull()){
		Int_t length = triggerDetectorMask.Length();
		Log(Form("mask = %s", triggerDetectorMask.Data()));
		  for (Int_t i = 0; i<length; i++){
			AliDebug(2,Form("%d-th bit = %c in index %d",i,triggerDetectorMask[length-1-i],length-1-i));
			if (triggerDetectorMask[length-1-i] == '1'){
				Log("****************************************");
				Log(Form("Processing Trigger data for %s",fgkDetectorsMapName[i]));
				Log("****************************************");

				result+=(this->*processTriggerDataArray[i])();
			}
		}
	}

	// result should be 0 to end successfully

	return result;

}
//______________________________________________________________________________________________
Short_t AliTRIPreprocessor::ProcessSPDTriggerData()
{
	//
	// Processing SPD Trigger Data
	//

	Log("************** Processing SPD Trigger data... **************");

	// Read new conditions from dcs fxs
	AliITSTriggerConditions* newCond = new AliITSTriggerConditions();
	TString fxsID = "pit_conditions";
	TList* list = GetFileSources(kDCS, fxsID.Data());
	if (!list) {
		AliError("FXS file not found.");
		return 1;
	}
	UInt_t nFiles = 0;
	while (list->At(nFiles)!=NULL) {
		TObjString* fileNameEntry = (TObjString*) list->At(nFiles);
		TString fileName = GetFile(kDCS, fxsID.Data(), fileNameEntry->GetString().Data());
		if (fileName.IsNull()) {
			Log(Form("GetFile failed to retrieve file %s.",fileNameEntry->GetString().Data()));
			return 1;
		}
		if (nFiles==0) newCond->ReadFromTextFile(fileName.Data());
		nFiles++;
	}
	if (nFiles!=1) {
		AliWarning(Form("Found %d files with id %s (expected exactly 1).",nFiles,fxsID.Data()));
	}

	// Read old conditions from ocdb
	AliITSTriggerConditions* oldCond = NULL;
	AliCDBEntry* pitCond = GetFromOCDB("SPD", "PITConditions");
	if (pitCond) {
		oldCond = (AliITSTriggerConditions*) pitCond->GetObject();
		if (!oldCond) {
			AliError("AliCDBEntry::GetObject() returned NULL.");
			return 1;
		}
	}
	else {
		Log("Old conditions not found in database.");
	}

	// Do we need to update db?
	Bool_t doUpdate = kTRUE;
	if (oldCond) {
		// compare to see if there were any changes...
		if (newCond->IsEqualTo(oldCond)) {
			Log("Old conditions equal to new conditions. Do nothing.");
			doUpdate = kFALSE;
		}
	}

	if (doUpdate) {
		// store new conditions in ocdb
		AliCDBMetaData metaData;
		metaData.SetResponsible("Henrik Tydesjo");
		metaData.SetComment("Created by Trigger PreProcessor");
		if (!Store("SPD", "PITConditions", newCond, &metaData, 0, kTRUE)) {
			Log("Failed to store conditions data.");
			return 1;
		}
		Log("Database updated.");
	}

	delete newCond;

	Log("************************* ...done.*************************");

	return 0; // 0 means success

}
//______________________________________________________________________________________________
Short_t AliTRIPreprocessor::ProcessTOFTriggerData()
{
	//
	// Processing TOF Trigger Data
	//

	Log("************** Processing TOF Trigger data... **************");
	Log("************** Fake function **************");
	Log("************************* ...done.*************************");
	return 0;
}
//______________________________________________________________________________________________
Short_t AliTRIPreprocessor::ProcessEmptyTriggerData()
{
	//
	// Processing TOF Trigger Data
	//

	Log("************** Trigger data Processing not yet implemented **************");
	return 0;
}

<commit_msg>Updating Run Types for TRIGGER pp.<commit_after>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/* $Id$*/

// Trigger preprocessor class.
// According to the TriggerDetectorMask read from the logbook_trigger_clusters
// DAQ table, the triggering detectors are identified, and the
// corresponding procedure is called.
// Data are stored in the OCDB, in /TRIGGER/<DET>/<level3>, where
// <DET> correspond to the triggering detector,
// and <level3> is defined in the detector procedure

#include "AliTRIPreprocessor.h"

#include "AliCDBMetaData.h"
#include "AliCDBEntry.h"
#include "AliLog.h"
#include "AliITSTriggerConditions.h"

#include <TTimeStamp.h>
#include <TObjString.h>
#include <TList.h>
#include <TROOT.h>
#include <TSystem.h>

ClassImp(AliTRIPreprocessor)

// names of detectors/systems in the DETECTORS_MAP in /date/db/detCodes.h
const char* AliTRIPreprocessor::fgkDetectorsMapName[AliTRIPreprocessor::kNDetectorsMap] = {"SPD"/*0*/, "SDD"/*1*/, "SSD"/*2*/, "TPC"/*3*/, "TRD"/*4*/,
									       "TOF"/*5*/, "HMP"/*6*/, "PHS"/*7*/, "CPV"/*8*/, "PMD"/*9*/,
									       "MCH"/*10*/,"MTR"/*11*/,"FMD"/*12*/,"T00"/*13*/,"V00"/*14*/,
									       "ZDC"/*15*/,"ACO"/*16*/,"TRI"/*17*/,"EMC"/*18*/,"TST"/*19*/,
									       ""/*20*/,   ""/*21*/,   ""/*22*/,   ""/*23*/,   ""/*24*/,
									       ""/*25*/,   ""/*26*/,   ""/*27*/,   ""/*28*/,   "GRP"/*29*/,
									       "HLT"/*30*/};

//______________________________________________________________________________________________
AliTRIPreprocessor::AliTRIPreprocessor(AliShuttleInterface* shuttle) :
  AliPreprocessor("TRI", shuttle),
  fShuttle(shuttle)

{
	//
	// constructor
	//

	AddRunType("PHYSICS");
	AddRunType("STANDALONE_PULSER");
}

//______________________________________________________________________________________________
AliTRIPreprocessor::~AliTRIPreprocessor()
{
	//
	// destructor
	//
}

//______________________________________________________________________________________________
void AliTRIPreprocessor::Initialize(Int_t run, UInt_t startTime,
	UInt_t endTime)
{

	//
	// Initialize preprocessor
	//

	AliPreprocessor::Initialize(run, startTime, endTime);

	Log(Form("\n\tRun %d \n\tStartTime %s \n\tEndTime %s", run,
		TTimeStamp(startTime).AsString(),
		TTimeStamp(endTime).AsString()));

}

//______________________________________________________________________________________________
Bool_t AliTRIPreprocessor::ProcessDCS()
{
	//
	// DCS data are never needed
	//

	return kFALSE;
}

//______________________________________________________________________________________________
UInt_t AliTRIPreprocessor::Process(TMap* /*dcsAliasMap*/)
{

	// Procees function:
	// After reading the TriggerDetectorMask, the
	// corresponding triggering detector procedures to
	// process the trigger data are called.

	typedef Short_t (AliTRIPreprocessor::*AliProcessTriggerData)();
	const AliProcessTriggerData processTriggerDataArray[AliTRIPreprocessor::kNDetectorsMap]= {
		&AliTRIPreprocessor::ProcessSPDTriggerData,
		&AliTRIPreprocessor::ProcessEmptyTriggerData,
		&AliTRIPreprocessor::ProcessEmptyTriggerData,
		&AliTRIPreprocessor::ProcessEmptyTriggerData,
		&AliTRIPreprocessor::ProcessEmptyTriggerData,
		&AliTRIPreprocessor::ProcessEmptyTriggerData,
		&AliTRIPreprocessor::ProcessEmptyTriggerData,
		&AliTRIPreprocessor::ProcessEmptyTriggerData,
		&AliTRIPreprocessor::ProcessEmptyTriggerData,
		&AliTRIPreprocessor::ProcessEmptyTriggerData,
		&AliTRIPreprocessor::ProcessEmptyTriggerData,
		&AliTRIPreprocessor::ProcessEmptyTriggerData,
		&AliTRIPreprocessor::ProcessEmptyTriggerData,
		&AliTRIPreprocessor::ProcessEmptyTriggerData,
		&AliTRIPreprocessor::ProcessEmptyTriggerData,
		&AliTRIPreprocessor::ProcessEmptyTriggerData,
		&AliTRIPreprocessor::ProcessEmptyTriggerData,
		&AliTRIPreprocessor::ProcessEmptyTriggerData,
		&AliTRIPreprocessor::ProcessEmptyTriggerData,
		&AliTRIPreprocessor::ProcessEmptyTriggerData,
		&AliTRIPreprocessor::ProcessEmptyTriggerData,
		&AliTRIPreprocessor::ProcessEmptyTriggerData,
		&AliTRIPreprocessor::ProcessEmptyTriggerData,
		&AliTRIPreprocessor::ProcessEmptyTriggerData,
		&AliTRIPreprocessor::ProcessEmptyTriggerData,
		&AliTRIPreprocessor::ProcessEmptyTriggerData,
		&AliTRIPreprocessor::ProcessEmptyTriggerData,
		&AliTRIPreprocessor::ProcessEmptyTriggerData,
		&AliTRIPreprocessor::ProcessEmptyTriggerData,
		&AliTRIPreprocessor::ProcessEmptyTriggerData,
		&AliTRIPreprocessor::ProcessEmptyTriggerData};

	// getting the list of triggering detectors from DAQ logbook

	TString triggerDetectorMask = (TString)GetTriggerDetectorMask();
	Int_t result=0;
	if (!triggerDetectorMask.IsNull()){
		Int_t length = triggerDetectorMask.Length();
		Log(Form("mask = %s", triggerDetectorMask.Data()));
		  for (Int_t i = 0; i<length; i++){
			AliDebug(2,Form("%d-th bit = %c in index %d",i,triggerDetectorMask[length-1-i],length-1-i));
			if (triggerDetectorMask[length-1-i] == '1'){
				Log("****************************************");
				Log(Form("Processing Trigger data for %s",fgkDetectorsMapName[i]));
				Log("****************************************");

				result+=(this->*processTriggerDataArray[i])();
			}
		}
	}

	// result should be 0 to end successfully

	return result;

}
//______________________________________________________________________________________________
Short_t AliTRIPreprocessor::ProcessSPDTriggerData()
{
	//
	// Processing SPD Trigger Data
	//

	Log("************** Processing SPD Trigger data... **************");

	// Read new conditions from dcs fxs
	AliITSTriggerConditions* newCond = new AliITSTriggerConditions();
	TString fxsID = "pit_conditions";
	TList* list = GetFileSources(kDCS, fxsID.Data());
	if (!list) {
		AliError("FXS file not found.");
		return 1;
	}
	UInt_t nFiles = 0;
	while (list->At(nFiles)!=NULL) {
		TObjString* fileNameEntry = (TObjString*) list->At(nFiles);
		TString fileName = GetFile(kDCS, fxsID.Data(), fileNameEntry->GetString().Data());
		if (fileName.IsNull()) {
			Log(Form("GetFile failed to retrieve file %s.",fileNameEntry->GetString().Data()));
			return 1;
		}
		if (nFiles==0) newCond->ReadFromTextFile(fileName.Data());
		nFiles++;
	}
	if (nFiles!=1) {
		AliWarning(Form("Found %d files with id %s (expected exactly 1).",nFiles,fxsID.Data()));
	}

	// Read old conditions from ocdb
	AliITSTriggerConditions* oldCond = NULL;
	AliCDBEntry* pitCond = GetFromOCDB("SPD", "PITConditions");
	if (pitCond) {
		oldCond = (AliITSTriggerConditions*) pitCond->GetObject();
		if (!oldCond) {
			AliError("AliCDBEntry::GetObject() returned NULL.");
			return 1;
		}
	}
	else {
		Log("Old conditions not found in database.");
	}

	// Do we need to update db?
	Bool_t doUpdate = kTRUE;
	if (oldCond) {
		// compare to see if there were any changes...
		if (newCond->IsEqualTo(oldCond)) {
			Log("Old conditions equal to new conditions. Do nothing.");
			doUpdate = kFALSE;
		}
	}

	if (doUpdate) {
		// store new conditions in ocdb
		AliCDBMetaData metaData;
		metaData.SetResponsible("Henrik Tydesjo");
		metaData.SetComment("Created by Trigger PreProcessor");
		if (!Store("SPD", "PITConditions", newCond, &metaData, 0, kTRUE)) {
			Log("Failed to store conditions data.");
			return 1;
		}
		Log("Database updated.");
	}

	delete newCond;

	Log("************************* ...done.*************************");

	return 0; // 0 means success

}
//______________________________________________________________________________________________
Short_t AliTRIPreprocessor::ProcessTOFTriggerData()
{
	//
	// Processing TOF Trigger Data
	//

	Log("************** Processing TOF Trigger data... **************");
	Log("************** Fake function **************");
	Log("************************* ...done.*************************");
	return 0;
}
//______________________________________________________________________________________________
Short_t AliTRIPreprocessor::ProcessEmptyTriggerData()
{
	//
	// Processing TOF Trigger Data
	//

	Log("************** Trigger data Processing not yet implemented **************");
	return 0;
}

<|endoftext|>


<commit_before>// Copyright (c) 2008-2010 Kent State University
// Copyright (c) 2011 Texas A&M University
//
// This file is distributed under the MIT License. See the accompanying file
// LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms
// and conditions.

#ifndef ORIGIN_MATH_BLAS_MATRIX_ALLOC_BASE_HPP
#define ORIGIN_MATH_BLAS_MATRIX_ALLOC_BASE_HPP
#include <cassert>
#include <memory>
#include <algorithm>

namespace origin { namespace blas { namespace detail {

/** The basic matrix base class used for handling
 *  memory allocations.
 */
template<typename T, typename Alloc>
class matrix_alloc_base {
public:
    typedef typename Alloc::template rebind<T>::other rebound_alloc_type;
    typedef typename std::allocator_traits<rebound_alloc_type>::allocator_type allocator_type;
    typedef typename std::allocator_traits<rebound_alloc_type>::value_type value_type;
    typedef typename std::allocator_traits<rebound_alloc_type>::pointer pointer;
    typedef typename std::allocator_traits<rebound_alloc_type>::reference reference;
    typedef typename std::allocator_traits<rebound_alloc_type>::const_pointer const_pointer;
    typedef typename std::allocator_traits<rebound_alloc_type>::const_reference const_reference;
    typedef typename std::allocator_traits<rebound_alloc_type>::difference_type difference_type;
    typedef typename std::allocator_traits<rebound_alloc_type>::size_type size_type;

};

}}} // end origin::blas::detail

#endif<commit_msg>Looking for concept/typetrait that allows me to verify allocator alignment for reuse.<commit_after>// Copyright (c) 2008-2010 Kent State University
// Copyright (c) 2011 Texas A&M University
//
// This file is distributed under the MIT License. See the accompanying file
// LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms
// and conditions.

#ifndef ORIGIN_MATH_BLAS_MATRIX_ALLOC_BASE_HPP
#define ORIGIN_MATH_BLAS_MATRIX_ALLOC_BASE_HPP
#include <cassert>
#include <memory>
#include <algorithm>

namespace origin { namespace blas { namespace detail {

/** The basic matrix base class used for handling
 *  memory allocations.
 */
template<typename T, typename Alloc>
class matrix_alloc_base {
public:
    typedef typename Alloc::template rebind<T>::other rebound_alloc_type;
    typedef typename std::allocator_traits<rebound_alloc_type>::allocator_type allocator_type;
    typedef typename std::allocator_traits<rebound_alloc_type>::value_type value_type;
    typedef typename std::allocator_traits<rebound_alloc_type>::pointer pointer;
    typedef typename std::allocator_traits<rebound_alloc_type>::reference reference;
    typedef typename std::allocator_traits<rebound_alloc_type>::const_pointer const_pointer;
    typedef typename std::allocator_traits<rebound_alloc_type>::const_reference const_reference;
    typedef typename std::allocator_traits<rebound_alloc_type>::difference_type difference_type;
    typedef typename std::allocator_traits<rebound_alloc_type>::size_type size_type;

private:
    struct matrix_alloc_impl_base {

    };

};

}}} // end origin::blas::detail

#endif<|endoftext|>


<commit_before>#include "PC.h"

PC::PC()
{
}

PC::~PC()
{
}
<commit_msg>켜기 만듬<commit_after>#include "PC.h"

PC::PC()
{
}

PC::~PC()
{
}

bool PC::TurnOnComputer() {
	is_power_on = true;
	return true;
}<|endoftext|>


<commit_before>//
// Options.cpp
//
// Copyright (c) 2001-2004 Virtual Terrain Project
// Free for all uses, see license.txt for details.
//

#include "vtlib/vtlib.h"
#include <string.h>
#include "Options.h"

#include <fstream>
using namespace std;

EnviroOptions g_Options;

#define STR_DATAPATH "DataPath"
#define STR_EARTHVIEW "EarthView"
#define STR_EARTHIMAGE "EarthImage"
#define STR_INITTERRAIN "InitialTerrain"
#define STR_FULLSCREEN "FullScreen"
#define STR_HTMLPANE "HTMLPane"
#define STR_FLOATBAR "FloatingToolBar"
#define STR_TEXTURE_COMPRESSION "TextureCompression"
#define STR_SPEEDTEST "SpeedTest"
#define STR_PLANTSIZE "PlantSize"
#define STR_PLANTSHADOWS "PlantShadows"
#define STR_SELECTIONCUTOFF "SelectionCutoff"
#define STR_DISABLE_MODEL_MIPMAPS "DisableModelMipmaps"
#define STR_CURSOR_THICKNESS "CursorThickness"

EnviroOptions::EnviroOptions()
{
	m_strImage = "ev11656_512";
	m_fSelectionCutoff = 15.0f;
	m_bStartInNeutral = false;
	m_bDisableModelMipmaps = false;
	m_bTextureCompression = true;
	m_fCursorThickness = 0.025;
}

EnviroOptions::~EnviroOptions()
{
}

bool EnviroOptions::Read(const char *szFilename)
{
	m_strFilename = szFilename;

	ifstream input(m_strFilename, ios::in | ios::binary);
	if (!input.is_open())
		return false;

	char buf[80];

	while (!input.eof())
	{
		if (input.peek() == '\n')
			input.ignore();
		input >> buf;

		// data value should been separated by a tab or space
		int next = input.peek();
		if (next != '\t' && next != ' ')
			continue;
		while (input.peek() == '\t' || input.peek() == ' ')
			input.ignore();

		if (strcmp(buf, STR_DATAPATH) == 0)
		{
			m_DataPaths.push_back(vtString(get_line_from_stream(input)));
		}
		else if (strcmp(buf, STR_EARTHVIEW) == 0)
			input >> m_bEarthView;
		else if (strcmp(buf, STR_EARTHIMAGE) == 0)
			m_strImage = get_line_from_stream(input);
		else if (strcmp(buf, STR_INITTERRAIN) == 0)
			m_strInitTerrain = get_line_from_stream(input);
		else if (strcmp(buf, STR_FULLSCREEN) == 0)
			input >> m_bFullscreen;
		else if (strcmp(buf, STR_HTMLPANE) == 0)
			input >> m_bHtmlpane;
		else if (strcmp(buf, STR_FLOATBAR) == 0)
			input >> m_bFloatingToolbar;
		else if (strcmp(buf, STR_TEXTURE_COMPRESSION) == 0)
			input >> m_bTextureCompression;
		else if (strcmp(buf, STR_SPEEDTEST) == 0)
			input >> m_bSpeedTest;
		else if (strcmp(buf, STR_PLANTSIZE) == 0)
			input >> m_fPlantScale;
		else if (strcmp(buf, STR_PLANTSHADOWS) == 0)
			input >> m_bShadows;
		else if (strcmp(buf, STR_SELECTIONCUTOFF) == 0)
			input >> m_fSelectionCutoff;
		else if (strcmp(buf, STR_DISABLE_MODEL_MIPMAPS) == 0)
			input >> m_bDisableModelMipmaps;
		else if (strcmp(buf, STR_CURSOR_THICKNESS) == 0)
			input >> m_fCursorThickness;
		else
		{
//			cout << "Input from INI file unrecognized.\n";
			get_line_from_stream(input);
		}
	}
	return true;
}

bool EnviroOptions::Write()
{
	ofstream output(m_strFilename, ios::binary);
	if (!output.is_open())
	{
		vtString msg;
		msg = "Couldn't write settings to file \"";
		msg += m_strFilename;
		msg += "\"\nPlease make sure it's writable.\n";
//		AfxMessageBox(msg);
//		MessageBox(NULL, msg, "Note", MB_OK);
		VTLOG(msg);
		return false;
	}

	// write to file
	for (unsigned int i = 0; i < m_DataPaths.size(); i++)
	{
		output << STR_DATAPATH << "\t\t";
		output << (const char *)(m_DataPaths[i]) << endl;
	}
	output << STR_EARTHVIEW << "\t\t";
	output << m_bEarthView << endl;
	output << STR_EARTHIMAGE << "\t\t";
	output << (const char *)m_strImage << endl;
	output << STR_INITTERRAIN << "\t";
	output << (const char *)m_strInitTerrain << endl;

	output << STR_FULLSCREEN << "\t\t";
	output << m_bFullscreen << endl;
	output << STR_HTMLPANE << "\t\t";
	output << m_bHtmlpane << endl;
	output << STR_FLOATBAR << "\t";
	output << m_bFloatingToolbar << endl;

	output << STR_TEXTURE_COMPRESSION << "\t";
	output << m_bTextureCompression << endl;
	output << STR_SPEEDTEST << "\t\t";
	output << m_bSpeedTest << endl;
	output << STR_PLANTSIZE << "\t\t";
	output << m_fPlantScale << endl;
	output << STR_PLANTSHADOWS << "\t";
	output << m_bShadows << endl;
	output << STR_SELECTIONCUTOFF << "\t";
	output << m_fSelectionCutoff << endl;
	output << STR_DISABLE_MODEL_MIPMAPS << "\t";
	output << m_bDisableModelMipmaps << endl;
	output << STR_CURSOR_THICKNESS << "\t";
	output << m_fCursorThickness << endl;

	return true;
}

<commit_msg>added vtLog.h<commit_after>//
// Options.cpp
//
// Copyright (c) 2001-2004 Virtual Terrain Project
// Free for all uses, see license.txt for details.
//

#include "vtlib/vtlib.h"
#include "vtdata/vtLog.h"
#include <string.h>
#include "Options.h"

#include <fstream>
using namespace std;

EnviroOptions g_Options;

#define STR_DATAPATH "DataPath"
#define STR_EARTHVIEW "EarthView"
#define STR_EARTHIMAGE "EarthImage"
#define STR_INITTERRAIN "InitialTerrain"
#define STR_FULLSCREEN "FullScreen"
#define STR_HTMLPANE "HTMLPane"
#define STR_FLOATBAR "FloatingToolBar"
#define STR_TEXTURE_COMPRESSION "TextureCompression"
#define STR_SPEEDTEST "SpeedTest"
#define STR_PLANTSIZE "PlantSize"
#define STR_PLANTSHADOWS "PlantShadows"
#define STR_SELECTIONCUTOFF "SelectionCutoff"
#define STR_DISABLE_MODEL_MIPMAPS "DisableModelMipmaps"
#define STR_CURSOR_THICKNESS "CursorThickness"

EnviroOptions::EnviroOptions()
{
	m_strImage = "ev11656_512";
	m_fSelectionCutoff = 15.0f;
	m_bStartInNeutral = false;
	m_bDisableModelMipmaps = false;
	m_bTextureCompression = true;
	m_fCursorThickness = 0.025;
}

EnviroOptions::~EnviroOptions()
{
}

bool EnviroOptions::Read(const char *szFilename)
{
	m_strFilename = szFilename;

	ifstream input(m_strFilename, ios::in | ios::binary);
	if (!input.is_open())
		return false;

	char buf[80];

	while (!input.eof())
	{
		if (input.peek() == '\n')
			input.ignore();
		input >> buf;

		// data value should been separated by a tab or space
		int next = input.peek();
		if (next != '\t' && next != ' ')
			continue;
		while (input.peek() == '\t' || input.peek() == ' ')
			input.ignore();

		if (strcmp(buf, STR_DATAPATH) == 0)
		{
			m_DataPaths.push_back(vtString(get_line_from_stream(input)));
		}
		else if (strcmp(buf, STR_EARTHVIEW) == 0)
			input >> m_bEarthView;
		else if (strcmp(buf, STR_EARTHIMAGE) == 0)
			m_strImage = get_line_from_stream(input);
		else if (strcmp(buf, STR_INITTERRAIN) == 0)
			m_strInitTerrain = get_line_from_stream(input);
		else if (strcmp(buf, STR_FULLSCREEN) == 0)
			input >> m_bFullscreen;
		else if (strcmp(buf, STR_HTMLPANE) == 0)
			input >> m_bHtmlpane;
		else if (strcmp(buf, STR_FLOATBAR) == 0)
			input >> m_bFloatingToolbar;
		else if (strcmp(buf, STR_TEXTURE_COMPRESSION) == 0)
			input >> m_bTextureCompression;
		else if (strcmp(buf, STR_SPEEDTEST) == 0)
			input >> m_bSpeedTest;
		else if (strcmp(buf, STR_PLANTSIZE) == 0)
			input >> m_fPlantScale;
		else if (strcmp(buf, STR_PLANTSHADOWS) == 0)
			input >> m_bShadows;
		else if (strcmp(buf, STR_SELECTIONCUTOFF) == 0)
			input >> m_fSelectionCutoff;
		else if (strcmp(buf, STR_DISABLE_MODEL_MIPMAPS) == 0)
			input >> m_bDisableModelMipmaps;
		else if (strcmp(buf, STR_CURSOR_THICKNESS) == 0)
			input >> m_fCursorThickness;
		else
		{
//			cout << "Input from INI file unrecognized.\n";
			get_line_from_stream(input);
		}
	}
	return true;
}

bool EnviroOptions::Write()
{
	ofstream output(m_strFilename, ios::binary);
	if (!output.is_open())
	{
		vtString msg;
		msg = "Couldn't write settings to file \"";
		msg += m_strFilename;
		msg += "\"\nPlease make sure it's writable.\n";
		VTLOG(msg);
		return false;
	}

	// write to file
	for (unsigned int i = 0; i < m_DataPaths.size(); i++)
	{
		output << STR_DATAPATH << "\t\t";
		output << (const char *)(m_DataPaths[i]) << endl;
	}
	output << STR_EARTHVIEW << "\t\t";
	output << m_bEarthView << endl;
	output << STR_EARTHIMAGE << "\t\t";
	output << (const char *)m_strImage << endl;
	output << STR_INITTERRAIN << "\t";
	output << (const char *)m_strInitTerrain << endl;

	output << STR_FULLSCREEN << "\t\t";
	output << m_bFullscreen << endl;
	output << STR_HTMLPANE << "\t\t";
	output << m_bHtmlpane << endl;
	output << STR_FLOATBAR << "\t";
	output << m_bFloatingToolbar << endl;

	output << STR_TEXTURE_COMPRESSION << "\t";
	output << m_bTextureCompression << endl;
	output << STR_SPEEDTEST << "\t\t";
	output << m_bSpeedTest << endl;
	output << STR_PLANTSIZE << "\t\t";
	output << m_fPlantScale << endl;
	output << STR_PLANTSHADOWS << "\t";
	output << m_bShadows << endl;
	output << STR_SELECTIONCUTOFF << "\t";
	output << m_fSelectionCutoff << endl;
	output << STR_DISABLE_MODEL_MIPMAPS << "\t";
	output << m_bDisableModelMipmaps << endl;
	output << STR_CURSOR_THICKNESS << "\t";
	output << m_fCursorThickness << endl;

	return true;
}

<|endoftext|>


<commit_before>#include "externalpotential.h"
#include "multipole.h"
#include "aux/eigensupport.h"
#include "functionparser.h"
#include "space.h"
#include "spdlog/spdlog.h"

namespace Faunus {
namespace Energy {

// ------------ Energybase -------------

void Energybase::to_json(json &) const {}

void Energybase::sync(Energybase *, Change &) {}

void Energybase::init() {}

void to_json(json &j, const Energybase &base) {
    assert(not base.name.empty());
    if (base.timer)
        j[base.name]["relative time"] = base.timer.result();
    if (not base.cite.empty())
        j[base.name]["reference"] = base.cite;
    base.to_json(j[base.name]);
}

// ------------ ExternalPotential -------------

// this calculates the interaction of a whole group
// with the applied external potential.
double ExternalPotential::_energy(const Group<Particle> &g) const {
    double u = 0;
    if (molids.find(g.id) != molids.end()) {
        if (COM and g.atomic == false) { // apply only to center of mass
            Particle cm;                 // temp. particle representing molecule
            cm.charge = Faunus::monopoleMoment(g.begin(), g.end());
            cm.pos = g.cm;
            return func(cm);
        } else {
            for (auto &p : g) { // loop over active particles
                u += func(p);
                if (std::isnan(u))
                    break;
            }
        }
    }
    return u;
}

ExternalPotential::ExternalPotential(const json &j, Space &spc) : spc(spc) {
    name = "external";
    COM = j.value("com", false);
    _names = j.at("molecules").get<decltype(_names)>(); // molecule names
    auto _ids = names2ids(molecules, _names);           // names --> molids
    molids = std::set<int>(_ids.begin(), _ids.end());   // vector --> set
    if (molids.empty())
        throw std::runtime_error(name + ": molecule list is empty");
}
double ExternalPotential::energy(Change &change) {
    assert(func != nullptr);
    double u = 0;
    if (change.dV or change.all or change.dN) {
        for (auto &g : spc.groups) { // check all groups
            u += _energy(g);
            if (std::isnan(u))
                break;
        }
    } else
        for (auto &d : change.groups) {
            auto &g = spc.groups.at(d.index); // check specified groups
            if (d.all or COM)                 // check all atoms in group
                u += _energy(g);              // _energy also checks for molecule id
            else {                            // check only specified atoms in group
                if (molids.find(g.id) != molids.end())
                    for (auto i : d.atoms)
                        u += func(*(g.begin() + i));
            }
            if (std::isnan(u))
                break;
        }
    return u;
}
void ExternalPotential::to_json(json &j) const {
    j["molecules"] = _names;
    j["com"] = COM;
}

// ------------ Confine -------------

Confine::Confine(const json &j, Tspace &spc) : ExternalPotential(j, spc) {
    name = "confine";
    k = value_inf(j, "k") * 1.0_kJmol; // get floating point; allow inf/-inf
    type = m.at(j.at("type"));

    if (type == sphere or type == cylinder) {
        radius = j.at("radius");
        origo = j.value("origo", origo);
        scale = j.value("scale", scale);
        if (type == cylinder)
            dir = {1, 1, 0};
        func = [&radius = radius, origo = origo, k = k, dir = dir](const Particle &p) {
            double d2 = (origo - p.pos).cwiseProduct(dir).squaredNorm() - radius * radius;
            if (d2 > 0)
                return 0.5 * k * d2;
            return 0.0;
        };

        // If volume is scaled, also scale the confining radius by adding a trigger
        // to `Space::scaleVolume()`
        if (scale)
            spc.scaleVolumeTriggers.push_back(
                [&radius = radius](Tspace &, double Vold, double Vnew) { radius *= std::cbrt(Vnew / Vold); });
    }

    if (type == cuboid) {
        low = j.at("low").get<Point>();
        high = j.at("high").get<Point>();
        func = [low = low, high = high, k = k](const Particle &p) {
            double u = 0;
            Point d = low - p.pos;
            for (int i = 0; i < 3; ++i)
                if (d[i] > 0)
                    u += d[i] * d[i];
            d = p.pos - high;
            for (int i = 0; i < 3; ++i)
                if (d[i] > 0)
                    u += d[i] * d[i];
            return 0.5 * k * u;
        };
    }
}
void Confine::to_json(json &j) const {
    if (type == cuboid)
        j = {{"low", low}, {"high", high}};
    if (type == sphere or type == cylinder)
        j = {{"radius", radius}};
    if (type == sphere) {
        j["origo"] = origo;
        j["scale"] = scale;
    }
    for (auto &i : m)
        if (i.second == type)
            j["type"] = i.first;
    j["k"] = k / 1.0_kJmol;
    ExternalPotential::to_json(j);
    _roundjson(j, 5);
}

// ------------ ExternalAkesson -------------

ExternalAkesson::ExternalAkesson(const json &j, Tspace &spc) : ExternalPotential(j, spc) {
    name = "akesson";
    cite = "doi:10/dhb9mj";

    SingleUseJSON _j = j; // json variant where items are deleted after access
    _j.erase("com");
    _j.erase("molecules");

    nstep = _j.at("nstep").get<unsigned int>();
    epsr = _j.at("epsr").get<double>();
    fixed = _j.value("fixed", false);
    nphi = _j.value("nphi", 10);

    halfz = 0.5 * spc.geo.getLength().z();
    lB = pc::lB(epsr);

    dz = _j.value("dz", 0.2); // read z resolution
    Q.setResolution(dz, -halfz, halfz);
    rho.setResolution(dz, -halfz, halfz);
    phi.setResolution(dz, -halfz, halfz);

    filename = _j.value("file", "mfcorr.dat"s);
    load();

    func = [&phi = phi](const typename Tspace::Tparticle &p) { return p.charge * phi(p.pos.z()); };

    if (not _j.empty()) // throw exception of unused/unknown keys are passed
        throw std::runtime_error("unused key(s) for '"s + name + "':\n" + _j.dump());
}

double ExternalAkesson::energy(Change &change) {
    if (not fixed)                    // pho(z) unconverged, keep sampling
        if (key == Energybase::OLD) { // only sample on accepted configs
            cnt++;
            if (cnt % nstep == 0)
                update_rho();
            if (cnt % nstep * nphi == 0)
                update_phi();
        }
    return ExternalPotential::energy(change);
}

ExternalAkesson::~ExternalAkesson() {
    // save only if still updating and if energy type is "OLD",
    // that is, accepted configurations (not trial)
    if (not fixed and key == Energybase::OLD)
        save();
}

void ExternalAkesson::to_json(json &j) const {
    j = {{"lB", lB},         {"dz", dz},       {"nphi", nphi},          {"epsr", epsr},
         {"file", filename}, {"nstep", nstep}, {"Nupdates", updatecnt}, {"fixed", fixed}};
    ExternalPotential::to_json(j);
    _roundjson(j, 5);
}

void ExternalAkesson::save() {
    std::ofstream f(filename);
    if (f) {
        f.precision(16);
        f << rho;
    } else
        throw std::runtime_error("cannot save file '"s + filename + "'");
}

void ExternalAkesson::load() {
    std::ifstream f(filename);
    if (f) {
        rho << f;
        update_phi();
    } else
        faunus_logger->warn("density file {} not loaded", filename);
}

double ExternalAkesson::phi_ext(double z, double a) const {
    double a2 = a * a, z2 = z * z;
    return -2 * pc::pi * z - 8 * a * std::log((std::sqrt(2 * a2 + z2) + a) / std::sqrt(a2 + z2)) +
           2 * z * (0.5 * pc::pi + std::asin((a2 * a2 - z2 * z2 - 2 * a2 * z2) / std::pow(a2 + z2, 2)));
}

void ExternalAkesson::sync(Energybase *basePtr, Change &) {
    if (not fixed) {
        auto other = dynamic_cast<decltype(this)>(basePtr);
        assert(other);
        // only trial energy (new) require sync
        if (other->key == Energybase::OLD)
            if (cnt != other->cnt) {
                assert(cnt < other->cnt && "trial cnt's must be smaller");
                cnt = other->cnt;
                rho = other->rho;
                phi = other->phi;
            }
    }
}

void ExternalAkesson::update_rho() {
    updatecnt++;
    Point L = spc.geo.getLength();
    double area = L.x() * L.y();
    if (L.x() not_eq L.y() or 0.5 * L.z() != halfz)
        throw std::runtime_error("Requires box Lx=Ly and Lz=const.");

    Q.clear();
    for (auto &g : spc.groups) // loop over all groups
        for (auto &p : g)      // ...and their active particles
            Q(p.pos.z()) += p.charge;
    for (double z = -halfz; z <= halfz; z += dz)
        rho(z) += Q(z) / area;
}

void ExternalAkesson::update_phi() {
    Point L = spc.geo.getLength();
    double a = 0.5 * L.x();
    for (double z = -halfz; z <= halfz; z += dz) {
        double s = 0;
        for (double zn = -halfz; zn <= halfz; zn += dz)
            if (rho(zn).cnt > 0)
                s += rho(zn).avg() * phi_ext(std::fabs(z - zn), a); // Eq. 14 in Greberg paper
        phi(z) = lB * s;
    }
}

// ------------ createGouyChapman -------------

std::function<double(const Particle &)> createGouyChapmanPotential(const json &j, const Geometry::Chameleon &geo) {
    if (geo.boundaryConditions().direction.z() != Geometry::FIXED)
        throw std::runtime_error("Gouy-Chapman requires non-periodicity in z-direction");

    double rho;
    double c0 = j.at("ionicstrength").get<double>() * 1.0_molar; // assuming 1:1 salt, so c0=I
    double lB = pc::lB(j.at("epsr").get<double>());
    double k = 1 / (3.04 / sqrt(c0));   // hack!
    double phi0 = j.value("phi0", 0.0); // Unitless potential = beta*e*phi0
    if (std::fabs(phi0) > 1e-6)
        rho = sqrt(2 * c0 / (pc::pi * lB)) * sinh(.5 * phi0); // Evans&Wennerstrom,Colloidal Domain p. 138-140
    else {
        rho = 1.0 / j.value("qarea", 0.0);
        if (rho > 1e9)
            rho = j.at("rho");
        phi0 = 2. * std::asinh(rho * std::sqrt(0.5 * lB * pc::pi / c0)); // [Evans..]
    }
    double gamma0 = std::tanh(phi0 / 4); // assuming z=1 [Evans..]
    double surface_z_pos = j.value("zpos", -0.5 * geo.getLength().z());
    bool linearize = j.value("linearize", false);

    // return gamma function for calculation of GC potential on single particle.
    return [=](const Particle &p) {
        if (p.charge != 0) {
            double x = std::exp(-k * std::fabs(surface_z_pos - p.pos.z()));
            if (linearize)
                return p.charge * phi0 * x;
            else {
                x = gamma0 * x;
                return 2 * p.charge * std::log((1 + x) / (1 - x));
            }
        }
        return 0.0;
    };
}

// ------------ CustomExternal -------------

CustomExternal::CustomExternal(const json &j, Tspace &spc) : ExternalPotential(j, spc) {
    expr = std::make_unique<ExprFunction<double>>();
    name = "customexternal";
    jin = j;
    auto &_j = jin["constants"];
    if (_j == nullptr)
        _j = json::object();
    _j["e0"] = pc::e0;
    _j["kB"] = pc::kB;
    _j["kT"] = pc::kT();
    _j["Nav"] = pc::Nav;
    _j["T"] = pc::temperature;
    std::string name = jin.at("function");

    // check if the custom potential match a name with a predefined meaning.
    if (name == "gouychapman")
        func = createGouyChapmanPotential(_j, spc.geo);
    else if (name == "something") {
        // add additional potential here
        // base::func = createSomeOtherPotential(_j);
    } else {
        // if nothing found above, it is assumed that `function`
        // is a valid expression.
        expr->set(jin, {{"q", &d.q}, {"x", &d.x}, {"y", &d.y}, {"z", &d.z}});
        func = [&](const Particle &a) {
            d.x = a.pos.x();
            d.y = a.pos.y();
            d.z = a.pos.z();
            d.q = a.charge;
            return expr->operator()();
        };
    }
}
void CustomExternal::to_json(json &j) const {
    j = jin;
    ExternalPotential::to_json(j);
}

// ------------- ParticleSelfEnergy ---------------

/*
 * Upon construction, make sure the ExternalPotential base class loop
 * over all groups and particles (com=false)
 */
ParticleSelfEnergy::ParticleSelfEnergy(Space &spc, std::function<double(const Particle &)> selfEnergy)
    : ExternalPotential({{"molecules", {"*"}}, {"com", false}}, spc) {
    assert(selfEnergy && "selfEnergy is not callable");
    func = selfEnergy;
#ifndef NDEBUG
    // test if self energy can be called
    assert(not Faunus::atoms.empty());
    Particle myparticle;
    myparticle.id=0;
    if (this->func) {
        double u = this->func(myparticle);
        assert(std::isfinite(u));
    }
#endif
    name = "particle-self-energy";
}

} // namespace Energy
} // namespace Faunus
<commit_msg>Fix external potential for inactive groups<commit_after>#include "externalpotential.h"
#include "multipole.h"
#include "aux/eigensupport.h"
#include "functionparser.h"
#include "space.h"
#include "spdlog/spdlog.h"

namespace Faunus {
namespace Energy {

// ------------ Energybase -------------

void Energybase::to_json(json &) const {}

void Energybase::sync(Energybase *, Change &) {}

void Energybase::init() {}

void to_json(json &j, const Energybase &base) {
    assert(not base.name.empty());
    if (base.timer)
        j[base.name]["relative time"] = base.timer.result();
    if (not base.cite.empty())
        j[base.name]["reference"] = base.cite;
    base.to_json(j[base.name]);
}

// ------------ ExternalPotential -------------

// this calculates the interaction of a whole group
// with the applied external potential.
double ExternalPotential::_energy(const Group<Particle> &g) const {
    double u = 0;
    if (molids.find(g.id) != molids.end()) {
        if (COM and g.atomic == false) { // apply only to center of mass
            if (g.size() == g.capacity()) { // only apply if group is active
                Particle cm;                // temp. particle representing molecule
                cm.charge = Faunus::monopoleMoment(g.begin(), g.end());
                cm.pos = g.cm;
                return func(cm);
            }
        } else {
            for (auto &p : g) { // loop over active particles
                u += func(p);
                if (std::isnan(u))
                    break;
            }
        }
    }
    return u;
}

ExternalPotential::ExternalPotential(const json &j, Space &spc) : spc(spc) {
    name = "external";
    COM = j.value("com", false);
    _names = j.at("molecules").get<decltype(_names)>(); // molecule names
    auto _ids = names2ids(molecules, _names);           // names --> molids
    molids = std::set<int>(_ids.begin(), _ids.end());   // vector --> set
    if (molids.empty())
        throw std::runtime_error(name + ": molecule list is empty");
}
double ExternalPotential::energy(Change &change) {
    assert(func != nullptr);
    double u = 0;
    if (change.dV or change.all or change.dN) {
        for (auto &g : spc.groups) { // check all groups
            u += _energy(g);
            if (std::isnan(u))
                break;
        }
    } else
        for (auto &d : change.groups) {
            auto &g = spc.groups.at(d.index); // check specified groups
            if (d.all or COM)                 // check all atoms in group
                u += _energy(g);              // _energy also checks for molecule id
            else {                            // check only specified atoms in group
                if (molids.find(g.id) != molids.end())
                    for (auto i : d.atoms)
                        u += func(*(g.begin() + i));
            }
            if (std::isnan(u))
                break;
        }
    return u;
}
void ExternalPotential::to_json(json &j) const {
    j["molecules"] = _names;
    j["com"] = COM;
}

// ------------ Confine -------------

Confine::Confine(const json &j, Tspace &spc) : ExternalPotential(j, spc) {
    name = "confine";
    k = value_inf(j, "k") * 1.0_kJmol; // get floating point; allow inf/-inf
    type = m.at(j.at("type"));

    if (type == sphere or type == cylinder) {
        radius = j.at("radius");
        origo = j.value("origo", origo);
        scale = j.value("scale", scale);
        if (type == cylinder)
            dir = {1, 1, 0};
        func = [&radius = radius, origo = origo, k = k, dir = dir](const Particle &p) {
            double d2 = (origo - p.pos).cwiseProduct(dir).squaredNorm() - radius * radius;
            if (d2 > 0)
                return 0.5 * k * d2;
            return 0.0;
        };

        // If volume is scaled, also scale the confining radius by adding a trigger
        // to `Space::scaleVolume()`
        if (scale)
            spc.scaleVolumeTriggers.push_back(
                [&radius = radius](Tspace &, double Vold, double Vnew) { radius *= std::cbrt(Vnew / Vold); });
    }

    if (type == cuboid) {
        low = j.at("low").get<Point>();
        high = j.at("high").get<Point>();
        func = [low = low, high = high, k = k](const Particle &p) {
            double u = 0;
            Point d = low - p.pos;
            for (int i = 0; i < 3; ++i)
                if (d[i] > 0)
                    u += d[i] * d[i];
            d = p.pos - high;
            for (int i = 0; i < 3; ++i)
                if (d[i] > 0)
                    u += d[i] * d[i];
            return 0.5 * k * u;
        };
    }
}
void Confine::to_json(json &j) const {
    if (type == cuboid)
        j = {{"low", low}, {"high", high}};
    if (type == sphere or type == cylinder)
        j = {{"radius", radius}};
    if (type == sphere) {
        j["origo"] = origo;
        j["scale"] = scale;
    }
    for (auto &i : m)
        if (i.second == type)
            j["type"] = i.first;
    j["k"] = k / 1.0_kJmol;
    ExternalPotential::to_json(j);
    _roundjson(j, 5);
}

// ------------ ExternalAkesson -------------

ExternalAkesson::ExternalAkesson(const json &j, Tspace &spc) : ExternalPotential(j, spc) {
    name = "akesson";
    cite = "doi:10/dhb9mj";

    SingleUseJSON _j = j; // json variant where items are deleted after access
    _j.erase("com");
    _j.erase("molecules");

    nstep = _j.at("nstep").get<unsigned int>();
    epsr = _j.at("epsr").get<double>();
    fixed = _j.value("fixed", false);
    nphi = _j.value("nphi", 10);

    halfz = 0.5 * spc.geo.getLength().z();
    lB = pc::lB(epsr);

    dz = _j.value("dz", 0.2); // read z resolution
    Q.setResolution(dz, -halfz, halfz);
    rho.setResolution(dz, -halfz, halfz);
    phi.setResolution(dz, -halfz, halfz);

    filename = _j.value("file", "mfcorr.dat"s);
    load();

    func = [&phi = phi](const typename Tspace::Tparticle &p) { return p.charge * phi(p.pos.z()); };

    if (not _j.empty()) // throw exception of unused/unknown keys are passed
        throw std::runtime_error("unused key(s) for '"s + name + "':\n" + _j.dump());
}

double ExternalAkesson::energy(Change &change) {
    if (not fixed)                    // pho(z) unconverged, keep sampling
        if (key == Energybase::OLD) { // only sample on accepted configs
            cnt++;
            if (cnt % nstep == 0)
                update_rho();
            if (cnt % nstep * nphi == 0)
                update_phi();
        }
    return ExternalPotential::energy(change);
}

ExternalAkesson::~ExternalAkesson() {
    // save only if still updating and if energy type is "OLD",
    // that is, accepted configurations (not trial)
    if (not fixed and key == Energybase::OLD)
        save();
}

void ExternalAkesson::to_json(json &j) const {
    j = {{"lB", lB},         {"dz", dz},       {"nphi", nphi},          {"epsr", epsr},
         {"file", filename}, {"nstep", nstep}, {"Nupdates", updatecnt}, {"fixed", fixed}};
    ExternalPotential::to_json(j);
    _roundjson(j, 5);
}

void ExternalAkesson::save() {
    std::ofstream f(filename);
    if (f) {
        f.precision(16);
        f << rho;
    } else
        throw std::runtime_error("cannot save file '"s + filename + "'");
}

void ExternalAkesson::load() {
    std::ifstream f(filename);
    if (f) {
        rho << f;
        update_phi();
    } else
        faunus_logger->warn("density file {} not loaded", filename);
}

double ExternalAkesson::phi_ext(double z, double a) const {
    double a2 = a * a, z2 = z * z;
    return -2 * pc::pi * z - 8 * a * std::log((std::sqrt(2 * a2 + z2) + a) / std::sqrt(a2 + z2)) +
           2 * z * (0.5 * pc::pi + std::asin((a2 * a2 - z2 * z2 - 2 * a2 * z2) / std::pow(a2 + z2, 2)));
}

void ExternalAkesson::sync(Energybase *basePtr, Change &) {
    if (not fixed) {
        auto other = dynamic_cast<decltype(this)>(basePtr);
        assert(other);
        // only trial energy (new) require sync
        if (other->key == Energybase::OLD)
            if (cnt != other->cnt) {
                assert(cnt < other->cnt && "trial cnt's must be smaller");
                cnt = other->cnt;
                rho = other->rho;
                phi = other->phi;
            }
    }
}

void ExternalAkesson::update_rho() {
    updatecnt++;
    Point L = spc.geo.getLength();
    double area = L.x() * L.y();
    if (L.x() not_eq L.y() or 0.5 * L.z() != halfz)
        throw std::runtime_error("Requires box Lx=Ly and Lz=const.");

    Q.clear();
    for (auto &g : spc.groups) // loop over all groups
        for (auto &p : g)      // ...and their active particles
            Q(p.pos.z()) += p.charge;
    for (double z = -halfz; z <= halfz; z += dz)
        rho(z) += Q(z) / area;
}

void ExternalAkesson::update_phi() {
    Point L = spc.geo.getLength();
    double a = 0.5 * L.x();
    for (double z = -halfz; z <= halfz; z += dz) {
        double s = 0;
        for (double zn = -halfz; zn <= halfz; zn += dz)
            if (rho(zn).cnt > 0)
                s += rho(zn).avg() * phi_ext(std::fabs(z - zn), a); // Eq. 14 in Greberg paper
        phi(z) = lB * s;
    }
}

// ------------ createGouyChapman -------------

std::function<double(const Particle &)> createGouyChapmanPotential(const json &j, const Geometry::Chameleon &geo) {
    if (geo.boundaryConditions().direction.z() != Geometry::FIXED)
        throw std::runtime_error("Gouy-Chapman requires non-periodicity in z-direction");

    double rho;
    double c0 = j.at("ionicstrength").get<double>() * 1.0_molar; // assuming 1:1 salt, so c0=I
    double lB = pc::lB(j.at("epsr").get<double>());
    double k = 1 / (3.04 / sqrt(c0));   // hack!
    double phi0 = j.value("phi0", 0.0); // Unitless potential = beta*e*phi0
    if (std::fabs(phi0) > 1e-6)
        rho = sqrt(2 * c0 / (pc::pi * lB)) * sinh(.5 * phi0); // Evans&Wennerstrom,Colloidal Domain p. 138-140
    else {
        rho = 1.0 / j.value("qarea", 0.0);
        if (rho > 1e9)
            rho = j.at("rho");
        phi0 = 2. * std::asinh(rho * std::sqrt(0.5 * lB * pc::pi / c0)); // [Evans..]
    }
    double gamma0 = std::tanh(phi0 / 4); // assuming z=1 [Evans..]
    double surface_z_pos = j.value("zpos", -0.5 * geo.getLength().z());
    bool linearize = j.value("linearize", false);

    // return gamma function for calculation of GC potential on single particle.
    return [=](const Particle &p) {
        if (p.charge != 0) {
            double x = std::exp(-k * std::fabs(surface_z_pos - p.pos.z()));
            if (linearize)
                return p.charge * phi0 * x;
            else {
                x = gamma0 * x;
                return 2 * p.charge * std::log((1 + x) / (1 - x));
            }
        }
        return 0.0;
    };
}

// ------------ CustomExternal -------------

CustomExternal::CustomExternal(const json &j, Tspace &spc) : ExternalPotential(j, spc) {
    expr = std::make_unique<ExprFunction<double>>();
    name = "customexternal";
    jin = j;
    auto &_j = jin["constants"];
    if (_j == nullptr)
        _j = json::object();
    _j["e0"] = pc::e0;
    _j["kB"] = pc::kB;
    _j["kT"] = pc::kT();
    _j["Nav"] = pc::Nav;
    _j["T"] = pc::temperature;
    std::string name = jin.at("function");

    // check if the custom potential match a name with a predefined meaning.
    if (name == "gouychapman")
        func = createGouyChapmanPotential(_j, spc.geo);
    else if (name == "something") {
        // add additional potential here
        // base::func = createSomeOtherPotential(_j);
    } else {
        // if nothing found above, it is assumed that `function`
        // is a valid expression.
        expr->set(jin, {{"q", &d.q}, {"x", &d.x}, {"y", &d.y}, {"z", &d.z}});
        func = [&](const Particle &a) {
            d.x = a.pos.x();
            d.y = a.pos.y();
            d.z = a.pos.z();
            d.q = a.charge;
            return expr->operator()();
        };
    }
}
void CustomExternal::to_json(json &j) const {
    j = jin;
    ExternalPotential::to_json(j);
}

// ------------- ParticleSelfEnergy ---------------

/*
 * Upon construction, make sure the ExternalPotential base class loop
 * over all groups and particles (com=false)
 */
ParticleSelfEnergy::ParticleSelfEnergy(Space &spc, std::function<double(const Particle &)> selfEnergy)
    : ExternalPotential({{"molecules", {"*"}}, {"com", false}}, spc) {
    assert(selfEnergy && "selfEnergy is not callable");
    func = selfEnergy;
#ifndef NDEBUG
    // test if self energy can be called
    assert(not Faunus::atoms.empty());
    Particle myparticle;
    myparticle.id=0;
    if (this->func) {
        double u = this->func(myparticle);
        assert(std::isfinite(u));
    }
#endif
    name = "particle-self-energy";
}

} // namespace Energy
} // namespace Faunus
<|endoftext|>


<commit_before>#include "js_helpers.h"
#include "common/RhodesApp.h"
#include "net/URI.h"
#include "logging/RhoLog.h"
#include "api_generator/Api.h"
#include <vector>

#undef DEFAULT_LOGCATEGORY
#define DEFAULT_LOGCATEGORY "js_helper"

namespace rho
{
namespace apiGenerator
{

using namespace rho::json;

static const String ID("id");
static const String METHOD("method");
static const String RHO_CLASS("__rhoClass");
static const String RHO_ID("__rhoID");
static const String RHO_CALLBACK("__rhoCallback");
static const String VM_ID("vmID");
static const String RHO_CALLBACK_PARAM("optParams");

std::vector<ApiHandler<Func_JS>*> g_modules;

void defineJSApiModule(ApiHandler<Func_JS>* pModule)
{
    g_modules.push_back(pModule);
    RAWTRACE2("Define %1, %d", pModule->getModuleId(), g_modules.size() -1);
}

ApiHandler<Func_JS>* getJSApiModule(const std::string& moduleId)
{
    for(std::vector<ApiHandler<Func_JS>*>::iterator moduleIt = g_modules.begin(); moduleIt != g_modules.end(); ++moduleIt)
    {
        if(strcmp((*moduleIt)->getModuleId(), moduleId.c_str()) == 0)
        {
            RAWTRACE2("Module %s, %d", (*moduleIt)->getModuleId(), moduleIt - g_modules.begin());
            return *moduleIt;
        }

    }
    RAWTRACE1("Module is not found: %s", moduleId.c_str());
    return 0;
}

rho::String js_entry_point(const char* szJSON)
{
    RAWTRACE(szJSON);

    rho::String strReqId, strModule, strMethod, strObjID, strCallbackID, strJsVmID, strCallbackParam;
    CJSONEntry oEntry(szJSON);

    if ( !oEntry.hasName(ID) )
    {
        RAWLOG_ERROR1("There is no %s string in JSON request", ID.c_str());
        return "{\"jsonrpc\": \"2.0\", \"error\": {\"code\": -32700, \"message\": \"Parse error\"}, \"id\": null}";
    }
    strReqId = oEntry.getString(ID.c_str());

    if ( !oEntry.hasName(RHO_CLASS) )
    {
        RAWLOG_ERROR1("There is no %s string in JSON request", RHO_CLASS.c_str());
        return "{\"jsonrpc\": \"2.0\", \"error\": {\"code\": -32700, \"message\": \"Parse error\"}, \"id\": " + strReqId + "}";
    }
    strModule = oEntry.getString(RHO_CLASS.c_str());

    if ( !oEntry.hasName(METHOD) )
    {
        RAWLOG_ERROR1("There is no %s string in JSON request object", METHOD.c_str());
        return "{\"jsonrpc\": \"2.0\", \"error\": {\"code\": -32700, \"message\": \"Parse error\"}, \"id\": " + strReqId + "}";
    }
    strMethod = oEntry.getString(METHOD.c_str());

    if ( oEntry.hasName(RHO_ID) )
        strObjID = oEntry.getString(RHO_ID.c_str());

    if ( oEntry.hasName(RHO_CALLBACK) ) {
        RAWTRACE("Parsing callback");

        CJSONEntry oCallback = oEntry.getEntry(RHO_CALLBACK.c_str());

        RAWTRACE1("Got %s JSON object", RHO_CALLBACK.c_str());

        if ( !oCallback.hasName(ID) )
        {
            RAWLOG_ERROR1("There is no %s string in __rhoCallback request", ID.c_str());
            return "{\"jsonrpc\": \"2.0\", \"error\": {\"code\": -32700, \"message\": \"Parse error\"}, \"id\": " + strReqId + "}";
        }

        const char* pcszCallbackID = oCallback.getString(ID.c_str());
        const char* pcszJsVmID = oCallback.getString(VM_ID.c_str());
        const char* pcszCallbackParam = oCallback.getString(RHO_CALLBACK_PARAM.c_str());

        if (pcszCallbackID)
            strCallbackID = pcszCallbackID;

        if (pcszJsVmID)
            strJsVmID = pcszJsVmID;//oCallback.getString(pcszJsVmID);

        if (pcszCallbackParam)
            strCallbackParam = pcszCallbackParam;
    }

    String_replace(strModule, '.', ':');

    ApiHandler<Func_JS>* pApiHandler = getJSApiModule(strModule);
    if (!pApiHandler)
    {
        RAWLOG_ERROR1("API Module is not found: %s", strModule.c_str());
        return "{\"jsonrpc\": \"2.0\", \"error\": {\"code\": -32601, \"message\": \"API module is not found.\"}, \"id\": " + strReqId + "}";
    }

    Func_JS pMethod = NULL;
    if (strObjID == "0")
    {
        pMethod = pApiHandler->getStaticMethod(strMethod);
        if (!pMethod)
        {
            RAWLOG_ERROR1("Static API method is not found: %s", strMethod.c_str());
            return "{\"jsonrpc\": \"2.0\", \"error\": {\"code\": -32601, \"message\": \"Static method is not found.\"}, \"id\": " + strReqId + "}";
        }
    }
    else
    {
        pMethod = pApiHandler->getInstanceMethod(strMethod);
        if (!pMethod)
        {
            RAWLOG_ERROR1("Instance API method is not found: %s", strMethod.c_str());
            return "{\"jsonrpc\": \"2.0\", \"error\": {\"code\": -32601, \"message\": \"Instance method is not found.\"}, \"id\": " + strReqId + "}";
        }
    }

    CJSONArray oParams(oEntry.getEntry("params"));

    RAWTRACE3("Calling API: object: %s, method: %s, callback id: %s", strObjID.c_str(), strMethod.c_str(), strCallbackID.c_str());
    String methodResult = pMethod( strObjID, oParams, strCallbackID, strJsVmID, strCallbackParam );
    #ifdef RHO_DEBUG
    String res = "{"+methodResult+"}";
    CJSONEntry jsonValidator(res.c_str());
    #endif
    return "{\"jsonrpc\": \"2.0\", " + methodResult + ", \"id\": " + strReqId + "}";
}

void rho_http_js_entry_point(void *arg, rho::String const &query )
{
    rho::String res = js_entry_point(query.c_str());
    rho_http_sendresponse(arg, res.c_str());
}

}
}
<commit_msg>Fix trace in js_helper.cpp<commit_after>#include "js_helpers.h"
#include "common/RhodesApp.h"
#include "net/URI.h"
#include "logging/RhoLog.h"
#include "api_generator/Api.h"
#include <vector>

#undef DEFAULT_LOGCATEGORY
#define DEFAULT_LOGCATEGORY "js_helper"

namespace rho
{
namespace apiGenerator
{

using namespace rho::json;

static const String ID("id");
static const String METHOD("method");
static const String RHO_CLASS("__rhoClass");
static const String RHO_ID("__rhoID");
static const String RHO_CALLBACK("__rhoCallback");
static const String VM_ID("vmID");
static const String RHO_CALLBACK_PARAM("optParams");

std::vector<ApiHandler<Func_JS>*> g_modules;

void defineJSApiModule(ApiHandler<Func_JS>* pModule)
{
    g_modules.push_back(pModule);
    RAWTRACE2("Define %s, %d", pModule->getModuleId(), g_modules.size() -1);
}

ApiHandler<Func_JS>* getJSApiModule(const std::string& moduleId)
{
    for(std::vector<ApiHandler<Func_JS>*>::iterator moduleIt = g_modules.begin(); moduleIt != g_modules.end(); ++moduleIt)
    {
        if(strcmp((*moduleIt)->getModuleId(), moduleId.c_str()) == 0)
        {
            RAWTRACE2("Module %s, %d", (*moduleIt)->getModuleId(), moduleIt - g_modules.begin());
            return *moduleIt;
        }

    }
    RAWTRACE1("Module is not found: %s", moduleId.c_str());
    return 0;
}

rho::String js_entry_point(const char* szJSON)
{
    RAWTRACE(szJSON);

    rho::String strReqId, strModule, strMethod, strObjID, strCallbackID, strJsVmID, strCallbackParam;
    CJSONEntry oEntry(szJSON);

    if ( !oEntry.hasName(ID) )
    {
        RAWLOG_ERROR1("There is no %s string in JSON request", ID.c_str());
        return "{\"jsonrpc\": \"2.0\", \"error\": {\"code\": -32700, \"message\": \"Parse error\"}, \"id\": null}";
    }
    strReqId = oEntry.getString(ID.c_str());

    if ( !oEntry.hasName(RHO_CLASS) )
    {
        RAWLOG_ERROR1("There is no %s string in JSON request", RHO_CLASS.c_str());
        return "{\"jsonrpc\": \"2.0\", \"error\": {\"code\": -32700, \"message\": \"Parse error\"}, \"id\": " + strReqId + "}";
    }
    strModule = oEntry.getString(RHO_CLASS.c_str());

    if ( !oEntry.hasName(METHOD) )
    {
        RAWLOG_ERROR1("There is no %s string in JSON request object", METHOD.c_str());
        return "{\"jsonrpc\": \"2.0\", \"error\": {\"code\": -32700, \"message\": \"Parse error\"}, \"id\": " + strReqId + "}";
    }
    strMethod = oEntry.getString(METHOD.c_str());

    if ( oEntry.hasName(RHO_ID) )
        strObjID = oEntry.getString(RHO_ID.c_str());

    if ( oEntry.hasName(RHO_CALLBACK) ) {
        RAWTRACE("Parsing callback");

        CJSONEntry oCallback = oEntry.getEntry(RHO_CALLBACK.c_str());

        RAWTRACE1("Got %s JSON object", RHO_CALLBACK.c_str());

        if ( !oCallback.hasName(ID) )
        {
            RAWLOG_ERROR1("There is no %s string in __rhoCallback request", ID.c_str());
            return "{\"jsonrpc\": \"2.0\", \"error\": {\"code\": -32700, \"message\": \"Parse error\"}, \"id\": " + strReqId + "}";
        }

        const char* pcszCallbackID = oCallback.getString(ID.c_str());
        const char* pcszJsVmID = oCallback.getString(VM_ID.c_str());
        const char* pcszCallbackParam = oCallback.getString(RHO_CALLBACK_PARAM.c_str());

        if (pcszCallbackID)
            strCallbackID = pcszCallbackID;

        if (pcszJsVmID)
            strJsVmID = pcszJsVmID;//oCallback.getString(pcszJsVmID);

        if (pcszCallbackParam)
            strCallbackParam = pcszCallbackParam;
    }

    String_replace(strModule, '.', ':');

    ApiHandler<Func_JS>* pApiHandler = getJSApiModule(strModule);
    if (!pApiHandler)
    {
        RAWLOG_ERROR1("API Module is not found: %s", strModule.c_str());
        return "{\"jsonrpc\": \"2.0\", \"error\": {\"code\": -32601, \"message\": \"API module is not found.\"}, \"id\": " + strReqId + "}";
    }

    Func_JS pMethod = NULL;
    if (strObjID == "0")
    {
        pMethod = pApiHandler->getStaticMethod(strMethod);
        if (!pMethod)
        {
            RAWLOG_ERROR1("Static API method is not found: %s", strMethod.c_str());
            return "{\"jsonrpc\": \"2.0\", \"error\": {\"code\": -32601, \"message\": \"Static method is not found.\"}, \"id\": " + strReqId + "}";
        }
    }
    else
    {
        pMethod = pApiHandler->getInstanceMethod(strMethod);
        if (!pMethod)
        {
            RAWLOG_ERROR1("Instance API method is not found: %s", strMethod.c_str());
            return "{\"jsonrpc\": \"2.0\", \"error\": {\"code\": -32601, \"message\": \"Instance method is not found.\"}, \"id\": " + strReqId + "}";
        }
    }

    CJSONArray oParams(oEntry.getEntry("params"));

    RAWTRACE3("Calling API: object: %s, method: %s, callback id: %s", strObjID.c_str(), strMethod.c_str(), strCallbackID.c_str());
    String methodResult = pMethod( strObjID, oParams, strCallbackID, strJsVmID, strCallbackParam );
    #ifdef RHO_DEBUG
    String res = "{"+methodResult+"}";
    CJSONEntry jsonValidator(res.c_str());
    #endif
    return "{\"jsonrpc\": \"2.0\", " + methodResult + ", \"id\": " + strReqId + "}";
}

void rho_http_js_entry_point(void *arg, rho::String const &query )
{
    rho::String res = js_entry_point(query.c_str());
    rho_http_sendresponse(arg, res.c_str());
}

}
}
<|endoftext|>