<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$

#include "AliMUONDigitizerV3.h"

#include "AliLog.h"
#include "AliMUONCalibrationData.h"
#include "AliMUONChamber.h"
#include "AliMUONConstants.h"
#include "AliMUONData.h"
#include "AliMUONDigit.h"
#include "AliMUONTriggerDecisionV1.h"
//#include "AliMUONTriggerElectronics.h"
#include "AliMUONCalibParam.h"
#include "AliMpDEManager.h"
#include "AliMpStationType.h"
#include "AliRun.h"
#include "AliRunDigitizer.h"
#include "AliRunLoader.h"
#include "Riostream.h"
#include "TRandom.h"
#include "TString.h"

ClassImp(AliMUONDigitizerV3)

//_____________________________________________________________________________
AliMUONDigitizerV3::AliMUONDigitizerV3(AliRunDigitizer* manager,
                                       ETriggerCodeVersion triggerCodeVersion)
: AliDigitizer(manager),
fZeroSuppression(6),
fSaturation(3000),
fIsInitialized(kFALSE),
fOutputData(0x0),
fCalibrationData(0x0),
fTriggerProcessor(0x0),
fTriggerCodeVersion(triggerCodeVersion)
{
  AliDebug(1,Form("AliRunDigitizer=%p",fManager));
}

//_____________________________________________________________________________
AliMUONDigitizerV3::~AliMUONDigitizerV3()
{
  AliDebug(1,"dtor");
  delete fOutputData;
  delete fCalibrationData;
  delete fTriggerProcessor;
}

//_____________________________________________________________________________
void
AliMUONDigitizerV3::ApplyResponseToDigit(AliMUONDigit& digit)
{
  // For trigger digits, simply sets the digit's charge to 0 or 1.
  //
  // For tracking digits, starting from an ideal digit's charge, we :
  //
  // - add some noise (thus leading to a realistic charge)
  // - divide by a gain (thus decalibrating the digit)
  // - add a pedestal (thus decalibrating the digit)
  // - sets the signal to zero if below ZeroSuppression() level (thus simulating
  //   zero suppression).
  //

  Int_t detElemId = digit.DetElemId();
  AliMpStationType stationType = AliMpDEManager::GetStationType(detElemId);
  if ( stationType == kStationTrigger )
  {
    if ( digit.Signal() > 0  )
    {
      digit.SetSignal(1);
    }
    else
    {
      digit.SetSignal(0);
    }
    return;
  }

  // The following is for tracking digits only.

  Int_t manuId = digit.ManuId();
  Int_t manuChannel = digit.ManuChannel();

  AliMUONCalibParam* pedestal = fCalibrationData->Pedestal(detElemId,manuId,manuChannel);
  if (!pedestal)
  {
    AliFatal(Form("Could not get pedestal for DE=%d manuId=%d manuChannel=%d",
                  detElemId,manuId,manuChannel));
  }
  Float_t adc_noise = gRandom->Gaus(0.0,pedestal->Sigma());

  AliMUONCalibParam* gain = fCalibrationData->Gain(detElemId,manuId,manuChannel);
  if (!gain)
  {
    AliFatal(Form("Could not get gain for DE=%d manuId=%d manuChannel=%d",
                  detElemId,manuId,manuChannel));
  }

  Float_t signal_noise = adc_noise*gain->Mean();

  Float_t signal = digit.Signal() + signal_noise;
  Int_t adc;

  if ( signal > fSaturation )
  {
    adc = fSaturation;
    digit.Saturated(kTRUE);
  }
  else
  {
    if ( gain->Mean() < 1E-6 )
    {
      AliFatal(Form("Got a too small gain %e for DE=%d manuId=%d manuChannel=%d",
                    gain->Mean(),detElemId,manuId,manuChannel));
    }
    adc = TMath::Nint( signal / gain->Mean() + pedestal->Mean() );

    if ( adc <= pedestal->Mean() + 3.0*pedestal->Sigma() )
    {
      adc = 0;
    }
  }
  digit.SetPhysicsSignal(TMath::Nint(signal));
  digit.SetSignal(adc);
  digit.SetADC(adc);
}

//_____________________________________________________________________________
void
AliMUONDigitizerV3::ApplyResponse()
{
  for ( Int_t ich = 0; ich < AliMUONConstants::NCh(); ++ich )
	{
    TClonesArray* digits = fOutputData->Digits(ich);
    Int_t n = digits->GetEntriesFast();
    for ( Int_t i = 0; i < n; ++i )
    {
      AliMUONDigit* d = static_cast<AliMUONDigit*>(digits->UncheckedAt(i));
      ApplyResponseToDigit(*d);
      if ( d->Signal() <= 0 )
      {
        digits->RemoveAt(i);
      }
    }
  }

  for ( Int_t ich = 0; ich < AliMUONConstants::NCh(); ++ich )
	{
    fOutputData->Digits(ich)->Compress();
  }
}

//_____________________________________________________________________________
void
AliMUONDigitizerV3::AddOrUpdateDigit(TClonesArray& array,
                                     const AliMUONDigit& digit)
{
  Int_t ix = FindDigitIndex(array,digit);

  if (ix>=0)
  {
    AliMUONDigit* d = static_cast<AliMUONDigit*>(array.UncheckedAt(ix));
    Bool_t ok = MergeDigits(digit,*d);
    if (!ok)
    {
      AliError("Digits are not mergeable !");
    }
    else
    {
      new(array[ix]) AliMUONDigit(*d);
    }
  }
  else
  {
    ix = array.GetLast() + 1;
    new(array[ix]) AliMUONDigit(digit);
  }

}

//_____________________________________________________________________________
void
AliMUONDigitizerV3::Exec(Option_t*)
{
  AliDebug(1, "Running digitizer.");

  if ( fManager->GetNinputs() == 0 )
  {
    AliWarning("No input set. Nothing to do.");
    return;
  }

  if ( !fIsInitialized )
  {
    AliError("Not initialized. Cannot perform the work. Sorry");
    return;
  }

  Int_t nInputFiles = fManager->GetNinputs();

  if ( fOutputData->TreeD() == 0x0 )
  {
    AliDebug(1,"Calling MakeDigitsContainer");
    fOutputData->GetLoader()->MakeDigitsContainer();
  }
  fOutputData->MakeBranch("D,GLT");
  fOutputData->SetTreeAddress("D,GLT");

  // Loop over all the input files, and merge the sdigits found in those
  // files.
  for ( Int_t iFile = 0; iFile < nInputFiles; ++iFile )
  {
    AliMUONData* inputData = GetDataAccess(fManager->GetInputFolderName(iFile));
    if (!inputData)
    {
      AliFatal(Form("Could not get access to input file #%d",iFile));
    }
    AliDebug(1,Form("inputData=%p",inputData));
    //FIXME: what about the fMask ???
    inputData->GetLoader()->LoadSDigits("READ");
    TTree* treeS = inputData->GetLoader()->TreeS();
    AliDebug(1,Form("TreeS=%p",treeS));
    inputData->SetTreeAddress("S");
    inputData->GetSDigits();
    MergeWithSDigits(*fOutputData,*inputData);
    inputData->ResetSDigits();
    inputData->GetLoader()->UnloadSDigits();
    delete inputData;
  }

  // At this point, we do have digit arrays (one per chamber) which contains
  // the merging of all the sdigits of the input file(s).
  // We now massage them to apply the detector response, i.e. this
  // is here that we do the "digitization" work.

  ApplyResponse();

  //

  // We generate the global and local trigger decisions.
  fTriggerProcessor->ExecuteTask();

  // Fill the output treeD
  fOutputData->Fill("D,GLT");

  // Write to the output tree(D).
  // Please note that as GlobalTrigger, LocalTrigger and Digits are in the same
  // tree (=TreeD) in different branches, this WriteDigits in fact writes all of
  // the 3 branches.
  fOutputData->GetLoader()->WriteDigits("OVERWRITE");

  // Finally, we clean up after ourselves.
  fOutputData->ResetDigits();
  fOutputData->ResetTrigger();
  fOutputData->GetLoader()->UnloadDigits();
}

//_____________________________________________________________________________
Int_t
AliMUONDigitizerV3::FindDigitIndex(TClonesArray& array, const AliMUONDigit& digit)
{
  // FIXME: this is of course not the best implementation you can think of.
  // Reconsider the use of hit/digit map...
  Int_t n = array.GetEntriesFast();
  for ( Int_t i = 0; i < n; ++i )
  {
    AliMUONDigit* d = static_cast<AliMUONDigit*>(array.UncheckedAt(i));
    if ( d->DetElemId() == digit.DetElemId() &&
         d->PadX() == digit.PadX() &&
         d->PadY() == digit.PadY() &&
         d->Cathode() == digit.Cathode() )
    {
      return i;
    }
  }
  return -1;
}

//_____________________________________________________________________________
AliMUONData*
AliMUONDigitizerV3::GetDataAccess(const TString& folderName)
{
  AliDebug(1,Form("Getting access to folder %s",folderName.Data()));
  AliRunLoader* runLoader = AliRunLoader::GetRunLoader(folderName);
  if (!runLoader)
  {
    AliError(Form("Could not get RunLoader from folder %s",folderName.Data()));
    return 0x0;
  }
  AliLoader* loader = static_cast<AliLoader*>(runLoader->GetLoader("MUONLoader"));
  if (!loader)
  {
    AliError(Form("Could not get MuonLoader from folder %s",folderName.Data()));
    return 0x0;
  }
  AliMUONData* data = new AliMUONData(loader,"MUON","MUONDataForDigitOutput");
  AliDebug(1,Form("AliMUONData=%p loader=%p",data,loader));
  return data;
}

//_____________________________________________________________________________
Bool_t
AliMUONDigitizerV3::Init()
{
  AliDebug(1,"");

  if ( fIsInitialized )
  {
    AliError("Object already initialized.");
    return kFALSE;
  }

  if (!fManager)
  {
    AliError("fManager is null !");
    return kFALSE;
  }

  fOutputData = GetDataAccess(fManager->GetOutputFolderName());
  if (!fOutputData)
  {
    AliError("Can not perform digitization. I'm sorry");
    return kFALSE;
  }
  AliDebug(1,Form("fOutputData=%p",fOutputData));

  AliRunLoader* runLoader = fOutputData->GetLoader()->GetRunLoader();
  AliRun* galice = runLoader->GetAliRun();
  Int_t runnumber = galice->GetRunNumber();

  fCalibrationData = new AliMUONCalibrationData(runnumber);

  switch (fTriggerCodeVersion)
  {
    case kTriggerDecision:
      fTriggerProcessor = new AliMUONTriggerDecisionV1(fOutputData);
      break;
    case kTriggerElectronics:
      AliFatal("Implement me!");
//      fTrigger = new AliMUONTriggerElectronics(fOutputData);
      break;
    default:
      AliFatal("Unknown trigger processor type");
      break;
  }

  fIsInitialized = kTRUE;
  return kTRUE;
}

//_____________________________________________________________________________
Bool_t
AliMUONDigitizerV3::MergeDigits(const AliMUONDigit& src, AliMUONDigit& srcAndDest)
{
  AliDebug(1,"Merging the following digits:");
  StdoutToAliDebug(1,src.Print(););
  StdoutToAliDebug(1,srcAndDest.Print(););

  Bool_t check = ( src.DetElemId() == srcAndDest.DetElemId() &&
                   src.PadX() == srcAndDest.PadX() &&
                   src.PadY() == srcAndDest.PadY() &&
                   src.Cathode() == srcAndDest.Cathode() );
  if (!check)
  {
    return kFALSE;
  }

  srcAndDest.AddSignal(src.Signal());
  srcAndDest.AddPhysicsSignal(src.Physics());
  StdoutToAliDebug(1,cout << "result:"; srcAndDest.Print(););
  return kTRUE;
}

//_____________________________________________________________________________
void
AliMUONDigitizerV3::MergeWithSDigits(AliMUONData& outputData,
                                     const AliMUONData& inputData)
{
  AliDebug(1,"");

	for ( Int_t ich = 0; ich < AliMUONConstants::NCh(); ++ich )
	{
    TClonesArray* iDigits = inputData.SDigits(ich);
    TClonesArray* oDigits = outputData.Digits(ich);
    if (!iDigits)
    {
      AliError(Form("Could not get sdigits for ich=%d",ich));
      return;
    }
    Int_t nSDigits = iDigits->GetEntriesFast();
    for ( Int_t k = 0; k < nSDigits; ++k )
		{
			AliMUONDigit* sdigit = static_cast<AliMUONDigit*>(iDigits->UncheckedAt(k));
      // FIXME: Merging logic should go here.
      // For testing, only put the digit in the output.
      if (!sdigit)
      {
        AliError(Form("Could not get sdigit for ich=%d and k=%d",ich,k));
      }
      else
      {
        AddOrUpdateDigit(*oDigits,*sdigit);
      }
		}
  }
}

//------------------------------------------------------------------------
//void AliMUONDigitizerv2::FillTriggerOutput()
//{
//  // Derived to fill TreeD and resets the trigger array in fMUONData.
//
//	AliDebug(3,"Filling trees with trigger.");
//	fMUONData->Fill("GLT");
//	fMUONData->ResetTrigger();
//}
//
//------------------------------------------------------------------------
//void AliMUONDigitizerv2::CreateTrigger()
//{
//  fMUONData->MakeBranch("GLT");
//  fMUONData->SetTreeAddress("GLT");
//  fTrigDec->Digits2Trigger();
//  FillTriggerOutput();
//
//}

<commit_msg>Option with new AliMUONTriggerElectronics class now available (Rachid, Laurent)<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$

#include "AliMUONDigitizerV3.h"

#include "AliLog.h"
#include "AliMUONCalibrationData.h"
#include "AliMUONChamber.h"
#include "AliMUONConstants.h"
#include "AliMUONData.h"
#include "AliMUONDigit.h"
#include "AliMUONTriggerDecisionV1.h"
#include "AliMUONTriggerElectronics.h"
#include "AliMUONCalibParam.h"
#include "AliMpDEManager.h"
#include "AliMpStationType.h"
#include "AliRun.h"
#include "AliRunDigitizer.h"
#include "AliRunLoader.h"
#include "Riostream.h"
#include "TRandom.h"
#include "TString.h"

ClassImp(AliMUONDigitizerV3)

//_____________________________________________________________________________
AliMUONDigitizerV3::AliMUONDigitizerV3(AliRunDigitizer* manager,
                                       ETriggerCodeVersion triggerCodeVersion)
: AliDigitizer(manager),
fZeroSuppression(6),
fSaturation(3000),
fIsInitialized(kFALSE),
fOutputData(0x0),
fCalibrationData(0x0),
fTriggerProcessor(0x0),
fTriggerCodeVersion(triggerCodeVersion)
{
  AliDebug(1,Form("AliRunDigitizer=%p",fManager));
}

//_____________________________________________________________________________
AliMUONDigitizerV3::~AliMUONDigitizerV3()
{
  AliDebug(1,"dtor");
  delete fOutputData;
  delete fCalibrationData;
  delete fTriggerProcessor;
}

//_____________________________________________________________________________
void
AliMUONDigitizerV3::ApplyResponseToDigit(AliMUONDigit& digit)
{
  // For trigger digits, simply sets the digit's charge to 0 or 1.
  //
  // For tracking digits, starting from an ideal digit's charge, we :
  //
  // - add some noise (thus leading to a realistic charge)
  // - divide by a gain (thus decalibrating the digit)
  // - add a pedestal (thus decalibrating the digit)
  // - sets the signal to zero if below ZeroSuppression() level (thus simulating
  //   zero suppression).
  //

  Int_t detElemId = digit.DetElemId();
  AliMpStationType stationType = AliMpDEManager::GetStationType(detElemId);
  if ( stationType == kStationTrigger )
  {
    if ( digit.Signal() > 0  )
    {
      digit.SetSignal(1);
    }
    else
    {
      digit.SetSignal(0);
    }
    return;
  }

  // The following is for tracking digits only.

  Int_t manuId = digit.ManuId();
  Int_t manuChannel = digit.ManuChannel();

  AliMUONCalibParam* pedestal = fCalibrationData->Pedestal(detElemId,manuId,manuChannel);
  if (!pedestal)
  {
    AliFatal(Form("Could not get pedestal for DE=%d manuId=%d manuChannel=%d",
                  detElemId,manuId,manuChannel));
  }
  Float_t adc_noise = gRandom->Gaus(0.0,pedestal->Sigma());

  AliMUONCalibParam* gain = fCalibrationData->Gain(detElemId,manuId,manuChannel);
  if (!gain)
  {
    AliFatal(Form("Could not get gain for DE=%d manuId=%d manuChannel=%d",
                  detElemId,manuId,manuChannel));
  }

  Float_t signal_noise = adc_noise*gain->Mean();

  Float_t signal = digit.Signal() + signal_noise;
  Int_t adc;

  if ( signal > fSaturation )
  {
    adc = fSaturation;
    digit.Saturated(kTRUE);
  }
  else
  {
    if ( gain->Mean() < 1E-6 )
    {
      AliFatal(Form("Got a too small gain %e for DE=%d manuId=%d manuChannel=%d",
                    gain->Mean(),detElemId,manuId,manuChannel));
    }
    adc = TMath::Nint( signal / gain->Mean() + pedestal->Mean() );

    if ( adc <= pedestal->Mean() + 3.0*pedestal->Sigma() )
    {
      adc = 0;
    }
  }
  digit.SetPhysicsSignal(TMath::Nint(signal));
  digit.SetSignal(adc);
  digit.SetADC(adc);
}

//_____________________________________________________________________________
void
AliMUONDigitizerV3::ApplyResponse()
{
  for ( Int_t ich = 0; ich < AliMUONConstants::NCh(); ++ich )
	{
    TClonesArray* digits = fOutputData->Digits(ich);
    Int_t n = digits->GetEntriesFast();
    for ( Int_t i = 0; i < n; ++i )
    {
      AliMUONDigit* d = static_cast<AliMUONDigit*>(digits->UncheckedAt(i));
      ApplyResponseToDigit(*d);
      if ( d->Signal() <= 0 )
      {
        digits->RemoveAt(i);
      }
    }
  }

  for ( Int_t ich = 0; ich < AliMUONConstants::NCh(); ++ich )
	{
    fOutputData->Digits(ich)->Compress();
  }
}

//_____________________________________________________________________________
void
AliMUONDigitizerV3::AddOrUpdateDigit(TClonesArray& array,
                                     const AliMUONDigit& digit)
{
  Int_t ix = FindDigitIndex(array,digit);

  if (ix>=0)
  {
    AliMUONDigit* d = static_cast<AliMUONDigit*>(array.UncheckedAt(ix));
    Bool_t ok = MergeDigits(digit,*d);
    if (!ok)
    {
      AliError("Digits are not mergeable !");
    }
    else
    {
      new(array[ix]) AliMUONDigit(*d);
    }
  }
  else
  {
    ix = array.GetLast() + 1;
    new(array[ix]) AliMUONDigit(digit);
  }

}

//_____________________________________________________________________________
void
AliMUONDigitizerV3::Exec(Option_t*)
{
  AliDebug(1, "Running digitizer.");

  if ( fManager->GetNinputs() == 0 )
  {
    AliWarning("No input set. Nothing to do.");
    return;
  }

  if ( !fIsInitialized )
  {
    AliError("Not initialized. Cannot perform the work. Sorry");
    return;
  }

  Int_t nInputFiles = fManager->GetNinputs();

  if ( fOutputData->TreeD() == 0x0 )
  {
    AliDebug(1,"Calling MakeDigitsContainer");
    fOutputData->GetLoader()->MakeDigitsContainer();
  }
  fOutputData->MakeBranch("D,GLT");
  fOutputData->SetTreeAddress("D,GLT");

  // Loop over all the input files, and merge the sdigits found in those
  // files.
  for ( Int_t iFile = 0; iFile < nInputFiles; ++iFile )
  {
    AliMUONData* inputData = GetDataAccess(fManager->GetInputFolderName(iFile));
    if (!inputData)
    {
      AliFatal(Form("Could not get access to input file #%d",iFile));
    }
    AliDebug(1,Form("inputData=%p",inputData));
    //FIXME: what about the fMask ???
    inputData->GetLoader()->LoadSDigits("READ");
    TTree* treeS = inputData->GetLoader()->TreeS();
    AliDebug(1,Form("TreeS=%p",treeS));
    inputData->SetTreeAddress("S");
    inputData->GetSDigits();
    MergeWithSDigits(*fOutputData,*inputData);
    inputData->ResetSDigits();
    inputData->GetLoader()->UnloadSDigits();
    delete inputData;
  }

  // At this point, we do have digit arrays (one per chamber) which contains
  // the merging of all the sdigits of the input file(s).
  // We now massage them to apply the detector response, i.e. this
  // is here that we do the "digitization" work.

  ApplyResponse();

  //

  // We generate the global and local trigger decisions.
  fTriggerProcessor->ExecuteTask();

  // Fill the output treeD
  fOutputData->Fill("D,GLT");

  // Write to the output tree(D).
  // Please note that as GlobalTrigger, LocalTrigger and Digits are in the same
  // tree (=TreeD) in different branches, this WriteDigits in fact writes all of
  // the 3 branches.
  fOutputData->GetLoader()->WriteDigits("OVERWRITE");

  // Finally, we clean up after ourselves.
  fOutputData->ResetDigits();
  fOutputData->ResetTrigger();
  fOutputData->GetLoader()->UnloadDigits();
}

//_____________________________________________________________________________
Int_t
AliMUONDigitizerV3::FindDigitIndex(TClonesArray& array, const AliMUONDigit& digit)
{
  // FIXME: this is of course not the best implementation you can think of.
  // Reconsider the use of hit/digit map...
  Int_t n = array.GetEntriesFast();
  for ( Int_t i = 0; i < n; ++i )
  {
    AliMUONDigit* d = static_cast<AliMUONDigit*>(array.UncheckedAt(i));
    if ( d->DetElemId() == digit.DetElemId() &&
         d->PadX() == digit.PadX() &&
         d->PadY() == digit.PadY() &&
         d->Cathode() == digit.Cathode() )
    {
      return i;
    }
  }
  return -1;
}

//_____________________________________________________________________________
AliMUONData*
AliMUONDigitizerV3::GetDataAccess(const TString& folderName)
{
  AliDebug(1,Form("Getting access to folder %s",folderName.Data()));
  AliRunLoader* runLoader = AliRunLoader::GetRunLoader(folderName);
  if (!runLoader)
  {
    AliError(Form("Could not get RunLoader from folder %s",folderName.Data()));
    return 0x0;
  }
  AliLoader* loader = static_cast<AliLoader*>(runLoader->GetLoader("MUONLoader"));
  if (!loader)
  {
    AliError(Form("Could not get MuonLoader from folder %s",folderName.Data()));
    return 0x0;
  }
  AliMUONData* data = new AliMUONData(loader,"MUON","MUONDataForDigitOutput");
  AliDebug(1,Form("AliMUONData=%p loader=%p",data,loader));
  return data;
}

//_____________________________________________________________________________
Bool_t
AliMUONDigitizerV3::Init()
{
  AliDebug(1,"");

  if ( fIsInitialized )
  {
    AliError("Object already initialized.");
    return kFALSE;
  }

  if (!fManager)
  {
    AliError("fManager is null !");
    return kFALSE;
  }

  fOutputData = GetDataAccess(fManager->GetOutputFolderName());
  if (!fOutputData)
  {
    AliError("Can not perform digitization. I'm sorry");
    return kFALSE;
  }
  AliDebug(1,Form("fOutputData=%p",fOutputData));

  AliRunLoader* runLoader = fOutputData->GetLoader()->GetRunLoader();
  AliRun* galice = runLoader->GetAliRun();
  Int_t runnumber = galice->GetRunNumber();

  fCalibrationData = new AliMUONCalibrationData(runnumber);

  switch (fTriggerCodeVersion)
  {
    case kTriggerDecision:
      fTriggerProcessor = new AliMUONTriggerDecisionV1(fOutputData);
      break;
    case kTriggerElectronics:
      fTriggerProcessor = new AliMUONTriggerElectronics(fOutputData);
      break;
    default:
      AliFatal("Unknown trigger processor type");
      break;
  }
  AliDebug(1,Form("Using the following trigger code %s - %s",
                  fTriggerProcessor->GetName(),fTriggerProcessor->GetTitle()));
  fIsInitialized = kTRUE;
  return kTRUE;
}

//_____________________________________________________________________________
Bool_t
AliMUONDigitizerV3::MergeDigits(const AliMUONDigit& src, AliMUONDigit& srcAndDest)
{
  AliDebug(1,"Merging the following digits:");
  StdoutToAliDebug(1,src.Print(););
  StdoutToAliDebug(1,srcAndDest.Print(););

  Bool_t check = ( src.DetElemId() == srcAndDest.DetElemId() &&
                   src.PadX() == srcAndDest.PadX() &&
                   src.PadY() == srcAndDest.PadY() &&
                   src.Cathode() == srcAndDest.Cathode() );
  if (!check)
  {
    return kFALSE;
  }

  srcAndDest.AddSignal(src.Signal());
  srcAndDest.AddPhysicsSignal(src.Physics());
  StdoutToAliDebug(1,cout << "result:"; srcAndDest.Print(););
  return kTRUE;
}

//_____________________________________________________________________________
void
AliMUONDigitizerV3::MergeWithSDigits(AliMUONData& outputData,
                                     const AliMUONData& inputData)
{
  AliDebug(1,"");

	for ( Int_t ich = 0; ich < AliMUONConstants::NCh(); ++ich )
	{
    TClonesArray* iDigits = inputData.SDigits(ich);
    TClonesArray* oDigits = outputData.Digits(ich);
    if (!iDigits)
    {
      AliError(Form("Could not get sdigits for ich=%d",ich));
      return;
    }
    Int_t nSDigits = iDigits->GetEntriesFast();
    for ( Int_t k = 0; k < nSDigits; ++k )
		{
			AliMUONDigit* sdigit = static_cast<AliMUONDigit*>(iDigits->UncheckedAt(k));
      // FIXME: Merging logic should go here.
      // For testing, only put the digit in the output.
      if (!sdigit)
      {
        AliError(Form("Could not get sdigit for ich=%d and k=%d",ich,k));
      }
      else
      {
        AddOrUpdateDigit(*oDigits,*sdigit);
      }
		}
  }
}

//------------------------------------------------------------------------
//void AliMUONDigitizerv2::FillTriggerOutput()
//{
//  // Derived to fill TreeD and resets the trigger array in fMUONData.
//
//	AliDebug(3,"Filling trees with trigger.");
//	fMUONData->Fill("GLT");
//	fMUONData->ResetTrigger();
//}
//
//------------------------------------------------------------------------
//void AliMUONDigitizerv2::CreateTrigger()
//{
//  fMUONData->MakeBranch("GLT");
//  fMUONData->SetTreeAddress("GLT");
//  fTrigDec->Digits2Trigger();
//  FillTriggerOutput();
//
//}

<|endoftext|>


<commit_before>// Copyright 2017 Global Phasing Ltd.

#include "gemmi/symmetry.hpp"

#include "common.h"
#include <pybind11/stl.h>
#include <pybind11/stl_bind.h>
#include <pybind11/numpy.h>
#include "miller_a.h"

namespace py = pybind11;
using namespace gemmi;

void add_symmetry(py::module& m) {
  py::enum_<CrystalSystem>(m, "CrystalSystem")
    .value("Triclinic", CrystalSystem::Triclinic)
    .value("Monoclinic", CrystalSystem::Monoclinic)
    .value("Orthorhombic", CrystalSystem::Orthorhombic)
    .value("Tetragonal", CrystalSystem::Tetragonal)
    .value("Trigonal", CrystalSystem::Trigonal)
    .value("Hexagonal", CrystalSystem::Hexagonal)
    .value("Cubic", CrystalSystem::Cubic)
    ;
  py::class_<Op>(m, "Op")
    .def(py::init<>(&Op::identity))
    .def(py::init(&parse_triplet))
    .def_property_readonly_static("DEN", [](py::object) { return Op::DEN; },
                           "Denominator (integer) for the translation vector.")
    .def_readwrite("rot", &Op::rot, "3x3 integer matrix.")
    .def_readwrite("tran", &Op::tran,
       "Numerators (integers) of the translation vector. Denominator DEN=24.")
    .def("triplet", &Op::triplet, "Returns coordinate triplet x,y,z.")
    .def("inverse", &Op::inverse, "Returns inverted operator.")
    .def("wrap", &Op::wrap, "Wrap the translation part to [0,1)")
    .def("translated", &Op::translated, py::arg("a"), "Adds a to tran")
    .def("transposed_rot", &Op::transposed_rot)
    .def("det_rot", &Op::det_rot, "Determinant of the 3x3 matrix.")
    .def("rot_type", &Op::rot_type)
    .def("combine", &Op::combine, py::arg("b"),
         "Combine two symmetry operations.")
    .def("seitz", [](const Op& self) {
            auto arr = self.int_seitz();
            auto mat = py::list();
            py::object fr = py::module::import("fractions").attr("Fraction");
            for (int i = 0; i < 4; ++i) {
              auto row = py::list();
              for (int j = 0; j < 4; ++j) {
                auto v = arr[i][j];
                if (i == 3 || v == 0)
                  row.append(v);
                else if (std::abs(v) == Op::DEN)
                  row.append(v / Op::DEN);
                else
                  row.append(fr(v, Op::DEN + 0));  // +0 to avoid linker error
              }
              mat.append(row);
            }
            return mat;
         }, "Returns Seitz matrix (fractions)")
    .def("float_seitz", &Op::float_seitz, "Returns Seitz matrix (floats)")
    .def("apply_to_xyz", &Op::apply_to_xyz, py::arg("xyz"))
    .def("apply_to_hkl", &Op::apply_to_hkl, py::arg("hkl"))
    .def("phase_shift", &Op::phase_shift, py::arg("hkl"))
    .def("__mul__", [](const Op& a, const Op& b) { return a * b; },
         py::is_operator())
    .def("__mul__", [](const Op &a, const std::string& b) {
            return a * parse_triplet(b);
         }, py::is_operator())
    .def("__rmul__", [](const Op& a, const std::string& b) {
            return parse_triplet(b) * a;
         }, py::is_operator())
    .def("__eq__", [](const Op& a, const Op& b) { return a == b; },
         py::is_operator())
    .def("__eq__", [](const Op& a, const std::string& b) {
            return a == parse_triplet(b);
         }, py::is_operator())
#if PY_MAJOR_VERSION < 3  // in Py3 != is inferred from ==
    .def("__ne__", [](const Op& a, const Op& b) { return a != b; },
         py::is_operator())
    .def("__ne__", [](const Op& a, const std::string& b) {
            return a != parse_triplet(b);
         }, py::is_operator())
#endif
    .def("__copy__", [](const Op& self) { return Op(self); })
    .def("__deepcopy__", [](const Op& self, py::dict) { return Op(self); }, py::arg("memo"))
    .def("__hash__", [](const Op& self) { return std::hash<Op>()(self); })
    .def("__repr__", [](const Op& self) {
        return "<gemmi.Op(\"" + self.triplet() + "\")>";
    });

  m.def("parse_triplet", &parse_triplet, py::arg("triplet"),
        "Parse coordinate triplet into gemmi.Op.");
  m.def("parse_triplet_part", &parse_triplet_part, py::arg("s"),
        "Parse one of the three parts of a triplet.");
  m.def("make_triplet_part", &make_triplet_part,
        py::arg("xyz"), py::arg("w"), py::arg("style")='x',
        "Make one of the three parts of a triplet.");

  py::class_<GroupOps>(m, "GroupOps")
    .def(py::init(&split_centering_vectors))
    .def("__iter__", [](const GroupOps& self) {
        return py::make_iterator(self);
    }, py::keep_alive<0, 1>())
    .def("__eq__", [](const GroupOps &a, const GroupOps &b) {
            return a.is_same_as(b);
    }, py::is_operator())
#if PY_MAJOR_VERSION < 3  // in Py3 != is inferred from ==
    .def("__ne__", [](const GroupOps &a, const GroupOps &b) {
            return !a.is_same_as(b);
    }, py::is_operator())
#endif
    .def("__len__", [](const GroupOps& g) { return g.order(); })
    .def("__deepcopy__", [](const GroupOps& g, py::dict) { return GroupOps(g); },
         py::arg("memo"))
    .def_readwrite("sym_ops", &GroupOps::sym_ops,
               "Symmetry operations (to be combined with centering vectors).")
    .def_readwrite("cen_ops", &GroupOps::cen_ops, "Centering vectors.")
    .def("add_missing_elements", &GroupOps::add_missing_elements)
    .def("find_centering", &GroupOps::find_centering)
    .def("has_same_centring", &GroupOps::has_same_centring)
    .def("has_same_rotations", &GroupOps::has_same_rotations)
    .def("is_centrosymmetric", &GroupOps::is_centrosymmetric)
    .def("is_reflection_centric", &GroupOps::is_reflection_centric)
    .def("centric_flag_array", [](const GroupOps& g, py::array_t<int> hkl) {
        return miller_function<bool>(g, &GroupOps::is_reflection_centric, hkl);
    })
    .def("epsilon_factor_without_centering", &GroupOps::epsilon_factor_without_centering)
    .def("epsilon_factor", &GroupOps::epsilon_factor)
    .def("epsilon_factor_array", [](const GroupOps& g, py::array_t<int> hkl) {
        return miller_function<int>(g, &GroupOps::epsilon_factor, hkl);
    })
    .def("epsilon_factor_without_centering_array", [](const GroupOps& g,
                                                      py::array_t<int> hkl) {
        return miller_function<int>(g, &GroupOps::epsilon_factor_without_centering, hkl);
    })
    .def("is_systematically_absent", &GroupOps::is_systematically_absent)
    .def("systematic_absences", [](const GroupOps& g, py::array_t<int> hkl) {
        return miller_function<bool>(g, &GroupOps::is_systematically_absent, hkl);
    })
    .def("find_grid_factors", &GroupOps::find_grid_factors,
         "Minimal multiplicity for real-space grid (e.g. 1,1,6 for P61).")
    .def("change_basis_forward", &GroupOps::change_basis_forward, py::arg("cob"),
         "Applies the change-of-basis operator (in place).")
    .def("change_basis_backward", &GroupOps::change_basis_backward, py::arg("cob"),
         "Applies inverse of the change-of-basis operator (in place).")
    .def("derive_symmorphic", &GroupOps::derive_symmorphic)
    .def("add_inversion", &GroupOps::add_inversion)
    ;

  py::class_<SpaceGroup, std::unique_ptr<SpaceGroup, py::nodelete>>(m, "SpaceGroup")
    .def(py::init([](int n) {
           return const_cast<SpaceGroup*>(&get_spacegroup_by_number(n));
         }), py::arg("ccp4"), py::return_value_policy::reference)
    .def(py::init([](const std::string& s) {
           return const_cast<SpaceGroup*>(&get_spacegroup_by_name(s));
         }), py::arg("hm"), py::return_value_policy::reference)
    .def_readonly("number", &SpaceGroup::number, "number 1-230.")
    .def_readonly("ccp4", &SpaceGroup::ccp4, "ccp4 number")
    // Intel Compiler would not compile .def_readonly("hm", ...),
    // the difference with hm, qualifier and hall is that they are char[N]
    .def_property_readonly("hm", [](const SpaceGroup &self) -> const char* {
        return self.hm;
    }, "Hermann-Mauguin name")
    .def_readonly("ext", &SpaceGroup::ext, "Extension (1, 2, H, R or none)")
    .def_property_readonly("qualifier", [](const SpaceGroup &s) -> const char* {
        return s.qualifier;
    }, "e.g. 'cab'")
    .def_property_readonly("hall", [](const SpaceGroup &self) -> const char* {
        return self.hall;
    }, "Hall symbol")
    .def_property_readonly("basisop", &SpaceGroup::basisop)
    .def("xhm", &SpaceGroup::xhm, "extended Hermann-Mauguin name")
    .def("centring_type", &SpaceGroup::centring_type)
    .def("short_name", &SpaceGroup::short_name,
         "H-M name w/o spaces and with 1's removed in '1 ... 1'.")
    .def("is_enantiomorphic", &SpaceGroup::is_enantiomorphic)
    .def("is_sohncke", &SpaceGroup::is_sohncke)
    .def("is_symmorphic", &SpaceGroup::is_symmorphic)
    .def("point_group_hm", &SpaceGroup::point_group_hm,
         "Returns H-M name of the point group.")
    .def("laue_str", &SpaceGroup::laue_str,
         "Returns name of the Laue class (for centrosymmetric groups "
         "the same as point_group_hm).")
    .def("crystal_system", &SpaceGroup::crystal_system)
    .def("crystal_system_str", &SpaceGroup::crystal_system_str,
         "Returns lower-case name of the crystal system.")
    .def("is_centrosymmetric", &SpaceGroup::is_centrosymmetric)
    .def("is_reference_setting", &SpaceGroup::is_reference_setting)
    .def("centred_to_primitive", &SpaceGroup::centred_to_primitive)
    .def("operations", &SpaceGroup::operations, "Group of operations")
    .def("switch_to_asu", [](const SpaceGroup& sg, py::array_t<int> hkl) {
        auto h = hkl.mutable_unchecked<2>();
        if (h.shape(1) < 3)
          throw std::domain_error("error: the size of the second dimension < 3");
        GroupOps gops = sg.operations();
        ReciprocalAsu asu(&sg);
        for (py::ssize_t i = 0; i < h.shape(0); ++i) {
          Op::Miller hkl = asu.to_asu({{h(i, 0), h(i, 1), h(i, 2)}}, gops).first;
          for (int j = 0; j != 3; ++j)
            h(i, j) = hkl[j];
        }
    }, py::arg("miller_array").noconvert())
    .def("__repr__", [](const SpaceGroup &self) {
        return "<gemmi.SpaceGroup(\"" + self.xhm() + "\")>";
    })
    .def(py::pickle(
        [](const SpaceGroup &self) {
          return self.xhm();
        },
        [](const std::string &s) {
          return const_cast<SpaceGroup*>(&get_spacegroup_by_name(s));
        }
    ));

  py::class_<ReciprocalAsu>(m, "ReciprocalAsu")
    .def(py::init<const SpaceGroup*>())
    .def("is_in", &ReciprocalAsu::is_in, py::arg("hkl"))
    .def("condition_str", &ReciprocalAsu::condition_str)
    .def("to_asu", &ReciprocalAsu::to_asu, py::arg("hkl"), py::arg("group_ops"))
    ;

  m.def("spacegroup_table", []() {
            return py::make_iterator(spacegroup_tables::main);
        }, py::return_value_policy::reference);
  m.def("spacegroup_table_itb", []() {
            return py::make_iterator(spacegroup_tables::main,
                                     spacegroup_tables::main + 530);
        }, py::return_value_policy::reference);
  m.def("generators_from_hall", &generators_from_hall, py::arg("hall"),
        "Parse Hall notation.");
  m.def("symops_from_hall", &symops_from_hall, py::arg("hall"),
        "Parse Hall notation.");
  m.def("find_spacegroup_by_number", &find_spacegroup_by_number,
        py::arg("ccp4"), py::return_value_policy::reference,
        "Returns space-group of given number.");
  m.def("find_spacegroup_by_name", &find_spacegroup_by_name,
        py::arg("hm"), py::arg("alpha")=0., py::arg("gamma")=0.,
        py::return_value_policy::reference,
        "Returns space-group with given name.");
  m.def("get_spacegroup_reference_setting", &get_spacegroup_reference_setting,
        py::arg("number"), py::return_value_policy::reference);
  m.def("find_spacegroup_by_ops", &find_spacegroup_by_ops,
        py::arg("group_ops"), py::return_value_policy::reference,
        "Returns space-group with identical operations.");
  m.def("seitz_to_op", &seitz_to_op);
}
<commit_msg>fix compilation with the latest pybind11<commit_after>// Copyright 2017 Global Phasing Ltd.

#include "gemmi/symmetry.hpp"

#include "common.h"
#include <pybind11/stl.h>
#include <pybind11/stl_bind.h>
#include <pybind11/numpy.h>
#include "miller_a.h"

namespace py = pybind11;
using namespace gemmi;

void add_symmetry(py::module& m) {
  py::enum_<CrystalSystem>(m, "CrystalSystem")
    .value("Triclinic", CrystalSystem::Triclinic)
    .value("Monoclinic", CrystalSystem::Monoclinic)
    .value("Orthorhombic", CrystalSystem::Orthorhombic)
    .value("Tetragonal", CrystalSystem::Tetragonal)
    .value("Trigonal", CrystalSystem::Trigonal)
    .value("Hexagonal", CrystalSystem::Hexagonal)
    .value("Cubic", CrystalSystem::Cubic)
    ;
  py::class_<Op>(m, "Op")
    .def(py::init<>(&Op::identity))
    .def(py::init(&parse_triplet))
    .def_property_readonly_static("DEN", [](py::object) { return Op::DEN; },
                           "Denominator (integer) for the translation vector.")
    .def_readwrite("rot", &Op::rot, "3x3 integer matrix.")
    .def_readwrite("tran", &Op::tran,
       "Numerators (integers) of the translation vector. Denominator DEN=24.")
    .def("triplet", &Op::triplet, "Returns coordinate triplet x,y,z.")
    .def("inverse", &Op::inverse, "Returns inverted operator.")
    .def("wrap", &Op::wrap, "Wrap the translation part to [0,1)")
    .def("translated", &Op::translated, py::arg("a"), "Adds a to tran")
    .def("transposed_rot", &Op::transposed_rot)
    .def("det_rot", &Op::det_rot, "Determinant of the 3x3 matrix.")
    .def("rot_type", &Op::rot_type)
    .def("combine", &Op::combine, py::arg("b"),
         "Combine two symmetry operations.")
    .def("seitz", [](const Op& self) {
            auto arr = self.int_seitz();
            auto mat = py::list();
            py::object fr = py::module::import("fractions").attr("Fraction");
            for (int i = 0; i < 4; ++i) {
              auto row = py::list();
              for (int j = 0; j < 4; ++j) {
                auto v = arr[i][j];
                if (i == 3 || v == 0)
                  row.append(v);
                else if (std::abs(v) == Op::DEN)
                  row.append(v / Op::DEN);
                else
                  row.append(fr(v, Op::DEN + 0));  // +0 to avoid linker error
              }
              mat.append(row);
            }
            return mat;
         }, "Returns Seitz matrix (fractions)")
    .def("float_seitz", &Op::float_seitz, "Returns Seitz matrix (floats)")
    .def("apply_to_xyz", &Op::apply_to_xyz, py::arg("xyz"))
    .def("apply_to_hkl", &Op::apply_to_hkl, py::arg("hkl"))
    .def("phase_shift", &Op::phase_shift, py::arg("hkl"))
    .def("__mul__", [](const Op& a, const Op& b) { return a * b; },
         py::is_operator())
    .def("__mul__", [](const Op &a, const std::string& b) {
            return a * parse_triplet(b);
         }, py::is_operator())
    .def("__rmul__", [](const Op& a, const std::string& b) {
            return parse_triplet(b) * a;
         }, py::is_operator())
    .def("__eq__", [](const Op& a, const Op& b) { return a == b; },
         py::is_operator())
    .def("__eq__", [](const Op& a, const std::string& b) {
            return a == parse_triplet(b);
         }, py::is_operator())
#if PY_MAJOR_VERSION < 3  // in Py3 != is inferred from ==
    .def("__ne__", [](const Op& a, const Op& b) { return a != b; },
         py::is_operator())
    .def("__ne__", [](const Op& a, const std::string& b) {
            return a != parse_triplet(b);
         }, py::is_operator())
#endif
    .def("__copy__", [](const Op& self) { return Op(self); })
    .def("__deepcopy__", [](const Op& self, py::dict) { return Op(self); }, py::arg("memo"))
    .def("__hash__", [](const Op& self) { return std::hash<Op>()(self); })
    .def("__repr__", [](const Op& self) {
        return "<gemmi.Op(\"" + self.triplet() + "\")>";
    });

  m.def("parse_triplet", &parse_triplet, py::arg("triplet"),
        "Parse coordinate triplet into gemmi.Op.");
  m.def("parse_triplet_part", &parse_triplet_part, py::arg("s"),
        "Parse one of the three parts of a triplet.");
  m.def("make_triplet_part", &make_triplet_part,
        py::arg("xyz"), py::arg("w"), py::arg("style")='x',
        "Make one of the three parts of a triplet.");

  py::class_<GroupOps>(m, "GroupOps")
    .def(py::init(&split_centering_vectors))
    .def("__iter__", [](const GroupOps& self) {
        return py::make_iterator(self);
    }, py::keep_alive<0, 1>())
    .def("__eq__", [](const GroupOps &a, const GroupOps &b) {
            return a.is_same_as(b);
    }, py::is_operator())
#if PY_MAJOR_VERSION < 3  // in Py3 != is inferred from ==
    .def("__ne__", [](const GroupOps &a, const GroupOps &b) {
            return !a.is_same_as(b);
    }, py::is_operator())
#endif
    .def("__len__", [](const GroupOps& g) { return g.order(); })
    .def("__deepcopy__", [](const GroupOps& g, py::dict) { return GroupOps(g); },
         py::arg("memo"))
    .def_readwrite("sym_ops", &GroupOps::sym_ops,
               "Symmetry operations (to be combined with centering vectors).")
    .def_readwrite("cen_ops", &GroupOps::cen_ops, "Centering vectors.")
    .def("add_missing_elements", &GroupOps::add_missing_elements)
    .def("find_centering", &GroupOps::find_centering)
    .def("has_same_centring", &GroupOps::has_same_centring)
    .def("has_same_rotations", &GroupOps::has_same_rotations)
    .def("is_centrosymmetric", &GroupOps::is_centrosymmetric)
    .def("is_reflection_centric", &GroupOps::is_reflection_centric)
    .def("centric_flag_array", [](const GroupOps& g, py::array_t<int> hkl) {
        return miller_function<bool>(g, &GroupOps::is_reflection_centric, hkl);
    })
    .def("epsilon_factor_without_centering", &GroupOps::epsilon_factor_without_centering)
    .def("epsilon_factor", &GroupOps::epsilon_factor)
    .def("epsilon_factor_array", [](const GroupOps& g, py::array_t<int> hkl) {
        return miller_function<int>(g, &GroupOps::epsilon_factor, hkl);
    })
    .def("epsilon_factor_without_centering_array", [](const GroupOps& g,
                                                      py::array_t<int> hkl) {
        return miller_function<int>(g, &GroupOps::epsilon_factor_without_centering, hkl);
    })
    .def("is_systematically_absent", &GroupOps::is_systematically_absent)
    .def("systematic_absences", [](const GroupOps& g, py::array_t<int> hkl) {
        return miller_function<bool>(g, &GroupOps::is_systematically_absent, hkl);
    })
    .def("find_grid_factors", &GroupOps::find_grid_factors,
         "Minimal multiplicity for real-space grid (e.g. 1,1,6 for P61).")
    .def("change_basis_forward", &GroupOps::change_basis_forward, py::arg("cob"),
         "Applies the change-of-basis operator (in place).")
    .def("change_basis_backward", &GroupOps::change_basis_backward, py::arg("cob"),
         "Applies inverse of the change-of-basis operator (in place).")
    .def("derive_symmorphic", &GroupOps::derive_symmorphic)
    .def("add_inversion", &GroupOps::add_inversion)
    ;

  py::class_<SpaceGroup, std::unique_ptr<SpaceGroup, py::nodelete>>(m, "SpaceGroup")
    .def(py::init([](int n) {
           return const_cast<SpaceGroup*>(&get_spacegroup_by_number(n));
         }), py::arg("ccp4"), py::return_value_policy::reference)
    .def(py::init([](const std::string& s) {
           return const_cast<SpaceGroup*>(&get_spacegroup_by_name(s));
         }), py::arg("hm"), py::return_value_policy::reference)
    .def_readonly("number", &SpaceGroup::number, "number 1-230.")
    .def_readonly("ccp4", &SpaceGroup::ccp4, "ccp4 number")
    // Intel Compiler would not compile .def_readonly("hm", ...),
    // the difference with hm, qualifier and hall is that they are char[N]
    .def_property_readonly("hm", [](const SpaceGroup &self) -> const char* {
        return self.hm;
    }, "Hermann-Mauguin name")
    .def_readonly("ext", &SpaceGroup::ext, "Extension (1, 2, H, R or none)")
    .def_property_readonly("qualifier", [](const SpaceGroup &s) -> const char* {
        return s.qualifier;
    }, "e.g. 'cab'")
    .def_property_readonly("hall", [](const SpaceGroup &self) -> const char* {
        return self.hall;
    }, "Hall symbol")
    .def_property_readonly("basisop", &SpaceGroup::basisop)
    .def("xhm", &SpaceGroup::xhm, "extended Hermann-Mauguin name")
    .def("centring_type", &SpaceGroup::centring_type)
    .def("short_name", &SpaceGroup::short_name,
         "H-M name w/o spaces and with 1's removed in '1 ... 1'.")
    .def("is_enantiomorphic", &SpaceGroup::is_enantiomorphic)
    .def("is_sohncke", &SpaceGroup::is_sohncke)
    .def("is_symmorphic", &SpaceGroup::is_symmorphic)
    .def("point_group_hm", &SpaceGroup::point_group_hm,
         "Returns H-M name of the point group.")
    .def("laue_str", &SpaceGroup::laue_str,
         "Returns name of the Laue class (for centrosymmetric groups "
         "the same as point_group_hm).")
    .def("crystal_system", &SpaceGroup::crystal_system)
    .def("crystal_system_str", &SpaceGroup::crystal_system_str,
         "Returns lower-case name of the crystal system.")
    .def("is_centrosymmetric", &SpaceGroup::is_centrosymmetric)
    .def("is_reference_setting", &SpaceGroup::is_reference_setting)
    .def("centred_to_primitive", &SpaceGroup::centred_to_primitive)
    .def("operations", &SpaceGroup::operations, "Group of operations")
    .def("switch_to_asu", [](const SpaceGroup& sg, py::array_t<int> hkl) {
        auto h = hkl.mutable_unchecked<2>();
        if (h.shape(1) < 3)
          throw std::domain_error("error: the size of the second dimension < 3");
        GroupOps gops = sg.operations();
        ReciprocalAsu asu(&sg);
        for (py::ssize_t i = 0; i < h.shape(0); ++i) {
          Op::Miller hkl = asu.to_asu({{h(i, 0), h(i, 1), h(i, 2)}}, gops).first;
          for (int j = 0; j != 3; ++j)
            h(i, j) = hkl[j];
        }
    }, py::arg("miller_array").noconvert())
    .def("__repr__", [](const SpaceGroup &self) {
        return "<gemmi.SpaceGroup(\"" + self.xhm() + "\")>";
    })
    .def(py::pickle(
        [](const SpaceGroup &self) {
          return self.xhm();
        },
        [](const std::string &s) {
          return const_cast<SpaceGroup*>(&get_spacegroup_by_name(s));
        }
    ));

  py::class_<ReciprocalAsu>(m, "ReciprocalAsu")
    .def(py::init<const SpaceGroup*>())
    .def("is_in", &ReciprocalAsu::is_in, py::arg("hkl"))
    .def("condition_str", &ReciprocalAsu::condition_str)
    .def("to_asu", &ReciprocalAsu::to_asu, py::arg("hkl"), py::arg("group_ops"))
    ;

  m.def("spacegroup_table", []() {
            return py::make_iterator(spacegroup_tables::main);
        }, py::return_value_policy::reference);
  m.def("spacegroup_table_itb", []() {
            return py::make_iterator(spacegroup_tables::main + 0,
                                     spacegroup_tables::main + 530);
        }, py::return_value_policy::reference);
  m.def("generators_from_hall", &generators_from_hall, py::arg("hall"),
        "Parse Hall notation.");
  m.def("symops_from_hall", &symops_from_hall, py::arg("hall"),
        "Parse Hall notation.");
  m.def("find_spacegroup_by_number", &find_spacegroup_by_number,
        py::arg("ccp4"), py::return_value_policy::reference,
        "Returns space-group of given number.");
  m.def("find_spacegroup_by_name", &find_spacegroup_by_name,
        py::arg("hm"), py::arg("alpha")=0., py::arg("gamma")=0.,
        py::return_value_policy::reference,
        "Returns space-group with given name.");
  m.def("get_spacegroup_reference_setting", &get_spacegroup_reference_setting,
        py::arg("number"), py::return_value_policy::reference);
  m.def("find_spacegroup_by_ops", &find_spacegroup_by_ops,
        py::arg("group_ops"), py::return_value_policy::reference,
        "Returns space-group with identical operations.");
  m.def("seitz_to_op", &seitz_to_op);
}
<|endoftext|>


<commit_before>#include <iostream>
using namespace std;

#define _unused(x) ((void)x)

// @@Example: create_table @@
#include <tightdb.hpp>
using namespace tightdb;

// defining a table
TIGHTDB_TABLE_3(MyTable,
//              columns: types:
                name,    String,
                age,     Int,
                hired,   Bool)

int main() {
    // creating an instance of the table
    MyTable table;
    // @@EndExample@@

    // @@Example: insert_rows @@
    table.add("Mary", 21, false);
    table.add("Lars", 21, true);
    table.add("Phil", 43, false);
    table.add("Anni", 54, true);
    // @@EndExample@@

    // @@Example: insert_at_index @@
    table.insert(2, "Frank", 34, true);
    // @@EndExample@@

    // @@Example: number_of_rows @@
    cout << table.size() << endl; // => 6
    cout << (table.is_empty() ? "Empty" : "Not empty") << endl; // => Not Empty
    // @@EndExample@@

    // @@Example: accessing_rows @@
    // Getting values
    StringData name  = table[3].name;  // => 'Anni'
    int age          = table[3].age;   // => 54
    bool hired       = table[3].hired; // => true

    // Changing values
    table[3].age = 43; // Getting younger
    table[3].age += 1; // Happy birthday!
    // @@EndExample@@

    _unused(age);
    _unused(hired);

    // @@Example: last_row @@
    cout << table.back().name << endl;                 // => "Anni"
    // @@EndExample@@

    // @@Example: updating_entire_row @@
    //table.set(4, "Eric", 50, true);
    // @@EndExample@@

    // @@Example: deleting_row @@
    table.remove(2);
    cout << table.size(); // => 5
    // @@EndExample@@

    cout << endl << endl;

    // @@Example: iteration @@
    for (size_t i = 0; i < table.size(); ++i) {
        MyTable::Cursor row = table[i];
        cout << row.name << " is " << row.age << " years old." << endl;
    }
    // @@EndExample@@

    // @@Example: simple_seach @@
    size_t row_ndx;
    row_ndx = table.column().name.find_first("Philip");  // => not_found (-1)
    row_ndx = table.column().name.find_first("Mary");    // => 1

    MyTable::View view = table.column().age.find_all(21);
    size_t cnt = view.size();         // cnt => 2
    // @@EndExample@@

    _unused(cnt);

    cout << endl << endl;

    // @@Example: advanced_search @@
    // Create query (current employees between 20 and 30 years old)
    MyTable::Query q = table.where().hired.equal(true)    // implicit logical-AND
                                    .age.between(20, 30);

    // Get number of matching entries
    cout << q.count() << endl;      // => 2

    // Get the average age
    cout << q.age.average() << endl; // => 26

    // Execute the query and return a table (view)
    MyTable::View res = q.find_all();
    for (size_t i = 0; i < res.size(); ++i) {
        StringData name = res[i].name;
        int        age  = res[i].age;

        cout << i << ": " << name << " is " << age << " years old." << endl;
    }
    // @@EndExample@@

    cout << endl << endl;

    // @@Example: serialisation @@
    // Create Table in Group
    Group group;
    MyTable::Ref t = group.get_table<MyTable>("employees");

    // Add some rows
    t->add("John", 20, true);
    t->add("Mary", 21, false);
    t->add("Lars", 21, true);
    t->add("Phil", 43, false);
    t->add("Anni", 54, true);

    // Remove database file if already existing
    remove("employees.tightdb");

    // Write to disk
    group.write("employees.tightdb");

    // Load a group from disk (and print contents)
    Group fromDisk("employees.tightdb");
    MyTable::Ref diskTable = fromDisk.get_table<MyTable>("employees");
    for (size_t i = 0; i < diskTable->size(); ++i)
        cout << i << ": " << diskTable[i].name << endl;

    // Write same group to memory buffer
    BinaryData buffer = group.write_to_mem();

    // Load a group from memory (and print contents)
    Group fromMem(buffer);
    MyTable::Ref memTable = fromMem.get_table<MyTable>("employees");
    for (size_t i = 0; i < memTable->size(); i++)
        cout << i << ": " << memTable[i].name << endl;
    // @@EndExample@@

    // @@Example: transaction @@
    // Open a shared group
    SharedGroup db("employees.tightdb");

    // Read transaction
    {
        ReadTransaction tr(db); // start transaction
        MyTable::ConstRef table = tr.get_table<MyTable>("employees");

        // Print table contents
        for (size_t i = 0; i < table->size(); ++i)
            cout << i << ": " << table[i].name << endl;
    }

    // Write transaction (will rollback on error)
    {
        WriteTransaction tr(db); // start transaction
        MyTable::Ref table = tr.get_table<MyTable>("employees");

        // Add row to table
        table->add("Bill", 53, true);

        tr.commit(); // end transaction
    }
    // @@EndExample@@
}

<commit_msg>Use C++ style casts in the tutorial<commit_after>#include <iostream>
using namespace std;

// @@Example: create_table @@
#include <tightdb.hpp>
using namespace tightdb;

// defining a table
TIGHTDB_TABLE_3(MyTable,
//              columns: types:
                name,    String,
                age,     Int,
                hired,   Bool)

int main() {
    // creating an instance of the table
    MyTable table;
    // @@EndExample@@

    // @@Example: insert_rows @@
    table.add("Mary", 21, false);
    table.add("Lars", 21, true);
    table.add("Phil", 43, false);
    table.add("Anni", 54, true);
    // @@EndExample@@

    // @@Example: insert_at_index @@
    table.insert(2, "Frank", 34, true);
    // @@EndExample@@

    // @@Example: number_of_rows @@
    cout << table.size() << endl; // => 6
    cout << (table.is_empty() ? "Empty" : "Not empty") << endl; // => Not Empty
    // @@EndExample@@

    // @@Example: accessing_rows @@
    // Getting values
    StringData name  = table[3].name;  // => 'Anni'
    int age          = table[3].age;   // => 54
    bool hired       = table[3].hired; // => true

    // Changing values
    table[3].age = 43; // Getting younger
    table[3].age += 1; // Happy birthday!
    // @@EndExample@@

    static_cast<void>(age);
    static_cast<void>(hired);

    // @@Example: last_row @@
    cout << table.back().name << endl;                 // => "Anni"
    // @@EndExample@@

    // @@Example: updating_entire_row @@
    //table.set(4, "Eric", 50, true);
    // @@EndExample@@

    // @@Example: deleting_row @@
    table.remove(2);
    cout << table.size(); // => 5
    // @@EndExample@@

    cout << endl << endl;

    // @@Example: iteration @@
    for (size_t i = 0; i < table.size(); ++i) {
        MyTable::Cursor row = table[i];
        cout << row.name << " is " << row.age << " years old." << endl;
    }
    // @@EndExample@@

    // @@Example: simple_seach @@
    size_t row_ndx;
    row_ndx = table.column().name.find_first("Philip");  // => not_found (-1)
    row_ndx = table.column().name.find_first("Mary");    // => 1

    MyTable::View view = table.column().age.find_all(21);
    size_t cnt = view.size();         // cnt => 2
    // @@EndExample@@

    static_cast<void>(cnt);

    cout << endl << endl;

    // @@Example: advanced_search @@
    // Create query (current employees between 20 and 30 years old)
    MyTable::Query q = table.where().hired.equal(true)    // implicit logical-AND
                                    .age.between(20, 30);

    // Get number of matching entries
    cout << q.count() << endl;      // => 2

    // Get the average age
    cout << q.age.average() << endl; // => 26

    // Execute the query and return a table (view)
    MyTable::View res = q.find_all();
    for (size_t i = 0; i < res.size(); ++i) {
        StringData name = res[i].name;
        int        age  = res[i].age;

        cout << i << ": " << name << " is " << age << " years old." << endl;
    }
    // @@EndExample@@

    cout << endl << endl;

    // @@Example: serialisation @@
    // Create Table in Group
    Group group;
    MyTable::Ref t = group.get_table<MyTable>("employees");

    // Add some rows
    t->add("John", 20, true);
    t->add("Mary", 21, false);
    t->add("Lars", 21, true);
    t->add("Phil", 43, false);
    t->add("Anni", 54, true);

    // Remove database file if already existing
    remove("employees.tightdb");

    // Write to disk
    group.write("employees.tightdb");

    // Load a group from disk (and print contents)
    Group fromDisk("employees.tightdb");
    MyTable::Ref diskTable = fromDisk.get_table<MyTable>("employees");
    for (size_t i = 0; i < diskTable->size(); ++i)
        cout << i << ": " << diskTable[i].name << endl;

    // Write same group to memory buffer
    BinaryData buffer = group.write_to_mem();

    // Load a group from memory (and print contents)
    Group fromMem(buffer);
    MyTable::Ref memTable = fromMem.get_table<MyTable>("employees");
    for (size_t i = 0; i < memTable->size(); i++)
        cout << i << ": " << memTable[i].name << endl;
    // @@EndExample@@

    // @@Example: transaction @@
    // Open a shared group
    SharedGroup db("employees.tightdb");

    // Read transaction
    {
        ReadTransaction tr(db); // start transaction
        MyTable::ConstRef table = tr.get_table<MyTable>("employees");

        // Print table contents
        for (size_t i = 0; i < table->size(); ++i)
            cout << i << ": " << table[i].name << endl;
    }

    // Write transaction (will rollback on error)
    {
        WriteTransaction tr(db); // start transaction
        MyTable::Ref table = tr.get_table<MyTable>("employees");

        // Add row to table
        table->add("Bill", 53, true);

        tr.commit(); // end transaction
    }
    // @@EndExample@@
}

<|endoftext|>


<commit_before>#include <cmath>
#include <cstdlib>
#include <ctime>
#include <string>
#include <sstream>
#include "StateSpace.h"
#include "PriorityQueue.h"
#include "State.h"
#include "encoder.h"
#include "CreateModule.h"

/**
 * @brief Gives a std::string representation of a primitive type
 *
 * @param x Primitive type such as int, double, long
 * @return std::string conversion of param x
 */
template<typename T> std::string to_string(T x) {
	return static_cast<std::ostringstream&>((std::ostringstream() << std::dec << x)).str();
}

//function to calculate a temperature for the select action function as a function of time
double temperature(unsigned long int t);

//function to select next action
int selectAction(const PriorityQueue<int, double>& a_queue,unsigned long int iterations);

//function to update a q value
void updateQ(StateSpace & space, int action, State & new_state, State & old_state, double alpha, double gamma);

int main()
{
	// STUFF WE DONT UNDERSTAND, AND DONT NEED TO
	//__________________________________________________________________________________________
	//__________________________________________________________________________________________
	// Libraries to load
	std::string bodyLibName = "bodyinfo";
	std::string movementLibName = "movementtools";

	// Name of camera module in library
	std::string bodyModuleName = "BodyInfo";
	std::string movementModuleName = "MovementTools";

	// Set broker name, ip and port, finding first available port from 54000
	const std::string brokerName = "MotionTimingBroker";
	int brokerPort = qi::os::findAvailablePort(54000);
	const std::string brokerIp = "0.0.0.0";

	// Default parent port and ip
	int pport = 9559;
	std::string pip = "127.0.0.1";

	// Need this for SOAP serialisation of floats to work
	setlocale(LC_NUMERIC, "C");

	// Create a broker
	boost::shared_ptr<AL::ALBroker> broker;
	try
	{
		broker = AL::ALBroker::createBroker(
				brokerName,
				brokerIp,
				brokerPort,
				pip,
				pport,
				0);
	}
	// Throw error and quit if a broker could not be created
	catch(...)
	{
		std::cerr << "Failed to connect broker to: "
			  << pip
			  << ":"
			  << pport
			  << std::endl;
		AL::ALBrokerManager::getInstance()->killAllBroker();
		AL::ALBrokerManager::kill();

		return 1;
	}

	// Add the broker to NAOqi
	AL::ALBrokerManager::setInstance(broker->fBrokerManager.lock());
	AL::ALBrokerManager::getInstance()->addBroker(broker);

	CreateModule(movementLibName, movementModuleName, broker, false, true);
	CreateModule(bodyLibName, bodyModuleName, broker, false, true);

	AL::ALProxy bodyInfoProxy(bodyModuleName, pip, pport);
	AL::ALProxy movementToolsProxy(movementModuleName, pip, pport);
	AL::ALMotionProxy motion(pip, pport);
	//__________________________________________________________________________________________
	//__________________________________________________________________________________________
	//END OF STUFF WE DONT UNDERSTAND, BREATHE NOW

	//learning factor
	const double alpha=0.5;
	//discount factor
	const double gamma=0.5;

	//seed rng
	std::srand(static_cast<unsigned int>(std::time(NULL)));

	int action_forwards = FORWARD;
	int action_backwards = BACKWARD;
	int chosen_action = action_forwards;

	//create a priority queue to copy to all the state space priority queues
	PriorityQueue<int,double> initiator_queue(MAX);
	initiator_queue.enqueueWithPriority(action_forwards,0);
	initiator_queue.enqueueWithPriority(action_backwards,0);

	//create encoder
	Encoder encoder;
	encoder.Calibrate();

	//create the state space
	StateSpace space(100,50,initiator_queue);

	//state objects
	State current_state(0,0,FORWARD);
	State old_state(0,0,FORWARD);

	unsigned long int i=0;
	while(true)
	{
		// set current state angle to angle received from encoder
		// and set current state velocity to difference in new and
		// old state angles over some time difference
		current_state.theta= M_PI * (encoder.GetAngle())/180;
		current_state.theta_dot=(current_state.theta - old_state.theta)/700; //Needs actual time
		current_state.robot_state=static_cast<ROBOT_STATE>(chosen_action);

		// call updateQ function with state space, old and current states
		// and learning rate, discount factor
		updateQ(space, chosen_action, old_state, current_state, alpha, gamma);

		// set old_state to current_state
		old_state=current_state;

		// determine chosen_action for current state
		chosen_action=selectAction(space[current_state],i);

		// depending upon chosen action, call robot movement tools proxy with either
		// swingForwards or swingBackwards commands.
		(chosen_action)?movementToolsProxy.callVoid("swingForwards"):movementToolsProxy.callVoid("swingBackwards");

		++i;
	}

	return 1;
}

/**
 * @brief Analog to temperature variable in Boltzmann Distribution.
 *
 * @return current system time in milliseconds
 */
double temperature(unsigned long int t)
{
	return 100000*std::exp((-32*t*t)/(26000*26000))+0.1;//0.1 is an offset
	//	^
	//	|
	//make this large
}

/**
 * @brief Selects an action to perform based on probabilities.
 *
 * @param a_queue A priority queue instance storing integral types with double type priorities,
 *		  represents the queue of possible actions with pre-initialised priority levels.
 * @return integer corresponding to chosen action
 */
int selectAction(const PriorityQueue<int, double>& a_queue,unsigned long int iterations) {

	// queue to store action values
	PriorityQueue<int, double> actionQueue(MAX);

	double sum = 0.0;

	// calculate partition function by iterating over action-values
	for (PriorityQueue<int, double>::const_iterator iter = a_queue.begin(), end = a_queue.end(); iter < end; ++iter) {
		sum += std::exp((iter->second) / temperature(iterations));
	}

	// compute Boltzmann factors for action-values and enqueue to actionQueue
	for (PriorityQueue<int, double>::const_iterator iter = a_queue.begin(); iter < a_queue.end(); ++iter) {
		double priority = std::exp(iter.operator*().second / temperature(iterations)) / sum;
		actionQueue.enqueueWithPriority(iter.operator*().first, priority);
	}

	// calculate cumulative probability distribution
	for (PriorityQueue<int, double>::const_iterator it1 = actionQueue.begin()++, it2 = actionQueue.begin(), end = actionQueue.end(); it1 < end; ++it1, ++it2) {
		// change priority of it1->first data item in actionQueue to
		// sum of priorities of it1 and it2 items
		actionQueue.changePriority(it1->first, it1->second + it2->second);
	}

	//generate RN between 0 and 1
	double rand_num = static_cast<double>(rand()) / RAND_MAX;

	// choose action based on random number relation to priorities within action queue
	for (PriorityQueue<int, double>::const_iterator iter = actionQueue.begin(), end = actionQueue.end(); iter < end; ++iter) {
		if (rand_num < iter->second)
			return iter->first;
	}

	return -1; //note that this line should never be reached
}

/**
 * @brief Updates the utility (Q-value) of the system
 *
 * @param space Reference to StateSpace object
 * @param new_state Reference to State instance giving the new system state
 * @param old_state Reference to State instance giving the old system state
 * @param alpha Learning rate of temporal difference learning algorithm
 * @param gamma Discount factor applied to q-learning equation
 */
void updateQ(StateSpace & space, int action, State & new_state, State & old_state, double alpha, double gamma)
{
    //oldQ value reference
    double oldQ = space[old_state].search(action).second;

    //reward given to current state
    double R = new_state.getReward();

    //optimal Q value for new state i.e. first element
    double maxQ = space[new_state].peekFront().second;

    //new Q value determined by Q learning algorithm
    double newQ = oldQ + alpha * (R + (gamma * maxQ) - oldQ);

    // change priority of action to new Q value
    space[old_state].changePriority(action, newQ);
}

/*old select action function in case the new one doesn't work
int selectAction(const PriorityQueue<int,double>& a_queue)
{
	typedef PriorityQueue<int,double> PQ;
	typedef std::vector< std::pair<int, double> > Vec_Pair;
	typedef std::pair<int, double> Pair;

	double sum= 0;
	size_t i = 0;

	size_t size = a_queue.getSize();
	Vec_Pair action_vec(size);

	//Calculate partition function by iterating over action-values
	for(PQ::const_iterator iter = a_queue.begin(),end=a_queue.end(); iter < end; ++iter)
	{
		sum += std::exp((iter->second)/temperature());
	}
	//Calculate boltzmann factors for action-values
	for(Vec_Pair::iterator it = action_vec.begin(),end=action_vec.end(); it < end; ++it)
	{
	    it->first = a_queue[i].first;
	    it->second = std::exp(a_queue[i].second /temperature()) / sum;
	    ++i;
	}

	//calculate cumulative probability distribution
	for(Vec_Pair::iterator it1 = action_vec.begin()++,it2 = action_vec.begin(),end=action_vec.end(); it1 < end; ++it1,++it2)
	{
	    it1->second += it2->second;
	}

	//generate RN between 0 and 1
	double rand_num = static_cast<double>(rand())/ RAND_MAX;

	//select action based on probability
	for(Vec_Pair::iterator it = action_vec.begin(),end=action_vec.end(); it < end; ++it)
	{
		//if RN falls within cumulative probability bin return the corresponding action
		if(rand_num < it->second)return it->first;
	}

	return -1; //note that this line should never be reached
}
*/
<commit_msg>changed temperature function<commit_after>#include <cmath>
#include <cstdlib>
#include <ctime>
#include <string>
#include <sstream>
#include "StateSpace.h"
#include "PriorityQueue.h"
#include "State.h"
#include "encoder.h"
#include "CreateModule.h"

/**
 * @brief Gives a std::string representation of a primitive type
 *
 * @param x Primitive type such as int, double, long
 * @return std::string conversion of param x
 */
template<typename T> std::string to_string(T x) {
	return static_cast<std::ostringstream&>((std::ostringstream() << std::dec << x)).str();
}

//function to calculate a temperature for the select action function as a function of time
double temperature(unsigned long int t);

//function to select next action
int selectAction(const PriorityQueue<int, double>& a_queue,unsigned long int iterations);

//function to update a q value
void updateQ(StateSpace & space, int action, State & new_state, State & old_state, double alpha, double gamma);

int main()
{
	// STUFF WE DONT UNDERSTAND, AND DONT NEED TO
	//__________________________________________________________________________________________
	//__________________________________________________________________________________________
	// Libraries to load
	std::string bodyLibName = "bodyinfo";
	std::string movementLibName = "movementtools";

	// Name of camera module in library
	std::string bodyModuleName = "BodyInfo";
	std::string movementModuleName = "MovementTools";

	// Set broker name, ip and port, finding first available port from 54000
	const std::string brokerName = "MotionTimingBroker";
	int brokerPort = qi::os::findAvailablePort(54000);
	const std::string brokerIp = "0.0.0.0";

	// Default parent port and ip
	int pport = 9559;
	std::string pip = "127.0.0.1";

	// Need this for SOAP serialisation of floats to work
	setlocale(LC_NUMERIC, "C");

	// Create a broker
	boost::shared_ptr<AL::ALBroker> broker;
	try
	{
		broker = AL::ALBroker::createBroker(
				brokerName,
				brokerIp,
				brokerPort,
				pip,
				pport,
				0);
	}
	// Throw error and quit if a broker could not be created
	catch(...)
	{
		std::cerr << "Failed to connect broker to: "
			  << pip
			  << ":"
			  << pport
			  << std::endl;
		AL::ALBrokerManager::getInstance()->killAllBroker();
		AL::ALBrokerManager::kill();

		return 1;
	}

	// Add the broker to NAOqi
	AL::ALBrokerManager::setInstance(broker->fBrokerManager.lock());
	AL::ALBrokerManager::getInstance()->addBroker(broker);

	CreateModule(movementLibName, movementModuleName, broker, false, true);
	CreateModule(bodyLibName, bodyModuleName, broker, false, true);

	AL::ALProxy bodyInfoProxy(bodyModuleName, pip, pport);
	AL::ALProxy movementToolsProxy(movementModuleName, pip, pport);
	AL::ALMotionProxy motion(pip, pport);
	//__________________________________________________________________________________________
	//__________________________________________________________________________________________
	//END OF STUFF WE DONT UNDERSTAND, BREATHE NOW

	//learning factor
	const double alpha=0.5;
	//discount factor
	const double gamma=0.5;

	//seed rng
	std::srand(static_cast<unsigned int>(std::time(NULL)));

	int action_forwards = FORWARD;
	int action_backwards = BACKWARD;
	int chosen_action = action_forwards;

	//create a priority queue to copy to all the state space priority queues
	PriorityQueue<int,double> initiator_queue(MAX);
	initiator_queue.enqueueWithPriority(action_forwards,0);
	initiator_queue.enqueueWithPriority(action_backwards,0);

	//create encoder
	Encoder encoder;
	encoder.Calibrate();

	//create the state space
	StateSpace space(100,50,initiator_queue);

	//state objects
	State current_state(0,0,FORWARD);
	State old_state(0,0,FORWARD);

	unsigned long int i=0;
	while(true)
	{
		// set current state angle to angle received from encoder
		// and set current state velocity to difference in new and
		// old state angles over some time difference
		current_state.theta= M_PI * (encoder.GetAngle())/180;
		current_state.theta_dot=(current_state.theta - old_state.theta)/700; //Needs actual time
		current_state.robot_state=static_cast<ROBOT_STATE>(chosen_action);

		// call updateQ function with state space, old and current states
		// and learning rate, discount factor
		updateQ(space, chosen_action, old_state, current_state, alpha, gamma);

		// set old_state to current_state
		old_state=current_state;

		// determine chosen_action for current state
		chosen_action=selectAction(space[current_state],i);

		// depending upon chosen action, call robot movement tools proxy with either
		// swingForwards or swingBackwards commands.
		(chosen_action)?movementToolsProxy.callVoid("swingForwards"):movementToolsProxy.callVoid("swingBackwards");

		++i;
	}

	return 1;
}

/**
 * @brief Analog to temperature variable in Boltzmann Distribution.
 *
 * @return current system time in milliseconds
 */
double temperature(unsigned long int t)
{
	return 100000.0*std::exp((-8.0*t*t)/(26000.0*26000.0))+0.1;//0.1 is an offset
	//	^
	//	|
	//make this large
}

/**
 * @brief Selects an action to perform based on probabilities.
 *
 * @param a_queue A priority queue instance storing integral types with double type priorities,
 *		  represents the queue of possible actions with pre-initialised priority levels.
 * @return integer corresponding to chosen action
 */
int selectAction(const PriorityQueue<int, double>& a_queue,unsigned long int iterations) {

	// queue to store action values
	PriorityQueue<int, double> actionQueue(MAX);

	double sum = 0.0;

	// calculate partition function by iterating over action-values
	for (PriorityQueue<int, double>::const_iterator iter = a_queue.begin(), end = a_queue.end(); iter < end; ++iter) {
		sum += std::exp((iter->second) / temperature(iterations));
	}

	// compute Boltzmann factors for action-values and enqueue to actionQueue
	for (PriorityQueue<int, double>::const_iterator iter = a_queue.begin(); iter < a_queue.end(); ++iter) {
		double priority = std::exp(iter.operator*().second / temperature(iterations)) / sum;
		actionQueue.enqueueWithPriority(iter.operator*().first, priority);
	}

	// calculate cumulative probability distribution
	for (PriorityQueue<int, double>::const_iterator it1 = actionQueue.begin()++, it2 = actionQueue.begin(), end = actionQueue.end(); it1 < end; ++it1, ++it2) {
		// change priority of it1->first data item in actionQueue to
		// sum of priorities of it1 and it2 items
		actionQueue.changePriority(it1->first, it1->second + it2->second);
	}

	//generate RN between 0 and 1
	double rand_num = static_cast<double>(rand()) / RAND_MAX;

	// choose action based on random number relation to priorities within action queue
	for (PriorityQueue<int, double>::const_iterator iter = actionQueue.begin(), end = actionQueue.end(); iter < end; ++iter) {
		if (rand_num < iter->second)
			return iter->first;
	}

	return -1; //note that this line should never be reached
}

/**
 * @brief Updates the utility (Q-value) of the system
 *
 * @param space Reference to StateSpace object
 * @param new_state Reference to State instance giving the new system state
 * @param old_state Reference to State instance giving the old system state
 * @param alpha Learning rate of temporal difference learning algorithm
 * @param gamma Discount factor applied to q-learning equation
 */
void updateQ(StateSpace & space, int action, State & new_state, State & old_state, double alpha, double gamma)
{
    //oldQ value reference
    double oldQ = space[old_state].search(action).second;

    //reward given to current state
    double R = new_state.getReward();

    //optimal Q value for new state i.e. first element
    double maxQ = space[new_state].peekFront().second;

    //new Q value determined by Q learning algorithm
    double newQ = oldQ + alpha * (R + (gamma * maxQ) - oldQ);

    // change priority of action to new Q value
    space[old_state].changePriority(action, newQ);
}

/*old select action function in case the new one doesn't work
int selectAction(const PriorityQueue<int,double>& a_queue)
{
	typedef PriorityQueue<int,double> PQ;
	typedef std::vector< std::pair<int, double> > Vec_Pair;
	typedef std::pair<int, double> Pair;

	double sum= 0;
	size_t i = 0;

	size_t size = a_queue.getSize();
	Vec_Pair action_vec(size);

	//Calculate partition function by iterating over action-values
	for(PQ::const_iterator iter = a_queue.begin(),end=a_queue.end(); iter < end; ++iter)
	{
		sum += std::exp((iter->second)/temperature());
	}
	//Calculate boltzmann factors for action-values
	for(Vec_Pair::iterator it = action_vec.begin(),end=action_vec.end(); it < end; ++it)
	{
	    it->first = a_queue[i].first;
	    it->second = std::exp(a_queue[i].second /temperature()) / sum;
	    ++i;
	}

	//calculate cumulative probability distribution
	for(Vec_Pair::iterator it1 = action_vec.begin()++,it2 = action_vec.begin(),end=action_vec.end(); it1 < end; ++it1,++it2)
	{
	    it1->second += it2->second;
	}

	//generate RN between 0 and 1
	double rand_num = static_cast<double>(rand())/ RAND_MAX;

	//select action based on probability
	for(Vec_Pair::iterator it = action_vec.begin(),end=action_vec.end(); it < end; ++it)
	{
		//if RN falls within cumulative probability bin return the corresponding action
		if(rand_num < it->second)return it->first;
	}

	return -1; //note that this line should never be reached
}
*/
<|endoftext|>


<commit_before>/* The Halfling Project - A Graphics Engine and Projects
 *
 * The Halfling Project is the legal property of Adrian Astley
 * Copyright Adrian Astley 2013 - 2014
 */

#include "obj_hfm_converter/util.h"

#include <iostream>

namespace ObjHmfConverter {

std::string ConvertToDDS(const char *filePath, std::tr2::sys::path &baseDirectory, std::tr2::sys::path &rootInputDirectory, std::tr2::sys::path &rootOutputDirectory) {
	std::tr2::sys::path relativePath(filePath);
	std::tr2::sys::path relativeDDSPath(relativePath);
	relativeDDSPath.replace_extension("dds");

	// If the file already exists in the output directory, we don't need to do anything
	std::tr2::sys::path outputFilePath(rootOutputDirectory.file_string() + "\\" + relativeDDSPath.file_string());
	if (exists(outputFilePath)) {
		return relativeDDSPath;
	}

	// Guarantee the output directory exists
	std::tr2::sys::path outputDirectory(outputFilePath.parent_path());
	create_directories(outputDirectory);

	// If input is already dds, but doesn't exist in the output directory, just copy the file to the output
	std::tr2::sys::path inputFilePath(rootInputDirectory.file_string() + "\\" + relativePath.file_string());
	if (_stricmp(relativePath.extension().c_str(), "dds") == 0) {
		copy_file(inputFilePath, outputFilePath);
		return relativeDDSPath;
	}

	// Otherwise, convert the file to DDS
	std::string call = baseDirectory.file_string() + "\\texconv.exe -ft dds -o " + outputDirectory.file_string() + " " + inputFilePath.file_string() + " > NUL";
	std::system(call.c_str());

	return relativeDDSPath;
}

D3D11_USAGE ParseUsageFromString(std::string &inputString) {
	if (_stricmp(inputString.c_str(), "default") == 0) {
		return D3D11_USAGE_DEFAULT;
	} else if (_stricmp(inputString.c_str(), "dynamic") == 0) {
		return D3D11_USAGE_DYNAMIC;
	} else if (_stricmp(inputString.c_str(), "staging") == 0) {
		return D3D11_USAGE_STAGING;
	} else {
		return D3D11_USAGE_IMMUTABLE;
	}
}

aiTextureType ParseTextureTypeFromString(std::string &inputString, aiTextureType defaultType) {
	if (_stricmp(inputString.c_str(), "diffuse") == 0) {
		return aiTextureType_DIFFUSE;
	} else if (_stricmp(inputString.c_str(), "normal") == 0) {
		return aiTextureType_NORMALS;
	} else if (_stricmp(inputString.c_str(), "height") == 0) {
		return aiTextureType_HEIGHT;
	} else if (_stricmp(inputString.c_str(), "displacement") == 0) {
		return aiTextureType_DISPLACEMENT;
	} else if (_stricmp(inputString.c_str(), "alpha") == 0) {
		return aiTextureType_OPACITY;
	} else if (_stricmp(inputString.c_str(), "specColor") == 0) {
		return aiTextureType_SPECULAR;
	} else if (_stricmp(inputString.c_str(), "specPower") == 0) {
		return aiTextureType_SHININESS;
	} else {
		return defaultType;
	}
}

void CreateDefaultIniFile(const char *filePath) {
	std::ofstream fout(filePath);

	// Make sure open was successful
	if (!fout) {
		std::cerr << "File could not be opened";
		return;
	}

	fout << "; Post-processing can automatically calculate the mesh normals and/or tangents"
	        "; If normals already exist, setting GenNormals to true will do nothing\n" <<
	        "; If tangents already exist, setting GenTangents to true will do nothing\n" <<
	        "[Post-Processing]\n" <<
	        "GenNormals = true\n" <<
	        "CalcTangents = true\n" <<
			"\n" <<
	        "; The booleans represent a high level override for these material properties.\n" <<
	        "; If the boolean is false, the property will be set to NULL, even if the property exists within the input model file\n" <<
	        "; If the boolean is true, but the value doesn't exist within the input model file, the property will be set to NULL\n" <<
	        "[MaterialPropertyOverrides]\n" <<
	        "AmbientColor = true\n" <<
	        "DiffuseColor = true\n" <<
	        "SpecColor = true\n" <<
	        "Opacity = true\n" <<
	        "SpecPower = true\n" <<
	        "SpecIntensity = true\n" <<
			"\n" <<
	        "; The booleans represent a high level override for these textures.\n" <<
	        "; If the boolean is false, the texture will be excluded, even if the texture exists within the input model file\n" <<
	        "; If the boolean is true, but the texture doesn't exist within the input model file properties, the texture will still be excluded\n" <<
	        "[TextureOverrides]\n" <<
	        "DiffuseColorMap = true\n" <<
	        "NormalMap = true\n" <<
	        "DisplacementMap = true\n" <<
	        "AlphaMap = true\n" <<
	        "SpecColorMap = true\n" <<
	        "SpecPowerMap = true\n" <<
			"\n" <<
	        "; Usages can be 'default', 'immutable', 'dynamic', or 'staging'\n" <<
	        "; In the case of a mis-spelling, immutable is assumed\n" <<
	        "[BufferDesc]\n" <<
	        "VertexBufferUsage = immutable\n" <<
	        "IndexBufferUsage = immutable\n" <<
			"\n" <<
	        "; TextureMapRedirects allow you to interpret certain textures as other kinds\n" <<
	        "; For example, OBJ doesn't directly support normal maps. Often, you will then see\n" <<
	        "; the normal map in the height (bump) map slot. These options allow you to specify\n" <<
	        "; what texture goes where.\n" <<
	        ";\n" <<
	        "; Any Maps that are excluded are treated as mapping to their own kind\n" <<
	        "; IE. excluding DiffuseColorMap is interpreted as:\n" <<
	        ";       DiffuseColorMap = diffuse\n" <<
	        ";\n" <<
	        "; The available kinds are: 'diffuse', 'normal', 'height', 'displacement', 'alpha', 'specColor', and 'specPower'\n" <<
	        "[TextureMapRedirects]\n" <<
	        "DiffuseColorMap = diffuse\n" <<
	        "NormalMap = normal\n" <<
	        "DisplacementMap = displacement\n" <<
	        "AlphaMap = alpha\n" <<
	        "SpecColorMap = specColor\n" <<
	        "SpecPowerMap = specPower\n";

	fout.flush();
	fout.close();
}

} // End of namespace ObjHmfConverter
<commit_msg>HMF_CONVERTER: Create a namespace alias for the std::tr2::sys::path class<commit_after>/* The Halfling Project - A Graphics Engine and Projects
 *
 * The Halfling Project is the legal property of Adrian Astley
 * Copyright Adrian Astley 2013 - 2014
 */

#include "obj_hfm_converter/util.h"

#include <iostream>

using filepath = std::tr2::sys::path;

namespace ObjHmfConverter {

std::string ConvertToDDS(const char *filePath, filepath &baseDirectory, filepath &rootInputDirectory, filepath &rootOutputDirectory) {
	filepath relativePath(filePath);
	filepath relativeDDSPath(relativePath);
	relativeDDSPath.replace_extension("dds");

	// If the file already exists in the output directory, we don't need to do anything
	filepath outputFilePath(rootOutputDirectory.file_string() + "\\" + relativeDDSPath.file_string());
	if (exists(outputFilePath)) {
		return relativeDDSPath;
	}

	// Guarantee the output directory exists
	filepath outputDirectory(outputFilePath.parent_path());
	create_directories(outputDirectory);

	// If input is already dds, but doesn't exist in the output directory, just copy the file to the output
	filepath inputFilePath(rootInputDirectory.file_string() + "\\" + relativePath.file_string());
	if (_stricmp(relativePath.extension().c_str(), "dds") == 0) {
		copy_file(inputFilePath, outputFilePath);
		return relativeDDSPath;
	}

	// Otherwise, convert the file to DDS
	std::string call = baseDirectory.file_string() + "\\texconv.exe -ft dds -o " + outputDirectory.file_string() + " " + inputFilePath.file_string() + " > NUL";
	std::system(call.c_str());

	return relativeDDSPath;
}

D3D11_USAGE ParseUsageFromString(std::string &inputString) {
	if (_stricmp(inputString.c_str(), "default") == 0) {
		return D3D11_USAGE_DEFAULT;
	} else if (_stricmp(inputString.c_str(), "dynamic") == 0) {
		return D3D11_USAGE_DYNAMIC;
	} else if (_stricmp(inputString.c_str(), "staging") == 0) {
		return D3D11_USAGE_STAGING;
	} else {
		return D3D11_USAGE_IMMUTABLE;
	}
}

aiTextureType ParseTextureTypeFromString(std::string &inputString, aiTextureType defaultType) {
	if (_stricmp(inputString.c_str(), "diffuse") == 0) {
		return aiTextureType_DIFFUSE;
	} else if (_stricmp(inputString.c_str(), "normal") == 0) {
		return aiTextureType_NORMALS;
	} else if (_stricmp(inputString.c_str(), "height") == 0) {
		return aiTextureType_HEIGHT;
	} else if (_stricmp(inputString.c_str(), "displacement") == 0) {
		return aiTextureType_DISPLACEMENT;
	} else if (_stricmp(inputString.c_str(), "alpha") == 0) {
		return aiTextureType_OPACITY;
	} else if (_stricmp(inputString.c_str(), "specColor") == 0) {
		return aiTextureType_SPECULAR;
	} else if (_stricmp(inputString.c_str(), "specPower") == 0) {
		return aiTextureType_SHININESS;
	} else {
		return defaultType;
	}
}

void CreateDefaultIniFile(const char *filePath) {
	std::ofstream fout(filePath);

	// Make sure open was successful
	if (!fout) {
		std::cerr << "File could not be opened";
		return;
	}

	fout << "; Post-processing can automatically calculate the mesh normals and/or tangents"
	        "; If normals already exist, setting GenNormals to true will do nothing\n" <<
	        "; If tangents already exist, setting GenTangents to true will do nothing\n" <<
	        "[Post-Processing]\n" <<
	        "GenNormals = true\n" <<
	        "CalcTangents = true\n" <<
			"\n" <<
	        "; The booleans represent a high level override for these material properties.\n" <<
	        "; If the boolean is false, the property will be set to NULL, even if the property exists within the input model file\n" <<
	        "; If the boolean is true, but the value doesn't exist within the input model file, the property will be set to NULL\n" <<
	        "[MaterialPropertyOverrides]\n" <<
	        "AmbientColor = true\n" <<
	        "DiffuseColor = true\n" <<
	        "SpecColor = true\n" <<
	        "Opacity = true\n" <<
	        "SpecPower = true\n" <<
	        "SpecIntensity = true\n" <<
			"\n" <<
	        "; The booleans represent a high level override for these textures.\n" <<
	        "; If the boolean is false, the texture will be excluded, even if the texture exists within the input model file\n" <<
	        "; If the boolean is true, but the texture doesn't exist within the input model file properties, the texture will still be excluded\n" <<
	        "[TextureOverrides]\n" <<
	        "DiffuseColorMap = true\n" <<
	        "NormalMap = true\n" <<
	        "DisplacementMap = true\n" <<
	        "AlphaMap = true\n" <<
	        "SpecColorMap = true\n" <<
	        "SpecPowerMap = true\n" <<
			"\n" <<
	        "; Usages can be 'default', 'immutable', 'dynamic', or 'staging'\n" <<
	        "; In the case of a mis-spelling, immutable is assumed\n" <<
	        "[BufferDesc]\n" <<
	        "VertexBufferUsage = immutable\n" <<
	        "IndexBufferUsage = immutable\n" <<
			"\n" <<
	        "; TextureMapRedirects allow you to interpret certain textures as other kinds\n" <<
	        "; For example, OBJ doesn't directly support normal maps. Often, you will then see\n" <<
	        "; the normal map in the height (bump) map slot. These options allow you to specify\n" <<
	        "; what texture goes where.\n" <<
	        ";\n" <<
	        "; Any Maps that are excluded are treated as mapping to their own kind\n" <<
	        "; IE. excluding DiffuseColorMap is interpreted as:\n" <<
	        ";       DiffuseColorMap = diffuse\n" <<
	        ";\n" <<
	        "; The available kinds are: 'diffuse', 'normal', 'height', 'displacement', 'alpha', 'specColor', and 'specPower'\n" <<
	        "[TextureMapRedirects]\n" <<
	        "DiffuseColorMap = diffuse\n" <<
	        "NormalMap = normal\n" <<
	        "DisplacementMap = displacement\n" <<
	        "AlphaMap = alpha\n" <<
	        "SpecColorMap = specColor\n" <<
	        "SpecPowerMap = specPower\n";

	fout.flush();
	fout.close();
}

} // End of namespace ObjHmfConverter
<|endoftext|>