<commit_before>// -*- mode: c++ -*-
/**************************************************************************
 * This file is property of and copyright by                              *
 * the Relativistic Heavy Ion Group (RHIG), Yale University, US, 2009     *
 *                                                                        *
 * Primary Author: Per Thomas Hille  <perthomas.hille@yale.edu>           *
 *                                                                        *
 * Contributors are mentioned in the code where appropriate.              *
 * Please report bugs to   perthomas.hille@yale.edu                       *
 *                                                                        *
 * 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.                  *
 **************************************************************************/

// The Peak-Finder algorithm
// The amplitude is extracted  as a
// weighted sum of the samples using the
// best possible weights.
// The wights is calculated only once and the
// Actual extraction of amplitude and peak position
// Is done with a simple vector multiplication, allowing for
// Extreemely fast computations.

#include "AliCaloRawAnalyzerPeakFinder.h"
#include "AliCaloBunchInfo.h"
#include "AliCaloFitResults.h"
#include "TMath.h"
#include "AliLog.h"
#include "AliCDBEntry.h"
#include "AliCDBManager.h"
#include "TFile.h"
#include "AliCaloPeakFinderVectors.h"
#include <iostream>
//#include "AliEMCALRawUtils.h"

using namespace std;

ClassImp( AliCaloRawAnalyzerPeakFinder )

AliCaloRawAnalyzerPeakFinder::AliCaloRawAnalyzerPeakFinder() :AliCaloRawAnalyzer("Peak-Finder", "PF"),
//    fAmp(0),
							      fPeakFinderVectors(0),
							      fRunOnAlien(false),
							      fIsInitialized(false)
{
  //Comment
  fAlgo= Algo::kPeakFinder;
  InitOCDB(fRunOnAlien);
  fPeakFinderVectors = new AliCaloPeakFinderVectors() ;
  ResetVectors();
  LoadVectorsOCDB();
}

void
AliCaloRawAnalyzerPeakFinder::InitOCDB(bool alien) const
{
  // Setting the default OCDB pathe depending on wether we work locally or on the GRID.
  AliCDBManager::Instance()->SetDefaultStorage(  alien == true ? "alien://$ALICE_ROOT/OCDB" : "local://$ALICE_ROOT/OCDB");
  AliCDBManager::Instance()->SetRun(100);
}

void
AliCaloRawAnalyzerPeakFinder::ResetVectors()
{
  //As name implies
  for(int i=0; i < PF::MAXSTART; i++)
    {
      for(int j=0; j < PF::SAMPLERANGE; j++ )
	{
	  for(int k=0; k < 100; k++ )
	    {
	      fPFAmpVectors[i][j][k] = 0;
	      fPFTofVectors[i][j][k] = 0;
	      fPFAmpVectorsCoarse[i][j][k] = 0;
	      fPFTofVectorsCoarse[i][j][k] = 0;
	    }
	}
    }
}

AliCaloRawAnalyzerPeakFinder::~AliCaloRawAnalyzerPeakFinder()
{
  //comment
}

Double_t
AliCaloRawAnalyzerPeakFinder::ScanCoarse(const Double_t *const array, const int length ) const
{
  // Fisrt (coarce) estimate of Amplitude using the Peak-Finder.
  // The output of the first iteration is sued to select vectors
  // for the second iteration.

  Double_t tmpTof = 0;
  Double_t tmpAmp= 0;

  for(int i=0; i < length; i++)
    {
      tmpTof += fPFTofVectorsCoarse[0][length][i]*array[i];
      tmpAmp += fPFAmpVectorsCoarse[0][length][i]*array[i];
    }

  tmpTof = tmpTof / tmpAmp ;
  return tmpTof;
}

AliCaloFitResults
AliCaloRawAnalyzerPeakFinder::Evaluate( const vector<AliCaloBunchInfo> &bunchvector, const UInt_t altrocfg1,  const UInt_t altrocfg2 )
{
  if( fIsInitialized == false )
    {
      cout << __FILE__ << ":" << __LINE__ << "ERROR, peakfinder vectors not loaded" << endl;
      return  AliCaloFitResults(kInvalid, kInvalid);
    }

  // Extracting the amplitude using the Peak-Finder algorithm
  // The amplitude is a weighted sum of the samples using
  // optimum weights.

  short maxampindex; //index of maximum amplitude
  short maxamp; //Maximum amplitude
  fAmp = 0;
  int index = SelectBunch( bunchvector,  &maxampindex,  &maxamp );

  if( index >= 0)
    {
      Float_t ped = ReverseAndSubtractPed( &(bunchvector.at(index))  ,  altrocfg1, altrocfg2, fReversed  );
      Float_t maxf = TMath::MaxElement(   bunchvector.at(index).GetLength(),  fReversed );
      short timebinOffset = maxampindex - (bunchvector.at( index ).GetLength()-1);

      if(  maxf < fAmpCut  ||  ( maxamp - ped) > fOverflowCut  ) // (maxamp - ped) > fOverflowCut = Close to saturation (use low gain then)
	{
	  return  AliCaloFitResults( maxamp, ped, Ret::kCrude, maxf, timebinOffset);
 	}
      else if ( maxf >= fAmpCut )
	{
	  int first = 0;
	  int last = 0;
	  short maxrev = maxampindex  -  bunchvector.at(index).GetStartBin();
	  SelectSubarray( fReversed,  bunchvector.at(index).GetLength(), maxrev, &first, &last, fFitArrayCut);
	  int nsamples =  last - first;

	  if( ( nsamples  )  >= fNsampleCut ) // no if statement needed really; keep for readability
	    {
	      int startbin = bunchvector.at(index).GetStartBin();
	      int n = last - first;
	      int pfindex = n - fNsampleCut;
	      pfindex = pfindex > PF::SAMPLERANGE ? PF::SAMPLERANGE : pfindex;

	      int dt =  maxampindex - startbin -2;
	      int tmpindex = 0;

	      Float_t tmptof = ScanCoarse( &fReversed[dt] , n );

	      if( tmptof < -1 )
		{
		  tmpindex = 0;
		}
	      else
		if( tmptof  > -1 && tmptof < 100 )
		  {
		    tmpindex = 1;
		  }
		else
		  {
		    tmpindex = 2;
		  }

	      double tof = 0;

	      for(int k=0; k < PF::SAMPLERANGE; k++   )
		{
		  tof +=  fPFTofVectors[0][pfindex][k]*fReversed[ dt  +k + tmpindex -1 ];
		}

	      for( int i=0; i < PF::SAMPLERANGE; i++ )
		{
		  {
		    fAmp += fPFAmpVectors[0][pfindex][i]*fReversed[ dt  +i  +tmpindex -1 ];
		  }
		}
	      if( TMath::Abs(  (maxf - fAmp  )/maxf )  >   0.1 )
		{
		  //	  cout << __FILE__ << ":" << __LINE__ << "WARNING: amp was" << fAmp <<", but was changed to "<< maxf << endl;
		  fAmp = maxf;
		}

	      //      tof = timebinOffset - 0.01*tof/fAmp; // clock ticks
	      tof = timebinOffset - 0.01*tof/fAmp - fL1Phase/TIMEBINWITH; // clock

	      // use local-array time for chi2 estimate
	      Float_t chi2 = CalculateChi2(fAmp, tof-timebinOffset+maxrev, first, last);
	      Int_t ndf = last - first - 1; // nsamples - 2
	      return AliCaloFitResults( maxamp, ped , Ret::kFitPar, fAmp, tof,
					timebinOffset, chi2, ndf,
					Ret::kDummy, AliCaloFitSubarray(index, maxrev, first, last) );
	    }
	  else
	    {
	      Float_t chi2 = CalculateChi2(maxf, maxrev, first, last);
	      Int_t ndf = last - first - 1; // nsamples - 2
	      return AliCaloFitResults( maxamp, ped , Ret::kCrude, maxf, timebinOffset,
					timebinOffset, chi2, ndf, Ret::kDummy, AliCaloFitSubarray(index, maxrev, first, last) );
	    }
	} // ampcut
    }
  return  AliCaloFitResults(kInvalid, kInvalid);
}

void
AliCaloRawAnalyzerPeakFinder::CopyVectors( const AliCaloPeakFinderVectors *const pfv )
{
  // As name implies
  if ( pfv != 0)
    {
      for(int i = 0;  i < PF::MAXSTART ; i++)
	{
	  for( int j=0; j < PF::SAMPLERANGE; j++)
	    {
	      pfv->GetVector( i, j, fPFAmpVectors[i][j] ,  fPFTofVectors[i][j],
			      fPFAmpVectorsCoarse[i][j] , fPFTofVectorsCoarse[i][j]  );

	      fPeakFinderVectors->SetVector( i, j, fPFAmpVectors[i][j], fPFTofVectors[i][j],
					     fPFAmpVectorsCoarse[i][j], fPFTofVectorsCoarse[i][j] );
	    }
	}
    }
  else
    {
      AliFatal( "pfv = ZERO !!!!!!!");
    }
}

void
AliCaloRawAnalyzerPeakFinder::LoadVectorsOCDB()
{
  //Loading of Peak-Finder  vectors from the
  //Offline Condition Database  (OCDB)
  AliCDBEntry* entry = AliCDBManager::Instance()->Get("EMCAL/Calib/PeakFinder/");

  if( entry != 0 )
  {

    cout << __FILE__ << ":" << __LINE__ << ": Printing metadata !! " << endl;
    entry->PrintMetaData();

    AliCaloPeakFinderVectors  *pfv = (AliCaloPeakFinderVectors *)entry->GetObject();
    if( pfv == 0 )
    {
      cout << __FILE__ << ":" << __LINE__ << "_ ERRROR " << endl;
    }

    CopyVectors( pfv );

    if( pfv != 0 )
    {
      fIsInitialized = true;
    }
  }

}

void
AliCaloRawAnalyzerPeakFinder::LoadVectorsASCII()
{
  //Read in the Peak finder vecors from ASCI files
  fIsInitialized= true;
  const Int_t buffersize = 256;
  for(int i = 0;  i < PF::MAXSTART ; i++)
  {
    for( int j=0; j < PF::SAMPLERANGE; j++)
    {
      char filenameCoarse[buffersize];
      char filename[buffersize];
      int n = j+fNsampleCut;
      double start = (double)i+0;

      snprintf(filename, buffersize,       "%s/EMCAL/vectors-emcal/start%.1fN%dtau0.235fs10dt1.0.txt", getenv("ALICE_ROOT"), start, n);
      snprintf(filenameCoarse, buffersize, "%s/EMCAL/vectors-emcal/start%.1fN%dtau0.235fs10dt3.0.txt", getenv("ALICE_ROOT"), start, n);

      FILE *fp  =  fopen(filename, "r");
      FILE *fpc =  fopen(filenameCoarse, "r");

      if( fp == 0 )
	    {
	      AliFatal( Form( "could not open file: %s", filename ) );
	    }
      else if(fpc == 0)
	    {
	      AliFatal( Form( "could not open file: %s", filenameCoarse ) );
	    }
      else
	    {
	      for(int m = 0; m < n ; m++ )
        {
          fscanf(fp, "%lf\t", &fPFAmpVectors[i][j][m] );
          fscanf(fpc, "%lf\t", &fPFAmpVectorsCoarse[i][j][m] );
        }
	      fscanf(fp,   "\n" );
	      fscanf(fpc,  "\n" );
	      for(int m = 0; m < n ; m++ )
        {
          fscanf(fp, "%lf\t",   &fPFTofVectors[i][j][m]  );
          fscanf(fpc, "%lf\t",  &fPFTofVectorsCoarse[i][j][m]  );
        }

	      fPeakFinderVectors->SetVector( i, j, fPFAmpVectors[i][j], fPFTofVectors[i][j],
                                      fPFAmpVectorsCoarse[i][j], fPFTofVectorsCoarse[i][j] );

	      fclose (fp);
	      fclose (fpc);
	    }

      delete fp;
      delete fpc;

    }
  }
}

void
AliCaloRawAnalyzerPeakFinder::WriteRootFile() const
{
  // Utility function to write Peak-Finder vectors to an root file
  // The output is used to create an OCDB entry.
  fPeakFinderVectors->PrintVectors();
  TFile *f = new TFile("peakfindervectors2.root",  "recreate" );
  fPeakFinderVectors->Write();
  f->Close();
  delete f;
}

void
AliCaloRawAnalyzerPeakFinder::PrintVectors()
{
  for(int i=0; i < 20; i++)
    {
      for( int j = 0; j < PF::MAXSTART; j ++ )
	{
	  for( int k=0; k < PF::SAMPLERANGE; k++ )
	    {
	      cout << fPFAmpVectors[j][k][i] << "\t" ;
	    }
	}
      cout << endl;
    }
  cout << __FILE__ << ":" << __LINE__ << ":.... DONE !!" << endl;
}
<commit_msg>coverity 2<commit_after>// -*- mode: c++ -*-
/**************************************************************************
 * This file is property of and copyright by                              *
 * the Relativistic Heavy Ion Group (RHIG), Yale University, US, 2009     *
 *                                                                        *
 * Primary Author: Per Thomas Hille  <perthomas.hille@yale.edu>           *
 *                                                                        *
 * Contributors are mentioned in the code where appropriate.              *
 * Please report bugs to   perthomas.hille@yale.edu                       *
 *                                                                        *
 * 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.                  *
 **************************************************************************/

// The Peak-Finder algorithm
// The amplitude is extracted  as a
// weighted sum of the samples using the
// best possible weights.
// The wights is calculated only once and the
// Actual extraction of amplitude and peak position
// Is done with a simple vector multiplication, allowing for
// Extreemely fast computations.

#include "AliCaloRawAnalyzerPeakFinder.h"
#include "AliCaloBunchInfo.h"
#include "AliCaloFitResults.h"
#include "TMath.h"
#include "AliLog.h"
#include "AliCDBEntry.h"
#include "AliCDBManager.h"
#include "TFile.h"
#include "AliCaloPeakFinderVectors.h"
#include <iostream>
//#include "AliEMCALRawUtils.h"

using namespace std;

ClassImp( AliCaloRawAnalyzerPeakFinder )

AliCaloRawAnalyzerPeakFinder::AliCaloRawAnalyzerPeakFinder() :AliCaloRawAnalyzer("Peak-Finder", "PF"),
//    fAmp(0),
							      fPeakFinderVectors(0),
							      fRunOnAlien(false),
							      fIsInitialized(false)
{
  //Comment
  fAlgo= Algo::kPeakFinder;
  InitOCDB(fRunOnAlien);
  fPeakFinderVectors = new AliCaloPeakFinderVectors() ;
  ResetVectors();
  LoadVectorsOCDB();
}

void
AliCaloRawAnalyzerPeakFinder::InitOCDB(bool alien) const
{
  // Setting the default OCDB pathe depending on wether we work locally or on the GRID.
  AliCDBManager::Instance()->SetDefaultStorage(  alien == true ? "alien://$ALICE_ROOT/OCDB" : "local://$ALICE_ROOT/OCDB");
  AliCDBManager::Instance()->SetRun(100);
}

void
AliCaloRawAnalyzerPeakFinder::ResetVectors()
{
  //As name implies
  for(int i=0; i < PF::MAXSTART; i++)
    {
      for(int j=0; j < PF::SAMPLERANGE; j++ )
	{
	  for(int k=0; k < 100; k++ )
	    {
	      fPFAmpVectors[i][j][k] = 0;
	      fPFTofVectors[i][j][k] = 0;
	      fPFAmpVectorsCoarse[i][j][k] = 0;
	      fPFTofVectorsCoarse[i][j][k] = 0;
	    }
	}
    }
}

AliCaloRawAnalyzerPeakFinder::~AliCaloRawAnalyzerPeakFinder()
{
  //comment
}

Double_t
AliCaloRawAnalyzerPeakFinder::ScanCoarse(const Double_t *const array, const int length ) const
{
  // Fisrt (coarce) estimate of Amplitude using the Peak-Finder.
  // The output of the first iteration is sued to select vectors
  // for the second iteration.

  Double_t tmpTof = 0;
  Double_t tmpAmp= 0;

  for(int i=0; i < length; i++)
    {
      tmpTof += fPFTofVectorsCoarse[0][length][i]*array[i];
      tmpAmp += fPFAmpVectorsCoarse[0][length][i]*array[i];
    }

  tmpTof = tmpTof / tmpAmp ;
  return tmpTof;
}

AliCaloFitResults
AliCaloRawAnalyzerPeakFinder::Evaluate( const vector<AliCaloBunchInfo> &bunchvector, const UInt_t altrocfg1,  const UInt_t altrocfg2 )
{
  if( fIsInitialized == false )
    {
      cout << __FILE__ << ":" << __LINE__ << "ERROR, peakfinder vectors not loaded" << endl;
      return  AliCaloFitResults(kInvalid, kInvalid);
    }

  // Extracting the amplitude using the Peak-Finder algorithm
  // The amplitude is a weighted sum of the samples using
  // optimum weights.

  short maxampindex; //index of maximum amplitude
  short maxamp; //Maximum amplitude
  fAmp = 0;
  int index = SelectBunch( bunchvector,  &maxampindex,  &maxamp );

  if( index >= 0)
    {
      Float_t ped = ReverseAndSubtractPed( &(bunchvector.at(index))  ,  altrocfg1, altrocfg2, fReversed  );
      Float_t maxf = TMath::MaxElement(   bunchvector.at(index).GetLength(),  fReversed );
      short timebinOffset = maxampindex - (bunchvector.at( index ).GetLength()-1);

      if(  maxf < fAmpCut  ||  ( maxamp - ped) > fOverflowCut  ) // (maxamp - ped) > fOverflowCut = Close to saturation (use low gain then)
	{
	  return  AliCaloFitResults( maxamp, ped, Ret::kCrude, maxf, timebinOffset);
 	}
      else if ( maxf >= fAmpCut )
	{
	  int first = 0;
	  int last = 0;
	  short maxrev = maxampindex  -  bunchvector.at(index).GetStartBin();
	  SelectSubarray( fReversed,  bunchvector.at(index).GetLength(), maxrev, &first, &last, fFitArrayCut);
	  int nsamples =  last - first;

	  if( ( nsamples  )  >= fNsampleCut ) // no if statement needed really; keep for readability
	    {
	      int startbin = bunchvector.at(index).GetStartBin();
	      int n = last - first;
	      int pfindex = n - fNsampleCut;
	      pfindex = pfindex > PF::SAMPLERANGE ? PF::SAMPLERANGE : pfindex;

	      int dt =  maxampindex - startbin -2;
	      int tmpindex = 0;

	      Float_t tmptof = ScanCoarse( &fReversed[dt] , n );

	      if( tmptof < -1 )
		{
		  tmpindex = 0;
		}
	      else
		if( tmptof  > -1 && tmptof < 100 )
		  {
		    tmpindex = 1;
		  }
		else
		  {
		    tmpindex = 2;
		  }

	      double tof = 0;

	      for(int k=0; k < PF::SAMPLERANGE; k++   )
		{
		  tof +=  fPFTofVectors[0][pfindex][k]*fReversed[ dt  +k + tmpindex -1 ];
		}

	      for( int i=0; i < PF::SAMPLERANGE; i++ )
		{
		  {
		    fAmp += fPFAmpVectors[0][pfindex][i]*fReversed[ dt  +i  +tmpindex -1 ];
		  }
		}
	      if( TMath::Abs(  (maxf - fAmp  )/maxf )  >   0.1 )
		{
		  //	  cout << __FILE__ << ":" << __LINE__ << "WARNING: amp was" << fAmp <<", but was changed to "<< maxf << endl;
		  fAmp = maxf;
		}

	      //      tof = timebinOffset - 0.01*tof/fAmp; // clock ticks
	      tof = timebinOffset - 0.01*tof/fAmp - fL1Phase/TIMEBINWITH; // clock

	      // use local-array time for chi2 estimate
	      Float_t chi2 = CalculateChi2(fAmp, tof-timebinOffset+maxrev, first, last);
	      Int_t ndf = last - first - 1; // nsamples - 2
	      return AliCaloFitResults( maxamp, ped , Ret::kFitPar, fAmp, tof,
					timebinOffset, chi2, ndf,
					Ret::kDummy, AliCaloFitSubarray(index, maxrev, first, last) );
	    }
	  else
	    {
	      Float_t chi2 = CalculateChi2(maxf, maxrev, first, last);
	      Int_t ndf = last - first - 1; // nsamples - 2
	      return AliCaloFitResults( maxamp, ped , Ret::kCrude, maxf, timebinOffset,
					timebinOffset, chi2, ndf, Ret::kDummy, AliCaloFitSubarray(index, maxrev, first, last) );
	    }
	} // ampcut
    }
  return  AliCaloFitResults(kInvalid, kInvalid);
}

void
AliCaloRawAnalyzerPeakFinder::CopyVectors( const AliCaloPeakFinderVectors *const pfv )
{
  // As name implies
  if ( pfv != 0)
    {
      for(int i = 0;  i < PF::MAXSTART ; i++)
	{
	  for( int j=0; j < PF::SAMPLERANGE; j++)
	    {
	      pfv->GetVector( i, j, fPFAmpVectors[i][j] ,  fPFTofVectors[i][j],
			      fPFAmpVectorsCoarse[i][j] , fPFTofVectorsCoarse[i][j]  );

	      fPeakFinderVectors->SetVector( i, j, fPFAmpVectors[i][j], fPFTofVectors[i][j],
					     fPFAmpVectorsCoarse[i][j], fPFTofVectorsCoarse[i][j] );
	    }
	}
    }
  else
    {
      AliFatal( "pfv = ZERO !!!!!!!");
    }
}

void
AliCaloRawAnalyzerPeakFinder::LoadVectorsOCDB()
{
  //Loading of Peak-Finder  vectors from the
  //Offline Condition Database  (OCDB)
  AliCDBEntry* entry = AliCDBManager::Instance()->Get("EMCAL/Calib/PeakFinder/");

  if( entry != 0 )
  {

    cout << __FILE__ << ":" << __LINE__ << ": Printing metadata !! " << endl;
    entry->PrintMetaData();

    AliCaloPeakFinderVectors  *pfv = (AliCaloPeakFinderVectors *)entry->GetObject();
    if( pfv == 0 )
    {
      cout << __FILE__ << ":" << __LINE__ << "_ ERRROR " << endl;
    }

    CopyVectors( pfv );

    if( pfv != 0 )
    {
      fIsInitialized = true;
    }
  }

}

void
AliCaloRawAnalyzerPeakFinder::LoadVectorsASCII()
{
  //Read in the Peak finder vecors from ASCI files
  fIsInitialized= true;
  const Int_t buffersize = 256;
  for(int i = 0;  i < PF::MAXSTART ; i++)
  {
    for( int j=0; j < PF::SAMPLERANGE; j++)
    {
      char filenameCoarse[buffersize];
      char filename[buffersize];
      int n = j+fNsampleCut;
      double start = (double)i+0;

      snprintf(filename, buffersize,       "%s/EMCAL/vectors-emcal/start%.1fN%dtau0.235fs10dt1.0.txt", getenv("ALICE_ROOT"), start, n);
      snprintf(filenameCoarse, buffersize, "%s/EMCAL/vectors-emcal/start%.1fN%dtau0.235fs10dt3.0.txt", getenv("ALICE_ROOT"), start, n);

      FILE *fp  =  fopen(filename, "r");
      FILE *fpc =  fopen(filenameCoarse, "r");

      if( fp == 0 )
	    {
	      AliFatal( Form( "could not open file: %s", filename ) );
	    }
      else if(fpc == 0)
	    {
	      AliFatal( Form( "could not open file: %s", filenameCoarse ) );
	    }
      else
	    {
	      for(int m = 0; m < n ; m++ )
        {
          fscanf(fp,  "%lf\t", &fPFAmpVectors[i][j][m] );
          fscanf(fpc, "%lf\t", &fPFAmpVectorsCoarse[i][j][m] );
        }
	      fscanf(fp,   "\n" );
	      fscanf(fpc,  "\n" );
	      for(int m = 0; m < n ; m++ )
        {
          fscanf(fp, "%lf\t",   &fPFTofVectors[i][j][m]  );
          fscanf(fpc, "%lf\t",  &fPFTofVectorsCoarse[i][j][m]  );
        }

	      fPeakFinderVectors->SetVector( i, j, fPFAmpVectors[i][j], fPFTofVectors[i][j],
                                      fPFAmpVectorsCoarse[i][j], fPFTofVectorsCoarse[i][j] );

	    }

      if(fp) fclose (fp );
      if(fpc)fclose (fpc);

    }
  }
}

void
AliCaloRawAnalyzerPeakFinder::WriteRootFile() const
{
  // Utility function to write Peak-Finder vectors to an root file
  // The output is used to create an OCDB entry.
  fPeakFinderVectors->PrintVectors();
  TFile *f = new TFile("peakfindervectors2.root",  "recreate" );
  fPeakFinderVectors->Write();
  f->Close();
  delete f;
}

void
AliCaloRawAnalyzerPeakFinder::PrintVectors()
{
  for(int i=0; i < 20; i++)
    {
      for( int j = 0; j < PF::MAXSTART; j ++ )
	{
	  for( int k=0; k < PF::SAMPLERANGE; k++ )
	    {
	      cout << fPFAmpVectors[j][k][i] << "\t" ;
	    }
	}
      cout << endl;
    }
  cout << __FILE__ << ":" << __LINE__ << ":.... DONE !!" << endl;
}
<|endoftext|>


<commit_before>//
//  AliEveDataSourceOnline.cpp
//  xAliRoot
//
//  Created by Jeremi Niedziela on 28/05/15.
//
//

#include "AliEveDataSourceOnline.h"
#include "AliEveConfigManager.h"

#include "AliZMQManager.h"
#include "AliOnlineReconstructionUtil.h"
#include "AliGRPPreprocessor.h"

#include <TEnv.h>
#include <TInterpreter.h>

#include <iostream>

using namespace std;

ClassImp(AliEveDataSourceOnline)

AliEveDataSourceOnline::AliEveDataSourceOnline(bool storageManager) :
    AliEveDataSource(storageManager),
    fEventListenerThread(0),
    fStorageManagerWatcherThread(0),
    fEventInUse(1),
    fWritingToEventIndex(0),
    fIsNewEventAvaliable(false),
    fFailCounter(0),
    fStorageDown(false),
    fFinished(false),
    fStorageManager(storageManager),
    fEventManager(0)
{
    fEventManager = AliEveEventManager::GetMaster();

    StorageManagerDown(); // turn SM off by default
    EventServerDown();    // assume that there are no events comming from online reco

    // start threads:
    fEventListenerThread = new TThread("fEventListenerThread",DispatchEventListener,(void*)this);
    fEventListenerThread->Run();

    if(fStorageManager){
        fStorageManagerWatcherThread = new TThread("fStorageManagerWatcherThread",DispatchStorageManagerWatcher,(void*)this);
        fStorageManagerWatcherThread->Run();
    }
}

AliEveDataSourceOnline::~AliEveDataSourceOnline()
{
    fFinished = true;
    if(fEventListenerThread)
    {
        fEventListenerThread->Join();
        fEventListenerThread->Kill();
        delete fEventListenerThread;
        cout<<"listener thread killed and deleted"<<endl;
    }
    if(fStorageManagerWatcherThread)
    {
        fStorageManagerWatcherThread->Join();
        fStorageManagerWatcherThread->Kill();
        delete fStorageManagerWatcherThread;
        cout<<"storage watcher thread killed and deleted"<<endl;
    }
}

void AliEveDataSourceOnline::GetNextEvent()
{
    AliZMQManager *eventManager = AliZMQManager::GetInstance();
    eventManager->CreateSocket(EVENTS_SERVER_SUB);

    fCurrentEvent[0]=0;
    fCurrentEvent[1]=0;

    AliESDEvent *tmpEvent;

    cout<<"Starting subscriber's loop"<<endl;
    while(!fFinished)
    {
        cout<<"Waiting for event from online reconstruction...";
        if(eventManager->Get(tmpEvent,EVENTS_SERVER_SUB))
        {
            if(tmpEvent)
            {
                cout<<"received. ("<<tmpEvent->GetRunNumber();
                if(tmpEvent->GetRunNumber()>=0)
                {
#if ROOT_VERSION_CODE < ROOT_VERSION(5,99,0)
                    gCINTMutex->Lock();
#endif
                    if(fEventInUse == 0){fWritingToEventIndex = 1;}
                    else if(fEventInUse == 1){fWritingToEventIndex = 0;}
                    cout<<","<<tmpEvent->GetEventNumberInFile()<<")"<<endl;
                    if(fCurrentEvent[fWritingToEventIndex])
                    {
                        delete fCurrentEvent[fWritingToEventIndex];
                        fCurrentEvent[fWritingToEventIndex]=0;
                    }
                    fCurrentEvent[fWritingToEventIndex] = tmpEvent;
                    fIsNewEventAvaliable = true;
                    gCINTMutex->UnLock();
#endif
                }
            }
            else
            {
                cout<<"received empty event."<<endl;
                sleep(1);
            }
        }
        else
        {
            cout<<"couldn't receive.";
            sleep(1);
        }
    }
}

void AliEveDataSourceOnline::CheckStorageStatus()
{
    if(!fStorageManager){return;}

    AliEveConfigManager *configManager = AliEveConfigManager::GetMaster();
    configManager->ConnectEventManagerSignals();

    AliZMQManager *eventManager = AliZMQManager::GetInstance();
    storageSockets socket = CLIENT_COMMUNICATION_REQ;
    eventManager->CreateSocket(socket);

    struct clientRequestStruct *request = new struct clientRequestStruct;
    request->messageType = REQUEST_CONNECTION;

    long response;
    bool receiveStatus = false;
    bool sendStatus = false;

    StorageManagerDown();// assume that storage manager is down

    while (!fFinished)
    {
        while(sendStatus==false)// send request message until success
        {
            sendStatus = eventManager->Send(request,socket);
            if(sendStatus==false)
            {
                //eventManager->RecreateSocket(socket);
                sleep(1);
            }
        }
        cout<<"EVENT DISPLAY -- message sent to SM"<<endl;

        receiveStatus = eventManager->Get(&response,socket); // try to reveive response
        if(receiveStatus == false) // if failed (or timeouted)
        {
            cout<<"EVENT DISPLAY -- failed to receive message from SM"<<endl;
            eventManager->RecreateSocket(socket); // destroy and open socket again, to be able to send message (currently, as receive failed, socket is still in RECV state

            if(!fStorageDown) // if requires change
            {
                cout<<"EVENT DISPLAY -- storage DOWN"<<endl;
                StorageManagerDown();
            }
        }
        else if(fStorageDown) // if success and requires change
        {
            cout<<"EVENT DISPLAY -- storage OK"<<endl;
            StorageManagerOk();
        }
        sleep(1);
        sendStatus=false;
    }

    AliEveEventManager *manager = fEventManager;
    manager->Disconnect("StorageManagerOk");
    manager->Disconnect("StorageManagerDown");
}

void AliEveDataSourceOnline::GotoEvent(Int_t event)
{
    cout<<"Go to event:"<<event<<endl;

    if (fStorageDown && -1 == event)
    {
        NextEvent();
        return;
    }

    if (fCurrentData.fESD)
    {
        // create new server request:
        struct serverRequestStruct *requestMessage = new struct serverRequestStruct;

        // set request type:
        if (event == -1)      {requestMessage->messageType = REQUEST_GET_LAST_EVENT;}
        else  if (event == 0) {requestMessage->messageType = REQUEST_GET_FIRST_EVENT;}
        else  if (event == 1) {requestMessage->messageType = REQUEST_GET_PREV_EVENT;}
        else  if (event == 2) {requestMessage->messageType = REQUEST_GET_NEXT_EVENT;}

        // set event struct:
        requestMessage->eventsRunNumber = fCurrentData.fESD->GetRunNumber();
        requestMessage->eventsEventNumber = fCurrentData.fESD->GetEventNumberInFile();

        // create event manager:
        AliZMQManager *eventManager = AliZMQManager::GetInstance();
        AliESDEvent *resultEvent = NULL;

#if ROOT_VERSION_CODE < ROOT_VERSION(5,99,0)
        gCINTMutex->Lock();
#endif

        // send request and receive event:
        eventManager->Send(requestMessage,SERVER_COMMUNICATION_REQ);
        eventManager->Get(resultEvent,SERVER_COMMUNICATION_REQ);

        if(resultEvent)
        {
//            DestroyElements();
            fCurrentData.fESD = resultEvent;
        }
        else
        {
            if(event==-1){cout<<"\n\nWARNING -- No last event is avaliable.\n\n"<<endl;}
            if(event==0){cout<<"\n\nWARNING -- No first event is avaliable.\n\n"<<endl;}
            if(event==1){cout<<"\n\nWARNING -- No previous event is avaliable.\n\n"<<endl;}
            if(event==2){cout<<"\n\nWARNING -- No next event is avaliable.\n\n"<<endl;}
        }

#if ROOT_VERSION_CODE < ROOT_VERSION(5,99,0)
        gCINTMutex->UnLock();
#endif
    }
    else
    {
        cout<<"\n\nWARNING -- No event has been already loaded. Loading the most recent event...\n\n"<<endl;

        struct serverRequestStruct *requestMessage = new struct serverRequestStruct;
        requestMessage->messageType = REQUEST_GET_LAST_EVENT;

        AliZMQManager *eventManager = AliZMQManager::GetInstance();
        AliESDEvent *resultEvent = NULL;

#if ROOT_VERSION_CODE < ROOT_VERSION(5,99,0)
        gCINTMutex->Lock();
#endif
        eventManager->Send(requestMessage,SERVER_COMMUNICATION_REQ);
        eventManager->Get(resultEvent,SERVER_COMMUNICATION_REQ);

        if(resultEvent)
        {
//            DestroyElements();
            fCurrentData.fESD = resultEvent;
        }
        else{cout<<"\n\nWARNING -- The most recent event is not avaliable.\n\n"<<endl;}
#if ROOT_VERSION_CODE < ROOT_VERSION(5,99,0)
        gCINTMutex->UnLock();
#endif
    }
}

void AliEveDataSourceOnline::NextEvent()
{
#if ROOT_VERSION_CODE < ROOT_VERSION(5,99,0)
    gCINTMutex->Lock();
#endif
    if(fIsNewEventAvaliable)
    {
        fEventManager->DestroyTransients();

        if(fWritingToEventIndex == 0) fEventInUse = 0;
        else if(fWritingToEventIndex == 1) fEventInUse = 1;

        if(fCurrentEvent[fEventInUse])
        {
            if(fCurrentEvent[fEventInUse]->GetRunNumber() >= 0)
            {
                fFailCounter=0;
                EventServerOk();
                cout<<"================ setting event to "<<fCurrentEvent[fEventInUse]->GetEventNumberInFile()<<"================"<<endl;

                StorageManagerDown(); // block SM while event is being loaded
                fEventManager->DestroyElements();
                if(fCurrentEvent[fEventInUse]->GetRunNumber() != fEventManager->GetCurrentRun()){
                    fEventManager->ResetMagneticField();
                    fEventManager->SetCurrentRun(fCurrentEvent[fEventInUse]->GetRunNumber());
                }
                fCurrentData.fESD = fCurrentEvent[fEventInUse];

                fEventManager->SetHasEvent(true);
                fEventManager->AfterNewEventLoaded();

                if (fEventManager->GetAutoLoad()) {
                    fEventManager->StartAutoLoadTimer();
                }
                fEventManager->NewEventLoaded();
            }
        }
        fIsNewEventAvaliable = false;
    }
    else
    {
        cout<<"No new event is avaliable."<<endl;
        fFailCounter++;
        fEventManager->NoEventLoaded();
    }
    if(fFailCounter==5)
    {
        EventServerDown();
        fFailCounter=0;
    }
#if ROOT_VERSION_CODE < ROOT_VERSION(5,99,0)
    gCINTMutex->UnLock();
#endif
    gSystem->ProcessEvents();
}

void AliEveDataSourceOnline::MarkCurrentEvent()
{
    if(!fStorageManager){return;}

    struct serverRequestStruct *requestMessage = new struct serverRequestStruct;
    requestMessage->eventsRunNumber = fCurrentData.fESD->GetRunNumber();
    requestMessage->eventsEventNumber = fCurrentData.fESD->GetEventNumberInFile();
    requestMessage->messageType = REQUEST_MARK_EVENT;

    AliZMQManager *eventManager = AliZMQManager::GetInstance();

    eventManager->Send(requestMessage,SERVER_COMMUNICATION_REQ);
    bool response;
    eventManager->Get(&response,SERVER_COMMUNICATION_REQ);

    if(response)
    {
        //fStatusLabel->SetText("Event marked");
        cout<<"ADMIN PANEL -- Event marked succesfully"<<endl;
    }
    else
    {
        //fStatusLabel->SetText("Couldn't mark this event");
        cout<<"ADMIN PANEL -- Could not matk event"<<endl;
    }
    if(requestMessage){delete requestMessage;}
}

void AliEveDataSourceOnline::StorageManagerOk()
{
//    Emit("StorageManagerOk()");
}
void AliEveDataSourceOnline::StorageManagerDown()
{
//    Emit("StorageManagerDown()");
}

void AliEveDataSourceOnline::EventServerOk()
{
//    Emit("EventServerOk()");
}
void AliEveDataSourceOnline::EventServerDown()
{
//    Emit("EventServerDown()");
}

<commit_msg>EveBase: fixed #if lost during merge<commit_after>//
//  AliEveDataSourceOnline.cpp
//  xAliRoot
//
//  Created by Jeremi Niedziela on 28/05/15.
//
//

#include "AliEveDataSourceOnline.h"
#include "AliEveConfigManager.h"

#include "AliZMQManager.h"
#include "AliOnlineReconstructionUtil.h"
#include "AliGRPPreprocessor.h"

#include <TEnv.h>
#include <TInterpreter.h>

#include <iostream>

using namespace std;

ClassImp(AliEveDataSourceOnline)

AliEveDataSourceOnline::AliEveDataSourceOnline(bool storageManager) :
    AliEveDataSource(storageManager),
    fEventListenerThread(0),
    fStorageManagerWatcherThread(0),
    fEventInUse(1),
    fWritingToEventIndex(0),
    fIsNewEventAvaliable(false),
    fFailCounter(0),
    fStorageDown(false),
    fFinished(false),
    fStorageManager(storageManager),
    fEventManager(0)
{
    fEventManager = AliEveEventManager::GetMaster();

    StorageManagerDown(); // turn SM off by default
    EventServerDown();    // assume that there are no events comming from online reco

    // start threads:
    fEventListenerThread = new TThread("fEventListenerThread",DispatchEventListener,(void*)this);
    fEventListenerThread->Run();

    if(fStorageManager){
        fStorageManagerWatcherThread = new TThread("fStorageManagerWatcherThread",DispatchStorageManagerWatcher,(void*)this);
        fStorageManagerWatcherThread->Run();
    }
}

AliEveDataSourceOnline::~AliEveDataSourceOnline()
{
    fFinished = true;
    if(fEventListenerThread)
    {
        fEventListenerThread->Join();
        fEventListenerThread->Kill();
        delete fEventListenerThread;
        cout<<"listener thread killed and deleted"<<endl;
    }
    if(fStorageManagerWatcherThread)
    {
        fStorageManagerWatcherThread->Join();
        fStorageManagerWatcherThread->Kill();
        delete fStorageManagerWatcherThread;
        cout<<"storage watcher thread killed and deleted"<<endl;
    }
}

void AliEveDataSourceOnline::GetNextEvent()
{
    AliZMQManager *eventManager = AliZMQManager::GetInstance();
    eventManager->CreateSocket(EVENTS_SERVER_SUB);

    fCurrentEvent[0]=0;
    fCurrentEvent[1]=0;

    AliESDEvent *tmpEvent;

    cout<<"Starting subscriber's loop"<<endl;
    while(!fFinished)
    {
        cout<<"Waiting for event from online reconstruction...";
        if(eventManager->Get(tmpEvent,EVENTS_SERVER_SUB))
        {
            if(tmpEvent)
            {
                cout<<"received. ("<<tmpEvent->GetRunNumber();
                if(tmpEvent->GetRunNumber()>=0)
                {
#if ROOT_VERSION_CODE < ROOT_VERSION(5,99,0)
                    gCINTMutex->Lock();
#endif
                    if(fEventInUse == 0){fWritingToEventIndex = 1;}
                    else if(fEventInUse == 1){fWritingToEventIndex = 0;}
                    cout<<","<<tmpEvent->GetEventNumberInFile()<<")"<<endl;
                    if(fCurrentEvent[fWritingToEventIndex])
                    {
                        delete fCurrentEvent[fWritingToEventIndex];
                        fCurrentEvent[fWritingToEventIndex]=0;
                    }
                    fCurrentEvent[fWritingToEventIndex] = tmpEvent;
                    fIsNewEventAvaliable = true;
#if ROOT_VERSION_CODE < ROOT_VERSION(5,99,0)
                    gCINTMutex->UnLock();
#endif
                }
            }
            else
            {
                cout<<"received empty event."<<endl;
                sleep(1);
            }
        }
        else
        {
            cout<<"couldn't receive.";
            sleep(1);
        }
    }
}

void AliEveDataSourceOnline::CheckStorageStatus()
{
    if(!fStorageManager){return;}

    AliEveConfigManager *configManager = AliEveConfigManager::GetMaster();
    configManager->ConnectEventManagerSignals();

    AliZMQManager *eventManager = AliZMQManager::GetInstance();
    storageSockets socket = CLIENT_COMMUNICATION_REQ;
    eventManager->CreateSocket(socket);

    struct clientRequestStruct *request = new struct clientRequestStruct;
    request->messageType = REQUEST_CONNECTION;

    long response;
    bool receiveStatus = false;
    bool sendStatus = false;

    StorageManagerDown();// assume that storage manager is down

    while (!fFinished)
    {
        while(sendStatus==false)// send request message until success
        {
            sendStatus = eventManager->Send(request,socket);
            if(sendStatus==false)
            {
                //eventManager->RecreateSocket(socket);
                sleep(1);
            }
        }
        cout<<"EVENT DISPLAY -- message sent to SM"<<endl;

        receiveStatus = eventManager->Get(&response,socket); // try to reveive response
        if(receiveStatus == false) // if failed (or timeouted)
        {
            cout<<"EVENT DISPLAY -- failed to receive message from SM"<<endl;
            eventManager->RecreateSocket(socket); // destroy and open socket again, to be able to send message (currently, as receive failed, socket is still in RECV state

            if(!fStorageDown) // if requires change
            {
                cout<<"EVENT DISPLAY -- storage DOWN"<<endl;
                StorageManagerDown();
            }
        }
        else if(fStorageDown) // if success and requires change
        {
            cout<<"EVENT DISPLAY -- storage OK"<<endl;
            StorageManagerOk();
        }
        sleep(1);
        sendStatus=false;
    }

    AliEveEventManager *manager = fEventManager;
    manager->Disconnect("StorageManagerOk");
    manager->Disconnect("StorageManagerDown");
}

void AliEveDataSourceOnline::GotoEvent(Int_t event)
{
    cout<<"Go to event:"<<event<<endl;

    if (fStorageDown && -1 == event)
    {
        NextEvent();
        return;
    }

    if (fCurrentData.fESD)
    {
        // create new server request:
        struct serverRequestStruct *requestMessage = new struct serverRequestStruct;

        // set request type:
        if (event == -1)      {requestMessage->messageType = REQUEST_GET_LAST_EVENT;}
        else  if (event == 0) {requestMessage->messageType = REQUEST_GET_FIRST_EVENT;}
        else  if (event == 1) {requestMessage->messageType = REQUEST_GET_PREV_EVENT;}
        else  if (event == 2) {requestMessage->messageType = REQUEST_GET_NEXT_EVENT;}

        // set event struct:
        requestMessage->eventsRunNumber = fCurrentData.fESD->GetRunNumber();
        requestMessage->eventsEventNumber = fCurrentData.fESD->GetEventNumberInFile();

        // create event manager:
        AliZMQManager *eventManager = AliZMQManager::GetInstance();
        AliESDEvent *resultEvent = NULL;

#if ROOT_VERSION_CODE < ROOT_VERSION(5,99,0)
        gCINTMutex->Lock();
#endif

        // send request and receive event:
        eventManager->Send(requestMessage,SERVER_COMMUNICATION_REQ);
        eventManager->Get(resultEvent,SERVER_COMMUNICATION_REQ);

        if(resultEvent)
        {
//            DestroyElements();
            fCurrentData.fESD = resultEvent;
        }
        else
        {
            if(event==-1){cout<<"\n\nWARNING -- No last event is avaliable.\n\n"<<endl;}
            if(event==0){cout<<"\n\nWARNING -- No first event is avaliable.\n\n"<<endl;}
            if(event==1){cout<<"\n\nWARNING -- No previous event is avaliable.\n\n"<<endl;}
            if(event==2){cout<<"\n\nWARNING -- No next event is avaliable.\n\n"<<endl;}
        }

#if ROOT_VERSION_CODE < ROOT_VERSION(5,99,0)
        gCINTMutex->UnLock();
#endif
    }
    else
    {
        cout<<"\n\nWARNING -- No event has been already loaded. Loading the most recent event...\n\n"<<endl;

        struct serverRequestStruct *requestMessage = new struct serverRequestStruct;
        requestMessage->messageType = REQUEST_GET_LAST_EVENT;

        AliZMQManager *eventManager = AliZMQManager::GetInstance();
        AliESDEvent *resultEvent = NULL;

#if ROOT_VERSION_CODE < ROOT_VERSION(5,99,0)
        gCINTMutex->Lock();
#endif
        eventManager->Send(requestMessage,SERVER_COMMUNICATION_REQ);
        eventManager->Get(resultEvent,SERVER_COMMUNICATION_REQ);

        if(resultEvent)
        {
//            DestroyElements();
            fCurrentData.fESD = resultEvent;
        }
        else{cout<<"\n\nWARNING -- The most recent event is not avaliable.\n\n"<<endl;}
#if ROOT_VERSION_CODE < ROOT_VERSION(5,99,0)
        gCINTMutex->UnLock();
#endif
    }
}

void AliEveDataSourceOnline::NextEvent()
{
#if ROOT_VERSION_CODE < ROOT_VERSION(5,99,0)
    gCINTMutex->Lock();
#endif
    if(fIsNewEventAvaliable)
    {
        fEventManager->DestroyTransients();

        if(fWritingToEventIndex == 0) fEventInUse = 0;
        else if(fWritingToEventIndex == 1) fEventInUse = 1;

        if(fCurrentEvent[fEventInUse])
        {
            if(fCurrentEvent[fEventInUse]->GetRunNumber() >= 0)
            {
                fFailCounter=0;
                EventServerOk();
                cout<<"================ setting event to "<<fCurrentEvent[fEventInUse]->GetEventNumberInFile()<<"================"<<endl;

                StorageManagerDown(); // block SM while event is being loaded
                fEventManager->DestroyElements();
                if(fCurrentEvent[fEventInUse]->GetRunNumber() != fEventManager->GetCurrentRun()){
                    fEventManager->ResetMagneticField();
                    fEventManager->SetCurrentRun(fCurrentEvent[fEventInUse]->GetRunNumber());
                }
                fCurrentData.fESD = fCurrentEvent[fEventInUse];

                fEventManager->SetHasEvent(true);
                fEventManager->AfterNewEventLoaded();

                if (fEventManager->GetAutoLoad()) {
                    fEventManager->StartAutoLoadTimer();
                }
                fEventManager->NewEventLoaded();
            }
        }
        fIsNewEventAvaliable = false;
    }
    else
    {
        cout<<"No new event is avaliable."<<endl;
        fFailCounter++;
        fEventManager->NoEventLoaded();
    }
    if(fFailCounter==5)
    {
        EventServerDown();
        fFailCounter=0;
    }
#if ROOT_VERSION_CODE < ROOT_VERSION(5,99,0)
    gCINTMutex->UnLock();
#endif
    gSystem->ProcessEvents();
}

void AliEveDataSourceOnline::MarkCurrentEvent()
{
    if(!fStorageManager){return;}

    struct serverRequestStruct *requestMessage = new struct serverRequestStruct;
    requestMessage->eventsRunNumber = fCurrentData.fESD->GetRunNumber();
    requestMessage->eventsEventNumber = fCurrentData.fESD->GetEventNumberInFile();
    requestMessage->messageType = REQUEST_MARK_EVENT;

    AliZMQManager *eventManager = AliZMQManager::GetInstance();

    eventManager->Send(requestMessage,SERVER_COMMUNICATION_REQ);
    bool response;
    eventManager->Get(&response,SERVER_COMMUNICATION_REQ);

    if(response)
    {
        //fStatusLabel->SetText("Event marked");
        cout<<"ADMIN PANEL -- Event marked succesfully"<<endl;
    }
    else
    {
        //fStatusLabel->SetText("Couldn't mark this event");
        cout<<"ADMIN PANEL -- Could not matk event"<<endl;
    }
    if(requestMessage){delete requestMessage;}
}

void AliEveDataSourceOnline::StorageManagerOk()
{
//    Emit("StorageManagerOk()");
}
void AliEveDataSourceOnline::StorageManagerDown()
{
//    Emit("StorageManagerDown()");
}

void AliEveDataSourceOnline::EventServerOk()
{
//    Emit("EventServerOk()");
}
void AliEveDataSourceOnline::EventServerDown()
{
//    Emit("EventServerDown()");
}

<|endoftext|>


<commit_before>/* Copyright 2020 The TensorFlow Authors. All Rights Reserved.

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

// This file implements logic for translating mixed IR to buffer form.
// Currently it supports MHLO and some operations from the Standard dialect.

#include <memory>

#include "mlir/Dialect/SCF/SCF.h"  // from @llvm-project
#include "mlir/Dialect/SCF/Transforms.h"  // from @llvm-project
#include "mlir/Dialect/Shape/IR/Shape.h"  // from @llvm-project
#include "mlir/Dialect/Shape/Transforms/Passes.h"  // from @llvm-project
#include "mlir/Dialect/StandardOps/IR/Ops.h"  // from @llvm-project
#include "mlir/Dialect/StandardOps/Transforms/DecomposeCallGraphTypes.h"  // from @llvm-project
#include "mlir/Dialect/StandardOps/Transforms/FuncConversions.h"  // from @llvm-project
#include "mlir/Dialect/StandardOps/Transforms/Passes.h"  // from @llvm-project
#include "mlir/IR/Function.h"  // from @llvm-project
#include "mlir/IR/MLIRContext.h"  // from @llvm-project
#include "mlir/IR/Operation.h"  // from @llvm-project
#include "mlir/IR/PatternMatch.h"  // from @llvm-project
#include "mlir/IR/StandardTypes.h"  // from @llvm-project
#include "mlir/IR/Visitors.h"  // from @llvm-project
#include "mlir/Transforms/Bufferize.h"  // from @llvm-project
#include "mlir/Transforms/DialectConversion.h"  // from @llvm-project
#include "tensorflow/compiler/mlir/hlo/include/mlir-hlo/Dialect/mhlo/IR/hlo_ops.h"
#include "tensorflow/compiler/mlir/hlo/include/mlir-hlo/Dialect/mhlo/IR/lhlo_ops.h"
#include "tensorflow/compiler/mlir/hlo/include/mlir-hlo/Dialect/mhlo/transforms/passes.h"
#include "tensorflow/compiler/mlir/hlo/include/mlir-hlo/Dialect/mhlo/transforms/rewriters.h"
#include "tensorflow/compiler/mlir/tools/kernel_gen/ir/tf_framework_ops.h"
#include "tensorflow/compiler/mlir/tools/kernel_gen/transforms/passes.h"
#include "tensorflow/compiler/mlir/tools/kernel_gen/transforms/rewriters.h"

namespace mlir {
namespace kernel_gen {
namespace transforms {
namespace {

#define GEN_PASS_CLASSES
#include "tensorflow/compiler/mlir/tools/kernel_gen/transforms/kernel_gen_passes.h.inc"

// TODO(herhut) : This could become a real pattern in bufferize pass. What we
// would need to do is insert a copy to model the semantics correctly. The same
// is true for the TensorLoad pattern that is already in there.  Then buffer
// assignment free insertion and copy removal should clean this up for us.
//
// This patten erases `tensor_store(src_unranked_tensor, dst_unranked_memref)`
// op and replaces the result of the defining op produced `dst_unranked_memref`
// with the rewritten `src_unranked_tensor`.
class UnrankedTensorStoreTestOnlyPattern
    : public OpConversionPattern<mlir::TensorStoreOp> {
 public:
  using OpConversionPattern<mlir::TensorStoreOp>::OpConversionPattern;

  LogicalResult matchAndRewrite(
      mlir::TensorStoreOp op, ArrayRef<Value> operands,
      ConversionPatternRewriter& rewriter) const final {
    rewriter.replaceOp(op.memref().getDefiningOp(), op.tensor());
    rewriter.replaceOp(op, {});
    return success();
  }
};

struct BufferizePass : public BufferizePassBase<BufferizePass> {
  void getDependentDialects(DialectRegistry& registry) const override {
    registry.insert<lmhlo::LmhloDialect>();
  }

 public:
  void runOnOperation() override {
    auto& context = getContext();
    ConversionTarget target(context);
    target.addLegalDialect<lmhlo::LmhloDialect, scf::SCFDialect,
                           StandardOpsDialect,
                           tf_framework::TFFrameworkDialect>();
    target.addLegalOp<ModuleOp, ModuleTerminatorOp, FuncOp>();
    target.addIllegalDialect<mhlo::MhloDialect>();
    target.addIllegalOp<DynamicTensorFromElementsOp, ExtractElementOp,
                        TensorFromElementsOp, TensorCastOp, TensorLoadOp,
                        TensorToMemrefOp>();
    target.addDynamicallyLegalOp<TensorStoreOp>([&](TensorStoreOp op) {
      return !op.tensor().getType().isa<UnrankedTensorType>();
    });

    BufferizeTypeConverter converter;
    auto typesAreLegal = [&converter](Operation* op) {
      return converter.isLegal(op->getOperandTypes()) &&
             converter.isLegal(op->getResultTypes());
    };
    target.addDynamicallyLegalOp<FuncOp>([&](FuncOp op) {
      auto inputs = op.getType().getInputs();
      auto results = op.getType().getResults();
      return converter.isLegal(inputs) && converter.isLegal(results) &&
             converter.isLegal(&op.getBody());
    });
    target.addDynamicallyLegalOp<CallOp, ConstantOp, DimOp, RankOp, ReturnOp,
                                 SelectOp>(typesAreLegal);

    OwningRewritePatternList patterns;
    mhlo::populateHLOToLHLOConversionPattern(&context, &converter, &patterns);
    populateFuncOpTypeConversionPattern(patterns, &context, converter);
    populateCallOpTypeConversionPattern(patterns, &context, converter);
    ValueDecomposer decomposer;
    populateDecomposeCallGraphTypesPatterns(&context, converter, decomposer,
                                            patterns);
    populateStdBufferizePatterns(&context, converter, patterns);
    populateExtraStdBufferizePattern(&context, &converter, &patterns);
    populateShapeStructuralTypeConversionsAndLegality(&context, converter,
                                                      patterns, target);
    scf::populateSCFStructuralTypeConversionsAndLegality(&context, converter,
                                                         patterns, target);
    patterns.insert<UnrankedTensorStoreTestOnlyPattern>(&context);

    auto module = getOperation();
    if (failed(applyFullConversion(module, target, std::move(patterns)))) {
      signalPassFailure();
    }
  }
};

}  // namespace

std::unique_ptr<OperationPass<ModuleOp> > CreateBufferizePass() {
  return std::make_unique<BufferizePass>();
}

}  // namespace transforms
}  // namespace kernel_gen
}  // namespace mlir
<commit_msg>Remove decompose types patterns.<commit_after>/* Copyright 2020 The TensorFlow Authors. All Rights Reserved.

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

// This file implements logic for translating mixed IR to buffer form.
// Currently it supports MHLO and some operations from the Standard dialect.

#include <memory>

#include "mlir/Dialect/SCF/SCF.h"  // from @llvm-project
#include "mlir/Dialect/SCF/Transforms.h"  // from @llvm-project
#include "mlir/Dialect/Shape/IR/Shape.h"  // from @llvm-project
#include "mlir/Dialect/Shape/Transforms/Passes.h"  // from @llvm-project
#include "mlir/Dialect/StandardOps/IR/Ops.h"  // from @llvm-project
#include "mlir/Dialect/StandardOps/Transforms/FuncConversions.h"  // from @llvm-project
#include "mlir/Dialect/StandardOps/Transforms/Passes.h"  // from @llvm-project
#include "mlir/IR/Function.h"  // from @llvm-project
#include "mlir/IR/MLIRContext.h"  // from @llvm-project
#include "mlir/IR/Operation.h"  // from @llvm-project
#include "mlir/IR/PatternMatch.h"  // from @llvm-project
#include "mlir/IR/StandardTypes.h"  // from @llvm-project
#include "mlir/IR/Visitors.h"  // from @llvm-project
#include "mlir/Transforms/Bufferize.h"  // from @llvm-project
#include "mlir/Transforms/DialectConversion.h"  // from @llvm-project
#include "tensorflow/compiler/mlir/hlo/include/mlir-hlo/Dialect/mhlo/IR/hlo_ops.h"
#include "tensorflow/compiler/mlir/hlo/include/mlir-hlo/Dialect/mhlo/IR/lhlo_ops.h"
#include "tensorflow/compiler/mlir/hlo/include/mlir-hlo/Dialect/mhlo/transforms/passes.h"
#include "tensorflow/compiler/mlir/hlo/include/mlir-hlo/Dialect/mhlo/transforms/rewriters.h"
#include "tensorflow/compiler/mlir/tools/kernel_gen/ir/tf_framework_ops.h"
#include "tensorflow/compiler/mlir/tools/kernel_gen/transforms/passes.h"
#include "tensorflow/compiler/mlir/tools/kernel_gen/transforms/rewriters.h"

namespace mlir {
namespace kernel_gen {
namespace transforms {
namespace {

#define GEN_PASS_CLASSES
#include "tensorflow/compiler/mlir/tools/kernel_gen/transforms/kernel_gen_passes.h.inc"

// TODO(herhut) : This could become a real pattern in bufferize pass. What we
// would need to do is insert a copy to model the semantics correctly. The same
// is true for the TensorLoad pattern that is already in there.  Then buffer
// assignment free insertion and copy removal should clean this up for us.
//
// This patten erases `tensor_store(src_unranked_tensor, dst_unranked_memref)`
// op and replaces the result of the defining op produced `dst_unranked_memref`
// with the rewritten `src_unranked_tensor`.
class UnrankedTensorStoreTestOnlyPattern
    : public OpConversionPattern<mlir::TensorStoreOp> {
 public:
  using OpConversionPattern<mlir::TensorStoreOp>::OpConversionPattern;

  LogicalResult matchAndRewrite(
      mlir::TensorStoreOp op, ArrayRef<Value> operands,
      ConversionPatternRewriter& rewriter) const final {
    rewriter.replaceOp(op.memref().getDefiningOp(), op.tensor());
    rewriter.replaceOp(op, {});
    return success();
  }
};

struct BufferizePass : public BufferizePassBase<BufferizePass> {
  void getDependentDialects(DialectRegistry& registry) const override {
    registry.insert<lmhlo::LmhloDialect>();
  }

 public:
  void runOnOperation() override {
    auto& context = getContext();
    ConversionTarget target(context);
    target.addLegalDialect<lmhlo::LmhloDialect, scf::SCFDialect,
                           StandardOpsDialect,
                           tf_framework::TFFrameworkDialect>();
    target.addLegalOp<ModuleOp, ModuleTerminatorOp, FuncOp>();
    target.addIllegalDialect<mhlo::MhloDialect>();
    target.addIllegalOp<DynamicTensorFromElementsOp, ExtractElementOp,
                        TensorFromElementsOp, TensorCastOp, TensorLoadOp,
                        TensorToMemrefOp>();
    target.addDynamicallyLegalOp<TensorStoreOp>([&](TensorStoreOp op) {
      return !op.tensor().getType().isa<UnrankedTensorType>();
    });

    BufferizeTypeConverter converter;
    auto typesAreLegal = [&converter](Operation* op) {
      return converter.isLegal(op->getOperandTypes()) &&
             converter.isLegal(op->getResultTypes());
    };
    target.addDynamicallyLegalOp<FuncOp>([&](FuncOp op) {
      auto inputs = op.getType().getInputs();
      auto results = op.getType().getResults();
      return converter.isLegal(inputs) && converter.isLegal(results) &&
             converter.isLegal(&op.getBody());
    });
    target.addDynamicallyLegalOp<CallOp, ConstantOp, DimOp, RankOp, SelectOp>(
        typesAreLegal);

    OwningRewritePatternList patterns;
    mhlo::populateHLOToLHLOConversionPattern(&context, &converter, &patterns);
    populateFuncOpTypeConversionPattern(patterns, &context, converter);
    populateCallOpTypeConversionPattern(patterns, &context, converter);
    populateStdBufferizePatterns(&context, converter, patterns);
    populateExtraStdBufferizePattern(&context, &converter, &patterns);
    populateShapeStructuralTypeConversionsAndLegality(&context, converter,
                                                      patterns, target);
    scf::populateSCFStructuralTypeConversionsAndLegality(&context, converter,
                                                         patterns, target);
    patterns.insert<UnrankedTensorStoreTestOnlyPattern>(&context);

    auto module = getOperation();
    if (failed(applyFullConversion(module, target, std::move(patterns)))) {
      signalPassFailure();
    }
  }
};

}  // namespace

std::unique_ptr<OperationPass<ModuleOp> > CreateBufferizePass() {
  return std::make_unique<BufferizePass>();
}

}  // namespace transforms
}  // namespace kernel_gen
}  // namespace mlir
<|endoftext|>


<commit_before>/******************************************************************************
 *                       ____    _    _____                                   *
 *                      / ___|  / \  |  ___|    C++                           *
 *                     | |     / _ \ | |_       Actor                         *
 *                     | |___ / ___ \|  _|      Framework                     *
 *                      \____/_/   \_|_|                                      *
 *                                                                            *
 * Copyright (C) 2011 - 2016                                                  *
 * Dominik Charousset <dominik.charousset (at) haw-hamburg.de>                *
 *                                                                            *
 * Distributed under the terms and conditions of the BSD 3-Clause License or  *
 * (at your option) under the terms and conditions of the Boost Software      *
 * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE.       *
 *                                                                            *
 * If you did not receive a copy of the license files, see                    *
 * http://opensource.org/licenses/BSD-3-Clause and                            *
 * http://www.boost.org/LICENSE_1_0.txt.                                      *
 ******************************************************************************/

#ifndef CAF_STREAM_DESERIALIZER_HPP
#define CAF_STREAM_DESERIALIZER_HPP

#include <limits>
#include <string>
#include <sstream>
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <iomanip>
#include <stdexcept>
#include <type_traits>

#include "caf/sec.hpp"
#include "caf/logger.hpp"
#include "caf/deserializer.hpp"

#include "caf/detail/ieee_754.hpp"
#include "caf/detail/network_order.hpp"

namespace caf {

/// Implements the deserializer interface with a binary serialization protocol.
template <class Streambuf>
class stream_deserializer : public deserializer {
  using streambuf_type = typename std::remove_reference<Streambuf>::type;
  using char_type = typename streambuf_type::char_type;
  using streambuf_base = std::basic_streambuf<char_type>;
  using streamsize = std::streamsize;

  static_assert(std::is_base_of<streambuf_base, streambuf_type>::value,
                "Streambuf must inherit from std::streambuf");

public:
  template <class... Ts>
  explicit stream_deserializer(actor_system& sys, Ts&&... xs)
    : deserializer(sys),
      streambuf_(std::forward<Ts>(xs)...) {
  }

  template <class... Ts>
  explicit stream_deserializer(execution_unit* ctx, Ts&&... xs)
    : deserializer(ctx),
      streambuf_(std::forward<Ts>(xs)...) {
  }

  template <
    class S,
    class = typename std::enable_if<
      std::is_same<
        typename std::remove_reference<S>::type,
        typename std::remove_reference<Streambuf>::type
      >::value
    >::type
  >
  explicit stream_deserializer(S&& sb)
    : deserializer(nullptr),
      streambuf_(std::forward<S>(sb)) {
  }

  error begin_object(uint16_t& typenr, std::string& name) override {
    return error::eval([&] { return apply_int(typenr); },
                       [&] { return typenr == 0 ? apply(name) : error{}; });
  }

  error end_object() override {
    return none;
  }

  error begin_sequence(size_t& num_elements) override {
    return varbyte_decode(num_elements);
  }

  error end_sequence() override {
    return none;
  }

  error apply_raw(size_t num_bytes, void* data) override {
    return range_check(streambuf_.sgetn(reinterpret_cast<char_type*>(data),
                                        static_cast<streamsize>(num_bytes)),
                       num_bytes);
  }

protected:
  // Decode an unsigned integral type as variable-byte-encoded byte sequence.
  template <class T>
  error varbyte_decode(T& x) {
    static_assert(std::is_unsigned<T>::value, "T must be an unsigned type");
    T n = 0;
    x = 0;
    uint8_t low7;
    do {
       auto c = streambuf_.sbumpc();
       using traits = typename streambuf_type::traits_type;
       if (traits::eq_int_type(c, traits::eof()))
         return sec::end_of_stream;
      low7 = static_cast<uint8_t>(traits::to_char_type(c));
      x |= static_cast<T>((low7 & 0x7F) << (7 * n));
      ++n;
    } while (low7 & 0x80);
    return none;
  }

  error apply_builtin(builtin type, void* val) override {
    CAF_ASSERT(val != nullptr);
    switch (type) {
      default: // i8_v or u8_v
        CAF_ASSERT(type == i8_v || type == u8_v);
        return apply_raw(sizeof(uint8_t), val);
      case i16_v:
      case u16_v:
        return apply_int(*reinterpret_cast<uint16_t*>(val));
      case i32_v:
      case u32_v:
        return apply_int(*reinterpret_cast<uint32_t*>(val));
      case i64_v:
      case u64_v:
        return apply_int(*reinterpret_cast<uint64_t*>(val));
      case float_v:
        return apply_float(*reinterpret_cast<float*>(val));
      case double_v:
        return apply_float(*reinterpret_cast<double*>(val));
      case ldouble_v: {
        // the IEEE-754 conversion does not work for long double
        // => fall back to string serialization (even though it sucks)
        std::string tmp;
        auto e = apply(tmp);
        if (e)
          return e;
        std::istringstream iss{std::move(tmp)};
        iss >> *reinterpret_cast<long double*>(val);
        return none;
      }
      case string8_v: {
        auto& str = *reinterpret_cast<std::string*>(val);
        size_t str_size;
        return error::eval([&] { return begin_sequence(str_size); },
                           [&] { str.resize(str_size);
                                 auto p = &str[0];
                                 auto data = reinterpret_cast<char_type*>(p);
                                 auto s = static_cast<streamsize>(str_size);
                                 return range_check(streambuf_.sgetn(data, s),
                                                    str_size); },
                           [&] { return end_sequence(); });
      }
      case string16_v: {
        auto& str = *reinterpret_cast<std::u16string*>(val);
        str.clear();
        size_t ns;
        return error::eval([&] { return begin_sequence(ns); },
                           [&] { return fill_range_c<uint16_t>(str, ns); },
                           [&] { return end_sequence(); });
      }
      case string32_v: {
        auto& str = *reinterpret_cast<std::u32string*>(val);
        str.clear();
        size_t ns;
        return error::eval([&] { return begin_sequence(ns); },
                           [&] { return fill_range_c<uint32_t>(str, ns); },
                           [&] { return end_sequence(); });
      }
    }
  }

private:
  error range_check(size_t got, size_t need) {
    if (got == need)
      return none;
    CAF_LOG_ERROR("range_check failed");
    return sec::end_of_stream;
  }

  template <class T>
  error apply_int(T& x) {
    T tmp;
    auto e = apply_raw(sizeof(T), &tmp);
    if (e)
      return e;
    x = detail::from_network_order(tmp);
    return none;
  }

  template <class T>
  error apply_float(T& x) {
    typename detail::ieee_754_trait<T>::packed_type tmp = 0;
    auto e = apply_int(tmp);
    if (e)
      return e;
    x = detail::unpack754(tmp);
    return none;
  }

  Streambuf streambuf_;
};

} // namespace caf

#endif // CAF_STREAM_DESERIALIZER_HPP
<commit_msg>Fix "change signedness" warnings<commit_after>/******************************************************************************
 *                       ____    _    _____                                   *
 *                      / ___|  / \  |  ___|    C++                           *
 *                     | |     / _ \ | |_       Actor                         *
 *                     | |___ / ___ \|  _|      Framework                     *
 *                      \____/_/   \_|_|                                      *
 *                                                                            *
 * Copyright (C) 2011 - 2016                                                  *
 * Dominik Charousset <dominik.charousset (at) haw-hamburg.de>                *
 *                                                                            *
 * Distributed under the terms and conditions of the BSD 3-Clause License or  *
 * (at your option) under the terms and conditions of the Boost Software      *
 * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE.       *
 *                                                                            *
 * If you did not receive a copy of the license files, see                    *
 * http://opensource.org/licenses/BSD-3-Clause and                            *
 * http://www.boost.org/LICENSE_1_0.txt.                                      *
 ******************************************************************************/

#ifndef CAF_STREAM_DESERIALIZER_HPP
#define CAF_STREAM_DESERIALIZER_HPP

#include <limits>
#include <string>
#include <sstream>
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <iomanip>
#include <stdexcept>
#include <type_traits>

#include "caf/sec.hpp"
#include "caf/logger.hpp"
#include "caf/deserializer.hpp"

#include "caf/detail/ieee_754.hpp"
#include "caf/detail/network_order.hpp"

namespace caf {

/// Implements the deserializer interface with a binary serialization protocol.
template <class Streambuf>
class stream_deserializer : public deserializer {
  using streambuf_type = typename std::remove_reference<Streambuf>::type;
  using char_type = typename streambuf_type::char_type;
  using streambuf_base = std::basic_streambuf<char_type>;
  using streamsize = std::streamsize;

  static_assert(std::is_base_of<streambuf_base, streambuf_type>::value,
                "Streambuf must inherit from std::streambuf");

public:
  template <class... Ts>
  explicit stream_deserializer(actor_system& sys, Ts&&... xs)
    : deserializer(sys),
      streambuf_(std::forward<Ts>(xs)...) {
  }

  template <class... Ts>
  explicit stream_deserializer(execution_unit* ctx, Ts&&... xs)
    : deserializer(ctx),
      streambuf_(std::forward<Ts>(xs)...) {
  }

  template <
    class S,
    class = typename std::enable_if<
      std::is_same<
        typename std::remove_reference<S>::type,
        typename std::remove_reference<Streambuf>::type
      >::value
    >::type
  >
  explicit stream_deserializer(S&& sb)
    : deserializer(nullptr),
      streambuf_(std::forward<S>(sb)) {
  }

  error begin_object(uint16_t& typenr, std::string& name) override {
    return error::eval([&] { return apply_int(typenr); },
                       [&] { return typenr == 0 ? apply(name) : error{}; });
  }

  error end_object() override {
    return none;
  }

  error begin_sequence(size_t& num_elements) override {
    return varbyte_decode(num_elements);
  }

  error end_sequence() override {
    return none;
  }

  error apply_raw(size_t num_bytes, void* data) override {
    return range_check(streambuf_.sgetn(reinterpret_cast<char_type*>(data),
                                        static_cast<streamsize>(num_bytes)),
                       num_bytes);
  }

protected:
  // Decode an unsigned integral type as variable-byte-encoded byte sequence.
  template <class T>
  error varbyte_decode(T& x) {
    static_assert(std::is_unsigned<T>::value, "T must be an unsigned type");
    T n = 0;
    x = 0;
    uint8_t low7;
    do {
       auto c = streambuf_.sbumpc();
       using traits = typename streambuf_type::traits_type;
       if (traits::eq_int_type(c, traits::eof()))
         return sec::end_of_stream;
      low7 = static_cast<uint8_t>(traits::to_char_type(c));
      x |= static_cast<T>((low7 & 0x7F) << (7 * n));
      ++n;
    } while (low7 & 0x80);
    return none;
  }

  error apply_builtin(builtin type, void* val) override {
    CAF_ASSERT(val != nullptr);
    switch (type) {
      default: // i8_v or u8_v
        CAF_ASSERT(type == i8_v || type == u8_v);
        return apply_raw(sizeof(uint8_t), val);
      case i16_v:
      case u16_v:
        return apply_int(*reinterpret_cast<uint16_t*>(val));
      case i32_v:
      case u32_v:
        return apply_int(*reinterpret_cast<uint32_t*>(val));
      case i64_v:
      case u64_v:
        return apply_int(*reinterpret_cast<uint64_t*>(val));
      case float_v:
        return apply_float(*reinterpret_cast<float*>(val));
      case double_v:
        return apply_float(*reinterpret_cast<double*>(val));
      case ldouble_v: {
        // the IEEE-754 conversion does not work for long double
        // => fall back to string serialization (even though it sucks)
        std::string tmp;
        auto e = apply(tmp);
        if (e)
          return e;
        std::istringstream iss{std::move(tmp)};
        iss >> *reinterpret_cast<long double*>(val);
        return none;
      }
      case string8_v: {
        auto& str = *reinterpret_cast<std::string*>(val);
        size_t str_size;
        return error::eval([&] { return begin_sequence(str_size); },
                           [&] { str.resize(str_size);
                                 auto p = &str[0];
                                 auto data = reinterpret_cast<char_type*>(p);
                                 auto s = static_cast<streamsize>(str_size);
                                 return range_check(streambuf_.sgetn(data, s),
                                                    str_size); },
                           [&] { return end_sequence(); });
      }
      case string16_v: {
        auto& str = *reinterpret_cast<std::u16string*>(val);
        str.clear();
        size_t ns;
        return error::eval([&] { return begin_sequence(ns); },
                           [&] { return fill_range_c<uint16_t>(str, ns); },
                           [&] { return end_sequence(); });
      }
      case string32_v: {
        auto& str = *reinterpret_cast<std::u32string*>(val);
        str.clear();
        size_t ns;
        return error::eval([&] { return begin_sequence(ns); },
                           [&] { return fill_range_c<uint32_t>(str, ns); },
                           [&] { return end_sequence(); });
      }
    }
  }

private:
  error range_check(std::streamsize got, size_t need) {
    if (got > 0 && static_cast<size_t>(got) == need)
      return none;
    CAF_LOG_ERROR("range_check failed");
    return sec::end_of_stream;
  }

  template <class T>
  error apply_int(T& x) {
    T tmp;
    auto e = apply_raw(sizeof(T), &tmp);
    if (e)
      return e;
    x = detail::from_network_order(tmp);
    return none;
  }

  template <class T>
  error apply_float(T& x) {
    typename detail::ieee_754_trait<T>::packed_type tmp = 0;
    auto e = apply_int(tmp);
    if (e)
      return e;
    x = detail::unpack754(tmp);
    return none;
  }

  Streambuf streambuf_;
};

} // namespace caf

#endif // CAF_STREAM_DESERIALIZER_HPP
<|endoftext|>


<commit_before>//
// Aspia Project
// Copyright (C) 2020 Dmitry Chapyshev <dmitry@aspia.ru>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
//

#include "base/command_line.h"
#include "base/logging.h"
#include "base/crypto/key_pair.h"
#include "base/files/base_paths.h"
#include "base/files/file_util.h"
#include "base/peer/user.h"
#include "build/version.h"
#include "router/database_factory_sqlite.h"
#include "router/database.h"
#include "router/settings.h"

#if defined(OS_WIN)
#include "router/win/service.h"
#include "router/win/service_util.h"
#else
#include "base/crypto/scoped_crypto_initializer.h"
#include "base/message_loop/message_loop.h"
#include "router/server.h"
#endif

#include <iostream>

namespace {

void initLogging()
{
    router::Settings settings;

    base::LoggingSettings logging_settings;
    logging_settings.min_log_level = settings.minLogLevel();

    base::initLogging(logging_settings);
}

void shutdownLogging()
{
    base::shutdownLogging();
}

bool generateKeys(base::ByteArray* private_key, base::ByteArray* public_key)
{
    base::KeyPair key_pair = base::KeyPair::create(base::KeyPair::Type::X25519);
    if (!key_pair.isValid())
    {
        std::cout << "Failed to generate keys" << std::endl;
        return false;
    }

    *private_key = key_pair.privateKey();
    *public_key = key_pair.publicKey();

    if (private_key->empty() || public_key->empty())
    {
        std::cout << "Empty keys generated";
        return false;
    }

    return true;
}

void generateAndPrintKeys()
{
    base::ByteArray private_key;
    base::ByteArray public_key;

    if (!generateKeys(&private_key, &public_key))
        return;

    std::cout << "Private key: " << base::toHex(private_key) << std::endl;
    std::cout << "Public key: " << base::toHex(public_key) << std::endl;
}

void createConfig()
{
    std::filesystem::path settings_file_path = router::Settings::filePath();

    std::error_code error_code;
    if (std::filesystem::exists(settings_file_path, error_code))
    {
        std::cout << "Settings file already exists. Continuation is impossible." << std::endl;
        return;
    }

    std::filesystem::path public_key_path;
    if (!base::BasePaths::commonAppData(&public_key_path))
    {
        std::cout << "Failed to get the path to the current directory" << std::endl;
        return;
    }

    public_key_path.append("aspia/router.pub");

    if (std::filesystem::exists(public_key_path, error_code))
    {
        std::cout << "Public key file already exists. Continuation is impossible." << std::endl;
        return;
    }

    std::unique_ptr<router::Database> db = router::DatabaseFactorySqlite().createDatabase();
    if (!db)
    {
        db = router::DatabaseFactorySqlite().openDatabase();
        if (db)
        {
            std::cout << "Database already exists. Continuation is impossible." << std::endl;
            return;
        }
    }

    const char16_t kUserName[] = u"admin";
    const char16_t kPassword[] = u"admin";

    base::User user = base::User::create(kUserName, kPassword);
    if (!user.isValid())
    {
        std::cout << "Failed to create user" << std::endl;
        return;
    }

    user.sessions = proto::ROUTER_SESSION_ADMIN | proto::ROUTER_SESSION_CLIENT;
    user.flags = base::User::ENABLED;

    if (!db->addUser(user))
    {
        std::cout << "Failed to add user to database" << std::endl;
        return;
    }

    std::cout << "User name: " << base::local8BitFromUtf16(kUserName) << std::endl;
    std::cout << "Password: " << base::local8BitFromUtf16(kPassword) << std::endl;

    base::ByteArray private_key;
    base::ByteArray public_key;
    if (!generateKeys(&private_key, &public_key))
        return;

    if (!base::writeFile(public_key_path, base::toHex(public_key)))
    {
        std::cout << "Failed to write public key to file: " << public_key_path << std::endl;
        return;
    }
    else
    {
        std::cout << "Public key file: " << public_key_path << std::endl;
    }

    // Save the configuration file.
    router::Settings settings;
    settings.reset();
    settings.setPrivateKey(private_key);
    settings.flush();

    std::cout << "Configuration successfully created. Don't forget to change your password!"
              << std::endl;
}

void showHelp()
{
    std::cout << "aspia_router [switch]" << std::endl
        << "Available switches:" << std::endl
#if defined(OS_WIN)
        << '\t' << "--install" << '\t' << "Install service" << std::endl
        << '\t' << "--remove" << '\t' << "Remove service" << std::endl
        << '\t' << "--start" << '\t' << "Start service" << std::endl
        << '\t' << "--stop" << '\t' << "Stop service" << std::endl
#endif // defined(OS_WIN)
        << '\t' << "--create-config" << '\t' << "Creates a configuration" << std::endl
        << '\t' << "--keygen" << '\t' << "Generating public and private keys" << std::endl
        << '\t' << "--help" << '\t' << "Show help" << std::endl;
}

} // namespace

#if defined(OS_WIN)
int wmain()
{
    initLogging();

    base::CommandLine::init(0, nullptr); // On Windows ignores arguments.
    base::CommandLine* command_line = base::CommandLine::forCurrentProcess();

    LOG(LS_INFO) << "Version: " << ASPIA_VERSION_STRING;
    LOG(LS_INFO) << "Command line: " << command_line->commandLineString();

    if (command_line->hasSwitch(u"install"))
    {
        router::installService();
    }
    else if (command_line->hasSwitch(u"remove"))
    {
        router::removeService();
    }
    else if (command_line->hasSwitch(u"start"))
    {
        router::startService();
    }
    else if (command_line->hasSwitch(u"stop"))
    {
        router::stopService();
    }
    else if (command_line->hasSwitch(u"keygen"))
    {
        generateAndPrintKeys();
    }
    else if (command_line->hasSwitch(u"create-config"))
    {
        createConfig();
    }
    else if (command_line->hasSwitch(u"help"))
    {
        showHelp();
    }
    else
    {
        router::Service().exec();
    }

    shutdownLogging();
    return 0;
}
#else
int main(int argc, const char* const* argv)
{
    initLogging();

    base::CommandLine::init(argc, argv);
    base::CommandLine* command_line = base::CommandLine::forCurrentProcess();

    LOG(LS_INFO) << "Version: " << ASPIA_VERSION_STRING;
    LOG(LS_INFO) << "Command line: " << command_line->commandLineString();

    std::unique_ptr<base::ScopedCryptoInitializer> crypto_initializer =
        std::make_unique<base::ScopedCryptoInitializer>();

    if (command_line->hasSwitch(u"keygen"))
    {
        generateAndPrintKeys();
    }
    else if (command_line->hasSwitch(u"create-config"))
    {
        createConfig();
    }
    else if (command_line->hasSwitch(u"help"))
    {
        showHelp();
    }
    else
    {
        std::unique_ptr<base::MessageLoop> message_loop =
            std::make_unique<base::MessageLoop>(base::MessageLoop::Type::ASIO);

        std::unique_ptr<router::Server> server =
            std::make_unique<router::Server>(message_loop->taskRunner());

        server->start();
        message_loop->run();

        server.reset();
        message_loop.reset();
    }

    crypto_initializer.reset();
    shutdownLogging();
}
#endif
<commit_msg>Creation directory for public key; additional debug messages.<commit_after>//
// Aspia Project
// Copyright (C) 2020 Dmitry Chapyshev <dmitry@aspia.ru>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
//

#include "base/command_line.h"
#include "base/logging.h"
#include "base/crypto/key_pair.h"
#include "base/files/base_paths.h"
#include "base/files/file_util.h"
#include "base/peer/user.h"
#include "build/version.h"
#include "router/database_factory_sqlite.h"
#include "router/database.h"
#include "router/settings.h"

#if defined(OS_WIN)
#include "router/win/service.h"
#include "router/win/service_util.h"
#else
#include "base/crypto/scoped_crypto_initializer.h"
#include "base/message_loop/message_loop.h"
#include "router/server.h"
#endif

#include <iostream>

namespace {

void initLogging()
{
    router::Settings settings;

    base::LoggingSettings logging_settings;
    logging_settings.min_log_level = settings.minLogLevel();

    base::initLogging(logging_settings);
}

void shutdownLogging()
{
    base::shutdownLogging();
}

bool generateKeys(base::ByteArray* private_key, base::ByteArray* public_key)
{
    base::KeyPair key_pair = base::KeyPair::create(base::KeyPair::Type::X25519);
    if (!key_pair.isValid())
    {
        std::cout << "Failed to generate keys" << std::endl;
        return false;
    }

    *private_key = key_pair.privateKey();
    *public_key = key_pair.publicKey();

    if (private_key->empty() || public_key->empty())
    {
        std::cout << "Empty keys generated";
        return false;
    }

    return true;
}

void generateAndPrintKeys()
{
    base::ByteArray private_key;
    base::ByteArray public_key;

    if (!generateKeys(&private_key, &public_key))
        return;

    std::cout << "Private key: " << base::toHex(private_key) << std::endl;
    std::cout << "Public key: " << base::toHex(public_key) << std::endl;
}

void createConfig()
{
    LOG(LS_INFO) << "Creation of initial configuration started";

    std::filesystem::path settings_file_path = router::Settings::filePath();

    LOG(LS_INFO) << "Settings file path: " << settings_file_path;

    std::error_code error_code;
    if (std::filesystem::exists(settings_file_path, error_code))
    {
        const char kMessage[] = "Settings file already exists. Continuation is impossible.";
        LOG(LS_WARNING) << kMessage;
        std::cout << kMessage << std::endl;
        return;
    }

    std::filesystem::path public_key_dir;
    if (!base::BasePaths::commonAppData(&public_key_dir))
    {
        LOG(LS_WARNING) << "base::BasePaths::commonAppData failed";
        std::cout << "Failed to get the path to the current directory" << std::endl;
        return;
    }

    public_key_dir.append("aspia");

    LOG(LS_INFO) << "Public key directory: " << public_key_dir;

    if (!std::filesystem::exists(public_key_dir, error_code))
    {
        LOG(LS_INFO) << "Public key directory does not exist ("
                     << base::utf16FromLocal8Bit(error_code.message()) << "). Attempt to create...";

        if (!std::filesystem::create_directories(public_key_dir, error_code))
        {
            LOG(LS_WARNING) << "Failed to create directory for public key: "
                            << base::utf16FromLocal8Bit(error_code.message());
            std::cout << "Failed to create directory for public key" << std::endl;
            return;
        }
        else
        {
            LOG(LS_INFO) << "Public key directory created successfully";
        }
    }
    else
    {
        LOG(LS_INFO) << "Public key directory already exists";
    }

    std::filesystem::path public_key_file = public_key_dir;
    public_key_file.append("router.pub");

    LOG(LS_INFO) << "Public key file: " << public_key_file;

    if (std::filesystem::exists(public_key_file, error_code))
    {
        const char kMessage[] = "Public key file already exists. Continuation is impossible.";
        LOG(LS_WARNING) << kMessage;
        std::cout << kMessage << std::endl;
        return;
    }
    else
    {
        LOG(LS_INFO) << "Public key does not exist yet";
    }

    std::unique_ptr<router::Database> db = router::DatabaseFactorySqlite().createDatabase();
    if (!db)
    {
        db = router::DatabaseFactorySqlite().openDatabase();
        if (db)
        {
            const char kMessage[] = "Database already exists. Continuation is impossible.";
            LOG(LS_WARNING) << kMessage;
            std::cout << kMessage << std::endl;
        }
        else
        {
            const char kMessage[] = "Failed to create new database.";
            LOG(LS_WARNING) << kMessage;
            std::cout << kMessage << std::endl;
        }
        return;
    }

    LOG(LS_INFO) << "Creating a user...";

    const char16_t kUserName[] = u"admin";
    const char16_t kPassword[] = u"admin";

    base::User user = base::User::create(kUserName, kPassword);
    if (!user.isValid())
    {
        const char kMessage[] = "Failed to create user";
        LOG(LS_WARNING) << kMessage;
        std::cout << kMessage << std::endl;
        return;
    }

    LOG(LS_INFO) << "User has been created. Adding a user to the database...";

    user.sessions = proto::ROUTER_SESSION_ADMIN | proto::ROUTER_SESSION_CLIENT;
    user.flags = base::User::ENABLED;

    if (!db->addUser(user))
    {
        const char kMessage[] = "Failed to add user to database";
        LOG(LS_WARNING) << kMessage;
        std::cout << kMessage << std::endl;
        return;
    }

    LOG(LS_INFO) << "User was successfully added to the database";

    std::cout << "User name: " << base::local8BitFromUtf16(kUserName) << std::endl;
    std::cout << "Password: " << base::local8BitFromUtf16(kPassword) << std::endl;

    LOG(LS_INFO) << "Generating encryption keys...";

    base::ByteArray private_key;
    base::ByteArray public_key;
    if (!generateKeys(&private_key, &public_key))
    {
        LOG(LS_WARNING) << "Failed to generate private and public keys";
        return;
    }

    LOG(LS_INFO) << "Private and public keys have been successfully generated";
    LOG(LS_INFO) << "Writing a public key to a file...";

    if (!base::writeFile(public_key_file, base::toHex(public_key)))
    {
        const char kMessage[] = "Failed to write public key to file: ";
        LOG(LS_WARNING) << kMessage << public_key_file;
        std::cout << kMessage << public_key_file << std::endl;
        return;
    }
    else
    {
        LOG(LS_INFO) << "Public key was successfully written to the file";
        std::cout << "Public key file: " << public_key_file << std::endl;
    }

    // Save the configuration file.
    router::Settings settings;
    settings.reset();
    settings.setPrivateKey(private_key);
    settings.flush();

    std::cout << "Configuration successfully created. Don't forget to change your password!"
              << std::endl;
}

void showHelp()
{
    std::cout << "aspia_router [switch]" << std::endl
        << "Available switches:" << std::endl
#if defined(OS_WIN)
        << '\t' << "--install" << '\t' << "Install service" << std::endl
        << '\t' << "--remove" << '\t' << "Remove service" << std::endl
        << '\t' << "--start" << '\t' << "Start service" << std::endl
        << '\t' << "--stop" << '\t' << "Stop service" << std::endl
#endif // defined(OS_WIN)
        << '\t' << "--create-config" << '\t' << "Creates a configuration" << std::endl
        << '\t' << "--keygen" << '\t' << "Generating public and private keys" << std::endl
        << '\t' << "--help" << '\t' << "Show help" << std::endl;
}

} // namespace

#if defined(OS_WIN)
int wmain()
{
    initLogging();

    base::CommandLine::init(0, nullptr); // On Windows ignores arguments.
    base::CommandLine* command_line = base::CommandLine::forCurrentProcess();

    LOG(LS_INFO) << "Version: " << ASPIA_VERSION_STRING;
    LOG(LS_INFO) << "Command line: " << command_line->commandLineString();

    if (command_line->hasSwitch(u"install"))
    {
        router::installService();
    }
    else if (command_line->hasSwitch(u"remove"))
    {
        router::removeService();
    }
    else if (command_line->hasSwitch(u"start"))
    {
        router::startService();
    }
    else if (command_line->hasSwitch(u"stop"))
    {
        router::stopService();
    }
    else if (command_line->hasSwitch(u"keygen"))
    {
        generateAndPrintKeys();
    }
    else if (command_line->hasSwitch(u"create-config"))
    {
        createConfig();
    }
    else if (command_line->hasSwitch(u"help"))
    {
        showHelp();
    }
    else
    {
        router::Service().exec();
    }

    shutdownLogging();
    return 0;
}
#else
int main(int argc, const char* const* argv)
{
    initLogging();

    base::CommandLine::init(argc, argv);
    base::CommandLine* command_line = base::CommandLine::forCurrentProcess();

    LOG(LS_INFO) << "Version: " << ASPIA_VERSION_STRING;
    LOG(LS_INFO) << "Command line: " << command_line->commandLineString();

    std::unique_ptr<base::ScopedCryptoInitializer> crypto_initializer =
        std::make_unique<base::ScopedCryptoInitializer>();

    if (command_line->hasSwitch(u"keygen"))
    {
        generateAndPrintKeys();
    }
    else if (command_line->hasSwitch(u"create-config"))
    {
        createConfig();
    }
    else if (command_line->hasSwitch(u"help"))
    {
        showHelp();
    }
    else
    {
        std::unique_ptr<base::MessageLoop> message_loop =
            std::make_unique<base::MessageLoop>(base::MessageLoop::Type::ASIO);

        std::unique_ptr<router::Server> server =
            std::make_unique<router::Server>(message_loop->taskRunner());

        server->start();
        message_loop->run();

        server.reset();
        message_loop.reset();
    }

    crypto_initializer.reset();
    shutdownLogging();
}
#endif
<|endoftext|>