<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.                  *
 **************************************************************************/

#include "AliAnalysisManager.h"
#include "AliAnalysisTaskSE.h"
#include "AliAnalysisTaskPHOSTriggerQA.h"
#include "AliESDCaloCluster.h"
#include "AliPHOSGeometry.h"
#include "AliESDEvent.h"
#include "AliESDCaloCells.h"
#include "AliLog.h"
#include "TObjArray.h"
#include "TList.h"
#include "TH1.h"
#include "TH2.h"

// QA of PHOS Trigger data.
//...
// Author: Boris Polishchuk
// Date  : 06.02.2012

ClassImp(AliAnalysisTaskPHOSTriggerQA)

//________________________________________________________________________
AliAnalysisTaskPHOSTriggerQA::AliAnalysisTaskPHOSTriggerQA() : AliAnalysisTaskSE(),
  fOutputContainer(0),fPHOSGeo(0),fEventCounter(0),fL1Threshold(-1)
{
  //Default constructor.
  // Initialize the PHOS geometry
  fPHOSGeo = AliPHOSGeometry::GetInstance("IHEP") ;

}

//________________________________________________________________________
AliAnalysisTaskPHOSTriggerQA::AliAnalysisTaskPHOSTriggerQA(const char *name, Int_t L1_threshold)
: AliAnalysisTaskSE(name),
  fOutputContainer(0),fPHOSGeo(0),fEventCounter(0),fL1Threshold(L1_threshold)
{

  // Output slots #0 write into a TH1 container
  DefineOutput(1,TList::Class());

  // Initialize the PHOS geometry
  fPHOSGeo = AliPHOSGeometry::GetInstance("IHEP") ;

}

//________________________________________________________________________
void AliAnalysisTaskPHOSTriggerQA::UserCreateOutputObjects()
{
  // Create histograms
  // Called once

  // ESD histograms
  if(fOutputContainer != NULL){
    delete fOutputContainer;
  }

  fOutputContainer = new TList();
  fOutputContainer->SetOwner(kTRUE);

  //Bin 1: total number of processed events.
  //Bin 2: number of events contained PHOS trigger digits.
  fOutputContainer->Add(new TH1F("hNev","Number of events",10,0.,10.));

  char key[55],titl[55];
  Int_t nCols = 56, nRows = 64;

  Int_t    nPtPhot  = 1000 ;
  Double_t ptPhotMax =  100. ;

  Int_t nTrMax = 1200;
  Float_t trMax = 600.;

  fOutputContainer->Add(new TH1F("hNtr","Number of fired 4x4 regions per event",nTrMax,0.,trMax));

  for(Int_t sm=1; sm<5; sm++) {

    snprintf(key,55,"hNtrSM%d",sm);
    snprintf(titl,55,"Number of fired 4x4 regions in SM%d",5-sm);
    fOutputContainer->Add(new TH1F(key,titl,nTrMax/3,0.,trMax/3));

    snprintf(key,55,"h4x4SM%d",sm);
    snprintf(titl,55,"SM%d 4x4 occupancy",5-sm);
    fOutputContainer->Add(new TH2F(key,titl,nRows,0.,nRows,nCols,0.,nCols));

    snprintf(key,55,"h4x4CluSM%d",sm);
    snprintf(titl,55,"SM%d 4x4 occupancy associated with clusters (E>2GeV)",5-sm);
    fOutputContainer->Add(new TH2F(key,titl,nRows,0.,nRows,nCols,0.,nCols));

    snprintf(key,55,"hCluSM%d",sm);
    snprintf(titl,55,"SM%d cluster occupancy",5-sm);
    fOutputContainer->Add(new TH2F(key,titl,nRows,0.,nRows,nCols,0.,nCols));

    snprintf(key,55,"hCluTSM%d",sm);
    snprintf(titl,55,"SM%d triggered cluster occupancy",5-sm);
    fOutputContainer->Add(new TH2F(key,titl,nRows,0.,nRows,nCols,0.,nCols));

    snprintf(key,55,"hPhotAllSM%d",sm);
    snprintf(titl,55,"SM%d cluster energy",5-sm);
    fOutputContainer->Add(new TH1F(key,titl,nPtPhot,0.,ptPhotMax));

    for(Int_t iTRU=1; iTRU<=8; iTRU++) {
      snprintf(key,55,"hPhotAllSM%dTRU%d",sm,iTRU);
      snprintf(titl,55,"SM%d: clusters energy in TRU%d",5-sm,iTRU);
      fOutputContainer->Add(new TH1F(key,titl,nPtPhot,0.,ptPhotMax));
    }

    snprintf(key,55,"hPhotTrigSM%d",sm);
    snprintf(titl,55,"SM%d triggered cluster energy",5-sm);
    fOutputContainer->Add(new TH1F(key,titl,nPtPhot,0.,ptPhotMax));

    for(Int_t iTRU=1; iTRU<=8; iTRU++) {
      snprintf(key,55,"hPhotTrigSM%dTRU%d",sm,iTRU);
      snprintf(titl,55,"SM%d: triggered clusters energy in TRU%d",5-sm,iTRU);
      fOutputContainer->Add(new TH1F(key,titl,nPtPhot,0.,ptPhotMax));
    }

  }

  PostData(1, fOutputContainer);

}

//________________________________________________________________________
void AliAnalysisTaskPHOSTriggerQA::UserExec(Option_t *)
{
  // Main loop, called for each event
  // Analyze ESD/AOD

  AliESDEvent *event = dynamic_cast<AliESDEvent*>(InputEvent());

  if (!event) {
    Printf("ERROR: Could not retrieve event");
    PostData(1, fOutputContainer);
    return;
  }

  FillHistogram("hNev",0.); // all events
  fEventCounter++;

  AliESDCaloTrigger* trgESD = event->GetCaloTrigger("PHOS");
  trgESD->Reset();

  if(trgESD->GetEntries())
    FillHistogram("hNev",1.); // triggered events

  TString trigClasses = event->GetFiredTriggerClasses();
  printf("\nEvent %d: %d non-zero trigger digits %s\n",
	 fEventCounter,trgESD->GetEntries(),trigClasses.Data());

  // Get PHOS rotation matrices from ESD and set them to the PHOS geometry
  char key[55] ;

  if(fEventCounter == 0) {
    for(Int_t mod=0; mod<5; mod++) {
      if(!event->GetPHOSMatrix(mod)) continue;
      fPHOSGeo->SetMisalMatrix(event->GetPHOSMatrix(mod),mod) ;
    }
  }

  Int_t multClu = event->GetNumberOfCaloClusters();
  AliESDCaloCells *phsCells = event->GetPHOSCells();

  Int_t inPHOS[3] = {};
  Int_t ntr = 0;

  //Loop over 4x4 fired regions
  while(trgESD->Next()) {

    // L1 threshold: -1-L0, 0-high, 1-medium, 2-low
    if(trgESD->GetL1TimeSum() != fL1Threshold) continue;
    ntr++;

    Int_t tmod,tabsId; // "Online" module number, bottom-left 4x4 edge cell absId
    trgESD->GetPosition(tmod,tabsId);

    Int_t trelid[4] ;
    fPHOSGeo->AbsToRelNumbering(tabsId,trelid);

    snprintf(key,55,"h4x4SM%d",trelid[0]);
    FillHistogram(key,trelid[2]-1,trelid[3]-1);

    inPHOS[trelid[0]-1]++;

    for (Int_t i=0; i<multClu; i++) {

      AliESDCaloCluster *c1 = event->GetCaloCluster(i);
      if(!c1->IsPHOS()) continue;
      if(c1->GetType() == AliESDCaloCluster::kPHOSCharged) continue; // reject CPV cluster

      if(c1->E()<0.3) continue;
      if(c1->GetNCells()<3) continue ;

      Int_t maxId, relid[4];
      MaxEnergyCellPos(phsCells,c1,maxId);

      fPHOSGeo->AbsToRelNumbering(maxId, relid);
      snprintf(key,55,"hPhotAllSM%d",relid[0]);
      FillHistogram(key,c1->E());

      snprintf(key,55,"hPhotAllSM%dTRU%d",relid[0],GetTRUNum(relid[2]-1,relid[3]-1));
      FillHistogram(key,c1->E());

      snprintf(key,55,"hCluSM%d",relid[0]);
      FillHistogram(key,relid[2]-1,relid[3]-1);

      if( Matched(trelid,relid) ) {

	snprintf(key,55,"hPhotTrigSM%d",relid[0]);
	FillHistogram(key,c1->E());

	snprintf(key,55,"hPhotTrigSM%dTRU%d",relid[0],GetTRUNum(relid[2]-1,relid[3]-1));
	FillHistogram(key,c1->E());

	snprintf(key,55,"hCluTSM%d",relid[0]);
	FillHistogram(key,relid[2]-1,relid[3]-1);

	if(c1->E()>2.) { // Eclu > 2 GeV
	  snprintf(key,55,"h4x4CluSM%d",trelid[0]);
	  FillHistogram(key,trelid[2]-1,trelid[3]-1);
	}
	continue;
      }

    }
  } //while(trgESD->Next())

  FillHistogram("hNtr",ntr); // number of selected triggers per event

  for(Int_t sm=1; sm<4; sm++) {
    snprintf(key,55,"hNtrSM%d",sm);
    if(inPHOS[sm-1]) FillHistogram(key,inPHOS[sm-1]);
  }

  // Post output data.
  PostData(1, fOutputContainer);

}

//_____________________________________________________________________________
void AliAnalysisTaskPHOSTriggerQA::FillHistogram(const char * key,Double_t x)const{
  //FillHistogram
  TH1I * tmpI = dynamic_cast<TH1I*>(fOutputContainer->FindObject(key)) ;
  if(tmpI){
    tmpI->Fill(x) ;
    return ;
  }
  TH1F * tmpF = dynamic_cast<TH1F*>(fOutputContainer->FindObject(key)) ;
  if(tmpF){
    tmpF->Fill(x) ;
    return ;
  }
  TH1D * tmpD = dynamic_cast<TH1D*>(fOutputContainer->FindObject(key)) ;
  if(tmpD){
    tmpD->Fill(x) ;
    return ;
  }
  AliInfo(Form("can not find histogram <%s> ",key)) ;
}
//_____________________________________________________________________________
void AliAnalysisTaskPHOSTriggerQA::FillHistogram(const char * key,Double_t x,Double_t y)const{
  //FillHistogram
  TObject * tmp = fOutputContainer->FindObject(key) ;
  if(!tmp){
    AliInfo(Form("can not find histogram <%s> ",key)) ;
    return ;
  }
  if(tmp->IsA() == TClass::GetClass("TH1F")){
    ((TH1F*)tmp)->Fill(x,y) ;
    return ;
  }
  if(tmp->IsA() == TClass::GetClass("TH2F")){
    ((TH2F*)tmp)->Fill(x,y) ;
    return ;
  }
  AliError(Form("Calling FillHistogram with 2 parameters for histo <%s> of type %s",key,tmp->IsA()->GetName())) ;
}

//_____________________________________________________________________________
void AliAnalysisTaskPHOSTriggerQA::MaxEnergyCellPos(AliESDCaloCells *cells, AliESDCaloCluster* clu, Int_t& maxId)
{
  Double_t eMax = -111;

  for (Int_t iDig=0; iDig< clu->GetNCells(); iDig++) {
    Int_t cellAbsId = clu->GetCellAbsId(iDig);
    Double_t eCell = cells->GetCellAmplitude(cellAbsId)*clu->GetCellAmplitudeFraction(iDig);
    if(eCell>eMax)  {
      eMax = eCell;
      maxId = cellAbsId;
    }
  }

}

//_____________________________________________________________________________
Bool_t AliAnalysisTaskPHOSTriggerQA::Matched(Int_t *trig_relid, Int_t *cluster_relid)
{
  //Returns kTRUE if cluster position coincides with 4x4 position.

  if( trig_relid[0] != cluster_relid[0] )            return kFALSE; // different modules!
  if( TMath::Abs(trig_relid[2]-cluster_relid[2])>3 ) return kFALSE; // X-distance too large!
  if( TMath::Abs(trig_relid[3]-cluster_relid[3])>3 ) return kFALSE; // Z-distance too large!

  return kTRUE;
}

//_______________________________________________________________________________
Int_t AliAnalysisTaskPHOSTriggerQA::GetTRUNum(Int_t cellX, Int_t cellZ)
{
  //Return TRU region number for given cell.
  //cellX: [0-63], cellZ: [0-55]

  Int_t iTRU=-111;

  //RCU0: TRU 1,2
  if(0<=cellX&&cellX<16) {

    if(0<=cellZ&&cellZ<28) iTRU=2;
    else iTRU=1;
  }

  //RCU1: TRU 3,4
  if(16<=cellX&&cellX<32) {

    if(0<=cellZ&&cellZ<28) iTRU=4;
    else iTRU=3;
  }

  //RCU2: TRU 5,6
  if(32<=cellX&&cellX<48) {

    if(0<=cellZ&&cellZ<28) iTRU=6;
    else iTRU=5;
  }

  //RCU3: TRU 7,8
  if(48<=cellX&&cellX<64) {

    if(0<=cellZ&&cellZ<28) iTRU=8;
    else iTRU=7;
  }

  return iTRU;
}
<commit_msg>Wrong multiple counting of "triggered" clusters fixed.<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.                  *
 **************************************************************************/

#include "AliAnalysisManager.h"
#include "AliAnalysisTaskSE.h"
#include "AliAnalysisTaskPHOSTriggerQA.h"
#include "AliESDCaloCluster.h"
#include "AliPHOSGeometry.h"
#include "AliESDEvent.h"
#include "AliESDCaloCells.h"
#include "AliLog.h"
#include "TObjArray.h"
#include "TList.h"
#include "TH1.h"
#include "TH2.h"

// QA of PHOS Trigger data.
//...
// Author: Boris Polishchuk
// Date  : 06.02.2012

ClassImp(AliAnalysisTaskPHOSTriggerQA)

//________________________________________________________________________
AliAnalysisTaskPHOSTriggerQA::AliAnalysisTaskPHOSTriggerQA() : AliAnalysisTaskSE(),
  fOutputContainer(0),fPHOSGeo(0),fEventCounter(0),fL1Threshold(-1)
{
  //Default constructor.
  // Initialize the PHOS geometry
  fPHOSGeo = AliPHOSGeometry::GetInstance("IHEP") ;

}

//________________________________________________________________________
AliAnalysisTaskPHOSTriggerQA::AliAnalysisTaskPHOSTriggerQA(const char *name, Int_t L1_threshold)
: AliAnalysisTaskSE(name),
  fOutputContainer(0),fPHOSGeo(0),fEventCounter(0),fL1Threshold(L1_threshold)
{

  // Output slots #0 write into a TH1 container
  DefineOutput(1,TList::Class());

  // Initialize the PHOS geometry
  fPHOSGeo = AliPHOSGeometry::GetInstance("IHEP") ;

}

//________________________________________________________________________
void AliAnalysisTaskPHOSTriggerQA::UserCreateOutputObjects()
{
  // Create histograms
  // Called once

  // ESD histograms
  if(fOutputContainer != NULL){
    delete fOutputContainer;
  }

  fOutputContainer = new TList();
  fOutputContainer->SetOwner(kTRUE);

  //Bin 1: total number of processed events.
  //Bin 2: number of events contained PHOS trigger digits.
  fOutputContainer->Add(new TH1F("hNev","Number of events",10,0.,10.));

  char key[55],titl[55];
  Int_t nCols = 56, nRows = 64;

  Int_t    nPtPhot  = 1000 ;
  Double_t ptPhotMax =  100. ;

  Int_t nTrMax = 1200;
  Float_t trMax = 600.;

  fOutputContainer->Add(new TH1F("hNtr","Number of fired 4x4 regions per event",nTrMax,0.,trMax));

  for(Int_t sm=1; sm<5; sm++) {

    snprintf(key,55,"hNtrSM%d",sm);
    snprintf(titl,55,"Number of fired 4x4 regions in SM%d",5-sm);
    fOutputContainer->Add(new TH1F(key,titl,nTrMax/3,0.,trMax/3));

    snprintf(key,55,"h4x4SM%d",sm);
    snprintf(titl,55,"SM%d 4x4 occupancy",5-sm);
    fOutputContainer->Add(new TH2F(key,titl,nRows,0.,nRows,nCols,0.,nCols));

    snprintf(key,55,"h4x4CluSM%d",sm);
    snprintf(titl,55,"SM%d 4x4 occupancy associated with clusters (E>2GeV)",5-sm);
    fOutputContainer->Add(new TH2F(key,titl,nRows,0.,nRows,nCols,0.,nCols));

    snprintf(key,55,"hCluSM%d",sm);
    snprintf(titl,55,"SM%d cluster occupancy",5-sm);
    fOutputContainer->Add(new TH2F(key,titl,nRows,0.,nRows,nCols,0.,nCols));

    snprintf(key,55,"hCluTSM%d",sm);
    snprintf(titl,55,"SM%d triggered cluster occupancy",5-sm);
    fOutputContainer->Add(new TH2F(key,titl,nRows,0.,nRows,nCols,0.,nCols));

    snprintf(key,55,"hPhotAllSM%d",sm);
    snprintf(titl,55,"SM%d cluster energy",5-sm);
    fOutputContainer->Add(new TH1F(key,titl,nPtPhot,0.,ptPhotMax));

    for(Int_t iTRU=1; iTRU<=8; iTRU++) {
      snprintf(key,55,"hPhotAllSM%dTRU%d",sm,iTRU);
      snprintf(titl,55,"SM%d: clusters energy in TRU%d",5-sm,iTRU);
      fOutputContainer->Add(new TH1F(key,titl,nPtPhot,0.,ptPhotMax));
    }

    snprintf(key,55,"hPhotTrigSM%d",sm);
    snprintf(titl,55,"SM%d triggered cluster energy",5-sm);
    fOutputContainer->Add(new TH1F(key,titl,nPtPhot,0.,ptPhotMax));

    for(Int_t iTRU=1; iTRU<=8; iTRU++) {
      snprintf(key,55,"hPhotTrigSM%dTRU%d",sm,iTRU);
      snprintf(titl,55,"SM%d: triggered clusters energy in TRU%d",5-sm,iTRU);
      fOutputContainer->Add(new TH1F(key,titl,nPtPhot,0.,ptPhotMax));
    }

  }

  PostData(1, fOutputContainer);

}

//________________________________________________________________________
void AliAnalysisTaskPHOSTriggerQA::UserExec(Option_t *)
{
  // Main loop, called for each event
  // Analyze ESD/AOD

  AliESDEvent *event = dynamic_cast<AliESDEvent*>(InputEvent());

  if (!event) {
    Printf("ERROR: Could not retrieve event");
    PostData(1, fOutputContainer);
    return;
  }

  FillHistogram("hNev",0.); // all events
  fEventCounter++;

  AliESDCaloTrigger* trgESD = event->GetCaloTrigger("PHOS");
  trgESD->Reset();

  if(trgESD->GetEntries())
    FillHistogram("hNev",1.); // triggered events

  TString trigClasses = event->GetFiredTriggerClasses();
  printf("\nEvent %d: %d non-zero trigger digits %s\n",
	 fEventCounter,trgESD->GetEntries(),trigClasses.Data());

  // Get PHOS rotation matrices from ESD and set them to the PHOS geometry
  char key[55] ;

  if(fEventCounter == 0) {
    for(Int_t mod=0; mod<5; mod++) {
      if(!event->GetPHOSMatrix(mod)) continue;
      fPHOSGeo->SetMisalMatrix(event->GetPHOSMatrix(mod),mod) ;
    }
  }

  Int_t multClu = event->GetNumberOfCaloClusters();
  AliESDCaloCells *phsCells = event->GetPHOSCells();

  Int_t inPHOS[3] = {};
  Int_t ntr = 0;

  Int_t kUsedCluster[] = {multClu*0};

  //Loop over 4x4 fired regions
  while(trgESD->Next()) {

    // L1 threshold: -1-L0, 0-high, 1-medium, 2-low
    if(trgESD->GetL1TimeSum() != fL1Threshold) continue;
    ntr++;

    Int_t tmod,tabsId; // "Online" module number, bottom-left 4x4 edge cell absId
    trgESD->GetPosition(tmod,tabsId);

    Int_t trelid[4] ;
    fPHOSGeo->AbsToRelNumbering(tabsId,trelid);

    snprintf(key,55,"h4x4SM%d",trelid[0]);
    FillHistogram(key,trelid[2]-1,trelid[3]-1);

    inPHOS[trelid[0]-1]++;

    for (Int_t i=0; i<multClu; i++) {

      AliESDCaloCluster *c1 = event->GetCaloCluster(i);
      if(kUsedCluster[i]) continue; // already matched to some trigger patch

      if(!c1->IsPHOS()) continue;
      if(c1->GetType() == AliESDCaloCluster::kPHOSCharged) continue; // reject CPV cluster

      if(c1->E()<0.3) continue;
      if(c1->GetNCells()<3) continue ;

      Int_t maxId, relid[4];
      MaxEnergyCellPos(phsCells,c1,maxId);

      fPHOSGeo->AbsToRelNumbering(maxId, relid);
      snprintf(key,55,"hPhotAllSM%d",relid[0]);
      FillHistogram(key,c1->E());

      snprintf(key,55,"hPhotAllSM%dTRU%d",relid[0],GetTRUNum(relid[2]-1,relid[3]-1));
      FillHistogram(key,c1->E());

      snprintf(key,55,"hCluSM%d",relid[0]);
      FillHistogram(key,relid[2]-1,relid[3]-1);

      if( Matched(trelid,relid) ) {

	kUsedCluster[i] = 1;

	snprintf(key,55,"hPhotTrigSM%d",relid[0]);
	FillHistogram(key,c1->E());

	snprintf(key,55,"hPhotTrigSM%dTRU%d",relid[0],GetTRUNum(relid[2]-1,relid[3]-1));
	FillHistogram(key,c1->E());

	snprintf(key,55,"hCluTSM%d",relid[0]);
	FillHistogram(key,relid[2]-1,relid[3]-1);

	if(c1->E()>2.) { // Eclu > 2 GeV
	  snprintf(key,55,"h4x4CluSM%d",trelid[0]);
	  FillHistogram(key,trelid[2]-1,trelid[3]-1);
	}
	continue;
      }

    }
  } //while(trgESD->Next())

  FillHistogram("hNtr",ntr); // number of selected triggers per event

  for(Int_t sm=1; sm<4; sm++) {
    snprintf(key,55,"hNtrSM%d",sm);
    if(inPHOS[sm-1]) FillHistogram(key,inPHOS[sm-1]);
  }

  // Post output data.
  PostData(1, fOutputContainer);

}

//_____________________________________________________________________________
void AliAnalysisTaskPHOSTriggerQA::FillHistogram(const char * key,Double_t x)const{
  //FillHistogram
  TH1I * tmpI = dynamic_cast<TH1I*>(fOutputContainer->FindObject(key)) ;
  if(tmpI){
    tmpI->Fill(x) ;
    return ;
  }
  TH1F * tmpF = dynamic_cast<TH1F*>(fOutputContainer->FindObject(key)) ;
  if(tmpF){
    tmpF->Fill(x) ;
    return ;
  }
  TH1D * tmpD = dynamic_cast<TH1D*>(fOutputContainer->FindObject(key)) ;
  if(tmpD){
    tmpD->Fill(x) ;
    return ;
  }
  AliInfo(Form("can not find histogram <%s> ",key)) ;
}
//_____________________________________________________________________________
void AliAnalysisTaskPHOSTriggerQA::FillHistogram(const char * key,Double_t x,Double_t y)const{
  //FillHistogram
  TObject * tmp = fOutputContainer->FindObject(key) ;
  if(!tmp){
    AliInfo(Form("can not find histogram <%s> ",key)) ;
    return ;
  }
  if(tmp->IsA() == TClass::GetClass("TH1F")){
    ((TH1F*)tmp)->Fill(x,y) ;
    return ;
  }
  if(tmp->IsA() == TClass::GetClass("TH2F")){
    ((TH2F*)tmp)->Fill(x,y) ;
    return ;
  }
  AliError(Form("Calling FillHistogram with 2 parameters for histo <%s> of type %s",key,tmp->IsA()->GetName())) ;
}

//_____________________________________________________________________________
void AliAnalysisTaskPHOSTriggerQA::MaxEnergyCellPos(AliESDCaloCells *cells, AliESDCaloCluster* clu, Int_t& maxId)
{
  Double_t eMax = -111;

  for (Int_t iDig=0; iDig< clu->GetNCells(); iDig++) {
    Int_t cellAbsId = clu->GetCellAbsId(iDig);
    Double_t eCell = cells->GetCellAmplitude(cellAbsId)*clu->GetCellAmplitudeFraction(iDig);
    if(eCell>eMax)  {
      eMax = eCell;
      maxId = cellAbsId;
    }
  }

}

//_____________________________________________________________________________
Bool_t AliAnalysisTaskPHOSTriggerQA::Matched(Int_t *trig_relid, Int_t *cluster_relid)
{
  //Returns kTRUE if cluster position coincides with 4x4 position.

  if( trig_relid[0] != cluster_relid[0] )            return kFALSE; // different modules!
  if( TMath::Abs(trig_relid[2]-cluster_relid[2])>3 ) return kFALSE; // X-distance too large!
  if( TMath::Abs(trig_relid[3]-cluster_relid[3])>3 ) return kFALSE; // Z-distance too large!

  return kTRUE;
}

//_______________________________________________________________________________
Int_t AliAnalysisTaskPHOSTriggerQA::GetTRUNum(Int_t cellX, Int_t cellZ)
{
  //Return TRU region number for given cell.
  //cellX: [0-63], cellZ: [0-55]

  Int_t iTRU=-111;

  //RCU0: TRU 1,2
  if(0<=cellX&&cellX<16) {

    if(0<=cellZ&&cellZ<28) iTRU=2;
    else iTRU=1;
  }

  //RCU1: TRU 3,4
  if(16<=cellX&&cellX<32) {

    if(0<=cellZ&&cellZ<28) iTRU=4;
    else iTRU=3;
  }

  //RCU2: TRU 5,6
  if(32<=cellX&&cellX<48) {

    if(0<=cellZ&&cellZ<28) iTRU=6;
    else iTRU=5;
  }

  //RCU3: TRU 7,8
  if(48<=cellX&&cellX<64) {

    if(0<=cellZ&&cellZ<28) iTRU=8;
    else iTRU=7;
  }

  return iTRU;
}
<|endoftext|>


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

#include "au/ThreadManager.h"

#include "engine/MemoryManager.h"
#include "engine/MemoryRequest.h"

#include "xmlparser/xmlParser.h"

#include "samson/client/SamsonClient.h"

#include "unitTest/common_engine_test.h"

#include "samson/common/ports.h"           // for SAMSON_WORKER_PORT

TEST(samson_client, test_1 )
{
   // SamsonClient to play with..
   samson::SamsonClient* samson_client = init_samson_client_test();

   // Connect to samsonWorker
   au::ErrorManager error;
   samson_client->initConnection( &error , "localhost" , SAMSON_WORKER_PORT , "anonymous" , "anonymous" );

   EXPECT_EQ( error.isActivated() , false) << "Error connecting samsonClient to samsonWorker";

   // Close samson client test
   close_samson_client_test( samson_client );

}

TEST(samson_client, DISABLED_test_2 )
{

   // SamsonClient to play with..
   samson::SamsonClient* samson_client = init_samson_client_test();

   // Connect to samsonWorker
   au::ErrorManager error;
   samson_client->initConnection( &error , "localhost" , SAMSON_WORKER_PORT , "anonymous" , "anonymous" );

   ASSERT_TRUE(samson_client->connection_ready()) << "Connection not ready";

   // Close samson client test
   close_samson_client_test( samson_client );
}
<commit_msg>Test for SamsonClient. One test worked, let's try with the second one<commit_after>
#include "gtest/gtest.h"

#include "au/ThreadManager.h"

#include "engine/MemoryManager.h"
#include "engine/MemoryRequest.h"

#include "xmlparser/xmlParser.h"

#include "samson/client/SamsonClient.h"

#include "unitTest/common_engine_test.h"

#include "samson/common/ports.h"           // for SAMSON_WORKER_PORT

TEST(samson_client, test_1 )
{
   // SamsonClient to play with..
   samson::SamsonClient* samson_client = init_samson_client_test();

   // Connect to samsonWorker
   au::ErrorManager error;
   samson_client->initConnection( &error , "localhost" , SAMSON_WORKER_PORT , "anonymous" , "anonymous" );

   EXPECT_EQ( error.isActivated() , false) << "Error connecting samsonClient to samsonWorker";

   // Close samson client test
   close_samson_client_test( samson_client );

}

TEST(samson_client, test_2 )
{

   // SamsonClient to play with..
   samson::SamsonClient* samson_client = init_samson_client_test();

   // Connect to samsonWorker
   au::ErrorManager error;
   samson_client->initConnection( &error , "localhost" , SAMSON_WORKER_PORT , "anonymous" , "anonymous" );

   ASSERT_TRUE(samson_client->connection_ready()) << "Connection not ready";

   // Close samson client test
   close_samson_client_test( samson_client );
}
<|endoftext|>


<commit_before>/*=============================================================================

  Library: CTK

  Copyright (c) German Cancer Research Center,
    Division of Medical and Biological Informatics

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

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

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

=============================================================================*/

// Qt includes
#include <QtPlugin>
#include <QRect>
#include <QDebug>
#include <QPushButton>
#include <QApplication>
#include <QLabel>

// CTK includes
#include "ctkDICOMImage.h"
#include "ctkExampleDicomAppLogic_p.h"
#include "ctkExampleDicomAppPlugin_p.h"

// DCMTK includes
#include <dcmimage.h>

//----------------------------------------------------------------------------
ctkExampleDicomAppLogic::ctkExampleDicomAppLogic()
  : HostTracker(ctkExampleDicomAppPlugin::getPluginContext()), Button(0)
{
  this->HostTracker.open();

  connect(this, SIGNAL(stateChanged(int)), this, SLOT(changeState(int)), Qt::QueuedConnection);
  emit stateChanged(ctkDicomAppHosting::IDLE);
}

//----------------------------------------------------------------------------
ctkExampleDicomAppLogic::~ctkExampleDicomAppLogic()
{
  ctkPluginContext* context = ctkExampleDicomAppPlugin::getPluginContext();
  QList <QSharedPointer<ctkPlugin> > plugins = context->getPlugins();
  for (int i = 0; i < plugins.size(); ++i)
  {
    qDebug() << plugins.at(i)->getSymbolicName ();
  }
}

//----------------------------------------------------------------------------
ctkDicomAppHosting::State ctkExampleDicomAppLogic::getState()
{
  return ctkDicomAppHosting::IDLE;
}

//----------------------------------------------------------------------------
bool ctkExampleDicomAppLogic::setState(ctkDicomAppHosting::State newState)
{
  qDebug() << "setState called";
  emit stateChanged(newState);
  return true;
}

//----------------------------------------------------------------------------
bool ctkExampleDicomAppLogic::bringToFront(const QRect& /*requestedScreenArea*/)
{
  return false;
}

//----------------------------------------------------------------------------
void ctkExampleDicomAppLogic::do_something()
{
  this->Button = new QPushButton("Button from App");
  connect(this->Button, SIGNAL(clicked()), this, SLOT(buttonClicked()));
  try
    {
    QRect preferred(50,50,100,100);
    qDebug() << "  Asking:getAvailableScreen";
    QRect rect = getHostInterface()->getAvailableScreen(preferred);
    qDebug() << "  got sth:" << rect.top();
    this->Button->move(rect.topLeft());
    this->Button->resize(rect.size());
    }
  catch (const std::runtime_error& e)
    {
    qCritical() << e.what();
    return;
    }
  this->Button->show();
}

//----------------------------------------------------------------------------
void ctkExampleDicomAppLogic::changeState(int anewstate)
{
  ctkDicomAppHosting::State newstate = static_cast<ctkDicomAppHosting::State>(anewstate);

  if (newstate == ctkDicomAppHosting::INPROGRESS)
    {
    do_something();
    }

  try
    {
    getHostInterface()->notifyStateChanged(newstate);
    }
  catch (const std::runtime_error& e)
    {
    qCritical() << e.what();
    return;
    }

  if (newstate == ctkDicomAppHosting::CANCELED)
    {
    qDebug() << "  Received changeState(CANCELED) ... now releasing all resources and afterwards changing to state IDLE.";
    qDebug() << "  Changing to state IDLE.";
    try
      {
      getHostInterface()->notifyStateChanged(ctkDicomAppHosting::IDLE);
      }
    catch (const std::runtime_error& e)
      {
      qCritical() << e.what();
      return;
      }
    }

  if (newstate == ctkDicomAppHosting::EXIT)
    {
    qDebug() << "  Received changeState(EXIT) ... exiting.";
    this->getHostInterface()->notifyStateChanged(ctkDicomAppHosting::EXIT);
    qApp->exit(0);
    }
}

//----------------------------------------------------------------------------
bool ctkExampleDicomAppLogic::notifyDataAvailable(ctkDicomAppHosting::AvailableData data, bool lastData)
{
  Q_UNUSED(lastData)
  QString s;
  if(this->Button == 0)
    {
    qCritical() << "Button is null!";
    return false;
    }
  s = "Received notifyDataAvailable with patients.count()= " + QString().setNum(data.patients.count());
  if(data.patients.count()>0)
    {
    s=s+" name:"+data.patients.begin()->name+" studies.count(): "+QString().setNum(data.patients.begin()->studies.count());
    if(data.patients.begin()->studies.count()>0)
    {
      s=s+" series.count():" + QString().setNum(data.patients.begin()->studies.begin()->series.count());
      if(data.patients.begin()->studies.begin()->series.count()>0)
      {
        s=s+" uid:" + data.patients.begin()->studies.begin()->series.begin()->seriesUID;
//        QUuid uuid("93097dc1-caf9-43a3-a814-51a57f8d861d");//data.patients.begin()->studies.begin()->series.begin()->seriesUID);
        uuid = data.patients.begin()->studies.begin()->series.begin()->objectDescriptors.begin()->descriptorUUID;
        s=s+" uuid:"+uuid.toString();
      }
    }
  }
  this->Button->setText(s);
  return false;
}

//----------------------------------------------------------------------------
QList<ctkDicomAppHosting::ObjectLocator> ctkExampleDicomAppLogic::getData(
  QList<QUuid> objectUUIDs,
  QList<QString> acceptableTransferSyntaxUIDs,
  bool includeBulkData)
{
  Q_UNUSED(objectUUIDs)
  Q_UNUSED(acceptableTransferSyntaxUIDs)
  Q_UNUSED(includeBulkData)
  return QList<ctkDicomAppHosting::ObjectLocator>();
}

//----------------------------------------------------------------------------
void ctkExampleDicomAppLogic::releaseData(QList<QUuid> objectUUIDs)
{
  Q_UNUSED(objectUUIDs)
}

ctkDicomHostInterface* ctkExampleDicomAppLogic::getHostInterface() const
{
  ctkDicomHostInterface* host = this->HostTracker.getService();
  if (!host) throw std::runtime_error("DICOM Host Interface not available");
  return host;
}

void ctkExampleDicomAppLogic::buttonClicked()
{
  QList<QUuid> uuidlist;
  uuidlist.append(uuid);
  QString transfersyntax("1.2.840.10008.1.2.1");
  QList<QString> transfersyntaxlist;
  transfersyntaxlist.append(transfersyntax);
  QList<ctkDicomAppHosting::ObjectLocator> locators;
  locators = getHostInterface()->getData(uuidlist, transfersyntaxlist, false);
  qDebug() << "got locators! " << QString().setNum(locators.count());

  QString s;
  s=s+" loc.count:"+QString().setNum(locators.count());
  if(locators.count()>0)
  {
    s=s+" URI: "+locators.begin()->URI;
    qDebug() << "URI: " << locators.begin()->URI;
    QString filename = locators.begin()->URI;
    if(filename.startsWith("file:/",Qt::CaseInsensitive))
      filename=filename.remove(0,6);
    qDebug()<<filename;
    DicomImage dcmtkImage(filename.toLatin1().data());
    ctkDICOMImage ctkImage(&dcmtkImage);

    QLabel* qtImage = new QLabel;
    qtImage->setPixmap(ctkImage.getPixmap(0));
    qtImage->show();
  }
  this->Button->setText(s);
}
<commit_msg>Comply with changed interface of ctkDICOMImage<commit_after>/*=============================================================================

  Library: CTK

  Copyright (c) German Cancer Research Center,
    Division of Medical and Biological Informatics

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

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

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

=============================================================================*/

// Qt includes
#include <QtPlugin>
#include <QRect>
#include <QDebug>
#include <QPushButton>
#include <QApplication>
#include <QLabel>

// CTK includes
#include "ctkDICOMImage.h"
#include "ctkExampleDicomAppLogic_p.h"
#include "ctkExampleDicomAppPlugin_p.h"

// DCMTK includes
#include <dcmimage.h>

//----------------------------------------------------------------------------
ctkExampleDicomAppLogic::ctkExampleDicomAppLogic()
  : HostTracker(ctkExampleDicomAppPlugin::getPluginContext()), Button(0)
{
  this->HostTracker.open();

  connect(this, SIGNAL(stateChanged(int)), this, SLOT(changeState(int)), Qt::QueuedConnection);
  emit stateChanged(ctkDicomAppHosting::IDLE);
}

//----------------------------------------------------------------------------
ctkExampleDicomAppLogic::~ctkExampleDicomAppLogic()
{
  ctkPluginContext* context = ctkExampleDicomAppPlugin::getPluginContext();
  QList <QSharedPointer<ctkPlugin> > plugins = context->getPlugins();
  for (int i = 0; i < plugins.size(); ++i)
  {
    qDebug() << plugins.at(i)->getSymbolicName ();
  }
}

//----------------------------------------------------------------------------
ctkDicomAppHosting::State ctkExampleDicomAppLogic::getState()
{
  return ctkDicomAppHosting::IDLE;
}

//----------------------------------------------------------------------------
bool ctkExampleDicomAppLogic::setState(ctkDicomAppHosting::State newState)
{
  qDebug() << "setState called";
  emit stateChanged(newState);
  return true;
}

//----------------------------------------------------------------------------
bool ctkExampleDicomAppLogic::bringToFront(const QRect& /*requestedScreenArea*/)
{
  return false;
}

//----------------------------------------------------------------------------
void ctkExampleDicomAppLogic::do_something()
{
  this->Button = new QPushButton("Button from App");
  connect(this->Button, SIGNAL(clicked()), this, SLOT(buttonClicked()));
  try
    {
    QRect preferred(50,50,100,100);
    qDebug() << "  Asking:getAvailableScreen";
    QRect rect = getHostInterface()->getAvailableScreen(preferred);
    qDebug() << "  got sth:" << rect.top();
    this->Button->move(rect.topLeft());
    this->Button->resize(rect.size());
    }
  catch (const std::runtime_error& e)
    {
    qCritical() << e.what();
    return;
    }
  this->Button->show();
}

//----------------------------------------------------------------------------
void ctkExampleDicomAppLogic::changeState(int anewstate)
{
  ctkDicomAppHosting::State newstate = static_cast<ctkDicomAppHosting::State>(anewstate);

  if (newstate == ctkDicomAppHosting::INPROGRESS)
    {
    do_something();
    }

  try
    {
    getHostInterface()->notifyStateChanged(newstate);
    }
  catch (const std::runtime_error& e)
    {
    qCritical() << e.what();
    return;
    }

  if (newstate == ctkDicomAppHosting::CANCELED)
    {
    qDebug() << "  Received changeState(CANCELED) ... now releasing all resources and afterwards changing to state IDLE.";
    qDebug() << "  Changing to state IDLE.";
    try
      {
      getHostInterface()->notifyStateChanged(ctkDicomAppHosting::IDLE);
      }
    catch (const std::runtime_error& e)
      {
      qCritical() << e.what();
      return;
      }
    }

  if (newstate == ctkDicomAppHosting::EXIT)
    {
    qDebug() << "  Received changeState(EXIT) ... exiting.";
    this->getHostInterface()->notifyStateChanged(ctkDicomAppHosting::EXIT);
    qApp->exit(0);
    }
}

//----------------------------------------------------------------------------
bool ctkExampleDicomAppLogic::notifyDataAvailable(ctkDicomAppHosting::AvailableData data, bool lastData)
{
  Q_UNUSED(lastData)
  QString s;
  if(this->Button == 0)
    {
    qCritical() << "Button is null!";
    return false;
    }
  s = "Received notifyDataAvailable with patients.count()= " + QString().setNum(data.patients.count());
  if(data.patients.count()>0)
    {
    s=s+" name:"+data.patients.begin()->name+" studies.count(): "+QString().setNum(data.patients.begin()->studies.count());
    if(data.patients.begin()->studies.count()>0)
    {
      s=s+" series.count():" + QString().setNum(data.patients.begin()->studies.begin()->series.count());
      if(data.patients.begin()->studies.begin()->series.count()>0)
      {
        s=s+" uid:" + data.patients.begin()->studies.begin()->series.begin()->seriesUID;
//        QUuid uuid("93097dc1-caf9-43a3-a814-51a57f8d861d");//data.patients.begin()->studies.begin()->series.begin()->seriesUID);
        uuid = data.patients.begin()->studies.begin()->series.begin()->objectDescriptors.begin()->descriptorUUID;
        s=s+" uuid:"+uuid.toString();
      }
    }
  }
  this->Button->setText(s);
  return false;
}

//----------------------------------------------------------------------------
QList<ctkDicomAppHosting::ObjectLocator> ctkExampleDicomAppLogic::getData(
  QList<QUuid> objectUUIDs,
  QList<QString> acceptableTransferSyntaxUIDs,
  bool includeBulkData)
{
  Q_UNUSED(objectUUIDs)
  Q_UNUSED(acceptableTransferSyntaxUIDs)
  Q_UNUSED(includeBulkData)
  return QList<ctkDicomAppHosting::ObjectLocator>();
}

//----------------------------------------------------------------------------
void ctkExampleDicomAppLogic::releaseData(QList<QUuid> objectUUIDs)
{
  Q_UNUSED(objectUUIDs)
}

ctkDicomHostInterface* ctkExampleDicomAppLogic::getHostInterface() const
{
  ctkDicomHostInterface* host = this->HostTracker.getService();
  if (!host) throw std::runtime_error("DICOM Host Interface not available");
  return host;
}

void ctkExampleDicomAppLogic::buttonClicked()
{
  QList<QUuid> uuidlist;
  uuidlist.append(uuid);
  QString transfersyntax("1.2.840.10008.1.2.1");
  QList<QString> transfersyntaxlist;
  transfersyntaxlist.append(transfersyntax);
  QList<ctkDicomAppHosting::ObjectLocator> locators;
  locators = getHostInterface()->getData(uuidlist, transfersyntaxlist, false);
  qDebug() << "got locators! " << QString().setNum(locators.count());

  QString s;
  s=s+" loc.count:"+QString().setNum(locators.count());
  if(locators.count()>0)
  {
    s=s+" URI: "+locators.begin()->URI;
    qDebug() << "URI: " << locators.begin()->URI;
    QString filename = locators.begin()->URI;
    if(filename.startsWith("file:/",Qt::CaseInsensitive))
      filename=filename.remove(0,6);
    qDebug()<<filename;
    DicomImage dcmtkImage(filename.toLatin1().data());
    ctkDICOMImage ctkImage(&dcmtkImage);

    QLabel* qtImage = new QLabel;
    QPixmap pixmap = QPixmap::fromImage(ctkImage.getImage(0),Qt::AvoidDither);
    if (pixmap.isNull())
    {
      qCritical() << "Failed to convert QImage to QPixmap" ;
    }
    else
    {
      qtImage->setPixmap(pixmap);
      qtImage->show();
    }
  }
  this->Button->setText(s);
}
<|endoftext|>


<commit_before>/*=========================================================================

Program:   Medical Imaging & Interaction Toolkit
Language:  C++
Date:      $Date$
Version:   $Revision$

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

// Blueberry
#include <berryISelectionService.h>
#include <berryIWorkbenchWindow.h>
#include <berryUIException.h>
#include <berryIWorkbenchPage.h>
#include <berryIPreferencesService.h>
#include <berryIPartListener.h>
#include <mitkGlobalInteraction.h>
#include <mitkDataStorageEditorInput.h>
#include "berryFileEditorInput.h"

// Qmitk
#include "QmitkDicomEditor.h"
#include "mitkPluginActivator.h"
#include <mitkDicomSeriesReader.h>

//#include "mitkProgressBar.h"

// Qt
#include <QCheckBox>
#include <QMessageBox>
#include <QWidget>

#include <QtSql>
#include <QSqlDatabase>
#include <QtCore/QVariant>
#include <QtGui/QAction>
#include <QtGui/QApplication>
#include <QtGui/QButtonGroup>
#include <QtGui/QGridLayout>
#include <QtGui/QHeaderView>
#include <QtGui/QPushButton>
#include <QtGui/QTextEdit>
#include <QtGui/QWidget>

//CTK
#include <ctkDICOMModel.h>
#include <ctkDICOMAppWidget.h>
#include <ctkDICOMQueryWidget.h>
#include <ctkFileDialog.h>
#include <ctkDICOMQueryRetrieveWidget.h>

const std::string QmitkDicomEditor::EDITOR_ID = "org.mitk.editors.dicomeditor";

QmitkDicomEditor::QmitkDicomEditor()
: m_Thread(new QThread())
, m_DicomDirectoryListener(new QmitkDicomDirectoryListener())
, m_ListenerDirectory(new QString())
, m_DatabaseDirectory(new QString())
, m_PluginDirectory(new QString())
{
}

QmitkDicomEditor::~QmitkDicomEditor()
{
    m_Thread->terminate();
    delete m_Handler;
    delete m_Publisher;
    delete m_StoreSCPLauncher;
    delete m_Thread;
    delete m_DicomDirectoryListener;
    delete m_ListenerDirectory;
    delete m_DatabaseDirectory;
    delete m_PluginDirectory;
}

void QmitkDicomEditor::CreateQtPartControl(QWidget *parent )
{
    m_Controls.setupUi( parent );
    TestHandler();

    SetPluginDirectory();
    SetDatabaseDirectory("DatabaseDirectory");
    SetListenerDirectory("ListenerDirectory");
    StartDicomDirectoryListener();

    m_Controls.m_ctkDICOMQueryRetrieveWidget->useProgressDialog(false);

    connect(m_Controls.externalDataWidget,SIGNAL(SignalAddDicomData(const QString&)),m_Controls.internalDataWidget,SLOT(StartDicomImport(const QString&)));
    connect(m_Controls.externalDataWidget,SIGNAL(SignalAddDicomData(const QStringList&)),m_Controls.internalDataWidget,SLOT(StartDicomImport(const QStringList&)));
    connect(m_Controls.externalDataWidget,SIGNAL(SignalDicomToDataManager(const QStringList&)),this,SLOT(OnViewButtonAddToDataManager(const QStringList&)));
    connect(m_Controls.externalDataWidget,SIGNAL(SignalChangePage(int)), this, SLOT(OnChangePage(int)));

    connect(m_Controls.internalDataWidget,SIGNAL(FinishedImport(const QString&)),this,SLOT(OnDicomImportFinished(const QString&)));
    connect(m_Controls.internalDataWidget,SIGNAL(FinishedImport(const QStringList&)),this,SLOT(OnDicomImportFinished(const QStringList&)));
    connect(m_Controls.internalDataWidget,SIGNAL(SignalDicomToDataManager(const QStringList&)),this,SLOT(OnViewButtonAddToDataManager(const QStringList&)));

    connect(m_Controls.CDButton, SIGNAL(clicked()), m_Controls.externalDataWidget, SLOT(OnFolderCDImport()));
    connect(m_Controls.FolderButton, SIGNAL(clicked()), m_Controls.externalDataWidget, SLOT(OnFolderCDImport()));
    connect(m_Controls.QueryRetrieveButton, SIGNAL(clicked()), this, SLOT(OnQueryRetrieve()));
    connect(m_Controls.LocalStorageButton, SIGNAL(clicked()), this, SLOT(OnLocalStorage()));

    //connect(m_Controls.radioButton,SIGNAL(clicked()),this,SLOT(StartStopStoreSCP()));
}

void QmitkDicomEditor::Init(berry::IEditorSite::Pointer site, berry::IEditorInput::Pointer input)
{
    this->SetSite(site);
    this->SetInput(input);
}

void QmitkDicomEditor::SetFocus()
{
}

berry::IPartListener::Events::Types QmitkDicomEditor::GetPartEventTypes() const
{
    return Events::CLOSED | Events::HIDDEN | Events::VISIBLE;
}

void QmitkDicomEditor::OnQueryRetrieve()
{
    OnChangePage(2);
    StartStopStoreSCP();
}

void QmitkDicomEditor::OnLocalStorage()
{
    OnChangePage(0);
}

void QmitkDicomEditor::OnChangePage(int page)
{
    try{
        m_Controls.stackedWidget->setCurrentIndex(page);
    }catch(std::exception e){
        MITK_ERROR <<"error: "<< e.what();
        return;
    }
}

void QmitkDicomEditor::OnDicomImportFinished(const QString& path)
{
}

void QmitkDicomEditor::OnDicomImportFinished(const QStringList& path)
{
}

void QmitkDicomEditor::StartDicomDirectoryListener()
{
    if(!m_Thread->isRunning())
    {
        m_DicomDirectoryListener->SetDicomListenerDirectory(*m_ListenerDirectory);
        connect(m_DicomDirectoryListener,SIGNAL(SignalAddDicomData(const QStringList&)),m_Controls.internalDataWidget,SLOT(StartDicomImport(const QStringList&)),Qt::DirectConnection);
        connect(m_Controls.internalDataWidget,SIGNAL(FinishedImport(const QStringList&)),m_DicomDirectoryListener,SLOT(OnDicomImportFinished(const QStringList&)),Qt::DirectConnection);
        m_DicomDirectoryListener->moveToThread(m_Thread);
        m_Thread->start();
    }
}

//TODO Remove
void QmitkDicomEditor::TestHandler()
{
    m_Handler = new DicomEventHandler();
    m_Handler->SubscribeSlots();
}

void QmitkDicomEditor::OnViewButtonAddToDataManager(const QStringList& eventProperties)
{
    ctkDictionary properties;
    properties["PatientName"] = eventProperties.at(0);
    properties["StudyUID"] = eventProperties.at(1);
    properties["StudyName"] = eventProperties.at(2);
    properties["SeriesUID"] = eventProperties.at(3);
    properties["SeriesName"] = eventProperties.at(4);
    properties["Path"] = eventProperties.at(5);

    m_Publisher = new QmitkDicomDataEventPublisher();
    m_Publisher->PublishSignals(mitk::PluginActivator::getContext());

    m_Publisher->AddSeriesToDataManagerEvent(properties);
}

void QmitkDicomEditor::StartStoreSCP()
{
    QString storagePort = m_Controls.m_ctkDICOMQueryRetrieveWidget->getServerParameters()["StoragePort"].toString();
    QString storageAET = m_Controls.m_ctkDICOMQueryRetrieveWidget->getServerParameters()["StorageAETitle"].toString();
    builder.AddPort(storagePort)->AddAETitle(storageAET)->AddTransferSyntax()->AddOtherNetworkOptions()->AddMode()->AddOutputDirectory(*m_ListenerDirectory);
    m_StoreSCPLauncher = new QmitkStoreSCPLauncher(&builder);
    m_StoreSCPLauncher->StartStoreSCP();
    m_Controls.radioButton->setChecked(true);
    m_Controls.radioButton->setText(storageAET+QString(" ")+storagePort);

}

void QmitkDicomEditor::StopStoreSCP()
{
        delete m_StoreSCPLauncher;
        m_Controls.radioButton->setChecked(false);
        m_Controls.radioButton->setText(QString("Storage service provider is not running!"));
}

void QmitkDicomEditor::StartStopStoreSCP()
{
    QString storagePort = m_Controls.m_ctkDICOMQueryRetrieveWidget->getServerParameters()["StoragePort"].toString();
    QString storageAET = m_Controls.m_ctkDICOMQueryRetrieveWidget->getServerParameters()["StorageAETitle"].toString();

    if(!((builder.GetAETitle()->compare(storageAET,Qt::CaseSensitive)==0)&&
        (builder.GetPort()->compare(storagePort,Qt::CaseSensitive)==0)))
    {
        if(m_Controls.radioButton->isChecked())
        {
            StopStoreSCP();
            StartStoreSCP();
        }else{
            StartStoreSCP();
        }
    }
}

void QmitkDicomEditor::SetPluginDirectory()
{
    mitk::PluginActivator::getContext()->getDataFile(*m_PluginDirectory);
    m_PluginDirectory->append("/");
}

void QmitkDicomEditor::SetDatabaseDirectory(const QString& databaseDirectory)
{
    m_DatabaseDirectory->clear();
    m_DatabaseDirectory->append(m_PluginDirectory);
    m_DatabaseDirectory->append(databaseDirectory);
    m_Controls.internalDataWidget->SetDatabaseDirectory(*m_DatabaseDirectory);
}

void QmitkDicomEditor::SetListenerDirectory(const QString& listenerDirectory)
{
    m_ListenerDirectory->clear();
    m_ListenerDirectory->append(m_PluginDirectory);
    m_ListenerDirectory->append(listenerDirectory);
}<commit_msg>fixed memory leak<commit_after>/*=========================================================================

Program:   Medical Imaging & Interaction Toolkit
Language:  C++
Date:      $Date$
Version:   $Revision$

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

// Blueberry
#include <berryISelectionService.h>
#include <berryIWorkbenchWindow.h>
#include <berryUIException.h>
#include <berryIWorkbenchPage.h>
#include <berryIPreferencesService.h>
#include <berryIPartListener.h>
#include <mitkGlobalInteraction.h>
#include <mitkDataStorageEditorInput.h>
#include "berryFileEditorInput.h"

// Qmitk
#include "QmitkDicomEditor.h"
#include "mitkPluginActivator.h"
#include <mitkDicomSeriesReader.h>

//#include "mitkProgressBar.h"

// Qt
#include <QCheckBox>
#include <QMessageBox>
#include <QWidget>

#include <QtSql>
#include <QSqlDatabase>
#include <QtCore/QVariant>
#include <QtGui/QAction>
#include <QtGui/QApplication>
#include <QtGui/QButtonGroup>
#include <QtGui/QGridLayout>
#include <QtGui/QHeaderView>
#include <QtGui/QPushButton>
#include <QtGui/QTextEdit>
#include <QtGui/QWidget>

//CTK
#include <ctkDICOMModel.h>
#include <ctkDICOMAppWidget.h>
#include <ctkDICOMQueryWidget.h>
#include <ctkFileDialog.h>
#include <ctkDICOMQueryRetrieveWidget.h>

const std::string QmitkDicomEditor::EDITOR_ID = "org.mitk.editors.dicomeditor";

QmitkDicomEditor::QmitkDicomEditor()
: m_Thread(new QThread())
, m_DicomDirectoryListener(new QmitkDicomDirectoryListener())
, m_ListenerDirectory(new QString())
, m_DatabaseDirectory(new QString())
, m_PluginDirectory(new QString())
, m_Publisher(new QmitkDicomDataEventPublisher())
, m_StoreSCPLauncher(new QmitkStoreSCPLauncher(&builder))
{
}

QmitkDicomEditor::~QmitkDicomEditor()
{
    m_Thread->terminate();
    delete m_Handler;
    delete m_Publisher;
    delete m_StoreSCPLauncher;
    delete m_Thread;
    delete m_DicomDirectoryListener;
    delete m_ListenerDirectory;
    delete m_DatabaseDirectory;
    delete m_PluginDirectory;
}

void QmitkDicomEditor::CreateQtPartControl(QWidget *parent )
{
    m_Controls.setupUi( parent );
    TestHandler();

    SetPluginDirectory();
    SetDatabaseDirectory("DatabaseDirectory");
    SetListenerDirectory("ListenerDirectory");
    StartDicomDirectoryListener();

    m_Controls.m_ctkDICOMQueryRetrieveWidget->useProgressDialog(false);

    connect(m_Controls.externalDataWidget,SIGNAL(SignalAddDicomData(const QString&)),m_Controls.internalDataWidget,SLOT(StartDicomImport(const QString&)));
    connect(m_Controls.externalDataWidget,SIGNAL(SignalAddDicomData(const QStringList&)),m_Controls.internalDataWidget,SLOT(StartDicomImport(const QStringList&)));
    connect(m_Controls.externalDataWidget,SIGNAL(SignalDicomToDataManager(const QStringList&)),this,SLOT(OnViewButtonAddToDataManager(const QStringList&)));
    connect(m_Controls.externalDataWidget,SIGNAL(SignalChangePage(int)), this, SLOT(OnChangePage(int)));

    connect(m_Controls.internalDataWidget,SIGNAL(FinishedImport(const QString&)),this,SLOT(OnDicomImportFinished(const QString&)));
    connect(m_Controls.internalDataWidget,SIGNAL(FinishedImport(const QStringList&)),this,SLOT(OnDicomImportFinished(const QStringList&)));
    connect(m_Controls.internalDataWidget,SIGNAL(SignalDicomToDataManager(const QStringList&)),this,SLOT(OnViewButtonAddToDataManager(const QStringList&)));

    connect(m_Controls.CDButton, SIGNAL(clicked()), m_Controls.externalDataWidget, SLOT(OnFolderCDImport()));
    connect(m_Controls.FolderButton, SIGNAL(clicked()), m_Controls.externalDataWidget, SLOT(OnFolderCDImport()));
    connect(m_Controls.QueryRetrieveButton, SIGNAL(clicked()), this, SLOT(OnQueryRetrieve()));
    connect(m_Controls.LocalStorageButton, SIGNAL(clicked()), this, SLOT(OnLocalStorage()));

    //connect(m_Controls.radioButton,SIGNAL(clicked()),this,SLOT(StartStopStoreSCP()));
}

void QmitkDicomEditor::Init(berry::IEditorSite::Pointer site, berry::IEditorInput::Pointer input)
{
    this->SetSite(site);
    this->SetInput(input);
}

void QmitkDicomEditor::SetFocus()
{
}

berry::IPartListener::Events::Types QmitkDicomEditor::GetPartEventTypes() const
{
    return Events::CLOSED | Events::HIDDEN | Events::VISIBLE;
}

void QmitkDicomEditor::OnQueryRetrieve()
{
    OnChangePage(2);
    StartStopStoreSCP();
}

void QmitkDicomEditor::OnLocalStorage()
{
    OnChangePage(0);
}

void QmitkDicomEditor::OnChangePage(int page)
{
    try{
        m_Controls.stackedWidget->setCurrentIndex(page);
    }catch(std::exception e){
        MITK_ERROR <<"error: "<< e.what();
        return;
    }
}

void QmitkDicomEditor::OnDicomImportFinished(const QString& path)
{
}

void QmitkDicomEditor::OnDicomImportFinished(const QStringList& path)
{
}

void QmitkDicomEditor::StartDicomDirectoryListener()
{
    if(!m_Thread->isRunning())
    {
        m_DicomDirectoryListener->SetDicomListenerDirectory(*m_ListenerDirectory);
        connect(m_DicomDirectoryListener,SIGNAL(SignalAddDicomData(const QStringList&)),m_Controls.internalDataWidget,SLOT(StartDicomImport(const QStringList&)),Qt::DirectConnection);
        connect(m_Controls.internalDataWidget,SIGNAL(FinishedImport(const QStringList&)),m_DicomDirectoryListener,SLOT(OnDicomImportFinished(const QStringList&)),Qt::DirectConnection);
        m_DicomDirectoryListener->moveToThread(m_Thread);
        m_Thread->start();
    }
}

//TODO Remove
void QmitkDicomEditor::TestHandler()
{
    m_Handler = new DicomEventHandler();
    m_Handler->SubscribeSlots();
}

void QmitkDicomEditor::OnViewButtonAddToDataManager(const QStringList& eventProperties)
{
    ctkDictionary properties;
    properties["PatientName"] = eventProperties.at(0);
    properties["StudyUID"] = eventProperties.at(1);
    properties["StudyName"] = eventProperties.at(2);
    properties["SeriesUID"] = eventProperties.at(3);
    properties["SeriesName"] = eventProperties.at(4);
    properties["Path"] = eventProperties.at(5);

    m_Publisher->PublishSignals(mitk::PluginActivator::getContext());
    m_Publisher->AddSeriesToDataManagerEvent(properties);
}

void QmitkDicomEditor::StartStoreSCP()
{
    QString storagePort = m_Controls.m_ctkDICOMQueryRetrieveWidget->getServerParameters()["StoragePort"].toString();
    QString storageAET = m_Controls.m_ctkDICOMQueryRetrieveWidget->getServerParameters()["StorageAETitle"].toString();
    builder.AddPort(storagePort)->AddAETitle(storageAET)->AddTransferSyntax()->AddOtherNetworkOptions()->AddMode()->AddOutputDirectory(*m_ListenerDirectory);
    m_StoreSCPLauncher = new QmitkStoreSCPLauncher(&builder);
    m_StoreSCPLauncher->StartStoreSCP();
    m_Controls.radioButton->setChecked(true);
    m_Controls.radioButton->setText(storageAET+QString(" ")+storagePort);

}

void QmitkDicomEditor::StopStoreSCP()
{
        delete m_StoreSCPLauncher;
        m_Controls.radioButton->setChecked(false);
        m_Controls.radioButton->setText(QString("Storage service provider is not running!"));
}

void QmitkDicomEditor::StartStopStoreSCP()
{
    QString storagePort = m_Controls.m_ctkDICOMQueryRetrieveWidget->getServerParameters()["StoragePort"].toString();
    QString storageAET = m_Controls.m_ctkDICOMQueryRetrieveWidget->getServerParameters()["StorageAETitle"].toString();

    if(!((builder.GetAETitle()->compare(storageAET,Qt::CaseSensitive)==0)&&
        (builder.GetPort()->compare(storagePort,Qt::CaseSensitive)==0)))
    {
        if(m_Controls.radioButton->isChecked())
        {
            StopStoreSCP();
            StartStoreSCP();
        }else{
            StartStoreSCP();
        }
    }
}

void QmitkDicomEditor::SetPluginDirectory()
{
    mitk::PluginActivator::getContext()->getDataFile(*m_PluginDirectory);
    m_PluginDirectory->append("/");
}

void QmitkDicomEditor::SetDatabaseDirectory(const QString& databaseDirectory)
{
    m_DatabaseDirectory->clear();
    m_DatabaseDirectory->append(m_PluginDirectory);
    m_DatabaseDirectory->append(databaseDirectory);
    m_Controls.internalDataWidget->SetDatabaseDirectory(*m_DatabaseDirectory);
}

void QmitkDicomEditor::SetListenerDirectory(const QString& listenerDirectory)
{
    m_ListenerDirectory->clear();
    m_ListenerDirectory->append(m_PluginDirectory);
    m_ListenerDirectory->append(listenerDirectory);
}<|endoftext|>


<commit_before>/*
 * Copyright (C) 2015 ScyllaDB
 */

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

#pragma once

#include <chrono>
#include <map>
#include <optional>
#include <concepts>
#include <seastar/core/byteorder.hh>
#include <seastar/core/sstring.hh>
#include "seastarx.hh"

//
// This hashing differs from std::hash<> in that it decouples knowledge about
// type structure from the way the hash value is calculated:
//  * appending_hash<T> instantiation knows about what data should be included in the hash for type T.
//  * Hasher object knows how to combine the data into the final hash.
//
// The appending_hash<T> should always feed some data into the hasher, regardless of the state the object is in,
// in order for the hash to be highly sensitive for value changes. For example, vector<optional<T>> should
// ideally feed different values for empty vector and a vector with a single empty optional.
//
// appending_hash<T> is machine-independent.
//

template<typename H>
concept Hasher =
    requires(H& h, const char* ptr, size_t size) {
        { h.update(ptr, size) } noexcept -> std::same_as<void>;
    };

class hasher {
public:
    virtual ~hasher() = default;
    virtual void update(const char* ptr, size_t size) noexcept = 0;
};

static_assert(Hasher<hasher>);

template<typename T, typename Enable = void>
struct appending_hash;

template<typename H, typename T, typename... Args>
requires Hasher<H>
inline
void feed_hash(H& h, const T& value, Args&&... args) noexcept {
    appending_hash<T>()(h, value, std::forward<Args>(args)...);
};

template<typename T>
struct appending_hash<T, std::enable_if_t<std::is_arithmetic<T>::value>> {
    template<typename H>
    requires Hasher<H>
    void operator()(H& h, T value) const noexcept {
        auto value_le = cpu_to_le(value);
        h.update(reinterpret_cast<const char*>(&value_le), sizeof(T));
    }
};

template<>
struct appending_hash<bool> {
    template<typename H>
    requires Hasher<H>
    void operator()(H& h, bool value) const noexcept {
        feed_hash(h, static_cast<uint8_t>(value));
    }
};

template<typename T>
struct appending_hash<T, std::enable_if_t<std::is_enum<T>::value>> {
    template<typename H>
    requires Hasher<H>
    void operator()(H& h, const T& value) const noexcept {
        feed_hash(h, static_cast<std::underlying_type_t<T>>(value));
    }
};

template<typename T>
struct appending_hash<std::optional<T>>  {
    template<typename H>
    requires Hasher<H>
    void operator()(H& h, const std::optional<T>& value) const noexcept {
        if (value) {
            feed_hash(h, true);
            feed_hash(h, *value);
        } else {
            feed_hash(h, false);
        }
    }
};

template<size_t N>
struct appending_hash<char[N]>  {
    template<typename H>
    requires Hasher<H>
    void operator()(H& h, const char (&value) [N]) const noexcept {
        feed_hash(h, N);
        h.update(value, N);
    }
};

template<typename T>
struct appending_hash<std::vector<T>> {
    template<typename H>
    requires Hasher<H>
    void operator()(H& h, const std::vector<T>& value) const noexcept {
        feed_hash(h, value.size());
        for (auto&& v : value) {
            appending_hash<T>()(h, v);
        }
    }
};

template<typename K, typename V>
struct appending_hash<std::map<K, V>> {
    template<typename H>
    requires Hasher<H>
    void operator()(H& h, const std::map<K, V>& value) const noexcept {
        feed_hash(h, value.size());
        for (auto&& e : value) {
            appending_hash<K>()(h, e.first);
            appending_hash<V>()(h, e.second);
        }
    }
};

template<>
struct appending_hash<sstring> {
    template<typename H>
    requires Hasher<H>
    void operator()(H& h, const sstring& v) const noexcept {
        feed_hash(h, v.size());
        h.update(reinterpret_cast<const char*>(v.cbegin()), v.size() * sizeof(sstring::value_type));
    }
};

template<>
struct appending_hash<std::string> {
    template<typename H>
    requires Hasher<H>
    void operator()(H& h, const std::string& v) const noexcept {
        feed_hash(h, v.size());
        h.update(reinterpret_cast<const char*>(v.data()), v.size() * sizeof(std::string::value_type));
    }
};

template<typename T, typename R>
struct appending_hash<std::chrono::duration<T, R>> {
    template<typename H>
    requires Hasher<H>
    void operator()(H& h, std::chrono::duration<T, R> v) const noexcept {
        feed_hash(h, v.count());
    }
};

template<typename Clock, typename Duration>
struct appending_hash<std::chrono::time_point<Clock, Duration>> {
    template<typename H>
    requires Hasher<H>
    void operator()(H& h, std::chrono::time_point<Clock, Duration> v) const noexcept {
        feed_hash(h, v.time_since_epoch().count());
    }
};
<commit_msg>hashing: appending_hash: convert from enable_if to concepts<commit_after>/*
 * Copyright (C) 2015 ScyllaDB
 */

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

#pragma once

#include <chrono>
#include <map>
#include <optional>
#include <concepts>
#include <seastar/core/byteorder.hh>
#include <seastar/core/sstring.hh>
#include "seastarx.hh"

//
// This hashing differs from std::hash<> in that it decouples knowledge about
// type structure from the way the hash value is calculated:
//  * appending_hash<T> instantiation knows about what data should be included in the hash for type T.
//  * Hasher object knows how to combine the data into the final hash.
//
// The appending_hash<T> should always feed some data into the hasher, regardless of the state the object is in,
// in order for the hash to be highly sensitive for value changes. For example, vector<optional<T>> should
// ideally feed different values for empty vector and a vector with a single empty optional.
//
// appending_hash<T> is machine-independent.
//

template<typename H>
concept Hasher =
    requires(H& h, const char* ptr, size_t size) {
        { h.update(ptr, size) } noexcept -> std::same_as<void>;
    };

class hasher {
public:
    virtual ~hasher() = default;
    virtual void update(const char* ptr, size_t size) noexcept = 0;
};

static_assert(Hasher<hasher>);

template<typename T>
struct appending_hash;

template<typename H, typename T, typename... Args>
requires Hasher<H>
inline
void feed_hash(H& h, const T& value, Args&&... args) noexcept {
    appending_hash<T>()(h, value, std::forward<Args>(args)...);
};

template<typename T>
requires std::is_arithmetic_v<T>
struct appending_hash<T> {
    template<typename H>
    requires Hasher<H>
    void operator()(H& h, T value) const noexcept {
        auto value_le = cpu_to_le(value);
        h.update(reinterpret_cast<const char*>(&value_le), sizeof(T));
    }
};

template<>
struct appending_hash<bool> {
    template<typename H>
    requires Hasher<H>
    void operator()(H& h, bool value) const noexcept {
        feed_hash(h, static_cast<uint8_t>(value));
    }
};

template<typename T>
requires std::is_enum_v<T>
struct appending_hash<T> {
    template<typename H>
    requires Hasher<H>
    void operator()(H& h, const T& value) const noexcept {
        feed_hash(h, static_cast<std::underlying_type_t<T>>(value));
    }
};

template<typename T>
struct appending_hash<std::optional<T>>  {
    template<typename H>
    requires Hasher<H>
    void operator()(H& h, const std::optional<T>& value) const noexcept {
        if (value) {
            feed_hash(h, true);
            feed_hash(h, *value);
        } else {
            feed_hash(h, false);
        }
    }
};

template<size_t N>
struct appending_hash<char[N]>  {
    template<typename H>
    requires Hasher<H>
    void operator()(H& h, const char (&value) [N]) const noexcept {
        feed_hash(h, N);
        h.update(value, N);
    }
};

template<typename T>
struct appending_hash<std::vector<T>> {
    template<typename H>
    requires Hasher<H>
    void operator()(H& h, const std::vector<T>& value) const noexcept {
        feed_hash(h, value.size());
        for (auto&& v : value) {
            appending_hash<T>()(h, v);
        }
    }
};

template<typename K, typename V>
struct appending_hash<std::map<K, V>> {
    template<typename H>
    requires Hasher<H>
    void operator()(H& h, const std::map<K, V>& value) const noexcept {
        feed_hash(h, value.size());
        for (auto&& e : value) {
            appending_hash<K>()(h, e.first);
            appending_hash<V>()(h, e.second);
        }
    }
};

template<>
struct appending_hash<sstring> {
    template<typename H>
    requires Hasher<H>
    void operator()(H& h, const sstring& v) const noexcept {
        feed_hash(h, v.size());
        h.update(reinterpret_cast<const char*>(v.cbegin()), v.size() * sizeof(sstring::value_type));
    }
};

template<>
struct appending_hash<std::string> {
    template<typename H>
    requires Hasher<H>
    void operator()(H& h, const std::string& v) const noexcept {
        feed_hash(h, v.size());
        h.update(reinterpret_cast<const char*>(v.data()), v.size() * sizeof(std::string::value_type));
    }
};

template<typename T, typename R>
struct appending_hash<std::chrono::duration<T, R>> {
    template<typename H>
    requires Hasher<H>
    void operator()(H& h, std::chrono::duration<T, R> v) const noexcept {
        feed_hash(h, v.count());
    }
};

template<typename Clock, typename Duration>
struct appending_hash<std::chrono::time_point<Clock, Duration>> {
    template<typename H>
    requires Hasher<H>
    void operator()(H& h, std::chrono::time_point<Clock, Duration> v) const noexcept {
        feed_hash(h, v.time_since_epoch().count());
    }
};
<|endoftext|>


<commit_before># pragma once
# include <Siv3D.hpp>
# include "AscChoiceManager.hpp"
# include "AscMessageManager.hpp"
# include "AscSoundManager.hpp"
# include "AscSpriteManager.hpp"

namespace asc
{
	using namespace s3d;

	using Commnad = std::pair<int32, String>;

	class Novel
	{
	private:

		bool m_isUpdating;

		int32 m_currentLine;

		int32 m_lastSeekPoint;

		Array<Commnad> m_commands;

		ChoiceManager m_choiceManager;

		SoundManager m_soundManager;

		MessageManager m_messageManager;

		SpriteManager m_spriteManager;

		void clearManager()
		{
			m_messageManager.clear();
			m_spriteManager.clear();
			m_choiceManager.clear();
		}

		void execute()
		{
			switch (m_commands[m_currentLine].first)
			{
			// Point
			case 0:
				m_isUpdating = false;
				m_lastSeekPoint = Parse<int32>(m_commands[m_currentLine].second);
				return;

			// Text
			case 1:
				m_messageManager.setText(m_commands[m_currentLine].second);
				m_messageManager.start();
				break;

			// Name
			case 2:
				m_messageManager.setName(m_commands[m_currentLine].second);
				break;

			// AddSprite
			case 3:
				m_spriteManager.add<Sprite>(m_commands[m_currentLine].second);
				break;

			// AddFixedSprite
			case 4:
				m_spriteManager.add<FixedSprite>(m_commands[m_currentLine].second);
				break;

			// Choice
			case 5:
				m_choiceManager.start(m_commands[m_currentLine].second);
				break;

			// Jump
			case 6:
				start(Parse<int32>(m_commands[m_currentLine].second));
				return;

			// AutomaticText
			case 7:
				m_messageManager.setText(m_commands[m_currentLine].second);
				m_messageManager.start(true);
				break;

			default:
				break;
			}

			m_currentLine++;
		}

	public:

		Novel() :
			m_isUpdating(false),
			m_currentLine(0),
			m_lastSeekPoint(-1),
			m_messageManager(std::bind(&SoundManager::playCharSound, m_soundManager))
		{
			m_commands.push_back({ 0, L"1"});
			m_commands.push_back({ 3, L"1,character1,0,0,640,720" });
			m_commands.push_back({ 3, L"3,character3,480,180,320,360" });
			m_commands.push_back({ 1, L"Characters" });
			m_commands.push_back({ 0, L"2" });
			m_commands.push_back({ 1, L"Only Text" });
			m_commands.push_back({ 0, L"3" });
			m_commands.push_back({ 7, L"Show Character?" });
			m_commands.push_back({ 5, L"1,Yes,2,No" });
			m_commands.push_back({ 0, L"4" });
			m_commands.push_back({ 1, L"Jump 2" });
			m_commands.push_back({ 6, L"2" });
			m_commands.push_back({ 0, L"-1" });
		}

		virtual ~Novel() = default;

		bool start(int32 seekPoint)
		{
			const auto size = m_commands.size() - 1;
			for (auto i = 0u; i < size; i++)
			{
				const auto index = (m_currentLine + i) % m_commands.size();

				const auto command = m_commands[index];
				if (
					command.first == 0 &&
					Parse<int32>(command.second) == seekPoint
				)
				{
					clearManager();
					m_currentLine = index + 1;
					m_isUpdating = true;

					return true;
				}
			}

			return false;
		}

		void update()
		{
			while (
				m_isUpdating &&
				!m_messageManager.isUpdating() &&
				!m_choiceManager.isUpdating()
			)
			{
				m_choiceManager.lastSelectedSeekPoint().then([&](int32 seekPoint){ start(seekPoint); });
				execute();
			}

			m_messageManager.update();
			m_choiceManager.update();
		}

		bool isUpdating() const
		{
			return m_isUpdating;
		}

		int32 seekPoint() const
		{
			return m_lastSeekPoint;
		}

		void draw() const
		{
			m_spriteManager.draw();
			m_messageManager.draw();
			m_choiceManager.draw();
		}
	};
}<commit_msg>SeekPoint is last started point.<commit_after># pragma once
# include <Siv3D.hpp>
# include "AscChoiceManager.hpp"
# include "AscMessageManager.hpp"
# include "AscSoundManager.hpp"
# include "AscSpriteManager.hpp"

namespace asc
{
	using namespace s3d;

	using Commnad = std::pair<int32, String>;

	class Novel
	{
	private:

		bool m_isUpdating;

		int32 m_currentLine;

		int32 m_lastSeekPoint;

		Array<Commnad> m_commands;

		ChoiceManager m_choiceManager;

		SoundManager m_soundManager;

		MessageManager m_messageManager;

		SpriteManager m_spriteManager;

		void clearManager()
		{
			m_messageManager.clear();
			m_spriteManager.clear();
			m_choiceManager.clear();
		}

		void execute()
		{
			switch (m_commands[m_currentLine].first)
			{
			// Point
			case 0:
				m_isUpdating = false;
				return;

			// Text
			case 1:
				m_messageManager.setText(m_commands[m_currentLine].second);
				m_messageManager.start();
				break;

			// Name
			case 2:
				m_messageManager.setName(m_commands[m_currentLine].second);
				break;

			// AddSprite
			case 3:
				m_spriteManager.add<Sprite>(m_commands[m_currentLine].second);
				break;

			// AddFixedSprite
			case 4:
				m_spriteManager.add<FixedSprite>(m_commands[m_currentLine].second);
				break;

			// Choice
			case 5:
				m_choiceManager.start(m_commands[m_currentLine].second);
				break;

			// Jump
			case 6:
				start(Parse<int32>(m_commands[m_currentLine].second));
				return;

			// AutomaticText
			case 7:
				m_messageManager.setText(m_commands[m_currentLine].second);
				m_messageManager.start(true);
				break;

			default:
				break;
			}

			m_currentLine++;
		}

	public:

		Novel() :
			m_isUpdating(false),
			m_currentLine(0),
			m_lastSeekPoint(-1),
			m_messageManager(std::bind(&SoundManager::playCharSound, m_soundManager))
		{
			m_commands.push_back({ 0, L"1"});
			m_commands.push_back({ 3, L"1,character1,0,0,640,720" });
			m_commands.push_back({ 3, L"3,character3,480,180,320,360" });
			m_commands.push_back({ 1, L"Characters" });
			m_commands.push_back({ 0, L"2" });
			m_commands.push_back({ 1, L"Only Text" });
			m_commands.push_back({ 0, L"3" });
			m_commands.push_back({ 7, L"Show Character?" });
			m_commands.push_back({ 5, L"1,Yes,2,No" });
			m_commands.push_back({ 0, L"4" });
			m_commands.push_back({ 1, L"Jump 2" });
			m_commands.push_back({ 6, L"2" });
			m_commands.push_back({ 0, L"-1" });
		}

		virtual ~Novel() = default;

		bool start(int32 seekPoint)
		{
			const auto size = m_commands.size() - 1;
			for (auto i = 0u; i < size; i++)
			{
				const auto index = (m_currentLine + i) % m_commands.size();

				const auto command = m_commands[index];
				if (
					command.first == 0 &&
					Parse<int32>(command.second) == seekPoint
				)
				{
					clearManager();
					m_currentLine = index + 1;
					m_lastSeekPoint = seekPoint;
					m_isUpdating = true;

					return true;
				}
			}

			return false;
		}

		void update()
		{
			while (
				m_isUpdating &&
				!m_messageManager.isUpdating() &&
				!m_choiceManager.isUpdating()
			)
			{
				m_choiceManager.lastSelectedSeekPoint().then([&](int32 seekPoint){ start(seekPoint); });
				execute();
			}

			m_messageManager.update();
			m_choiceManager.update();
		}

		bool isUpdating() const
		{
			return m_isUpdating;
		}

		int32 seekPoint() const
		{
			return m_lastSeekPoint;
		}

		void draw() const
		{
			m_spriteManager.draw();
			m_messageManager.draw();
			m_choiceManager.draw();
		}
	};
}<|endoftext|>


<commit_before>/*
 * DbgCliTopic.cpp
 *
 *  Created on: 11.02.2015
 *      Author: niklausd
 */

#include "DbgCliTopic.h"
#include <string.h>
#include <stdlib.h>

#ifdef ARDUINO
#include "Arduino.h"
#else
#include <stdio.h>
#endif

DbgCli_Topic::DbgCli_Topic(DbgCli_Node* parentNode, const char* nodeName, const char* helpText)
: DbgCli_Node(parentNode, nodeName, helpText)
, m_firstChild(0)
{ }

DbgCli_Topic::~DbgCli_Topic()
{
  DbgCli_Node* next = m_firstChild;
  while (0 != next)
  {
    DbgCli_Node* toBeDeleted = next;
    delete next;

    next = next->getNextSibling();
  }
}

void DbgCli_Topic::addChildNode(DbgCli_Node* node)
{
  if (0 == m_firstChild)
  {
    m_firstChild = node;
  }
  else
  {
    DbgCli_Node* next = m_firstChild;

    while (0 != next->getNextSibling())
    {
      next = next->getNextSibling();
    }
    next->setNextSibling(node);
  }
}

void DbgCli_Topic::removeChildNode(DbgCli_Node* node)
{
  if (m_firstChild == node)
  {
    m_firstChild = node->getNextSibling();
  }
  else
  {
    DbgCli_Node* next = m_firstChild;
    while ((next != 0) && (next->getNextSibling() != node))
    {
      next = next->getNextSibling();
    }
    if (next != 0)
    {
      next->setNextSibling(node->getNextSibling());
    }
  }
}

void DbgCli_Topic::printAllChildNodes()
{
#ifdef ARDUINO
  Serial.print("Node ");
  Serial.print(this->getNodeName());
  Serial.print(": ");
  Serial.println(this->getHelpText());
  DbgCli_Node* tmpNode = this->getFirstChild();
  if (0 != tmpNode)
  {
    Serial.print("Contains: ");
    Serial.print(tmpNode->getNodeName());
    tmpNode = tmpNode->getNextSibling();
    while (0 != tmpNode)
    {
      Serial.print(", ");
      Serial.print(tmpNode->getNodeName());
      tmpNode = tmpNode->getNextSibling();
    }
    Serial.println(" ");
  }
#else
  printf("Node %s: %s\n", this->getNodeName(), this->getHelpText());
  DbgCli_Node* tmpNode = this->getFirstChild();
  if (0 != tmpNode)
  {
    printf("Contains: %s", tmpNode->getNodeName());
    tmpNode = tmpNode->getNextSibling();
    while (0 != tmpNode)
    {
      printf(", %s", tmpNode->getNodeName());
      tmpNode = tmpNode->getNextSibling();
    }
    printf("\n");
  }
#endif
}

DbgCli_Node* DbgCli_Topic::getChildNode(const char* nodeName)
{
  bool found = false;

  DbgCli_Node* tmpNode = m_firstChild;
  while ((0 != tmpNode) && !found)
  {
    found = (strcmp(tmpNode->getNodeName(), nodeName) == 0);
    if (!found)
    {
      tmpNode = tmpNode->getNextSibling();
    }
  }
  return tmpNode;
}

DbgCli_Node* DbgCli_Topic::getFirstChild()
{
  return m_firstChild;
}

void DbgCli_Topic::execute(unsigned int argc, const char** args, unsigned int idxToFirstArgToHandle)
{
  if (idxToFirstArgToHandle < argc)
  {
    const char* nodeName = args[idxToFirstArgToHandle];
//  #ifdef ARDUINO
//    Serial.print("DbgCli_Topic::execute, curNodeName: ");
//    Serial.print(this->getNodeName());
//    Serial.print(", nodeName: ");
//    Serial.println(nodeName);
//  #else
//    printf("DbgCli_Topic::execute, curNodeName: %s", this->getNodeName());
//    printf(", nodeName: %s\n",nodeName);
//  #endif

    DbgCli_Node* tmpNode = this->getChildNode(nodeName); //get child or sibling with this nodeName
    if (0 != tmpNode)
    {
      idxToFirstArgToHandle++;
      tmpNode->execute(argc, args, idxToFirstArgToHandle);
    }
    else if (0==strcmp(DbgCli_Topic::RootNode()->getNodeName(),nodeName))
    {
      // root node was executed
      this->printAllChildNodes();
    }
    else
    {
      // at least one node not found
  #ifdef ARDUINO
      Serial.print("Node or cmd \"");
      Serial.print(nodeName);
      Serial.println("\" not found!");
  #else
      printf("Node or cmd \"%s\" not found!\n", nodeName);
  #endif
    }
  }
  else
  { // at last node and its a topic
    this->printAllChildNodes();
  }
}
<commit_msg>fix silly mistake in DbgCli_Topic destructor<commit_after>/*
 * DbgCliTopic.cpp
 *
 *  Created on: 11.02.2015
 *      Author: niklausd
 */

#include "DbgCliTopic.h"
#include <string.h>
#include <stdlib.h>

#ifdef ARDUINO
#include "Arduino.h"
#else
#include <stdio.h>
#endif

DbgCli_Topic::DbgCli_Topic(DbgCli_Node* parentNode, const char* nodeName, const char* helpText)
: DbgCli_Node(parentNode, nodeName, helpText)
, m_firstChild(0)
{ }

DbgCli_Topic::~DbgCli_Topic()
{
  DbgCli_Node* next = m_firstChild;
  while (0 != next)
  {
    DbgCli_Node* toBeDeleted = next;
    next = next->getNextSibling();
    delete toBeDeleted;
    toBeDeleted = 0;
  }
}

void DbgCli_Topic::addChildNode(DbgCli_Node* node)
{
  if (0 == m_firstChild)
  {
    m_firstChild = node;
  }
  else
  {
    DbgCli_Node* next = m_firstChild;

    while (0 != next->getNextSibling())
    {
      next = next->getNextSibling();
    }
    next->setNextSibling(node);
  }
}

void DbgCli_Topic::removeChildNode(DbgCli_Node* node)
{
  if (m_firstChild == node)
  {
    m_firstChild = node->getNextSibling();
  }
  else
  {
    DbgCli_Node* next = m_firstChild;
    while ((next != 0) && (next->getNextSibling() != node))
    {
      next = next->getNextSibling();
    }
    if (next != 0)
    {
      next->setNextSibling(node->getNextSibling());
    }
  }
}

void DbgCli_Topic::printAllChildNodes()
{
#ifdef ARDUINO
  Serial.print("Node ");
  Serial.print(this->getNodeName());
  Serial.print(": ");
  Serial.println(this->getHelpText());
  DbgCli_Node* tmpNode = this->getFirstChild();
  if (0 != tmpNode)
  {
    Serial.print("Contains: ");
    Serial.print(tmpNode->getNodeName());
    tmpNode = tmpNode->getNextSibling();
    while (0 != tmpNode)
    {
      Serial.print(", ");
      Serial.print(tmpNode->getNodeName());
      tmpNode = tmpNode->getNextSibling();
    }
    Serial.println(" ");
  }
#else
  printf("Node %s: %s\n", this->getNodeName(), this->getHelpText());
  DbgCli_Node* tmpNode = this->getFirstChild();
  if (0 != tmpNode)
  {
    printf("Contains: %s", tmpNode->getNodeName());
    tmpNode = tmpNode->getNextSibling();
    while (0 != tmpNode)
    {
      printf(", %s", tmpNode->getNodeName());
      tmpNode = tmpNode->getNextSibling();
    }
    printf("\n");
  }
#endif
}

DbgCli_Node* DbgCli_Topic::getChildNode(const char* nodeName)
{
  bool found = false;

  DbgCli_Node* tmpNode = m_firstChild;
  while ((0 != tmpNode) && !found)
  {
    found = (strcmp(tmpNode->getNodeName(), nodeName) == 0);
    if (!found)
    {
      tmpNode = tmpNode->getNextSibling();
    }
  }
  return tmpNode;
}

DbgCli_Node* DbgCli_Topic::getFirstChild()
{
  return m_firstChild;
}

void DbgCli_Topic::execute(unsigned int argc, const char** args, unsigned int idxToFirstArgToHandle)
{
  if (idxToFirstArgToHandle < argc)
  {
    const char* nodeName = args[idxToFirstArgToHandle];
//  #ifdef ARDUINO
//    Serial.print("DbgCli_Topic::execute, curNodeName: ");
//    Serial.print(this->getNodeName());
//    Serial.print(", nodeName: ");
//    Serial.println(nodeName);
//  #else
//    printf("DbgCli_Topic::execute, curNodeName: %s", this->getNodeName());
//    printf(", nodeName: %s\n",nodeName);
//  #endif

    DbgCli_Node* tmpNode = this->getChildNode(nodeName); //get child or sibling with this nodeName
    if (0 != tmpNode)
    {
      idxToFirstArgToHandle++;
      tmpNode->execute(argc, args, idxToFirstArgToHandle);
    }
    else if (0==strcmp(DbgCli_Topic::RootNode()->getNodeName(),nodeName))
    {
      // root node was executed
      this->printAllChildNodes();
    }
    else
    {
      // at least one node not found
  #ifdef ARDUINO
      Serial.print("Node or cmd \"");
      Serial.print(nodeName);
      Serial.println("\" not found!");
  #else
      printf("Node or cmd \"%s\" not found!\n", nodeName);
  #endif
    }
  }
  else
  { // at last node and its a topic
    this->printAllChildNodes();
  }
}
<|endoftext|>


<commit_before>#include "Webclient.hpp"

Webclient::Webclient() :
	curl(curl_easy_init())
{
	curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
	curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 10);
	curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, Webclient::curlCallback);
	curl_easy_setopt(curl, CURLOPT_WRITEDATA, this);
	curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 2);
	curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10);
	curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, "gzip");
	curl_easy_setopt(curl, CURLOPT_USERAGENT, "GoogleLiteBot");
}

Webclient::~Webclient()
{
	// Cleanup CURL
	curl_easy_cleanup(curl);
}

std::string Webclient::getURL(std::string& url)
{
	// Set the link
	curl_easy_setopt(curl, CURLOPT_URL, url.c_str());

	// Clear the current buffer
	buffer.str("");

	CURLcode res = curl_easy_perform(curl);

	if (res != 0) {
		CrawlException ex;
		throw ex;
	}

	char* effectiveURL;
	curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &effectiveURL);
	url = effectiveURL;

	return buffer.str();
}

size_t Webclient::curlCallback(char* buffer, size_t size, size_t nmemb, Webclient* client)
{
	const size_t real_size = size * nmemb;

	client->buffer.write(buffer, real_size);

	return real_size;
}
<commit_msg>Non-http 200 codes are now discarded.<commit_after>#include "Webclient.hpp"

Webclient::Webclient() :
	curl(curl_easy_init())
{
	curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
	curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 10);
	curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, Webclient::curlCallback);
	curl_easy_setopt(curl, CURLOPT_WRITEDATA, this);
	curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 2);
	curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10);
	curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, "gzip");
	curl_easy_setopt(curl, CURLOPT_USERAGENT, "MIRBot/1.0 - A robot made for a course at Leiden University - Abuse: l.j.peters@umail.leidenuniv.nl");
}

Webclient::~Webclient()
{
	// Cleanup CURL
	curl_easy_cleanup(curl);
}

std::string Webclient::getURL(std::string& url)
{
	// Set the link
	curl_easy_setopt(curl, CURLOPT_URL, url.c_str());

	// Clear the current buffer
	buffer.str("");

	CURLcode res = curl_easy_perform(curl);
	long http_code;

	curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);

	if (res != 0 || http_code != 200) {
		CrawlException ex;
		throw ex;
	}

	char* effectiveURL;
	curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &effectiveURL);
	url = effectiveURL;

	return buffer.str();
}

size_t Webclient::curlCallback(char* buffer, size_t size, size_t nmemb, Webclient* client)
{
	const size_t real_size = size * nmemb;

	client->buffer.write(buffer, real_size);

	return real_size;
}
<|endoftext|>