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

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkSymmetricEllipsoidInteriorExteriorSpatialFunctionExample.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) 2002 Insight Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm 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.

=========================================================================*/
#include "itkSymmetricEllipsoidInteriorExteriorSpatialFunction.h"

#include "itkImage.h"
#include "itkImageRegionIterator.h"
#include "itkFloodFilledSpatialFunctionConditionalIterator.h"
#include "itkImageFileWriter.h"
#include "itkVTKImageIO.h"

#include "vnl/vnl_matrix.h"

int main()
{
   std::cout << "itkSymmetricEllipsoidInteriorExteriorSpatialFunction example start" << std::endl;

  // This example will create an ellipsoid (3-D) in an image
  const unsigned int dimension = 3;

  // Image size and spacing parameters
  unsigned long xExtent = 50;
  unsigned long yExtent = 50;
  unsigned long zExtent = 50;
  unsigned long sourceImageSize[]  = { xExtent, yExtent, zExtent };
  double sourceImageSpacing[] = { 1.0,1.0,1.0 };
  double sourceImageOrigin[] = { 0,0,0 };

  // Calculate image volume
  unsigned long imageVolume = xExtent * yExtent * zExtent;

        // Image typedef
  typedef itk::Image< unsigned char, dimension> TImageType;

  // Creates the sourceImage (but doesn't set the size or allocate memory)
  TImageType::Pointer sourceImage = TImageType::New();
  sourceImage->SetOrigin(sourceImageOrigin);
  sourceImage->SetSpacing(sourceImageSpacing);

  std::cout << "New physical sourceImage created\n";

  //-----The following block allocates the sourceImage-----

  // Create a size object native to the sourceImage type
  TImageType::SizeType sourceImageSizeObject;
  // Set the size object to the array defined earlier
  sourceImageSizeObject.SetSize( sourceImageSize );
  // Create a region object native to the sourceImage type
  TImageType::RegionType largestPossibleRegion;
  // Resize the region
  largestPossibleRegion.SetSize( sourceImageSizeObject );
  // Set the largest legal region size (i.e. the size of the whole sourceImage) to what we just defined
  sourceImage->SetLargestPossibleRegion( largestPossibleRegion );
  // Set the buffered region
  sourceImage->SetBufferedRegion( largestPossibleRegion );
  // Set the requested region
  sourceImage->SetRequestedRegion( largestPossibleRegion );
  // Now allocate memory for the sourceImage
  sourceImage->Allocate();

  std::cout << "New physical sourceImage allocated\n";

  // Initialize the image to hold all 128
  itk::ImageRegionIterator<TImageType> it =
     itk::ImageRegionIterator<TImageType>(sourceImage, largestPossibleRegion);

  int numImagePixels = 0;
  unsigned char exteriorPixelValue = 128;
  for(it.GoToBegin(); !it.IsAtEnd(); ++it)
    {
    it.Set(exteriorPixelValue);
    ++numImagePixels;
    }

  //-----Create ellipsoid in sourceImage-----------------

  // Symmetric Ellipsoid spatial function typedef
  typedef itk::SymmetricEllipsoidInteriorExteriorSpatialFunction<double, dimension> TSymEllipsoidFunctionType;

  // Point position typedef
  typedef TSymEllipsoidFunctionType::InputType TSymEllipsoidFunctionVectorType;

  // Create a symmetric ellipsoid spatial function for the source image
  TSymEllipsoidFunctionType::Pointer spatialFunc = TSymEllipsoidFunctionType::New();

  // Define and set the center of the ellipsoid in physical space
  TSymEllipsoidFunctionVectorType center;
  center[0] = xExtent/2;
  center[1] = yExtent/2;
  center[2] = zExtent/2;
  spatialFunc->SetCenter(center);

  // Define and set the orientation and axes lengths of the ellipsoid
  // NOTE: Orienation vector must be normalized!!!!
  itk::Vector<double, 3> orientation;
  orientation[0] = 1/sqrt(2.0);
  orientation[1] = 1/sqrt(2.0);
  orientation[2] = 0;

  double uniqueAxisLength = 45;
  double symmetricAxesLength = 30;

  spatialFunc->SetOrientation(orientation, uniqueAxisLength, symmetricAxesLength);

  TImageType::IndexType seedPos;
  const TImageType::IndexValueType pos[] = {center[0], center[1], center[2]};
  seedPos.SetIndex(pos);

  itk::FloodFilledSpatialFunctionConditionalIterator<TImageType, TSymEllipsoidFunctionType>
    sfi = itk::FloodFilledSpatialFunctionConditionalIterator<TImageType,
     TSymEllipsoidFunctionType>(sourceImage, spatialFunc, seedPos);

  // Iterate through the entire image and set interior pixels to 255
  unsigned char interiorPixelValue = 255;
  for(; !sfi.IsAtEnd(); ++sfi)
    {
    sfi.Set(interiorPixelValue);
    }

  TImageType::PixelType apixel;
  int numExteriorPixels = 0; // Number of pixels not filled by spatial function
  int numInteriorPixels = 0; // Number of pixels filled by spatial function
  int numErrorPixels = 0; // Number of pixels not set by spatial function

  TImageType::IndexValueType indexarray[3] = {0,0,0};

  // Iterate through source image and get pixel values and count pixels
  // iterated through, not filled by spatial function, filled by spatial
  // function, and not set by the spatial function.
  for(int x = 0; x < xExtent; x++)
    {
     for(int y = 0; y < yExtent; y++)
        {
        for(int z = 0; z < zExtent; z++)
          {
          indexarray[0] = x;
          indexarray[1] = y;
          indexarray[2] = z;
          TImageType::IndexType index;
          index.SetIndex(indexarray);
          apixel = sourceImage->GetPixel(index);
          if(apixel == exteriorPixelValue)
          ++numExteriorPixels;
          else if(apixel == interiorPixelValue)
          ++numInteriorPixels;
          else if(apixel != interiorPixelValue || apixel != exteriorPixelValue)
          ++numErrorPixels;
          }
       }
    }

  // Volume of ellipsoid using V=(4/3)*pi*(a/2)*(b/2)*(c/2)
  double volume = 4.18879013333*(uniqueAxisLength/2)*(symmetricAxesLength/2)*(symmetricAxesLength/2);

  // Percent difference in volume measurement and calculation.
  double volumeError = (fabs(volume - numInteriorPixels)/volume)*100;

  // Test the center of the ellipsoid which should be within the sphere
  // and return 1.
  double testPosition[dimension];
  bool functionValue;
  testPosition[0] = center[0];
  testPosition[1] = center[1];
  testPosition[2] = center[2];
  functionValue = spatialFunc->Evaluate(testPosition);

  // 5% error was randomly chosen as a successful ellipsoid fill.
  // This should actually be some function of the image/ellipsoid size.
  if(volumeError > 5 || functionValue == 0)
    {
    std::cerr << std::endl << "calculated ellipsoid volume = " << volume << std::endl
              << "measured ellipsoid volume = " << numInteriorPixels << std::endl
              << "volume error = " << volumeError << "%" << std::endl
              << "function value = " << functionValue << std::endl
              << "itkSymmetricEllipsoidInteriorExteriorSpatialFunction failed :(" << std::endl;

    return EXIT_FAILURE;
    }

  else if(numImagePixels != (imageVolume))
    {
    // Make sure that the number of pixels iterated through from source image
    // is equal to the pre-defined image size.
    std::cerr << "Number of pixels iterated through in sourceimage = "
              << numImagePixels << std::endl;
    return EXIT_FAILURE;
    }

  else
    {
    std::cout << std::endl << "calculated ellipsoid volume = " << volume << std::endl
              << "measured ellipsoid volume = " << numInteriorPixels << std::endl
              << "volume error = " << volumeError << "%" << std::endl
              << "function value = " << functionValue << std::endl
              << "itkSymmetricEllipsoidInteriorExteriorSpatialFunction ended succesfully!" << std::endl;

    // Write the ellipsoid image to a vtk image file
    itk::VTKImageIO::Pointer vtkIO;
    vtkIO = itk::VTKImageIO::New();
    itk::ImageFileWriter<TImageType>::Pointer writer;
    writer = itk::ImageFileWriter<TImageType>::New();
    writer->SetInput(sourceImage);
    writer->SetFileName("ellipsoid.vtk");
    writer->SetImageIO(vtkIO);
    writer->Write();

    return EXIT_SUCCESS;
    }
}
<commit_msg>FIX: Fixed compile error<commit_after>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkSymmetricEllipsoidInteriorExteriorSpatialFunctionExample.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) 2002 Insight Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm 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.

=========================================================================*/
#include "itkSymmetricEllipsoidInteriorExteriorSpatialFunction.h"

#include "itkImage.h"
#include "itkImageRegionIterator.h"
#include "itkFloodFilledSpatialFunctionConditionalIterator.h"
#include "itkImageFileWriter.h"
#include "itkVTKImageIO.h"

#include "vnl/vnl_matrix.h"

int main()
{
   std::cout << "itkSymmetricEllipsoidInteriorExteriorSpatialFunction example start" << std::endl;

  // This example will create an ellipsoid (3-D) in an image
  const unsigned int dimension = 3;

  // Image size and spacing parameters
  unsigned long xExtent = 50;
  unsigned long yExtent = 50;
  unsigned long zExtent = 50;
  unsigned long sourceImageSize[]  = { xExtent, yExtent, zExtent };
  double sourceImageSpacing[] = { 1.0,1.0,1.0 };
  double sourceImageOrigin[] = { 0,0,0 };

  // Calculate image volume
  unsigned long imageVolume = xExtent * yExtent * zExtent;

        // Image typedef
  typedef itk::Image< unsigned char, dimension> TImageType;

  // Creates the sourceImage (but doesn't set the size or allocate memory)
  TImageType::Pointer sourceImage = TImageType::New();
  sourceImage->SetOrigin(sourceImageOrigin);
  sourceImage->SetSpacing(sourceImageSpacing);

  std::cout << "New physical sourceImage created\n";

  //-----The following block allocates the sourceImage-----

  // Create a size object native to the sourceImage type
  TImageType::SizeType sourceImageSizeObject;
  // Set the size object to the array defined earlier
  sourceImageSizeObject.SetSize( sourceImageSize );
  // Create a region object native to the sourceImage type
  TImageType::RegionType largestPossibleRegion;
  // Resize the region
  largestPossibleRegion.SetSize( sourceImageSizeObject );
  // Set the largest legal region size (i.e. the size of the whole sourceImage) to what we just defined
  sourceImage->SetLargestPossibleRegion( largestPossibleRegion );
  // Set the buffered region
  sourceImage->SetBufferedRegion( largestPossibleRegion );
  // Set the requested region
  sourceImage->SetRequestedRegion( largestPossibleRegion );
  // Now allocate memory for the sourceImage
  sourceImage->Allocate();

  std::cout << "New physical sourceImage allocated\n";

  // Initialize the image to hold all 128
  itk::ImageRegionIterator<TImageType> it =
     itk::ImageRegionIterator<TImageType>(sourceImage, largestPossibleRegion);

  int numImagePixels = 0;
  unsigned char exteriorPixelValue = 128;
  for(it.GoToBegin(); !it.IsAtEnd(); ++it)
    {
    it.Set(exteriorPixelValue);
    ++numImagePixels;
    }

  //-----Create ellipsoid in sourceImage-----------------

  // Symmetric Ellipsoid spatial function typedef
  typedef itk::SymmetricEllipsoidInteriorExteriorSpatialFunction<dimension> TSymEllipsoidFunctionType;

  // Point position typedef
  typedef TSymEllipsoidFunctionType::InputType TSymEllipsoidFunctionVectorType;

  // Create a symmetric ellipsoid spatial function for the source image
  TSymEllipsoidFunctionType::Pointer spatialFunc = TSymEllipsoidFunctionType::New();

  // Define and set the center of the ellipsoid in physical space
  TSymEllipsoidFunctionVectorType center;
  center[0] = xExtent/2;
  center[1] = yExtent/2;
  center[2] = zExtent/2;
  spatialFunc->SetCenter(center);

  // Define and set the orientation and axes lengths of the ellipsoid
  // NOTE: Orienation vector must be normalized!!!!
  itk::Vector<double, 3> orientation;
  orientation[0] = 1/sqrt(2.0);
  orientation[1] = 1/sqrt(2.0);
  orientation[2] = 0;

  double uniqueAxisLength = 45;
  double symmetricAxesLength = 30;

  spatialFunc->SetOrientation(orientation, uniqueAxisLength, symmetricAxesLength);

  TImageType::IndexType seedPos;
  const TImageType::IndexValueType pos[] = {center[0], center[1], center[2]};
  seedPos.SetIndex(pos);

  itk::FloodFilledSpatialFunctionConditionalIterator<TImageType, TSymEllipsoidFunctionType>
    sfi = itk::FloodFilledSpatialFunctionConditionalIterator<TImageType,
     TSymEllipsoidFunctionType>(sourceImage, spatialFunc, seedPos);

  // Iterate through the entire image and set interior pixels to 255
  unsigned char interiorPixelValue = 255;
  for(; !sfi.IsAtEnd(); ++sfi)
    {
    sfi.Set(interiorPixelValue);
    }

  TImageType::PixelType apixel;
  int numExteriorPixels = 0; // Number of pixels not filled by spatial function
  int numInteriorPixels = 0; // Number of pixels filled by spatial function
  int numErrorPixels = 0; // Number of pixels not set by spatial function

  TImageType::IndexValueType indexarray[3] = {0,0,0};

  // Iterate through source image and get pixel values and count pixels
  // iterated through, not filled by spatial function, filled by spatial
  // function, and not set by the spatial function.
  for(int x = 0; x < xExtent; x++)
    {
     for(int y = 0; y < yExtent; y++)
        {
        for(int z = 0; z < zExtent; z++)
          {
          indexarray[0] = x;
          indexarray[1] = y;
          indexarray[2] = z;
          TImageType::IndexType index;
          index.SetIndex(indexarray);
          apixel = sourceImage->GetPixel(index);
          if(apixel == exteriorPixelValue)
          ++numExteriorPixels;
          else if(apixel == interiorPixelValue)
          ++numInteriorPixels;
          else if(apixel != interiorPixelValue || apixel != exteriorPixelValue)
          ++numErrorPixels;
          }
       }
    }

  // Volume of ellipsoid using V=(4/3)*pi*(a/2)*(b/2)*(c/2)
  double volume = 4.18879013333*(uniqueAxisLength/2)*(symmetricAxesLength/2)*(symmetricAxesLength/2);

  // Percent difference in volume measurement and calculation.
  double volumeError = (fabs(volume - numInteriorPixels)/volume)*100;

  // Test the center of the ellipsoid which should be within the sphere
  // and return 1.
  double testPosition[dimension];
  bool functionValue;
  testPosition[0] = center[0];
  testPosition[1] = center[1];
  testPosition[2] = center[2];
  functionValue = spatialFunc->Evaluate(testPosition);

  // 5% error was randomly chosen as a successful ellipsoid fill.
  // This should actually be some function of the image/ellipsoid size.
  if(volumeError > 5 || functionValue == 0)
    {
    std::cerr << std::endl << "calculated ellipsoid volume = " << volume << std::endl
              << "measured ellipsoid volume = " << numInteriorPixels << std::endl
              << "volume error = " << volumeError << "%" << std::endl
              << "function value = " << functionValue << std::endl
              << "itkSymmetricEllipsoidInteriorExteriorSpatialFunction failed :(" << std::endl;

    return EXIT_FAILURE;
    }

  else if(numImagePixels != (imageVolume))
    {
    // Make sure that the number of pixels iterated through from source image
    // is equal to the pre-defined image size.
    std::cerr << "Number of pixels iterated through in sourceimage = "
              << numImagePixels << std::endl;
    return EXIT_FAILURE;
    }

  else
    {
    std::cout << std::endl << "calculated ellipsoid volume = " << volume << std::endl
              << "measured ellipsoid volume = " << numInteriorPixels << std::endl
              << "volume error = " << volumeError << "%" << std::endl
              << "function value = " << functionValue << std::endl
              << "itkSymmetricEllipsoidInteriorExteriorSpatialFunction ended succesfully!" << std::endl;

    // Write the ellipsoid image to a vtk image file
    itk::VTKImageIO::Pointer vtkIO;
    vtkIO = itk::VTKImageIO::New();
    itk::ImageFileWriter<TImageType>::Pointer writer;
    writer = itk::ImageFileWriter<TImageType>::New();
    writer->SetInput(sourceImage);
    writer->SetFileName("ellipsoid.vtk");
    writer->SetImageIO(vtkIO);
    writer->Write();

    return EXIT_SUCCESS;
    }
}
<|endoftext|>


<commit_before>/*

DAcase2.c

This program connects to the DAQ data source passed as argument
and populates local "./result.txt" file with the ids of events received
during the run.

The program exits when being asked to shut down (daqDA_checkshutdown)
or End of Run event.

Messages on stdout are exported to DAQ log system.

contact: alice-datesupport@cern.ch

*/

#include "event.h"
#include "monitor.h"
extern "C" {
#include "daqDA.h"
}

#include <stdio.h>
#include <stdlib.h>

#include <TSystem.h>

#include "AliRawReader.h"
#include "AliRawReaderDate.h"
#include "AliPHOSDA2.h"
#include "AliPHOSRawDecoderv1.h"
#include "AliCaloAltroMapping.h"

/* Main routine
      Arguments:
      1- monitoring data source
*/
int main(int argc, char **argv) {

  int status;

  if (argc!=2) {
    printf("Wrong number of arguments\n");
    return -1;
  }

  /* open result file */
  FILE *fp=NULL;
  fp=fopen("./result.txt","a");
  if (fp==NULL) {
    printf("Failed to open file\n");
    return -1;
  }

  /* Open mapping files */
  AliAltroMapping *mapping[4];
  TString path = gSystem->Getenv("ALICE_ROOT");
  path += "/PHOS/mapping/RCU";
  TString path2;
  for(Int_t i = 0; i < 4; i++) {
    path2 = path;
    path2 += i;
    path2 += ".data";
    mapping[i] = new AliCaloAltroMapping(path2.Data());
  }

  /* define data source : this is argument 1 */
  status=monitorSetDataSource( argv[1] );
  if (status!=0) {
    printf("monitorSetDataSource() failed : %s\n",monitorDecodeError(status));
    return -1;
  }

  /* declare monitoring program */
  status=monitorDeclareMp( __FILE__ );
  if (status!=0) {
    printf("monitorDeclareMp() failed : %s\n",monitorDecodeError(status));
    return -1;
  }

  /* define wait event timeout - 1s max */
  monitorSetNowait();
  monitorSetNoWaitNetworkTimeout(1000);

  /* log start of process */
  printf("DA2 (bad channels finding) started.\n");

  /* init some counters */
  int nevents_physics=0;
  int nevents_total=0;

  AliRawReader *rawReader = NULL;

  AliPHOSDA1 da2(2); // DA2 ("Checking for bad channels") for module2

  Float_t q[64][56][2];

  Int_t gain = -1;
  Int_t X = -1;
  Int_t Z = -1;

  /* main loop (infinite) */
  for(;;) {
    struct eventHeaderStruct *event;
    eventTypeType eventT;

    /* check shutdown condition */
    if (daqDA_checkShutdown()) {break;}

    /* get next event (blocking call until timeout) */
    status=monitorGetEventDynamic((void **)&event);
    if (status==MON_ERR_EOF) {
      printf ("End of File detected\n");
      break; /* end of monitoring file has been reached */
    }

    if (status!=0) {
      printf("monitorGetEventDynamic() failed : %s\n",monitorDecodeError(status));
      break;
    }

    /* retry if got no event */
    if (event==NULL) {
      continue;
    }

    /* use event - here, just write event id to result file */
    eventT=event->eventType;

    if (eventT==PHYSICS_EVENT) {
      fprintf(fp,"Run #%lu, event size: %lu, BC:%u, Orbit:%u, Period:%u\n",
	  (unsigned long)event->eventRunNb,
        (unsigned long)event->eventSize,
        EVENT_ID_GET_BUNCH_CROSSING(event->eventId),
        EVENT_ID_GET_ORBIT(event->eventId),
        EVENT_ID_GET_PERIOD(event->eventId)
      );

      for(Int_t iX=0; iX<64; iX++) {
	for(Int_t iZ=0; iZ<56; iZ++) {
	  for(Int_t iGain=0; iGain<2; iGain++) {
	    q[iX][iZ][iGain] = 0.;
	  }
	}
      }

      rawReader = new AliRawReaderDate((void*)event);
      AliPHOSRawDecoderv1 dc(rawReader,mapping);
      dc.SubtractPedestals(kTRUE);

      while(dc.NextDigit()) {

	X = dc.GetRow() - 1;
	Z = dc.GetColumn() - 1;

	if(dc.IsLowGain()) gain = 0;
	else
	  gain = 1;

	q[X][Z][gain] = dc.GetSampleQuality();

      }

      da2.FillQualityHistograms(q);
      //da1.UpdateHistoFile();

      delete rawReader;
      nevents_physics++;
    }

    nevents_total++;

    /* free resources */
    free(event);

    /* exit when last event received, no need to wait for TERM signal */
    if (eventT==END_OF_RUN) {
      printf("EOR event detected\n");
      break;
    }
  }

  for(Int_t i = 0; i < 4; i++) delete mapping[i];

  /* write report */
  fprintf(fp,"Run #%s, received %d physics events out of %d\n",getenv("DATE_RUN_NUMBER"),nevents_physics,nevents_total);

  /* close result file */
  fclose(fp);

  return status;
}
<commit_msg>Old version is deleted<commit_after><|endoftext|>


<commit_before>/*
contact: Boris.Polishchuk@cern.ch
link: see comments in the $ALICE_ROOT/PHOS/AliPHOSRcuDA1.cxx
reference run: /castor/cern.ch/alice/phos/2007/10/04/18/07000008249001.1000.root
run type: STANDALONE
DA type: MON
number of events needed: 1000
input files: RCU0.data  RCU1.data  RCU2.data  RCU3.data
Output files: PHOS_Module2_LED.root
Trigger types used: CALIBRATION_EVENT
*/

#include "event.h"
#include "monitor.h"
extern "C" {
#include "daqDA.h"
}

#include <stdio.h>
#include <stdlib.h>

#include <TSystem.h>
#include <TROOT.h>
#include <TPluginManager.h>

#include "AliRawReader.h"
#include "AliRawReaderDate.h"
#include "AliPHOSRcuDA1.h"
#include "AliPHOSRawFitterv0.h"
#include "AliCaloAltroMapping.h"
#include "AliCaloRawStreamV3.h"

/* Main routine
      Arguments:
      1- monitoring data source
*/
int main(int argc, char **argv) {

  gROOT->GetPluginManager()->AddHandler("TVirtualStreamerInfo",
					"*",
					"TStreamerInfo",
					"RIO",
					"TStreamerInfo()");

  int status;

  if (argc!=2) {
    printf("Wrong number of arguments\n");
    return -1;
  }

  /* Retrieve mapping files from DAQ DB */
  const char* mapFiles[4] = {"RCU0.data","RCU1.data","RCU2.data","RCU3.data"};

  for(Int_t iFile=0; iFile<4; iFile++) {
    int failed = daqDA_DB_getFile(mapFiles[iFile], mapFiles[iFile]);
    if(failed) {
      printf("Cannot retrieve file %s from DAQ DB. Exit.\n",mapFiles[iFile]);
      return -1;
    }
  }

  /* Open mapping files */
  AliAltroMapping *mapping[4];
  TString path = "./";
  path += "RCU";
  TString path2;
  for(Int_t i = 0; i < 4; i++) {
    path2 = path;
    path2 += i;
    path2 += ".data";
    mapping[i] = new AliCaloAltroMapping(path2.Data());
  }

  /* define data source : this is argument 1 */
  status=monitorSetDataSource( argv[1] );
  if (status!=0) {
    printf("monitorSetDataSource() failed : %s\n",monitorDecodeError(status));
    return -1;
  }

  /* declare monitoring program */
  status=monitorDeclareMp( __FILE__ );
  if (status!=0) {
    printf("monitorDeclareMp() failed : %s\n",monitorDecodeError(status));
    return -1;
  }

  /* define wait event timeout - 1s max */
  monitorSetNowait();
  monitorSetNoWaitNetworkTimeout(1000);

   /* init some counters */
  int nevents_physics=0;
  int nevents_total=0;

  Int_t fMod = 2; // module 2!
  AliRawReader *rawReader = NULL;

  AliPHOSRcuDA1 da1(fMod,-1,0); // DA1 for module2, no input/output file

  Float_t e[64][56][2];
  Float_t t[64][56][2];

  Int_t gain     = -1;
  Int_t cellX    = -1;
  Int_t cellZ    = -1;
  Int_t nBunches =  0;
  Int_t nFired   = -1;
  Int_t sigStart, sigLength;

  TH1I fFiredCells("fFiredCells","Number of fired cells per event",100,0,1000);

  /* main loop (infinite) */
  for(;;) {
    struct eventHeaderStruct *event;
    eventTypeType eventT;

    /* check shutdown condition */
    if (daqDA_checkShutdown()) {break;}

    /* get next event (blocking call until timeout) */
    status=monitorGetEventDynamic((void **)&event);
    if (status==MON_ERR_EOF) {
      printf ("End of File detected\n");
      break; /* end of monitoring file has been reached */
    }

    if (status!=0) {
      printf("monitorGetEventDynamic() failed : %s\n",monitorDecodeError(status));
      break;
    }

    /* retry if got no event */
    if (event==NULL) {
      continue;
    }

    /* use event - here, just write event id to result file */
    eventT=event->eventType;

    if (eventT==PHYSICS_EVENT) {

      for(Int_t iX=0; iX<64; iX++) {
	for(Int_t iZ=0; iZ<56; iZ++) {
	  for(Int_t iGain=0; iGain<2; iGain++) {
	    e[iX][iZ][iGain] = 0.;
	    t[iX][iZ][iGain] = 0.;
	  }
	}
      }

      nFired = 0;

      rawReader = new AliRawReaderDate((void*)event);
      AliCaloRawStreamV3 stream(rawReader,"PHOS",mapping);
      AliPHOSRawFitterv0 fitter();
      fitter.SubtractPedestals(kTRUE); // assume that data is non-ZS

      while (stream.NextDDL()) {
	while (stream.NextChannel()) {

	  cellX    = stream.GetCellX();
	  cellZ    = stream.GetCellZ();
	  caloFlag = stream.GetCaloFlag();  // 0=LG, 1=HG, 2=TRU

	  // In case of oscillating signals with ZS, a channel can have several bunches
	  nBunches = 0;
	  while (stream.NextBunch()) {
	    nBunches++;
	    if (nBunches > 1) continue;
	    sigStart  = fRawStream.GetStartTimeBin();
	    sigLength = fRawStream.GetBunchLength();
	    fitter.SetSamples(fRawStream->GetSignals(),sigStart,sigLength);
	  } // End of NextBunch()

	  fitter.SetNBunches(nBunches);
	  fitter.SetChannelGeo(module,cellX,cellZ,caloFlag);
	  fitter.Eval();

	  if (nBunches>1 || caloFlag!=0 || caloFlag!=1 || fitter.GetSignalQuality()>1) continue;

	  e[cellX][cellZ][caloFlag] = fitter.GetEnergy();
	  t[cellX][cellZ][caloFlag] = fitter.GetTime();

	  if(caloFlag==1 && fitter.GetEnergy()>40)
	    nFired++;
	}
      }

      da1.FillHistograms(e,t);
      fFiredCells.Fill(nFired);

      delete rawReader;
      nevents_physics++;
    }

    nevents_total++;

    /* free resources */
    free(event);

    /* exit when last event received, no need to wait for TERM signal */
    if (eventT==END_OF_RUN) {
      printf("EOR event detected\n");
      break;
    }
  }

  for(Int_t i = 0; i < 4; i++) delete mapping[i];

  /* Be sure that all histograms are saved */

  char localfile[128];
  sprintf(localfile,"PHOS_Module%d_LED.root",fMod);
  TFile* f = new TFile(localfile,"recreate");

  const TH2F* h2=0;
  const TH1F* h1=0;

  Int_t nGood=0;    // >10 entries in peak
  Int_t nMax=-111;  // max. number of entries in peak
  Int_t iXmax=-1;
  Int_t iZmax=-1;

  for(Int_t iX=0; iX<64; iX++) {
    for(Int_t iZ=0; iZ<56; iZ++) {

      h1 = da1.GetHgLgRatioHistogram(iX,iZ); // High Gain/Low Gain ratio
      if(h1) {
	if(h1->GetMaximum()>10.) nGood++;
	if(h1->GetMaximum()>nMax) {nMax = (Int_t)h1->GetMaximum(); iXmax=iX; iZmax=iZ;}
	h1->Write();
      }

      for(Int_t iGain=0; iGain<2; iGain++) {
	h2 = da1.GetTimeEnergyHistogram(iX,iZ,iGain); // Time vs Energy
	if(h2) h2->Write();
      }

    }
  }

  fFiredCells.Write();
  f->Close();

  /* Store output files to the File Exchange Server */
  daqDA_FES_storeFile("PHOS_Module2_LED.root","LED");

  printf("%d physics events of %d total processed.\n",nevents_physics,nevents_total);
  printf("%d histograms has >10 entries in maximum, max. is %d entries ",nGood,nMax);
  printf("(module,iX,iZ)=(%d,%d,%d)",fMod,iXmax,iZmax);
  printf("\n");

  return status;
}
<commit_msg>Hardcoded module number removed; fixed errors of previous commit.<commit_after>/*
contact: Boris.Polishchuk@cern.ch
link: see comments in the $ALICE_ROOT/PHOS/AliPHOSRcuDA1.cxx
reference run: /castor/cern.ch/alice/phos/2007/10/04/18/07000008249001.1000.root
run type: STANDALONE
DA type: MON
number of events needed: 1000
input files: RCU0.data  RCU1.data  RCU2.data  RCU3.data
Output files: PHOS_Module2_LED.root
Trigger types used: CALIBRATION_EVENT
*/

#include "event.h"
#include "monitor.h"
extern "C" {
#include "daqDA.h"
}

#include <stdio.h>
#include <stdlib.h>

#include <TSystem.h>
#include <TROOT.h>
#include <TPluginManager.h>

#include "AliRawReader.h"
#include "AliRawReaderDate.h"
#include "AliPHOSRcuDA1.h"
#include "AliPHOSRawFitterv0.h"
#include "AliCaloAltroMapping.h"
#include "AliCaloRawStreamV3.h"

/* Main routine
      Arguments:
      1- monitoring data source
*/
int main(int argc, char **argv) {

  gROOT->GetPluginManager()->AddHandler("TVirtualStreamerInfo",
					"*",
					"TStreamerInfo",
					"RIO",
					"TStreamerInfo()");

  int status;

  if (argc!=2) {
    printf("Wrong number of arguments\n");
    return -1;
  }

  /* Retrieve mapping files from DAQ DB */
  const char* mapFiles[4] = {"RCU0.data","RCU1.data","RCU2.data","RCU3.data"};

  for(Int_t iFile=0; iFile<4; iFile++) {
    int failed = daqDA_DB_getFile(mapFiles[iFile], mapFiles[iFile]);
    if(failed) {
      printf("Cannot retrieve file %s from DAQ DB. Exit.\n",mapFiles[iFile]);
      return -1;
    }
  }

  /* Open mapping files */
  AliAltroMapping *mapping[4];
  TString path = "./";
  path += "RCU";
  TString path2;
  for(Int_t i = 0; i < 4; i++) {
    path2 = path;
    path2 += i;
    path2 += ".data";
    mapping[i] = new AliCaloAltroMapping(path2.Data());
  }

  /* define data source : this is argument 1 */
  status=monitorSetDataSource( argv[1] );
  if (status!=0) {
    printf("monitorSetDataSource() failed : %s\n",monitorDecodeError(status));
    return -1;
  }

  /* declare monitoring program */
  status=monitorDeclareMp( __FILE__ );
  if (status!=0) {
    printf("monitorDeclareMp() failed : %s\n",monitorDecodeError(status));
    return -1;
  }

  /* define wait event timeout - 1s max */
  monitorSetNowait();
  monitorSetNoWaitNetworkTimeout(1000);

   /* init some counters */
  int nevents_physics=0;
  int nevents_total=0;

  AliRawReader *rawReader = NULL;
  AliPHOSRcuDA1* dAs[5];

  for(Int_t iMod=0; iMod<5; iMod++) {
    dAs[iMod] = 0;
  }

  Float_t e[64][56][2];
  Float_t t[64][56][2];

  Int_t cellX    = -1;
  Int_t cellZ    = -1;
  Int_t nBunches =  0;
  Int_t nFired   = -1;
  Int_t sigStart, sigLength;
  Int_t caloFlag;

  TH1I fFiredCells("fFiredCells","Number of fired cells per event",100,0,1000);

  /* main loop (infinite) */
  for(;;) {
    struct eventHeaderStruct *event;
    eventTypeType eventT;

    /* check shutdown condition */
    if (daqDA_checkShutdown()) {break;}

    /* get next event (blocking call until timeout) */
    status=monitorGetEventDynamic((void **)&event);
    if (status==MON_ERR_EOF) {
      printf ("End of File detected\n");
      break; /* end of monitoring file has been reached */
    }

    if (status!=0) {
      printf("monitorGetEventDynamic() failed : %s\n",monitorDecodeError(status));
      break;
    }

    /* retry if got no event */
    if (event==NULL) {
      continue;
    }

    /* use event - here, just write event id to result file */
    eventT=event->eventType;

    if (eventT==PHYSICS_EVENT) {

      nFired = 0;

      rawReader = new AliRawReaderDate((void*)event);
      AliCaloRawStreamV3 stream(rawReader,"PHOS",mapping);
      AliPHOSRawFitterv0 fitter;
      fitter.SubtractPedestals(kTRUE); // assume that data is non-ZS

      while (stream.NextDDL()) {
	while (stream.NextChannel()) {

	  cellX    = stream.GetCellX();
	  cellZ    = stream.GetCellZ();
	  caloFlag = stream.GetCaloFlag();  // 0=LG, 1=HG, 2=TRU

	  // In case of oscillating signals with ZS, a channel can have several bunches
	  nBunches = 0;
	  while (stream.NextBunch()) {
	    nBunches++;
	    if (nBunches > 1) continue;
	    sigStart  = stream.GetStartTimeBin();
	    sigLength = stream.GetBunchLength();
	    fitter.SetSamples(stream.GetSignals(),sigStart,sigLength);
	  } // End of NextBunch()

	  fitter.SetNBunches(nBunches);
	  fitter.SetChannelGeo(stream.GetModule(),cellX,cellZ,caloFlag);
	  fitter.Eval();

	  if(nBunches>1) continue;
// 	  if (nBunches>1 || caloFlag!=0 || caloFlag!=1 || fitter.GetSignalQuality()>1) continue;

	  e[cellX][cellZ][caloFlag] = fitter.GetEnergy();
	  t[cellX][cellZ][caloFlag] = fitter.GetTime();

	  if(caloFlag==1 && fitter.GetEnergy()>40)
	    nFired++;
	}

	if(dAs[stream.GetModule()])
	  dAs[stream.GetModule()]->FillHistograms(e,t);
	else
	  dAs[stream.GetModule()] = new AliPHOSRcuDA1(stream.GetModule(),-1,0);

	for(Int_t iX=0; iX<64; iX++) {
	  for(Int_t iZ=0; iZ<56; iZ++) {
	    for(Int_t iGain=0; iGain<2; iGain++) {
	      e[iX][iZ][iGain] = 0.;
	      t[iX][iZ][iGain] = 0.;
	    }
	  }
	}

      }

      fFiredCells.Fill(nFired);

      delete rawReader;
      nevents_physics++;
    }

    nevents_total++;

    /* free resources */
    free(event);

    /* exit when last event received, no need to wait for TERM signal */
    if (eventT==END_OF_RUN) {
      printf("EOR event detected\n");
      break;
    }
  }

  for(Int_t i = 0; i < 4; i++) delete mapping[i];

  /* Be sure that all histograms are saved */

  const TH2F* h2=0;
  const TH1F* h1=0;
  char localfile[128];

  Int_t nGood=0;    // >10 entries in peak
  Int_t nMax=-111;  // max. number of entries in peak
  Int_t iXmax=-1;
  Int_t iZmax=-1;
  Int_t iModMax=-1;

  for(Int_t iMod=0; iMod<5; iMod++) {
    if(!dAs[iMod]) continue;

    printf("DA1 for module %d detected.\n",iMod);
    sprintf(localfile,"PHOS_Module%d_LED.root",iMod);
    TFile* f = new TFile(localfile,"recreate");

    for(Int_t iX=0; iX<64; iX++) {
      for(Int_t iZ=0; iZ<56; iZ++) {

	h1 = dAs[iMod]->GetHgLgRatioHistogram(iX,iZ); // High Gain/Low Gain ratio
	if(h1) {
	  if(h1->GetMaximum()>10.) nGood++;
	  if(h1->GetMaximum()>nMax) {
	    nMax = (Int_t)h1->GetMaximum(); iXmax=iX; iZmax=iZ; iModMax=iMod;
	  }
	  h1->Write();
	}

	for(Int_t iGain=0; iGain<2; iGain++) {
	  h2 = dAs[iMod]->GetTimeEnergyHistogram(iX,iZ,iGain); // Time vs Energy
	  if(h2) h2->Write();
	}

      }
    }

    fFiredCells.Write();
    f->Close();

    /* Store output files to the File Exchange Server */
    daqDA_FES_storeFile(localfile,"LED");
  }

  printf("%d physics events of %d total processed.\n",nevents_physics,nevents_total);
  printf("%d histograms has >10 entries in maximum, max. is %d entries ",nGood,nMax);
  printf("(module,iX,iZ)=(%d,%d,%d)",iModMax,iXmax,iZmax);
  printf("\n");

  return status;
}
<|endoftext|>


<commit_before>/*
* Prime Generation
* (C) 1999-2007,2018 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#include <botan/numthry.h>
#include <botan/rng.h>
#include <botan/internal/bit_ops.h>
#include <botan/loadstor.h>
#include <algorithm>

namespace Botan {

namespace {

class Prime_Sieve final
   {
   public:
      Prime_Sieve(const BigInt& init_value, size_t sieve_size) :
         m_sieve(std::min(sieve_size, PRIME_TABLE_SIZE))
         {
         for(size_t i = 0; i != m_sieve.size(); ++i)
            m_sieve[i] = static_cast<uint16_t>(init_value % PRIMES[i]);
         }

      void step(word increment)
         {
         for(size_t i = 0; i != m_sieve.size(); ++i)
            {
            m_sieve[i] = (m_sieve[i] + increment) % PRIMES[i];
            }
         }

      bool passes(bool check_2p1 = false) const
         {
         for(size_t i = 0; i != m_sieve.size(); ++i)
            {
            /*
            In this case, p is a multiple of PRIMES[i]
            */
            if(m_sieve[i] == 0)
               return false;

            if(check_2p1)
               {
               /*
               In this case, 2*p+1 will be a multiple of PRIMES[i]

               So if potentially generating a safe prime, we want to
               avoid this value because 2*p+1 will certainly not be prime.

               See "Safe Prime Generation with a Combined Sieve" M. Wiener
               https://eprint.iacr.org/2003/186.pdf
               */
               if(m_sieve[i] == (PRIMES[i] - 1) / 2)
                  return false;
               }
            }

         return true;
         }

   private:
      std::vector<uint16_t> m_sieve;
   };

}

/*
* Generate a random prime
*/
BigInt random_prime(RandomNumberGenerator& rng,
                    size_t bits, const BigInt& coprime,
                    size_t equiv, size_t modulo,
                    size_t prob)
   {
   if(coprime.is_negative())
      {
      throw Invalid_Argument("random_prime: coprime must be >= 0");
      }
   if(modulo == 0)
      {
      throw Invalid_Argument("random_prime: Invalid modulo value");
      }

   equiv %= modulo;

   if(equiv == 0)
      throw Invalid_Argument("random_prime Invalid value for equiv/modulo");

   // Handle small values:
   if(bits <= 1)
      {
      throw Invalid_Argument("random_prime: Can't make a prime of " +
                             std::to_string(bits) + " bits");
      }
   else if(bits == 2)
      {
      return ((rng.next_byte() % 2) ? 2 : 3);
      }
   else if(bits == 3)
      {
      return ((rng.next_byte() % 2) ? 5 : 7);
      }
   else if(bits == 4)
      {
      return ((rng.next_byte() % 2) ? 11 : 13);
      }
   else if(bits <= 16)
      {
      for(;;)
         {
         // This is slightly biased, but for small primes it does not seem to matter
         const uint8_t b0 = rng.next_byte();
         const uint8_t b1 = rng.next_byte();
         const size_t idx = make_uint16(b0, b1) % PRIME_TABLE_SIZE;
         const uint16_t small_prime = PRIMES[idx];

         if(high_bit(small_prime) == bits)
            return small_prime;
         }
      }

   const size_t MAX_ATTEMPTS = 32*1024;

   while(true)
      {
      BigInt p(rng, bits);

      // Force lowest and two top bits on
      p.set_bit(bits - 1);
      p.set_bit(bits - 2);
      p.set_bit(0);

      // Force p to be equal to equiv mod modulo
      p += (modulo - (p % modulo)) + equiv;

      Prime_Sieve sieve(p, bits);

      size_t counter = 0;
      while(true)
         {
         ++counter;

         if(counter > MAX_ATTEMPTS)
            {
            break; // don't try forever, choose a new starting point
            }

         p += modulo;

         sieve.step(modulo);

         if(sieve.passes(true) == false)
            continue;

         if(coprime > 1)
            {
            /*
            * Check if gcd(p - 1, coprime) != 1 by computing the inverse. The
            * gcd algorithm is not constant time, but modular inverse is (for
            * odd modulus anyway). This avoids a side channel attack against RSA
            * key generation, though RSA keygen should be using generate_rsa_prime.
            */
            if(inverse_mod(p - 1, coprime).is_zero())
               continue;
            }

         if(p.bits() > bits)
            break;

         if(is_prime(p, rng, prob, true))
            return p;
         }
      }
   }

BigInt generate_rsa_prime(RandomNumberGenerator& keygen_rng,
                          RandomNumberGenerator& prime_test_rng,
                          size_t bits,
                          const BigInt& coprime,
                          size_t prob)
   {
   if(bits < 512)
      throw Invalid_Argument("generate_rsa_prime bits too small");

   /*
   * The restriction on coprime <= 64 bits is arbitrary but generally speaking
   * very large RSA public exponents are a bad idea both for performance and due
   * to attacks on small d.
   */
   if(coprime <= 1 || coprime.is_even() || coprime.bits() > 64)
      throw Invalid_Argument("generate_rsa_prime coprime must be small odd positive integer");

   const size_t MAX_ATTEMPTS = 32*1024;

   while(true)
      {
      BigInt p(keygen_rng, bits);

      // Force lowest and two top bits on
      p.set_bit(bits - 1);
      p.set_bit(bits - 2);
      p.set_bit(0);

      Prime_Sieve sieve(p, bits);

      const word step = 2;

      size_t counter = 0;
      while(true)
         {
         ++counter;

         if(counter > MAX_ATTEMPTS)
            {
            break; // don't try forever, choose a new starting point
            }

         p += step;

         sieve.step(step);

         if(sieve.passes() == false)
            continue;

         /*
         * Check if p - 1 and coprime are relatively prime by computing the inverse.
         *
         * We avoid gcd here because that algorithm is not constant time.
         * Modular inverse is (for odd modulus anyway).
         *
         * We earlier verified that coprime argument is odd. Thus the factors of 2
         * in (p - 1) cannot possibly be factors in coprime, so remove them from p - 1.
         * Using an odd modulus allows the const time algorithm to be used.
         *
         * This assumes coprime < p - 1 which is always true for RSA.
         */
         BigInt p1 = p - 1;
         p1 >>= low_zero_bits(p1);
         if(inverse_mod(coprime, p1).is_zero())
            {
            BOTAN_DEBUG_ASSERT(gcd(p1, coprime) > 1);
            continue;
            }

         BOTAN_DEBUG_ASSERT(gcd(p1, coprime) == 1);

         if(p.bits() > bits)
            break;

         if(is_prime(p, prime_test_rng, prob, true))
            return p;
         }
      }
   }

/*
* Generate a random safe prime
*/
BigInt random_safe_prime(RandomNumberGenerator& rng, size_t bits)
   {
   if(bits <= 64)
      throw Invalid_Argument("random_safe_prime: Can't make a prime of " +
                             std::to_string(bits) + " bits");

   BigInt q, p;
   for(;;)
      {
      /*
      Generate q == 2 (mod 3)

      Otherwise [q == 1 (mod 3) case], 2*q+1 == 3 (mod 3) and not prime.

      Initially allow a very high error prob (1/2**8) to allow for fast checks,
      then if 2*q+1 turns out to be a prime go back and strongly check q.
      */
      q = random_prime(rng, bits - 1, 0, 2, 3, 8);
      p = (q << 1) + 1;

      if(is_prime(p, rng, 128, true))
         {
         // We did only a weak check before, go back and verify q before returning
         if(is_prime(q, rng, 128, true))
            return p;
         }
      }
   }

}
<commit_msg>Improve speed of prime generation especially for RSA keygen<commit_after>/*
* Prime Generation
* (C) 1999-2007,2018,2019 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#include <botan/numthry.h>
#include <botan/rng.h>
#include <botan/internal/bit_ops.h>
#include <botan/loadstor.h>
#include <botan/reducer.h>
#include <botan/internal/primality.h>
#include <algorithm>

namespace Botan {

namespace {

class Prime_Sieve final
   {
   public:
      Prime_Sieve(const BigInt& init_value, size_t sieve_size) :
         m_sieve(std::min(sieve_size, PRIME_TABLE_SIZE))
         {
         for(size_t i = 0; i != m_sieve.size(); ++i)
            m_sieve[i] = static_cast<uint16_t>(init_value % PRIMES[i]);
         }

      void step(word increment)
         {
         for(size_t i = 0; i != m_sieve.size(); ++i)
            {
            m_sieve[i] = (m_sieve[i] + increment) % PRIMES[i];
            }
         }

      bool passes(bool check_2p1 = false) const
         {
         for(size_t i = 0; i != m_sieve.size(); ++i)
            {
            /*
            In this case, p is a multiple of PRIMES[i]
            */
            if(m_sieve[i] == 0)
               return false;

            if(check_2p1)
               {
               /*
               In this case, 2*p+1 will be a multiple of PRIMES[i]

               So if potentially generating a safe prime, we want to
               avoid this value because 2*p+1 will certainly not be prime.

               See "Safe Prime Generation with a Combined Sieve" M. Wiener
               https://eprint.iacr.org/2003/186.pdf
               */
               if(m_sieve[i] == (PRIMES[i] - 1) / 2)
                  return false;
               }
            }

         return true;
         }

   private:
      std::vector<uint16_t> m_sieve;
   };

}

/*
* Generate a random prime
*/
BigInt random_prime(RandomNumberGenerator& rng,
                    size_t bits, const BigInt& coprime,
                    size_t equiv, size_t modulo,
                    size_t prob)
   {
   if(coprime.is_negative())
      {
      throw Invalid_Argument("random_prime: coprime must be >= 0");
      }
   if(modulo == 0)
      {
      throw Invalid_Argument("random_prime: Invalid modulo value");
      }

   equiv %= modulo;

   if(equiv == 0)
      throw Invalid_Argument("random_prime Invalid value for equiv/modulo");

   // Handle small values:

   if(bits <= 16)
      {
      if(equiv != 1 || modulo != 2 || coprime != 0)
         throw Not_Implemented("random_prime equiv/modulo/coprime options not usable for small primes");

      if(bits <= 1)
         {
         throw Invalid_Argument("random_prime: Can't make a prime of " +
                                std::to_string(bits) + " bits");
         }
      else if(bits == 2)
         {
         return ((rng.next_byte() % 2) ? 2 : 3);
         }
      else if(bits == 3)
         {
         return ((rng.next_byte() % 2) ? 5 : 7);
         }
      else if(bits == 4)
         {
         return ((rng.next_byte() % 2) ? 11 : 13);
         }
      else
         {
         for(;;)
            {
            // This is slightly biased, but for small primes it does not seem to matter
            const uint8_t b0 = rng.next_byte();
            const uint8_t b1 = rng.next_byte();
            const size_t idx = make_uint16(b0, b1) % PRIME_TABLE_SIZE;
            const uint16_t small_prime = PRIMES[idx];

            if(high_bit(small_prime) == bits)
               return small_prime;
            }
         }
      }

   const size_t MAX_ATTEMPTS = 32*1024;

   while(true)
      {
      BigInt p(rng, bits);

      // Force lowest and two top bits on
      p.set_bit(bits - 1);
      p.set_bit(bits - 2);
      p.set_bit(0);

      // Force p to be equal to equiv mod modulo
      p += (modulo - (p % modulo)) + equiv;

      Prime_Sieve sieve(p, bits);

      size_t counter = 0;
      while(true)
         {
         ++counter;

         if(counter > MAX_ATTEMPTS)
            {
            break; // don't try forever, choose a new starting point
            }

         p += modulo;

         sieve.step(modulo);

         // p can be even if modulo is odd, continue on in that case
         if(p.is_even() || sieve.passes(true) == false)
            continue;

         Modular_Reducer mod_p(p);

         if(is_miller_rabin_probable_prime(p, mod_p, rng, 1) == false)
            continue;

         if(coprime > 1)
            {
            /*
            * Check if gcd(p - 1, coprime) != 1 by computing the inverse. The
            * gcd algorithm is not constant time, but modular inverse is (for
            * odd modulus anyway). This avoids a side channel attack against RSA
            * key generation, though RSA keygen should be using generate_rsa_prime.
            */
            if(inverse_mod(p - 1, coprime).is_zero())
               {
               continue;
               }
            }

         if(p.bits() > bits)
            break;

         const size_t t = miller_rabin_test_iterations(bits, prob, true);

         if(is_miller_rabin_probable_prime(p, mod_p, rng, t) == false)
            continue;

         if(is_lucas_probable_prime(p, mod_p))
            return p;
         }
      }
   }

BigInt generate_rsa_prime(RandomNumberGenerator& keygen_rng,
                          RandomNumberGenerator& prime_test_rng,
                          size_t bits,
                          const BigInt& coprime,
                          size_t prob)
   {
   if(bits < 512)
      throw Invalid_Argument("generate_rsa_prime bits too small");

   /*
   * The restriction on coprime <= 64 bits is arbitrary but generally speaking
   * very large RSA public exponents are a bad idea both for performance and due
   * to attacks on small d.
   */
   if(coprime <= 1 || coprime.is_even() || coprime.bits() > 64)
      throw Invalid_Argument("generate_rsa_prime coprime must be small odd positive integer");

   const size_t MAX_ATTEMPTS = 32*1024;

   while(true)
      {
      BigInt p(keygen_rng, bits);

      // Force lowest and two top bits on
      p.set_bit(bits - 1);
      p.set_bit(bits - 2);
      p.set_bit(0);

      Prime_Sieve sieve(p, bits);

      const word step = 2;

      size_t counter = 0;
      while(true)
         {
         ++counter;

         if(counter > MAX_ATTEMPTS)
            {
            break; // don't try forever, choose a new starting point
            }

         p += step;

         sieve.step(step);

         if(sieve.passes() == false)
            continue;

         Modular_Reducer mod_p(p);

         /*
         * Do a single primality test first before checking coprimality, since
         * currently a single Miller-Rabin test is faster than computing modular
         * inverse, and this eliminates almost all wasted modular inverses.
         */
         if(is_miller_rabin_probable_prime(p, mod_p, prime_test_rng, 1) == false)
            continue;

         /*
         * Check if p - 1 and coprime are relatively prime by computing the inverse.
         *
         * We avoid gcd here because that algorithm is not constant time.
         * Modular inverse is (for odd modulus anyway).
         *
         * We earlier verified that coprime argument is odd. Thus the factors of 2
         * in (p - 1) cannot possibly be factors in coprime, so remove them from p - 1.
         * Using an odd modulus allows the const time algorithm to be used.
         *
         * This assumes coprime < p - 1 which is always true for RSA.
         */
         BigInt p1 = p - 1;
         p1 >>= low_zero_bits(p1);
         if(inverse_mod(coprime, p1).is_zero())
            {
            BOTAN_DEBUG_ASSERT(gcd(p1, coprime) > 1);
            continue;
            }

         BOTAN_DEBUG_ASSERT(gcd(p1, coprime) == 1);

         if(p.bits() > bits)
            break;

         const size_t t = miller_rabin_test_iterations(bits, prob, true);

         if(is_miller_rabin_probable_prime(p, mod_p, prime_test_rng, t) == true)
            return p;
         }
      }
   }

/*
* Generate a random safe prime
*/
BigInt random_safe_prime(RandomNumberGenerator& rng, size_t bits)
   {
   if(bits <= 64)
      throw Invalid_Argument("random_safe_prime: Can't make a prime of " +
                             std::to_string(bits) + " bits");

   BigInt q, p;
   for(;;)
      {
      /*
      Generate q == 2 (mod 3)

      Otherwise [q == 1 (mod 3) case], 2*q+1 == 3 (mod 3) and not prime.

      Initially allow a very high error prob (1/2**8) to allow for fast checks,
      then if 2*q+1 turns out to be a prime go back and strongly check q.
      */
      q = random_prime(rng, bits - 1, 0, 2, 3, 8);
      p = (q << 1) + 1;

      if(is_prime(p, rng, 128, true))
         {
         // We did only a weak check before, go back and verify q before returning
         if(is_prime(q, rng, 128, true))
            return p;
         }
      }
   }

}
<|endoftext|>


<commit_before>#include <getopt.h>
#include <string>
#include <math.h>

#include <boost/lexical_cast.hpp>

#include <boost/asio.hpp>
#include <boost/lexical_cast.hpp>
#include <libwatcher/client.h>
#include <libwatcher/gpsMessage.h>
#include <libwatcher/labelMessage.h>
#include <libwatcher/edgeMessage.h>
#include <libwatcher/watcherColors.h>
#include "logger.h"
#include "sendMessageHandler.h"

using namespace std;
using namespace watcher;
using namespace watcher::event;
using namespace boost;

#define PI (3.141592653589793) // Isn't this #DEFINEd somewhere?

void usage(const char *progName)
{
    fprintf(stderr, "Usage: %s [args]\n", basename(progName));
    fprintf(stderr, "Args:\n");
    fprintf(stderr, "   -s, --server=address        The addres of the node running watcherd\n");
    fprintf(stderr, "\n");
    fprintf(stderr, "Optional args:\n");
    fprintf(stderr, "   -p, --logProps              log.properties file, which controls logging for this program\n");
    fprintf(stderr, "   -r, --radius                The radius of the circle in some unknown unit\n");
    fprintf(stderr, "   -S, --hideSecondRing        Don't send message to draw the outer, second hand ring\n");
    fprintf(stderr, "   -H, --hideHourRing          Don't send message to draw the inner, hour hand ring\n");
    fprintf(stderr, "\n");
    fprintf(stderr, "   -h, --help                  Show this message\n");

    exit(1);
}

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

    int c;
    string server;
    string logProps(string(basename(argv[0]))+string(".log.properties"));
    double radius=50.0;
    bool showSecondRing=true, showHourRing=true;

    while (true)
    {
        int option_index = 0;
        static struct option long_options[] = {
            {"server", required_argument, 0, 's'},
            {"logProps", required_argument, 0, 'p'},
            {"radius", no_argument, 0, 'r'},
            {"hideSecondRing", required_argument, 0, 'S'},
            {"hideHourRing", required_argument, 0, 'H'},
            {"help", no_argument, 0, 'h'},
            {0, 0, 0, 0}
        };

        c = getopt_long(argc, argv, "r:s:p:SHh?", long_options, &option_index);

        if (c == -1)
            break;

        switch(c)
        {
            case 's':
                server=optarg;
                break;
            case 'p':
                logProps=optarg;
                break;
            case 'r':
                radius=lexical_cast<double>(optarg);
                break;
            case 'S':
                showSecondRing=false;
                break;
            case 'H':
                showHourRing=false;
                break;
            case 'h':
            case '?':
            default:
                usage(argv[0]);
                break;
        }
    }

    if (server=="")
    {
        usage(argv[0]);
        exit(1);
    }

    //
    // Now do some actual work.
    //
    LOAD_LOG_PROPS(logProps);

    Client client(server);
    LOG_INFO("Connecting to " << server << " and sending message.");
    // Do not add empty handler - default Client handler does not close connection.
    // client.addMessageHandler(SendMessageHandler::create());

    unsigned int loopTime=1;
    // Create hour, min, sec, and center nodes.
    NodeIdentifier centerId=NodeIdentifier::from_string("192.168.1.100");
    NodeIdentifier hourId=NodeIdentifier::from_string("192.168.1.101");
    NodeIdentifier minId=NodeIdentifier::from_string("192.168.1.102");
    NodeIdentifier secId=NodeIdentifier::from_string("192.168.1.103");

    const GUILayer layer("Clock");
    const double step=(2*PI)/60;
    struct
    {
        double theta;
        NodeIdentifier *id;
        const char *label;
        Color color;
        double length;
    } nodeData[]=
    {
        { 0,   &hourId, "hour", Color::red,   radius },
        { 0,    &minId,  "min", Color::blue,  radius*.8 },
        { 0,    &secId,  "sec", Color::green, radius},
    };
    while (true)  // draw everything all the time as we don't know when watcher will start
    {
        // Draw center node
        GPSMessagePtr gpsMess(new GPSMessage(radius, radius, 0));
        gpsMess->layer=layer;
        gpsMess->fromNodeID=centerId;
        if(!client.sendMessage(gpsMess))
        {
            LOG_ERROR("Error sending gps message: " << *gpsMess);
            TRACE_EXIT_RET(EXIT_FAILURE);
            return EXIT_FAILURE;
        }
        // draw hour, min, and second nodes, connecting them to center.
        for (unsigned int i=0; i<sizeof(nodeData)/sizeof(nodeData[0]); i++)
        {
            // update location offsets by current time.
            time_t nowInSecs=time(NULL);
            struct tm *now=localtime(&nowInSecs);
            if (*nodeData[i].id==hourId)
                nodeData[i].theta=step*((now->tm_hour*(60/12))+(now->tm_min/12));
            else if(*nodeData[i].id==minId)
                nodeData[i].theta=step*now->tm_min;
            else if(*nodeData[i].id==secId)
                nodeData[i].theta=step*now->tm_sec;

            // Move hour. min, and sec nodes to appropriate locations.
            GPSMessagePtr gpsMess(new GPSMessage(
                        (sin(nodeData[i].theta)*nodeData[i].length)+radius,
                        (cos(nodeData[i].theta)*nodeData[i].length)+radius,
                        (double)i));
            gpsMess->layer=layer;
            gpsMess->fromNodeID=*nodeData[i].id;
            if(!client.sendMessage(gpsMess))
            {
                LOG_ERROR("Error sending gps message: " << *gpsMess);
                TRACE_EXIT_RET(EXIT_FAILURE);
                return EXIT_FAILURE;
            }

            LabelMessagePtr labMess(new LabelMessage(nodeData[i].label));
            labMess->layer=layer;
            labMess->expiration=loopTime*2000;  // 2000 to stop blinking
            EdgeMessagePtr edgeMess(new EdgeMessage(centerId, *nodeData[i].id, layer, nodeData[i].color, 2));
            edgeMess->middleLabel=labMess;
            if(!client.sendMessage(edgeMess))
            {
                LOG_ERROR("Error sending edge message: " << *edgeMess);
                TRACE_EXIT_RET(EXIT_FAILURE);
                return EXIT_FAILURE;
            }
        }

        if (showHourRing)
        {
            // add nodes at clock face number locations.
            double theta=(2*PI)/12;
            for (unsigned int i=0; i<12; i++, theta+=(2*PI)/12)
            {
                NodeIdentifier thisId=NodeIdentifier::from_string("192.168.2." + lexical_cast<string>(i+1));
                GPSMessagePtr gpsMess(new GPSMessage((sin(theta)*radius)+radius, (cos(theta)*radius)+radius, 0.0));
                gpsMess->layer=layer;
                gpsMess->fromNodeID=thisId;
                if(!client.sendMessage(gpsMess))
                {
                    LOG_ERROR("Error sending gps message: " << *gpsMess);
                    TRACE_EXIT_RET(EXIT_FAILURE);
                    return EXIT_FAILURE;
                }
            }
        }

        if (showSecondRing)
        {
            // add nodes at clock face second locations.
            double theta=(2*PI)/60;
            for (unsigned int i=0; i<60; i++, theta+=(2*PI)/60)
            {
                NodeIdentifier thisId=NodeIdentifier::from_string("192.168.3." + lexical_cast<string>(i+1));
                double faceRad=radius*1.15;
                GPSMessagePtr gpsMess(new GPSMessage((sin(theta)*faceRad)+radius, (cos(theta)*faceRad)+radius, 0.0));
                gpsMess->layer=layer;
                gpsMess->fromNodeID=thisId;
                if(!client.sendMessage(gpsMess))
                {
                    LOG_ERROR("Error sending gps message: " << *gpsMess);
                    TRACE_EXIT_RET(EXIT_FAILURE);
                    return EXIT_FAILURE;
                }
            }
        }
        sleep(loopTime);
    }

    client.wait();

    TRACE_EXIT_RET(EXIT_SUCCESS);
    return EXIT_SUCCESS;
}

<commit_msg>showClock: apparently I have not looked at an analog clock for awhile. :)<commit_after>#include <getopt.h>
#include <string>
#include <math.h>

#include <boost/lexical_cast.hpp>

#include <boost/asio.hpp>
#include <boost/lexical_cast.hpp>
#include <libwatcher/client.h>
#include <libwatcher/gpsMessage.h>
#include <libwatcher/labelMessage.h>
#include <libwatcher/edgeMessage.h>
#include <libwatcher/watcherColors.h>
#include "logger.h"
#include "sendMessageHandler.h"

using namespace std;
using namespace watcher;
using namespace watcher::event;
using namespace boost;

#define PI (3.141592653589793) // Isn't this #DEFINEd somewhere?

void usage(const char *progName)
{
    fprintf(stderr, "Usage: %s [args]\n", basename(progName));
    fprintf(stderr, "Args:\n");
    fprintf(stderr, "   -s, --server=address        The addres of the node running watcherd\n");
    fprintf(stderr, "\n");
    fprintf(stderr, "Optional args:\n");
    fprintf(stderr, "   -p, --logProps              log.properties file, which controls logging for this program\n");
    fprintf(stderr, "   -r, --radius                The radius of the circle in some unknown unit\n");
    fprintf(stderr, "   -S, --hideSecondRing        Don't send message to draw the outer, second hand ring\n");
    fprintf(stderr, "   -H, --hideHourRing          Don't send message to draw the inner, hour hand ring\n");
    fprintf(stderr, "\n");
    fprintf(stderr, "   -h, --help                  Show this message\n");

    exit(1);
}

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

    int c;
    string server;
    string logProps(string(basename(argv[0]))+string(".log.properties"));
    double radius=50.0;
    bool showSecondRing=true, showHourRing=true;

    while (true)
    {
        int option_index = 0;
        static struct option long_options[] = {
            {"server", required_argument, 0, 's'},
            {"logProps", required_argument, 0, 'p'},
            {"radius", no_argument, 0, 'r'},
            {"hideSecondRing", required_argument, 0, 'S'},
            {"hideHourRing", required_argument, 0, 'H'},
            {"help", no_argument, 0, 'h'},
            {0, 0, 0, 0}
        };

        c = getopt_long(argc, argv, "r:s:p:SHh?", long_options, &option_index);

        if (c == -1)
            break;

        switch(c)
        {
            case 's':
                server=optarg;
                break;
            case 'p':
                logProps=optarg;
                break;
            case 'r':
                radius=lexical_cast<double>(optarg);
                break;
            case 'S':
                showSecondRing=false;
                break;
            case 'H':
                showHourRing=false;
                break;
            case 'h':
            case '?':
            default:
                usage(argv[0]);
                break;
        }
    }

    if (server=="")
    {
        usage(argv[0]);
        exit(1);
    }

    //
    // Now do some actual work.
    //
    LOAD_LOG_PROPS(logProps);

    Client client(server);
    LOG_INFO("Connecting to " << server << " and sending message.");
    // Do not add empty handler - default Client handler does not close connection.
    // client.addMessageHandler(SendMessageHandler::create());

    unsigned int loopTime=1;
    // Create hour, min, sec, and center nodes.
    NodeIdentifier centerId=NodeIdentifier::from_string("192.168.1.100");
    NodeIdentifier hourId=NodeIdentifier::from_string("192.168.1.101");
    NodeIdentifier minId=NodeIdentifier::from_string("192.168.1.102");
    NodeIdentifier secId=NodeIdentifier::from_string("192.168.1.103");

    const GUILayer layer("Clock");
    const double step=(2*PI)/60;
    struct
    {
        double theta;
        NodeIdentifier *id;
        const char *label;
        Color color;
        double length;
    } nodeData[]=
    {
        { 0,   &hourId, "hour", Color::red,   radius*0.7 },
        { 0,    &minId,  "min", Color::blue,  radius },
        { 0,    &secId,  "sec", Color::green, radius},
    };
    while (true)  // draw everything all the time as we don't know when watcher will start
    {
        // Draw center node
        GPSMessagePtr gpsMess(new GPSMessage(radius, radius, 0));
        gpsMess->layer=layer;
        gpsMess->fromNodeID=centerId;
        if(!client.sendMessage(gpsMess))
        {
            LOG_ERROR("Error sending gps message: " << *gpsMess);
            TRACE_EXIT_RET(EXIT_FAILURE);
            return EXIT_FAILURE;
        }
        // draw hour, min, and second nodes, connecting them to center.
        for (unsigned int i=0; i<sizeof(nodeData)/sizeof(nodeData[0]); i++)
        {
            // update location offsets by current time.
            time_t nowInSecs=time(NULL);
            struct tm *now=localtime(&nowInSecs);
            if (*nodeData[i].id==hourId)
                nodeData[i].theta=step*((now->tm_hour*(60/12))+(now->tm_min/12));
            else if(*nodeData[i].id==minId)
                nodeData[i].theta=step*now->tm_min;
            else if(*nodeData[i].id==secId)
                nodeData[i].theta=step*now->tm_sec;

            // Move hour. min, and sec nodes to appropriate locations.
            GPSMessagePtr gpsMess(new GPSMessage(
                        (sin(nodeData[i].theta)*nodeData[i].length)+radius,
                        (cos(nodeData[i].theta)*nodeData[i].length)+radius,
                        (double)i));
            gpsMess->layer=layer;
            gpsMess->fromNodeID=*nodeData[i].id;
            if(!client.sendMessage(gpsMess))
            {
                LOG_ERROR("Error sending gps message: " << *gpsMess);
                TRACE_EXIT_RET(EXIT_FAILURE);
                return EXIT_FAILURE;
            }

            LabelMessagePtr labMess(new LabelMessage(nodeData[i].label));
            labMess->layer=layer;
            labMess->expiration=loopTime*2000;  // 2000 to stop blinking
            EdgeMessagePtr edgeMess(new EdgeMessage(centerId, *nodeData[i].id, layer, nodeData[i].color, 2));
            edgeMess->middleLabel=labMess;
            if(!client.sendMessage(edgeMess))
            {
                LOG_ERROR("Error sending edge message: " << *edgeMess);
                TRACE_EXIT_RET(EXIT_FAILURE);
                return EXIT_FAILURE;
            }
        }

        if (showHourRing)
        {
            // add nodes at clock face number locations.
            double theta=(2*PI)/12;
            for (unsigned int i=0; i<12; i++, theta+=(2*PI)/12)
            {
                NodeIdentifier thisId=NodeIdentifier::from_string("192.168.2." + lexical_cast<string>(i+1));
                GPSMessagePtr gpsMess(new GPSMessage((sin(theta)*radius)+radius, (cos(theta)*radius)+radius, 0.0));
                gpsMess->layer=layer;
                gpsMess->fromNodeID=thisId;
                if(!client.sendMessage(gpsMess))
                {
                    LOG_ERROR("Error sending gps message: " << *gpsMess);
                    TRACE_EXIT_RET(EXIT_FAILURE);
                    return EXIT_FAILURE;
                }
            }
        }

        if (showSecondRing)
        {
            // add nodes at clock face second locations.
            double theta=(2*PI)/60;
            for (unsigned int i=0; i<60; i++, theta+=(2*PI)/60)
            {
                NodeIdentifier thisId=NodeIdentifier::from_string("192.168.3." + lexical_cast<string>(i+1));
                double faceRad=radius*1.15;
                GPSMessagePtr gpsMess(new GPSMessage((sin(theta)*faceRad)+radius, (cos(theta)*faceRad)+radius, 0.0));
                gpsMess->layer=layer;
                gpsMess->fromNodeID=thisId;
                if(!client.sendMessage(gpsMess))
                {
                    LOG_ERROR("Error sending gps message: " << *gpsMess);
                    TRACE_EXIT_RET(EXIT_FAILURE);
                    return EXIT_FAILURE;
                }
            }
        }
        sleep(loopTime);
    }

    client.wait();

    TRACE_EXIT_RET(EXIT_SUCCESS);
    return EXIT_SUCCESS;
}

<|endoftext|>


<commit_before>// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/sync_file_system/sync_task_manager.h"

#include "base/debug/trace_event.h"
#include "base/location.h"
#include "chrome/browser/sync_file_system/sync_file_metadata.h"

using fileapi::FileSystemURL;

namespace sync_file_system {

class SyncTaskManager::TaskToken {
 public:
  explicit TaskToken(const base::WeakPtr<SyncTaskManager>& manager)
      : manager_(manager) {
  }

  void UpdateTask(const tracked_objects::Location& location) {
    location_ = location;
    DVLOG(2) << "Token updated: " << location_.ToString();
  }

  const tracked_objects::Location& location() const { return location_; }

  ~TaskToken() {
    // All task on Client must hold TaskToken instance to ensure
    // no other tasks are running. Also, as soon as a task finishes to work,
    // it must return the token to TaskManager.
    // Destroying a token with valid |client| indicates the token was
    // dropped by a task without returning.
    if (manager_.get() && manager_->client_.get()) {
      NOTREACHED()
          << "Unexpected TaskToken deletion from: " << location_.ToString();

      // Reinitializes the token.
      manager_->NotifyTaskDone(
          make_scoped_ptr(new TaskToken(manager_)),
          SYNC_STATUS_OK);
    }
  }

 private:
  base::WeakPtr<SyncTaskManager> manager_;
  tracked_objects::Location location_;

  DISALLOW_COPY_AND_ASSIGN(TaskToken);
};

SyncTaskManager::PendingTask::PendingTask() {}

SyncTaskManager::PendingTask::PendingTask(
    const base::Closure& task, Priority pri, int seq)
    : task(task), priority(pri), seq(seq) {}

SyncTaskManager::PendingTask::~PendingTask() {}

bool SyncTaskManager::PendingTaskComparator::operator()(
    const PendingTask& left,
    const PendingTask& right) const {
  if (left.priority != right.priority)
    return left.priority < right.priority;
  return left.seq > right.seq;
}

SyncTaskManager::SyncTaskManager(
    base::WeakPtr<Client> client)
    : client_(client),
      last_operation_status_(SYNC_STATUS_OK),
      pending_task_seq_(0) {
}

SyncTaskManager::~SyncTaskManager() {
  client_.reset();
  token_.reset();
}

void SyncTaskManager::Initialize(SyncStatusCode status) {
  DCHECK(!token_);
  NotifyTaskDone(make_scoped_ptr(new TaskToken(AsWeakPtr())),
                 status);
}

void SyncTaskManager::ScheduleTask(
    const Task& task,
    const SyncStatusCallback& callback) {
  ScheduleTaskAtPriority(task, PRIORITY_MED, callback);
}

void SyncTaskManager::ScheduleSyncTask(
    scoped_ptr<SyncTask> task,
    const SyncStatusCallback& callback) {
  scoped_ptr<TaskToken> token(GetToken(FROM_HERE));
  if (!token) {
    PushPendingTask(
        base::Bind(&SyncTaskManager::ScheduleSyncTask,
                   AsWeakPtr(), base::Passed(&task), callback),
        PRIORITY_MED);
    return;
  }
  DCHECK(!running_task_);
  running_task_ = task.Pass();
  running_task_->Run(CreateCompletionCallback(token.Pass(), callback));
}

void SyncTaskManager::ScheduleTaskAtPriority(
    const Task& task,
    Priority priority,
    const SyncStatusCallback& callback) {
  scoped_ptr<TaskToken> token(GetToken(FROM_HERE));
  if (!token) {
    PushPendingTask(
        base::Bind(&SyncTaskManager::ScheduleTask, AsWeakPtr(),
                   task, callback),
        priority);
    return;
  }
  task.Run(CreateCompletionCallback(token.Pass(), callback));
}

void SyncTaskManager::ScheduleTaskIfIdle(const Task& task) {
  scoped_ptr<TaskToken> token(GetToken(FROM_HERE));
  if (!token)
    return;
  task.Run(CreateCompletionCallback(token.Pass(), SyncStatusCallback()));
}

void SyncTaskManager::ScheduleSyncTaskIfIdle(scoped_ptr<SyncTask> task) {
  scoped_ptr<TaskToken> token(GetToken(FROM_HERE));
  if (!token)
    return;
  DCHECK(!running_task_);
  running_task_ = task.Pass();
  running_task_->Run(CreateCompletionCallback(token.Pass(),
                                              SyncStatusCallback()));
}

void SyncTaskManager::NotifyTaskDone(
    scoped_ptr<TaskToken> token,
    SyncStatusCode status) {
  DCHECK(token);
  last_operation_status_ = status;
  token_ = token.Pass();
  scoped_ptr<SyncTask> task = running_task_.Pass();
  TRACE_EVENT_ASYNC_END0("Sync FileSystem", "GetToken", this);

  DVLOG(3) << "NotifyTaskDone: " << "finished with status=" << status
           << " (" << SyncStatusCodeToString(status) << ")"
           << " " << token_->location().ToString();

  if (client_)
    client_->NotifyLastOperationStatus(last_operation_status_);

  if (!current_callback_.is_null())
    current_callback_.Run(status);
  current_callback_.Reset();

  if (!pending_tasks_.empty()) {
    base::Closure closure = pending_tasks_.top().task;
    pending_tasks_.pop();
    closure.Run();
    return;
  }

  if (client_)
    client_->MaybeScheduleNextTask();
}

scoped_ptr<SyncTaskManager::TaskToken> SyncTaskManager::GetToken(
    const tracked_objects::Location& from_here) {
  if (!token_)
    return scoped_ptr<TaskToken>();
  TRACE_EVENT_ASYNC_BEGIN1("Sync FileSystem", "GetToken", this,
                           "where", from_here.ToString());
  token_->UpdateTask(from_here);
  return token_.Pass();
}

SyncStatusCallback SyncTaskManager::CreateCompletionCallback(
    scoped_ptr<TaskToken> token,
    const SyncStatusCallback& callback) {
  DCHECK(token);
  DCHECK(current_callback_.is_null());
  current_callback_ = callback;
  return base::Bind(&SyncTaskManager::NotifyTaskDone,
                    AsWeakPtr(), base::Passed(&token));
}

void SyncTaskManager::PushPendingTask(
    const base::Closure& closure, Priority priority) {
  pending_tasks_.push(PendingTask(closure, priority, pending_task_seq_++));
}

}  // namespace sync_file_system
<commit_msg>Fix SyncTaskManager current_callback handling<commit_after>// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/sync_file_system/sync_task_manager.h"

#include "base/debug/trace_event.h"
#include "base/location.h"
#include "chrome/browser/sync_file_system/sync_file_metadata.h"

using fileapi::FileSystemURL;

namespace sync_file_system {

class SyncTaskManager::TaskToken {
 public:
  explicit TaskToken(const base::WeakPtr<SyncTaskManager>& manager)
      : manager_(manager) {
  }

  void UpdateTask(const tracked_objects::Location& location) {
    location_ = location;
    DVLOG(2) << "Token updated: " << location_.ToString();
  }

  const tracked_objects::Location& location() const { return location_; }

  ~TaskToken() {
    // All task on Client must hold TaskToken instance to ensure
    // no other tasks are running. Also, as soon as a task finishes to work,
    // it must return the token to TaskManager.
    // Destroying a token with valid |client| indicates the token was
    // dropped by a task without returning.
    if (manager_.get() && manager_->client_.get()) {
      NOTREACHED()
          << "Unexpected TaskToken deletion from: " << location_.ToString();

      // Reinitializes the token.
      manager_->NotifyTaskDone(
          make_scoped_ptr(new TaskToken(manager_)),
          SYNC_STATUS_OK);
    }
  }

 private:
  base::WeakPtr<SyncTaskManager> manager_;
  tracked_objects::Location location_;

  DISALLOW_COPY_AND_ASSIGN(TaskToken);
};

SyncTaskManager::PendingTask::PendingTask() {}

SyncTaskManager::PendingTask::PendingTask(
    const base::Closure& task, Priority pri, int seq)
    : task(task), priority(pri), seq(seq) {}

SyncTaskManager::PendingTask::~PendingTask() {}

bool SyncTaskManager::PendingTaskComparator::operator()(
    const PendingTask& left,
    const PendingTask& right) const {
  if (left.priority != right.priority)
    return left.priority < right.priority;
  return left.seq > right.seq;
}

SyncTaskManager::SyncTaskManager(
    base::WeakPtr<Client> client)
    : client_(client),
      last_operation_status_(SYNC_STATUS_OK),
      pending_task_seq_(0) {
}

SyncTaskManager::~SyncTaskManager() {
  client_.reset();
  token_.reset();
}

void SyncTaskManager::Initialize(SyncStatusCode status) {
  DCHECK(!token_);
  NotifyTaskDone(make_scoped_ptr(new TaskToken(AsWeakPtr())),
                 status);
}

void SyncTaskManager::ScheduleTask(
    const Task& task,
    const SyncStatusCallback& callback) {
  ScheduleTaskAtPriority(task, PRIORITY_MED, callback);
}

void SyncTaskManager::ScheduleSyncTask(
    scoped_ptr<SyncTask> task,
    const SyncStatusCallback& callback) {
  scoped_ptr<TaskToken> token(GetToken(FROM_HERE));
  if (!token) {
    PushPendingTask(
        base::Bind(&SyncTaskManager::ScheduleSyncTask,
                   AsWeakPtr(), base::Passed(&task), callback),
        PRIORITY_MED);
    return;
  }
  DCHECK(!running_task_);
  running_task_ = task.Pass();
  running_task_->Run(CreateCompletionCallback(token.Pass(), callback));
}

void SyncTaskManager::ScheduleTaskAtPriority(
    const Task& task,
    Priority priority,
    const SyncStatusCallback& callback) {
  scoped_ptr<TaskToken> token(GetToken(FROM_HERE));
  if (!token) {
    PushPendingTask(
        base::Bind(&SyncTaskManager::ScheduleTask, AsWeakPtr(),
                   task, callback),
        priority);
    return;
  }
  task.Run(CreateCompletionCallback(token.Pass(), callback));
}

void SyncTaskManager::ScheduleTaskIfIdle(const Task& task) {
  scoped_ptr<TaskToken> token(GetToken(FROM_HERE));
  if (!token)
    return;
  task.Run(CreateCompletionCallback(token.Pass(), SyncStatusCallback()));
}

void SyncTaskManager::ScheduleSyncTaskIfIdle(scoped_ptr<SyncTask> task) {
  scoped_ptr<TaskToken> token(GetToken(FROM_HERE));
  if (!token)
    return;
  DCHECK(!running_task_);
  running_task_ = task.Pass();
  running_task_->Run(CreateCompletionCallback(token.Pass(),
                                              SyncStatusCallback()));
}

void SyncTaskManager::NotifyTaskDone(
    scoped_ptr<TaskToken> token,
    SyncStatusCode status) {
  DCHECK(token);
  last_operation_status_ = status;
  token_ = token.Pass();
  scoped_ptr<SyncTask> task = running_task_.Pass();
  TRACE_EVENT_ASYNC_END0("Sync FileSystem", "GetToken", this);

  DVLOG(3) << "NotifyTaskDone: " << "finished with status=" << status
           << " (" << SyncStatusCodeToString(status) << ")"
           << " " << token_->location().ToString();

  if (client_)
    client_->NotifyLastOperationStatus(last_operation_status_);

  if (!current_callback_.is_null()) {
    SyncStatusCallback callback = current_callback_;
    current_callback_.Reset();
    callback.Run(status);
  }

  if (!pending_tasks_.empty()) {
    base::Closure closure = pending_tasks_.top().task;
    pending_tasks_.pop();
    closure.Run();
    return;
  }

  if (client_)
    client_->MaybeScheduleNextTask();
}

scoped_ptr<SyncTaskManager::TaskToken> SyncTaskManager::GetToken(
    const tracked_objects::Location& from_here) {
  if (!token_)
    return scoped_ptr<TaskToken>();
  TRACE_EVENT_ASYNC_BEGIN1("Sync FileSystem", "GetToken", this,
                           "where", from_here.ToString());
  token_->UpdateTask(from_here);
  return token_.Pass();
}

SyncStatusCallback SyncTaskManager::CreateCompletionCallback(
    scoped_ptr<TaskToken> token,
    const SyncStatusCallback& callback) {
  DCHECK(token);
  DCHECK(current_callback_.is_null());
  current_callback_ = callback;
  return base::Bind(&SyncTaskManager::NotifyTaskDone,
                    AsWeakPtr(), base::Passed(&token));
}

void SyncTaskManager::PushPendingTask(
    const base::Closure& closure, Priority priority) {
  pending_tasks_.push(PendingTask(closure, priority, pending_task_seq_++));
}

}  // namespace sync_file_system
<|endoftext|>


<commit_before>#include "xchainer/device.h"

#include <algorithm>
#include <type_traits>

#include "xchainer/array.h"
#include "xchainer/context.h"
#include "xchainer/error.h"
#include "xchainer/native/native_backend.h"
#include "xchainer/routines/creation.h"

namespace xchainer {
namespace {

thread_local Device* t_default_device = nullptr;
static_assert(std::is_pod<decltype(t_default_device)>::value, "t_default_device must be POD");

}  // namespace

void Device::CheckDevicesCompatible(const Array& array) {
    if (this != &array.device()) {
        throw DeviceError{"Device (", name(), ") is not compatible with array's device (", array.device().name(), ")."};
    }
}

namespace internal {

Device* GetDefaultDeviceNoExcept() noexcept { return t_default_device; }

}  // namespace internal

Device& GetDefaultDevice() {
    if (t_default_device == nullptr) {
        t_default_device = &GetDefaultContext().GetDevice({native::NativeBackend::kDefaultName, 0});
    }
    return *t_default_device;
}

void SetDefaultDevice(Device* device) {
    if (device != nullptr && &device->backend().context() != &GetDefaultContext()) {
        throw ContextError{"Context mismatch between default device and default context."};
    }
    t_default_device = device;
}

namespace {

// Differentiable mean.
// TODO(niboshi): Move to routines
Array Mean(const Array& a, const Axes& axis, bool keepdims) {
    return a.Sum(axis, keepdims) / xchainer::internal::CountItemsAlongAxes(a.shape(), axis);
}

// Differentiable variance.
// TODO(niboshi): Move to routines
Array Var(const Array& a, const Array& mean, const Axes& axis, bool keepdims) {
    Array diff = a - mean;
    return Mean(diff * diff, axis, keepdims);
}

// Differentiable sqrt.
// TODO(niboshi): Move to routines
Array Sqrt(const Array& x) {
    Array out = EmptyLike(x, x.device());
    x.device().Sqrt(x, out);
    // TODO(niboshi): Implement backward
    return out;
}

// Differentiable reciprocal.
// TODO(niboshi): Move to routines
Array Reciprocal(const Array& x) { return OnesLike(x, x.device()) / x; }

struct ApplyBatchNormResult {
    Array out;
    Array inv_std;
};

ApplyBatchNormResult ApplyBatchNorm(
        const Array& x, const Array& gamma, const Array& beta, const Array& mean, const Array& var, Scalar eps, const Axes& axis) {
#ifndef NDEBUG
    {
        Shape reduced_shape = xchainer::internal::ReduceShape(x.shape(), axis, true);
        assert(gamma.shape() == reduced_shape);
        assert(beta.shape() == reduced_shape);

        int64_t reduced_total_size = reduced_shape.GetTotalSize();
        assert(mean.GetTotalSize() == reduced_total_size);
        assert(var.GetTotalSize() == reduced_total_size);

        assert(x.IsConstant());
        assert(mean.IsConstant());
        assert(var.IsConstant());
    }
#endif  // NDEBUG
    Array inv_std = Reciprocal(Sqrt(var + eps));

    Array out = (x - mean) * inv_std * gamma.AsConstant() + beta.AsConstant();

    return {std::move(out), std::move(inv_std)};
}

}  // namespace

Array GenericBatchNormForwardBackward::Forward(
        const Array& x,
        const Array& gamma,
        const Array& beta,
        const Array& running_mean,
        const Array& running_var,
        Scalar eps,
        Scalar decay,
        const Axes& axis) {
    Array x_const = x.AsConstant();
    Array x_mean = Mean(x_const, axis, true);
    Array x_var = Var(x_const, x_mean, axis, true);

    ApplyBatchNormResult result = ApplyBatchNorm(x_const, gamma, beta, x_mean, x_var, eps, axis);
    Array& out = result.out;
    Array& x_inv_std = result.inv_std;

    Scalar inv_decay = Scalar{1.0 - static_cast<double>(decay)};
    int64_t n = x.GetTotalSize() / gamma.GetTotalSize();
    running_mean *= decay;
    running_mean += inv_decay * x_mean;
    running_var *= decay;
    running_var += inv_decay * (static_cast<double>(n) / std::max(n - 1, int64_t{1})) * x_var;

    x_mean_ = std::make_shared<Array>(x_mean);
    x_inv_std_ = std::make_shared<Array>(x_inv_std);
    return std::move(out);
}

std::array<Array, 3> GenericBatchNormForwardBackward::Backward(
        const Array& x, const Array& gamma, const Array& gout, Scalar /*eps*/, const Axes& axis) {
    // Note: x_inv_std_ has the information of eps.
    const Array x_const = x.AsConstant();
    const Array gamma_const = gamma.AsConstant();
    const Array gout_const = gout.AsConstant();
    const Array& x_mean = *x_mean_;
    const Array& x_inv_std = *x_inv_std_;

    double inv_n = 1.0 / (x.GetTotalSize() / gamma.GetTotalSize());
    Array x_hat = (x_const - x_mean) * x_inv_std;
    Array ggamma = (gout_const * x_hat).Sum(axis);
    Array gbeta = gout_const.Sum(axis);
    Array gx = (gamma_const * x_inv_std) * (gout_const - (x_hat * ggamma + gbeta) * inv_n);

    axis_ = axis;
    x_ = std::make_shared<Array>(x);
    gamma_ = std::make_shared<Array>(gamma);
    gx_ = std::make_shared<Array>(gx);
    ggamma_ = std::make_shared<Array>(ggamma);
    gout_ = std::make_shared<Array>(gout);

    return {std::move(gx), std::move(ggamma), std::move(gbeta)};
}

std::array<Array, 3> GenericBatchNormForwardBackward::DoubleBackward(const Array& ggx, const Array& gggamma, const Array& ggbeta) {
    const Array& gout = *gout_;
    const Array& x = *x_;
    const Array& gamma = *gamma_;
    const Array& x_inv_std = *x_inv_std_;
    const Array& x_mean = *x_mean_;
    const Axes& axis = axis_;
    const Array& gx = *gx_;
    const Array& ggamma = *ggamma_;

    // Auxiliary values
    double inv_n = 1.0 / (x.GetTotalSize() / gamma.GetTotalSize());
    Array r = (gx * ggx).Sum(axis);
    Array coeff = gamma * x_inv_std;
    Array coeff_m = coeff * inv_n;
    Array x_hat = (x - x_mean) * x_inv_std;

    Array gggamma2 = gggamma - coeff_m * (x_hat * ggx).Sum(axis);
    Array ggbeta2 = ggbeta - coeff_m * ggx.Sum(axis);

    Array gx_hat2 = gggamma2 * gout - coeff_m * ggamma * ggx;
    Array gstd2 = -x_inv_std * (r + (x_hat * gx_hat2).Sum(axis));
    Array gmean2 = -x_inv_std * gx_hat2.Sum(axis);
    Array gx2 = x_inv_std * gx_hat2 + inv_n * (gmean2 + x_hat * gstd2);
    Array ggy2 = gggamma2 * x_hat + ggbeta2 + coeff * ggx;

    Array ggamma2 = r / gamma;

    return {std::move(gx2), std::move(ggamma2), std::move(ggy2)};
}

Array Device::FixedBatchNorm(
        const Array& x, const Array& gamma, const Array& beta, const Array& mean, const Array& var, Scalar eps, const Axes& axis) {
    ApplyBatchNormResult result = ApplyBatchNorm(x.AsConstant(), gamma, beta, mean.AsConstant(), var.AsConstant(), eps, axis);
    return std::move(result.out);
}

}  // namespace xchainer
<commit_msg>Apply AsConstant() at caller<commit_after>#include "xchainer/device.h"

#include <algorithm>
#include <type_traits>

#include "xchainer/array.h"
#include "xchainer/context.h"
#include "xchainer/error.h"
#include "xchainer/native/native_backend.h"
#include "xchainer/routines/creation.h"

namespace xchainer {
namespace {

thread_local Device* t_default_device = nullptr;
static_assert(std::is_pod<decltype(t_default_device)>::value, "t_default_device must be POD");

}  // namespace

void Device::CheckDevicesCompatible(const Array& array) {
    if (this != &array.device()) {
        throw DeviceError{"Device (", name(), ") is not compatible with array's device (", array.device().name(), ")."};
    }
}

namespace internal {

Device* GetDefaultDeviceNoExcept() noexcept { return t_default_device; }

}  // namespace internal

Device& GetDefaultDevice() {
    if (t_default_device == nullptr) {
        t_default_device = &GetDefaultContext().GetDevice({native::NativeBackend::kDefaultName, 0});
    }
    return *t_default_device;
}

void SetDefaultDevice(Device* device) {
    if (device != nullptr && &device->backend().context() != &GetDefaultContext()) {
        throw ContextError{"Context mismatch between default device and default context."};
    }
    t_default_device = device;
}

namespace {

// Differentiable mean.
// TODO(niboshi): Move to routines
Array Mean(const Array& a, const Axes& axis, bool keepdims) {
    return a.Sum(axis, keepdims) / xchainer::internal::CountItemsAlongAxes(a.shape(), axis);
}

// Differentiable variance.
// TODO(niboshi): Move to routines
Array Var(const Array& a, const Array& mean, const Axes& axis, bool keepdims) {
    Array diff = a - mean;
    return Mean(diff * diff, axis, keepdims);
}

// Differentiable sqrt.
// TODO(niboshi): Move to routines
Array Sqrt(const Array& x) {
    Array out = EmptyLike(x, x.device());
    x.device().Sqrt(x, out);
    // TODO(niboshi): Implement backward
    return out;
}

// Differentiable reciprocal.
// TODO(niboshi): Move to routines
Array Reciprocal(const Array& x) { return OnesLike(x, x.device()) / x; }

struct ApplyBatchNormResult {
    Array out;
    Array inv_std;
};

ApplyBatchNormResult ApplyBatchNorm(
        const Array& x, const Array& gamma, const Array& beta, const Array& mean, const Array& var, Scalar eps, const Axes& axis) {
#ifndef NDEBUG
    {
        Shape reduced_shape = xchainer::internal::ReduceShape(x.shape(), axis, true);
        assert(gamma.shape() == reduced_shape);
        assert(beta.shape() == reduced_shape);

        int64_t reduced_total_size = reduced_shape.GetTotalSize();
        assert(mean.GetTotalSize() == reduced_total_size);
        assert(var.GetTotalSize() == reduced_total_size);

        assert(x.IsConstant());
        assert(gamma.IsConstant());
        assert(beta.IsConstant());
        assert(mean.IsConstant());
        assert(var.IsConstant());
    }
#endif  // NDEBUG
    Array inv_std = Reciprocal(Sqrt(var + eps));

    Array out = (x - mean) * inv_std * gamma + beta;

    return {std::move(out), std::move(inv_std)};
}

}  // namespace

Array GenericBatchNormForwardBackward::Forward(
        const Array& x,
        const Array& gamma,
        const Array& beta,
        const Array& running_mean,
        const Array& running_var,
        Scalar eps,
        Scalar decay,
        const Axes& axis) {
    Array x_const = x.AsConstant();
    Array x_mean = Mean(x_const, axis, true);
    Array x_var = Var(x_const, x_mean, axis, true);

    ApplyBatchNormResult result = ApplyBatchNorm(x_const, gamma.AsConstant(), beta.AsConstant(), x_mean, x_var, eps, axis);
    Array& out = result.out;
    Array& x_inv_std = result.inv_std;

    Scalar inv_decay = Scalar{1.0 - static_cast<double>(decay)};
    int64_t n = x.GetTotalSize() / gamma.GetTotalSize();
    running_mean *= decay;
    running_mean += inv_decay * x_mean;
    running_var *= decay;
    running_var += inv_decay * (static_cast<double>(n) / std::max(n - 1, int64_t{1})) * x_var;

    x_mean_ = std::make_shared<Array>(x_mean);
    x_inv_std_ = std::make_shared<Array>(x_inv_std);
    return std::move(out);
}

std::array<Array, 3> GenericBatchNormForwardBackward::Backward(
        const Array& x, const Array& gamma, const Array& gout, Scalar /*eps*/, const Axes& axis) {
    // Note: x_inv_std_ has the information of eps.
    const Array x_const = x.AsConstant();
    const Array gamma_const = gamma.AsConstant();
    const Array gout_const = gout.AsConstant();
    const Array& x_mean = *x_mean_;
    const Array& x_inv_std = *x_inv_std_;

    double inv_n = 1.0 / (x.GetTotalSize() / gamma.GetTotalSize());
    Array x_hat = (x_const - x_mean) * x_inv_std;
    Array ggamma = (gout_const * x_hat).Sum(axis);
    Array gbeta = gout_const.Sum(axis);
    Array gx = (gamma_const * x_inv_std) * (gout_const - (x_hat * ggamma + gbeta) * inv_n);

    axis_ = axis;
    x_ = std::make_shared<Array>(x);
    gamma_ = std::make_shared<Array>(gamma);
    gx_ = std::make_shared<Array>(gx);
    ggamma_ = std::make_shared<Array>(ggamma);
    gout_ = std::make_shared<Array>(gout);

    return {std::move(gx), std::move(ggamma), std::move(gbeta)};
}

std::array<Array, 3> GenericBatchNormForwardBackward::DoubleBackward(const Array& ggx, const Array& gggamma, const Array& ggbeta) {
    const Array& gout = *gout_;
    const Array& x = *x_;
    const Array& gamma = *gamma_;
    const Array& x_inv_std = *x_inv_std_;
    const Array& x_mean = *x_mean_;
    const Axes& axis = axis_;
    const Array& gx = *gx_;
    const Array& ggamma = *ggamma_;

    // Auxiliary values
    double inv_n = 1.0 / (x.GetTotalSize() / gamma.GetTotalSize());
    Array r = (gx * ggx).Sum(axis);
    Array coeff = gamma * x_inv_std;
    Array coeff_m = coeff * inv_n;
    Array x_hat = (x - x_mean) * x_inv_std;

    Array gggamma2 = gggamma - coeff_m * (x_hat * ggx).Sum(axis);
    Array ggbeta2 = ggbeta - coeff_m * ggx.Sum(axis);

    Array gx_hat2 = gggamma2 * gout - coeff_m * ggamma * ggx;
    Array gstd2 = -x_inv_std * (r + (x_hat * gx_hat2).Sum(axis));
    Array gmean2 = -x_inv_std * gx_hat2.Sum(axis);
    Array gx2 = x_inv_std * gx_hat2 + inv_n * (gmean2 + x_hat * gstd2);
    Array ggy2 = gggamma2 * x_hat + ggbeta2 + coeff * ggx;

    Array ggamma2 = r / gamma;

    return {std::move(gx2), std::move(ggamma2), std::move(ggy2)};
}

Array Device::FixedBatchNorm(
        const Array& x, const Array& gamma, const Array& beta, const Array& mean, const Array& var, Scalar eps, const Axes& axis) {
    ApplyBatchNormResult result =
            ApplyBatchNorm(x.AsConstant(), gamma.AsConstant(), beta.AsConstant(), mean.AsConstant(), var.AsConstant(), eps, axis);
    return std::move(result.out);
}

}  // namespace xchainer
<|endoftext|>