<commit_before>// Copyright (c) 2015 The Brick Authors.

#include "brick/window_util.h"

#include <gtk/gtk.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>

#include "include/internal/cef_linux.h"
#include "include/base/cef_logging.h"

#include "brick/brick_app.h"

namespace {
  GList *default_icons = NULL;
  CefWindowHandle leader_window_;
  double device_scale_factor = 0;
  const double kCSSDefaultDPI = 96.0;

  int
  XErrorHandlerImpl(Display *display, XErrorEvent *event) {
    LOG(WARNING)
    << "X error received: "
    << "type " << event->type << ", "
    << "serial " << event->serial << ", "
    << "error_code " << static_cast<int>(event->error_code) << ", "
    << "request_code " << static_cast<int>(event->request_code) << ", "
    << "minor_code " << static_cast<int>(event->minor_code);
    return 0;
  }

  int
  XIOErrorHandlerImpl(Display *display) {
    return 0;
  }
}  // namespace

namespace window_util {

  CefWindowHandle
  GetParent(CefWindowHandle handle) {
    ::Window root;
    ::Window parent;
    ::Window *children;
    unsigned int nchildren;
    XQueryTree(cef_get_xdisplay(), handle, &root, &parent, &children, &nchildren);
    XFree(children);

    return parent;
  }

  void
  Resize(CefWindowHandle handle, int width, int height) {
    XResizeWindow(
       cef_get_xdisplay(),
       handle,
       (unsigned int) width,
       (unsigned int) height
    );
  }

  void
  SetMinSize(CefWindowHandle handle, int width, int height) {
    XSizeHints *size_hints = XAllocSizeHints();
    if (!size_hints) {
      LOG(ERROR) << "SetMinSize: Can't allocate memory for XAllocSizeHints";
      return;
    }

    size_hints->flags = PMinSize;
    size_hints->min_width = width;
    size_hints->min_height = height;

    XSetWMNormalHints(
       cef_get_xdisplay(),
       handle,
       size_hints
    );
    XFree(size_hints);
  }

  void
  ConfigureAsDialog(CefWindowHandle handle) {
    ::XDisplay *display = cef_get_xdisplay();

    Atom type = XInternAtom(display, "_NET_WM_WINDOW_TYPE", False);
    Atom value = XInternAtom(display, "_NET_WM_WINDOW_TYPE_DIALOG", False);
    XChangeProperty(display, handle, type, XA_ATOM, 32, PropModeReplace, reinterpret_cast<unsigned char *>(&value), 1);
  }

  void
  ConfigureAsTopmost(CefWindowHandle handle) {
    ConfigureAsDialog(handle);

    ::XDisplay *display = cef_get_xdisplay();

    Atom state[2];
    state[0] = XInternAtom(display, "_NET_WM_STATE_SKIP_TASKBAR", False);
    state[1] = XInternAtom(display, "_NET_WM_STATE_SKIP_PAGER", False);
    Atom wm_state = XInternAtom(display, "_NET_WM_STATE", False);
    XChangeProperty (display, handle, wm_state, XA_ATOM, 32, PropModeReplace, reinterpret_cast<unsigned char *>(&state), 2);
  }

  void
  SetGroupByLeader(CefWindowHandle handle) {
    ::XDisplay *display = cef_get_xdisplay();
    XWMHints base_hints;
    XWMHints * h = XGetWMHints(display, handle);
    if (!h) {
      h = &base_hints;
      h->flags = 0;
    }
    h->flags |= WindowGroupHint;
    h->window_group = leader_window_;
    XSetWMHints(display, handle, h);
    if(h != &base_hints) {
      XFree(h);
    }
  }

  void
  SetClientLeader(CefWindowHandle handle) {
    ::XDisplay *display = cef_get_xdisplay();

    Atom type = XInternAtom(display, "WM_CLIENT_LEADER", False);
    XChangeProperty(display, handle, type, XA_WINDOW, 32, PropModeReplace, reinterpret_cast<unsigned char *>(&leader_window_), 1);
    SetGroupByLeader(handle);
  }

  void
  FixSize(CefWindowHandle handle, int width, int height) {
    XSizeHints *size_hints = XAllocSizeHints();
    ::XDisplay *display = cef_get_xdisplay();

    if (!size_hints) {
      LOG(ERROR) << "FixSize: Can't allocate memory for XAllocSizeHints";
      return;
    }

    if (width && height) {
      size_hints->flags = PSize | PMinSize | PMaxSize;
      size_hints->width = width;
      size_hints->height = height;
      size_hints->min_width = width;
      size_hints->min_height = height;
      size_hints->max_width = width;
      size_hints->max_height = height;
    } else {
      size_hints->flags = PMinSize | PMaxSize;
      size_hints->max_width = width;
      size_hints->max_height = height;
    }

    XSetWMNormalHints(
       display,
       handle,
       size_hints
    );
    XFree(size_hints);
  }

  void
  InitAsPopup(CefWindowHandle handle) {
    ConfigureAsDialog(handle);
  }

  void
  Hide(CefWindowHandle handle) {
    ::Display *display = cef_get_xdisplay();
    DCHECK(display);

    XUnmapWindow(display, handle);
  }

  void
  Show(CefWindowHandle handle) {
    ::Display *display = cef_get_xdisplay();
    DCHECK(display);

    XMapWindow(display, handle);
  }

  void
  CenterPosition(CefWindowHandle handle) {
    ::Display *display = cef_get_xdisplay();
    DCHECK(display);

    XSizeHints *size_hints = XAllocSizeHints();
    if (!size_hints) {
      LOG(ERROR) << "CenterPosition: Can't allocate memory for XAllocSizeHints";
      return;
    }

    size_hints->flags = PWinGravity;
    size_hints->win_gravity = CenterGravity;

    XSetWMNormalHints(
       display,
       handle,
       size_hints
    );
    XFree(size_hints);
  }

  void
  SetTitle(CefWindowHandle handle, std::string title) {
    std::string titleStr(title);

    // Retrieve the X11 display shared with Chromium.
    ::Display *display = cef_get_xdisplay();
    DCHECK(display);

    DCHECK(handle != kNullWindowHandle);

    // Retrieve the atoms required by the below XChangeProperty call.
    const char *kAtoms[] = {
       "_NET_WM_NAME",
       "UTF8_STRING"
    };
    Atom atoms[2];
    int result = XInternAtoms(display, const_cast<char **>(kAtoms), 2, false,
       atoms);
    if (!result)
      NOTREACHED();

    // Set the window title.
    XChangeProperty(display,
       handle,
       atoms[0],
       atoms[1],
       8,
       PropModeReplace,
       reinterpret_cast<const unsigned char *>(titleStr.c_str()),
       titleStr.size());

    // TODO(erg): This is technically wrong. So XStoreName and friends expect
    // this in Host Portable Character Encoding instead of UTF-8, which I believe
    // is Compound Text. This shouldn't matter 90% of the time since this is the
    // fallback to the UTF8 property above.
    XStoreName(display, handle, titleStr.c_str());
  }

  void
  SetClassHints(CefWindowHandle handle, char *res_name, char *res_class) {
    XClassHint *class_hints = XAllocClassHint();
    ::XDisplay *display = cef_get_xdisplay();

    if (!class_hints) {
      LOG(ERROR) << "SetClassHints: Can't allocate memory for XAllocClassHint";
      return;
    }

    class_hints->res_name = res_name;
    class_hints->res_class = res_class;

    XSetClassHint(display, handle, class_hints);
    XFree(class_hints);
  }

  void
  SetLeaderWindow(CefWindowHandle handle) {
    leader_window_ = handle;
  }

  CefWindowHandle
  GetLeaderWindow() {
    return leader_window_;
  }

  void
  InitHooks() {
    XSetErrorHandler(XErrorHandlerImpl);
    XSetIOErrorHandler(XIOErrorHandlerImpl);
  }

  void
  InitWindow(CefWindowHandle handle, bool is_leader) {
    if (is_leader)
      SetLeaderWindow(handle);
    else
      SetClientLeader(handle);

    SetClassHints(handle, const_cast<char *>(APP_COMMON_NAME), const_cast<char *>(APP_NAME));
  }

  GList*
  GetDefaultIcons() {
    return default_icons;
  }

  void SetDefaultIcons(GList* icons) {
    if (default_icons) {
      g_list_foreach(default_icons, (GFunc) g_object_unref, NULL);
      g_list_free(default_icons);
    }

    default_icons = icons;
    gtk_window_set_default_icon_list(icons);
  }

  BrowserWindow*
  LookupBrowserWindow(CefWindowHandle native_window) {
    GdkWindow * gdk_window = GDK_WINDOW(gdk_xid_table_lookup(native_window));
    return reinterpret_cast<BrowserWindow*>(
        g_object_get_data(G_OBJECT(gdk_window), "wrapper")
    );
  }

  BrowserWindow*
  LookupBrowserWindow(GdkEvent* event) {
    if (event->type == GDK_NOTHING) {
      // GDK_NOTHING event doesn't have any windows
      return NULL;
    }

    GObject *object = G_OBJECT(event->any.window);
    if (!G_IS_OBJECT(object)) {
      LOG(ERROR) << "Try lookup browser window of bad native window"
         << ", event type: " << event->type
         << ", event window: " << event->any.window;
      return NULL;
    }

    return reinterpret_cast<BrowserWindow*>(
        g_object_get_data(object, "wrapper")
    );
  }

  void
  FlushChanges() {
    ::XDisplay *display = cef_get_xdisplay();

    XFlush(display);
  }

  CefRect
  GetDefaultScreenRect() {
    GdkRectangle monitor_rect;
    gdk_screen_get_monitor_geometry(gdk_screen_get_default(), 0, &monitor_rect);

    return CefRect(
       monitor_rect.x,
       monitor_rect.y,
       monitor_rect.width,
       monitor_rect.height
    );
  }

  double
  GetDPI() {
    GtkSettings* gtk_settings = gtk_settings_get_default();
    DCHECK(gtk_settings);
    gint gtk_dpi = -1;
    g_object_get(gtk_settings, "gtk-xft-dpi", &gtk_dpi, NULL);

    // GTK multiplies the DPI by 1024 before storing it.
    return (gtk_dpi > 0) ? gtk_dpi / 1024.0 : kCSSDefaultDPI;
  }

  double
  GetDeviceScaleFactor() {
    if (!device_scale_factor)
      device_scale_factor = floor((GetDPI() / kCSSDefaultDPI) * 100) / 100;

    return device_scale_factor;
  }
}  // namespace window_util
<commit_msg>Fixed building with GCC 6<commit_after>// Copyright (c) 2015 The Brick Authors.

#include "brick/window_util.h"

#include <gtk/gtk.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <cmath>

#include "include/internal/cef_linux.h"
#include "include/base/cef_logging.h"

#include "brick/brick_app.h"

namespace {
  GList *default_icons = NULL;
  CefWindowHandle leader_window_;
  double device_scale_factor = 0;
  const double kCSSDefaultDPI = 96.0;

  int
  XErrorHandlerImpl(Display *display, XErrorEvent *event) {
    LOG(WARNING)
    << "X error received: "
    << "type " << event->type << ", "
    << "serial " << event->serial << ", "
    << "error_code " << static_cast<int>(event->error_code) << ", "
    << "request_code " << static_cast<int>(event->request_code) << ", "
    << "minor_code " << static_cast<int>(event->minor_code);
    return 0;
  }

  int
  XIOErrorHandlerImpl(Display *display) {
    return 0;
  }
}  // namespace

namespace window_util {

  CefWindowHandle
  GetParent(CefWindowHandle handle) {
    ::Window root;
    ::Window parent;
    ::Window *children;
    unsigned int nchildren;
    XQueryTree(cef_get_xdisplay(), handle, &root, &parent, &children, &nchildren);
    XFree(children);

    return parent;
  }

  void
  Resize(CefWindowHandle handle, int width, int height) {
    XResizeWindow(
       cef_get_xdisplay(),
       handle,
       (unsigned int) width,
       (unsigned int) height
    );
  }

  void
  SetMinSize(CefWindowHandle handle, int width, int height) {
    XSizeHints *size_hints = XAllocSizeHints();
    if (!size_hints) {
      LOG(ERROR) << "SetMinSize: Can't allocate memory for XAllocSizeHints";
      return;
    }

    size_hints->flags = PMinSize;
    size_hints->min_width = width;
    size_hints->min_height = height;

    XSetWMNormalHints(
       cef_get_xdisplay(),
       handle,
       size_hints
    );
    XFree(size_hints);
  }

  void
  ConfigureAsDialog(CefWindowHandle handle) {
    ::XDisplay *display = cef_get_xdisplay();

    Atom type = XInternAtom(display, "_NET_WM_WINDOW_TYPE", False);
    Atom value = XInternAtom(display, "_NET_WM_WINDOW_TYPE_DIALOG", False);
    XChangeProperty(display, handle, type, XA_ATOM, 32, PropModeReplace, reinterpret_cast<unsigned char *>(&value), 1);
  }

  void
  ConfigureAsTopmost(CefWindowHandle handle) {
    ConfigureAsDialog(handle);

    ::XDisplay *display = cef_get_xdisplay();

    Atom state[2];
    state[0] = XInternAtom(display, "_NET_WM_STATE_SKIP_TASKBAR", False);
    state[1] = XInternAtom(display, "_NET_WM_STATE_SKIP_PAGER", False);
    Atom wm_state = XInternAtom(display, "_NET_WM_STATE", False);
    XChangeProperty (display, handle, wm_state, XA_ATOM, 32, PropModeReplace, reinterpret_cast<unsigned char *>(&state), 2);
  }

  void
  SetGroupByLeader(CefWindowHandle handle) {
    ::XDisplay *display = cef_get_xdisplay();
    XWMHints base_hints;
    XWMHints * h = XGetWMHints(display, handle);
    if (!h) {
      h = &base_hints;
      h->flags = 0;
    }
    h->flags |= WindowGroupHint;
    h->window_group = leader_window_;
    XSetWMHints(display, handle, h);
    if(h != &base_hints) {
      XFree(h);
    }
  }

  void
  SetClientLeader(CefWindowHandle handle) {
    ::XDisplay *display = cef_get_xdisplay();

    Atom type = XInternAtom(display, "WM_CLIENT_LEADER", False);
    XChangeProperty(display, handle, type, XA_WINDOW, 32, PropModeReplace, reinterpret_cast<unsigned char *>(&leader_window_), 1);
    SetGroupByLeader(handle);
  }

  void
  FixSize(CefWindowHandle handle, int width, int height) {
    XSizeHints *size_hints = XAllocSizeHints();
    ::XDisplay *display = cef_get_xdisplay();

    if (!size_hints) {
      LOG(ERROR) << "FixSize: Can't allocate memory for XAllocSizeHints";
      return;
    }

    if (width && height) {
      size_hints->flags = PSize | PMinSize | PMaxSize;
      size_hints->width = width;
      size_hints->height = height;
      size_hints->min_width = width;
      size_hints->min_height = height;
      size_hints->max_width = width;
      size_hints->max_height = height;
    } else {
      size_hints->flags = PMinSize | PMaxSize;
      size_hints->max_width = width;
      size_hints->max_height = height;
    }

    XSetWMNormalHints(
       display,
       handle,
       size_hints
    );
    XFree(size_hints);
  }

  void
  InitAsPopup(CefWindowHandle handle) {
    ConfigureAsDialog(handle);
  }

  void
  Hide(CefWindowHandle handle) {
    ::Display *display = cef_get_xdisplay();
    DCHECK(display);

    XUnmapWindow(display, handle);
  }

  void
  Show(CefWindowHandle handle) {
    ::Display *display = cef_get_xdisplay();
    DCHECK(display);

    XMapWindow(display, handle);
  }

  void
  CenterPosition(CefWindowHandle handle) {
    ::Display *display = cef_get_xdisplay();
    DCHECK(display);

    XSizeHints *size_hints = XAllocSizeHints();
    if (!size_hints) {
      LOG(ERROR) << "CenterPosition: Can't allocate memory for XAllocSizeHints";
      return;
    }

    size_hints->flags = PWinGravity;
    size_hints->win_gravity = CenterGravity;

    XSetWMNormalHints(
       display,
       handle,
       size_hints
    );
    XFree(size_hints);
  }

  void
  SetTitle(CefWindowHandle handle, std::string title) {
    std::string titleStr(title);

    // Retrieve the X11 display shared with Chromium.
    ::Display *display = cef_get_xdisplay();
    DCHECK(display);

    DCHECK(handle != kNullWindowHandle);

    // Retrieve the atoms required by the below XChangeProperty call.
    const char *kAtoms[] = {
       "_NET_WM_NAME",
       "UTF8_STRING"
    };
    Atom atoms[2];
    int result = XInternAtoms(display, const_cast<char **>(kAtoms), 2, false,
       atoms);
    if (!result)
      NOTREACHED();

    // Set the window title.
    XChangeProperty(display,
       handle,
       atoms[0],
       atoms[1],
       8,
       PropModeReplace,
       reinterpret_cast<const unsigned char *>(titleStr.c_str()),
       titleStr.size());

    // TODO(erg): This is technically wrong. So XStoreName and friends expect
    // this in Host Portable Character Encoding instead of UTF-8, which I believe
    // is Compound Text. This shouldn't matter 90% of the time since this is the
    // fallback to the UTF8 property above.
    XStoreName(display, handle, titleStr.c_str());
  }

  void
  SetClassHints(CefWindowHandle handle, char *res_name, char *res_class) {
    XClassHint *class_hints = XAllocClassHint();
    ::XDisplay *display = cef_get_xdisplay();

    if (!class_hints) {
      LOG(ERROR) << "SetClassHints: Can't allocate memory for XAllocClassHint";
      return;
    }

    class_hints->res_name = res_name;
    class_hints->res_class = res_class;

    XSetClassHint(display, handle, class_hints);
    XFree(class_hints);
  }

  void
  SetLeaderWindow(CefWindowHandle handle) {
    leader_window_ = handle;
  }

  CefWindowHandle
  GetLeaderWindow() {
    return leader_window_;
  }

  void
  InitHooks() {
    XSetErrorHandler(XErrorHandlerImpl);
    XSetIOErrorHandler(XIOErrorHandlerImpl);
  }

  void
  InitWindow(CefWindowHandle handle, bool is_leader) {
    if (is_leader)
      SetLeaderWindow(handle);
    else
      SetClientLeader(handle);

    SetClassHints(handle, const_cast<char *>(APP_COMMON_NAME), const_cast<char *>(APP_NAME));
  }

  GList*
  GetDefaultIcons() {
    return default_icons;
  }

  void SetDefaultIcons(GList* icons) {
    if (default_icons) {
      g_list_foreach(default_icons, (GFunc) g_object_unref, NULL);
      g_list_free(default_icons);
    }

    default_icons = icons;
    gtk_window_set_default_icon_list(icons);
  }

  BrowserWindow*
  LookupBrowserWindow(CefWindowHandle native_window) {
    GdkWindow * gdk_window = GDK_WINDOW(gdk_xid_table_lookup(native_window));
    return reinterpret_cast<BrowserWindow*>(
        g_object_get_data(G_OBJECT(gdk_window), "wrapper")
    );
  }

  BrowserWindow*
  LookupBrowserWindow(GdkEvent* event) {
    if (event->type == GDK_NOTHING) {
      // GDK_NOTHING event doesn't have any windows
      return NULL;
    }

    GObject *object = G_OBJECT(event->any.window);
    if (!G_IS_OBJECT(object)) {
      LOG(ERROR) << "Try lookup browser window of bad native window"
         << ", event type: " << event->type
         << ", event window: " << event->any.window;
      return NULL;
    }

    return reinterpret_cast<BrowserWindow*>(
        g_object_get_data(object, "wrapper")
    );
  }

  void
  FlushChanges() {
    ::XDisplay *display = cef_get_xdisplay();

    XFlush(display);
  }

  CefRect
  GetDefaultScreenRect() {
    GdkRectangle monitor_rect;
    gdk_screen_get_monitor_geometry(gdk_screen_get_default(), 0, &monitor_rect);

    return CefRect(
       monitor_rect.x,
       monitor_rect.y,
       monitor_rect.width,
       monitor_rect.height
    );
  }

  double
  GetDPI() {
    GtkSettings* gtk_settings = gtk_settings_get_default();
    DCHECK(gtk_settings);
    gint gtk_dpi = -1;
    g_object_get(gtk_settings, "gtk-xft-dpi", &gtk_dpi, NULL);

    // GTK multiplies the DPI by 1024 before storing it.
    return (gtk_dpi > 0) ? gtk_dpi / 1024.0 : kCSSDefaultDPI;
  }

  double
  GetDeviceScaleFactor() {
    if (!device_scale_factor)
      device_scale_factor = floor((GetDPI() / kCSSDefaultDPI) * 100) / 100;

    return device_scale_factor;
  }
}  // namespace window_util
<|endoftext|>


<commit_before> /*
 * @file   AliForwardTriggerBiasCorrection.cxx
 * @author Valentina Zaccolo
 * @date   Mon Feb  3 11:30:24 2014
 **
 * @brief
 *
 *
 * @ingroup pwglf_forward_multdist
 */

#include <TH1D.h>
#include "AliForwardTriggerBiasCorrection.h"
#include "AliForwardMultiplicityDistribution.h"
#include "AliAODForwardMult.h"
#include "AliAODCentralMult.h"
#include "AliAODEvent.h"
#include "AliFMDMCEventInspector.h"
#include "AliAODMCHeader.h"
#include "AliAODMCParticle.h"

ClassImp(AliForwardTriggerBiasCorrection)
#if 0
; // This is for Emacs - do not delete
#endif
//_____________________________________________________________________
AliBaseMultTask::Bin*
AliForwardTriggerBiasCorrection::MakeBin(Double_t l, Double_t h)
{
  return new Bin(l,h);
}
//_____________________________________________________________________
Bool_t AliForwardTriggerBiasCorrection::IsESDClass(AliAODForwardMult* m) const
{
  return (m->IsTriggerBits(AliAODForwardMult::kInel) ||
	  m->IsTriggerBits(AliAODForwardMult::kV0AND));
}

//=====================================================================
void AliForwardTriggerBiasCorrection::Bin::CreateOutputObjects(TList* cont,
								Int_t max)
{
  //
  // Define eta bin output histos
  //
  AliBaseMultTask::Bin::CreateOutputObjects(cont, max);
  TList* out = static_cast<TList*>(cont->FindObject(GetName()));
  if (!out) return;

  fMCClass         = new TH1D("fMCClass","fMCClass", max,-0.5,max-.5);
  fESDClass        = new TH1D("fESDClass","fESDClass", max,-0.5,max-.5);
  fMCESDClass      = new TH1D("fMCESDClass","fMCESDClass", max,-0.5,max-.5);

  out->Add(fMCClass);
  out->Add(fESDClass);
  out->Add(fMCESDClass);
}

//_____________________________________________________________________
void
AliForwardTriggerBiasCorrection::
Bin::Process(TH1D*              dndetaForward,
	     TH1D*              dndetaCentral,
	     TH1D*              normForward,
	     TH1D*              normCentral,
	     TH1D*              mc,
	     Double_t           ipZ,
	     Bool_t             pileup,
	     Bool_t             selectedTrigger,
	     Bool_t             isMCClass,
	     Bool_t             isESDClass,
	     const AliAODEvent& aodevent,
	     Double_t           minIPz,
	     Double_t           maxIPz)
{
  //
  // Process a single eta bin
  //
  Double_t mcMult, mcErr, statErr, sysErr;
  Double_t mult = CalcMult(dndetaForward,
			   dndetaCentral,
			   normForward,
			   normCentral,
			   mc,
			   ipZ,
			   statErr,
			   sysErr,
			   mcMult,
			   mcErr);
  Double_t trMult  = mcMult;
  Double_t mcIPz   = ipZ;
  if (true) {
    // retreive MC particles from event
    TClonesArray* mcArray =
      static_cast<TClonesArray*>(aodevent.
				 FindListObject(AliAODMCParticle::
						StdBranchName()));
    if(!mcArray){
      AliWarning("No MC array found in AOD. Try making it again.");
      return;
    }
    AliAODMCHeader* header =
      static_cast<AliAODMCHeader*>(aodevent.
				   FindListObject(AliAODMCHeader::
						  StdBranchName()));
    if (!header) {
      AliWarning("No header found.");
      return;
    }
    // Track loop: find MC truth multiplicity in selected eta bin - this
    // is probably redundant
    trMult           = 0;
    mcIPz            = header->GetVtxZ();
    Int_t    ntracks = mcArray->GetEntriesFast();
    for (Int_t it = 0; it < ntracks; it++) {
      AliAODMCParticle* particle = (AliAODMCParticle*)mcArray->At(it);
      if (!particle) {
	AliError(Form("Could not receive track %d", it));
	continue;
      }
    if (!particle->IsPhysicalPrimary()) continue;
    if (particle->Charge() == 0) continue;
    if (particle->Eta() > fEtaLow && particle->Eta() < fEtaHigh-0.0001)
      trMult++;
    }
  }

  // fill fMCClass with multiplicity of MC truth NSD events with MC
  // truth |vtxz|<4
  if (mcIPz > minIPz && mcIPz < maxIPz) {
    if(isMCClass){
      fMCClass->Fill(trMult);
    }
  }
  // fill fESDClass with multiplicity from events with a reconstructed
  // NSD trigger and reconstructed |vtxz|<4
  if (ipZ > minIPz && ipZ < maxIPz){
    if(isESDClass){
      fESDClass->Fill(trMult);
    }
  }
  // fullfilling both requirements of fMCClass and fESDClass
  if(/* mcIPz > minIPz &&
	mcIPz < maxIPz && */
     ipZ               > minIPz &&
     ipZ               < maxIPz &&
     isMCClass && isESDClass){
    fMCESDClass->Fill(trMult);
  }

  if (!selectedTrigger) return;
  fHist->Fill(mult);
  fHistMC->Fill(mcMult);
}

//_____________________________________________________________________
//
//
// EOF
<commit_msg>Do not loop over MC particles, as we already have the info in the primary particle histogram<commit_after> /*
 * @file   AliForwardTriggerBiasCorrection.cxx
 * @author Valentina Zaccolo
 * @date   Mon Feb  3 11:30:24 2014
 **
 * @brief
 *
 *
 * @ingroup pwglf_forward_multdist
 */

#include <TH1D.h>
#include "AliForwardTriggerBiasCorrection.h"
#include "AliForwardMultiplicityDistribution.h"
#include "AliAODForwardMult.h"
#include "AliAODCentralMult.h"
#include "AliAODEvent.h"
#include "AliFMDMCEventInspector.h"
#include "AliAODMCHeader.h"
#include "AliAODMCParticle.h"

ClassImp(AliForwardTriggerBiasCorrection)
#if 0
; // This is for Emacs - do not delete
#endif
//_____________________________________________________________________
AliBaseMultTask::Bin*
AliForwardTriggerBiasCorrection::MakeBin(Double_t l, Double_t h)
{
  return new Bin(l,h);
}
//_____________________________________________________________________
Bool_t AliForwardTriggerBiasCorrection::IsESDClass(AliAODForwardMult* m) const
{
  return (m->IsTriggerBits(AliAODForwardMult::kInel) ||
	  m->IsTriggerBits(AliAODForwardMult::kV0AND));
}

//=====================================================================
void AliForwardTriggerBiasCorrection::Bin::CreateOutputObjects(TList* cont,
								Int_t max)
{
  //
  // Define eta bin output histos
  //
  AliBaseMultTask::Bin::CreateOutputObjects(cont, max);
  TList* out = static_cast<TList*>(cont->FindObject(GetName()));
  if (!out) return;

  fMCClass         = new TH1D("fMCClass","fMCClass", max,-0.5,max-.5);
  fESDClass        = new TH1D("fESDClass","fESDClass", max,-0.5,max-.5);
  fMCESDClass      = new TH1D("fMCESDClass","fMCESDClass", max,-0.5,max-.5);

  out->Add(fMCClass);
  out->Add(fESDClass);
  out->Add(fMCESDClass);
}

//_____________________________________________________________________
void
AliForwardTriggerBiasCorrection::
Bin::Process(TH1D*              dndetaForward,
	     TH1D*              dndetaCentral,
	     TH1D*              normForward,
	     TH1D*              normCentral,
	     TH1D*              mc,
	     Double_t           ipZ,
	     Bool_t             pileup,
	     Bool_t             selectedTrigger,
	     Bool_t             isMCClass,
	     Bool_t             isESDClass,
	     const AliAODEvent& aodevent,
	     Double_t           minIPz,
	     Double_t           maxIPz)
{
  //
  // Process a single eta bin
  //
  Double_t mcMult, mcErr, statErr, sysErr;
  Double_t mult = CalcMult(dndetaForward,
			   dndetaCentral,
			   normForward,
			   normCentral,
			   mc,
			   ipZ,
			   statErr,
			   sysErr,
			   mcMult,
			   mcErr);
  Double_t trMult  = mcMult;
  Double_t mcIPz   = mc->GetBinContent(0,0); // IP from MC stored here
  // The stuff below is redundant.  We've already filled the MC
  // histogram with the exact same information, and we have the IPz
  // from MC in the under-flow bin 0,0 of the MC histogram.
  // Furthermore, we use the information stored in the MC histogram to
  // form the response matrix, so we should also use the same
  // information to build the trigger bias correction.
  //
  // In fact, this class is really not very useful, since we could
  // have the same code in the MC class for doing the response matrix.
  // That would ensure that we have the same number in.
#if 0
  // MC particles from event
  TClonesArray* mcArray =
    static_cast<TClonesArray*>(aodevent.
			       FindListObject(AliAODMCParticle::
					      StdBranchName()));
  if(!mcArray){
    AliWarning("No MC array found in AOD. Try making it again.");
    return;
  }
  AliAODMCHeader* header =
    static_cast<AliAODMCHeader*>(aodevent.
				 FindListObject(AliAODMCHeader::
						StdBranchName()));
  if (!header) {
    AliWarning("No header found.");
    return;
  }
  // Track loop: find MC truth multiplicity in selected eta bin - this
  // is probably redundant
  trMult           = 0;
  mcIPz            = header->GetVtxZ();
  Int_t    ntracks = mcArray->GetEntriesFast();
  for (Int_t it = 0; it < ntracks; it++) {
    AliAODMCParticle* particle = (AliAODMCParticle*)mcArray->At(it);
    if (!particle) {
      AliError(Form("Could not receive track %d", it));
      continue;
    }
    if (!particle->IsPhysicalPrimary()) continue;
    if (particle->Charge() == 0) continue;
    if (particle->Eta() > fEtaLow && particle->Eta() < fEtaHigh-0.0001)
      trMult++;
  }
#endif

  // fill fMCClass with multiplicity of MC truth NSD events with MC
  // truth |vtxz|<4
  if (mcIPz > minIPz && mcIPz < maxIPz) {
    if(isMCClass){
      fMCClass->Fill(trMult);
    }
  }
  // fill fESDClass with multiplicity from events with a reconstructed
  // NSD trigger and reconstructed |vtxz|<4
  if (ipZ > minIPz && ipZ < maxIPz){
    if(isESDClass){
      fESDClass->Fill(trMult);
    }
  }
  // fullfilling both requirements of fMCClass and fESDClass
  if(/* mcIPz > minIPz &&
	mcIPz < maxIPz && */
     ipZ               > minIPz &&
     ipZ               < maxIPz &&
     isMCClass && isESDClass){
    fMCESDClass->Fill(trMult);
  }

  if (!selectedTrigger) return;
  fHist->Fill(mult);
  fHistMC->Fill(mcMult);
}

//_____________________________________________________________________
//
//
// EOF
<|endoftext|>


<commit_before>/*
 * summation.cc
 *
 *  Copyright (C) 2013 Diamond Light Source
 *
 *  Author: James Parkhurst
 *
 *  This code is distributed under the BSD license, a copy of which is
 *  included in the root directory of this package.
 */
#include <boost/python.hpp>
#include <boost/python/def.hpp>
#include <dials/algorithms/integration/summation.h>
#include <dials/model/data/reflection.h>
#include <dials/algorithms/shoebox/mask_code.h>

using namespace boost::python;

namespace dials { namespace algorithms { namespace boost_python {

  using dials::model::Reflection;

  template <typename FloatType>
  void summation_wrapper(const char *name)
  {
    typedef Summation<FloatType> SummationType;

    class_ <SummationType> ("Summation", no_init)
      .def(init <const af::const_ref<FloatType>&,
                 const af::const_ref<FloatType>&>((
          arg("signal"),
          arg("background"))))
      .def(init <const af::const_ref<FloatType>&,
                 const af::const_ref<FloatType>&,
                 const af::const_ref<bool>&>((
          arg("signal"),
          arg("background"),
          arg("mask"))))
      .def(init <const af::const_ref< FloatType, af::c_grid<2> >&,
                 const af::const_ref< FloatType, af::c_grid<2> >&>((
          arg("signal"),
          arg("background"))))
      .def(init <const af::const_ref< FloatType, af::c_grid<2> >&,
                 const af::const_ref< FloatType, af::c_grid<2> >&,
                 const af::const_ref< bool, af::c_grid<2> >&>((
          arg("signal"),
          arg("background"),
          arg("mask"))))
      .def(init <const af::const_ref< FloatType, af::c_grid<3> >&,
                 const af::const_ref< FloatType, af::c_grid<3> >&>((
          arg("signal"),
          arg("background"))))
      .def(init <const af::const_ref< FloatType, af::c_grid<3> >&,
                 const af::const_ref< FloatType, af::c_grid<3> >&,
                 const af::const_ref< bool, af::c_grid<3> >&>((
          arg("signal"),
          arg("background"),
          arg("mask"))))
      .def("intensity",
        &SummationType::intensity)
      .def("variance",
        &SummationType::variance)
      .def("standard_deviation",
        &SummationType::standard_deviation)
      .def("signal_intensity",
        &SummationType::signal_intensity)
      .def("signal_variance",
        &SummationType::signal_variance)
      .def("signal_standard_deviation",
        &SummationType::signal_standard_deviation)
      .def("background_intensity",
        &SummationType::background_intensity)
      .def("background_variance",
        &SummationType::background_variance)
      .def("background_standard_deviation",
        &SummationType::background_standard_deviation);
  }

  template <typename FloatType>
  Summation<FloatType> make_summation_1d(
    const af::const_ref<FloatType> &image,
    const af::const_ref<FloatType> &background) {
    return Summation<FloatType>(image, background);
  }

  template <typename FloatType>
  Summation<FloatType> make_summation_1d_bg(
    const af::const_ref<FloatType> &image,
    const af::const_ref<FloatType> &background,
    const af::const_ref<bool> &mask) {
    return Summation<FloatType>(image, background, mask);
  }

  template <typename FloatType>
  Summation<FloatType> make_summation_2d(
    const af::const_ref<FloatType, af::c_grid<2> > &image,
    const af::const_ref<FloatType, af::c_grid<2> > &background) {
    return Summation<FloatType>(image, background);
  }

  template <typename FloatType>
  Summation<FloatType> make_summation_2d_bg(
    const af::const_ref<FloatType, af::c_grid<2> > &image,
    const af::const_ref<FloatType, af::c_grid<2> > &background,
    const af::const_ref<bool, af::c_grid<2> > &mask) {
    return Summation<FloatType>(image, background, mask);
  }

  template <typename FloatType>
  Summation<FloatType> make_summation_3d(
    const af::const_ref<FloatType, af::c_grid<3> > &image,
    const af::const_ref<FloatType, af::c_grid<3> > &background) {
    return Summation<FloatType>(image, background);
  }

  template <typename FloatType>
  Summation<FloatType> make_summation_3d_bg(
    const af::const_ref<FloatType, af::c_grid<3> > &image,
    const af::const_ref<FloatType, af::c_grid<3> > &background,
    const af::const_ref<bool, af::c_grid<3> > &mask) {
    return Summation<FloatType>(image, background, mask);
  }

  template <typename FloatType>
  void summation_suite() {

    def("integrate_by_summation",
      &make_summation_1d<FloatType>, (
        arg("image"),
        arg("background")));

    def("integrate_by_summation",
      &make_summation_1d_bg<FloatType>, (
        arg("image"),
        arg("background"),
        arg("mask")));

    def("integrate_by_summation",
      &make_summation_2d<FloatType>, (
        arg("image"),
        arg("background")));

    def("integrate_by_summation",
      &make_summation_2d_bg<FloatType>, (
        arg("image"),
        arg("background"),
        arg("mask")));

    def("integrate_by_summation",
      &make_summation_3d<FloatType>, (
        arg("image"),
        arg("background")));

    def("integrate_by_summation",
      &make_summation_3d_bg<FloatType>, (
        arg("image"),
        arg("background"),
        arg("mask")));
  }

  void summation_with_reflection(Reflection &r) {

    af::const_ref< int, af::c_grid<3> > shoebox_mask =
      r.get_shoebox_mask().const_ref();
    af::versa< bool, af::c_grid<3> > mask(shoebox_mask.accessor(),
      af::init_functor_null<bool>());
    for (std::size_t i = 0; i < mask.size(); ++i) {
      mask[i] = (shoebox_mask[i] & shoebox::Valid) ? true : false;
    }

    // Integrate the reflection
    Summation<Reflection::float_type> result(
      r.get_shoebox().const_ref(),
      r.get_shoebox_background().const_ref(),
      mask.const_ref());

    // Set the intensity and variance
    r.set_intensity(result.intensity());
    r.set_intensity_variance(result.variance());
  }

  void summation_with_reflection_list(af::ref<Reflection> reflections) {
    #pragma omp parallel for
    for (std::size_t i = 0; i < reflections.size(); ++i) {
      try {
        if (reflections[i].is_valid()) {
          summation_with_reflection(reflections[i]);
        }
      } catch (dials::error) {
        reflections[i].set_valid(false);
      }
    }
  }

  void export_summation() {
    summation_wrapper<float>("SummationFloat");
    summation_wrapper<double>("SummationDouble");

    summation_suite<float>();
    summation_suite<double>();

    def("integrate_by_summation", &summation_with_reflection);
    def("integrate_by_summation", &summation_with_reflection_list);
  }

}}} // namespace = dials::algorithms::boost_python
<commit_msg>Fixed bug, now just integrating those pixels set as foreground.<commit_after>/*
 * summation.cc
 *
 *  Copyright (C) 2013 Diamond Light Source
 *
 *  Author: James Parkhurst
 *
 *  This code is distributed under the BSD license, a copy of which is
 *  included in the root directory of this package.
 */
#include <boost/python.hpp>
#include <boost/python/def.hpp>
#include <dials/algorithms/integration/summation.h>
#include <dials/model/data/reflection.h>
#include <dials/algorithms/shoebox/mask_code.h>

using namespace boost::python;

namespace dials { namespace algorithms { namespace boost_python {

  using dials::model::Reflection;

  template <typename FloatType>
  void summation_wrapper(const char *name)
  {
    typedef Summation<FloatType> SummationType;

    class_ <SummationType> ("Summation", no_init)
      .def(init <const af::const_ref<FloatType>&,
                 const af::const_ref<FloatType>&>((
          arg("signal"),
          arg("background"))))
      .def(init <const af::const_ref<FloatType>&,
                 const af::const_ref<FloatType>&,
                 const af::const_ref<bool>&>((
          arg("signal"),
          arg("background"),
          arg("mask"))))
      .def(init <const af::const_ref< FloatType, af::c_grid<2> >&,
                 const af::const_ref< FloatType, af::c_grid<2> >&>((
          arg("signal"),
          arg("background"))))
      .def(init <const af::const_ref< FloatType, af::c_grid<2> >&,
                 const af::const_ref< FloatType, af::c_grid<2> >&,
                 const af::const_ref< bool, af::c_grid<2> >&>((
          arg("signal"),
          arg("background"),
          arg("mask"))))
      .def(init <const af::const_ref< FloatType, af::c_grid<3> >&,
                 const af::const_ref< FloatType, af::c_grid<3> >&>((
          arg("signal"),
          arg("background"))))
      .def(init <const af::const_ref< FloatType, af::c_grid<3> >&,
                 const af::const_ref< FloatType, af::c_grid<3> >&,
                 const af::const_ref< bool, af::c_grid<3> >&>((
          arg("signal"),
          arg("background"),
          arg("mask"))))
      .def("intensity",
        &SummationType::intensity)
      .def("variance",
        &SummationType::variance)
      .def("standard_deviation",
        &SummationType::standard_deviation)
      .def("signal_intensity",
        &SummationType::signal_intensity)
      .def("signal_variance",
        &SummationType::signal_variance)
      .def("signal_standard_deviation",
        &SummationType::signal_standard_deviation)
      .def("background_intensity",
        &SummationType::background_intensity)
      .def("background_variance",
        &SummationType::background_variance)
      .def("background_standard_deviation",
        &SummationType::background_standard_deviation);
  }

  template <typename FloatType>
  Summation<FloatType> make_summation_1d(
    const af::const_ref<FloatType> &image,
    const af::const_ref<FloatType> &background) {
    return Summation<FloatType>(image, background);
  }

  template <typename FloatType>
  Summation<FloatType> make_summation_1d_bg(
    const af::const_ref<FloatType> &image,
    const af::const_ref<FloatType> &background,
    const af::const_ref<bool> &mask) {
    return Summation<FloatType>(image, background, mask);
  }

  template <typename FloatType>
  Summation<FloatType> make_summation_2d(
    const af::const_ref<FloatType, af::c_grid<2> > &image,
    const af::const_ref<FloatType, af::c_grid<2> > &background) {
    return Summation<FloatType>(image, background);
  }

  template <typename FloatType>
  Summation<FloatType> make_summation_2d_bg(
    const af::const_ref<FloatType, af::c_grid<2> > &image,
    const af::const_ref<FloatType, af::c_grid<2> > &background,
    const af::const_ref<bool, af::c_grid<2> > &mask) {
    return Summation<FloatType>(image, background, mask);
  }

  template <typename FloatType>
  Summation<FloatType> make_summation_3d(
    const af::const_ref<FloatType, af::c_grid<3> > &image,
    const af::const_ref<FloatType, af::c_grid<3> > &background) {
    return Summation<FloatType>(image, background);
  }

  template <typename FloatType>
  Summation<FloatType> make_summation_3d_bg(
    const af::const_ref<FloatType, af::c_grid<3> > &image,
    const af::const_ref<FloatType, af::c_grid<3> > &background,
    const af::const_ref<bool, af::c_grid<3> > &mask) {
    return Summation<FloatType>(image, background, mask);
  }

  template <typename FloatType>
  void summation_suite() {

    def("integrate_by_summation",
      &make_summation_1d<FloatType>, (
        arg("image"),
        arg("background")));

    def("integrate_by_summation",
      &make_summation_1d_bg<FloatType>, (
        arg("image"),
        arg("background"),
        arg("mask")));

    def("integrate_by_summation",
      &make_summation_2d<FloatType>, (
        arg("image"),
        arg("background")));

    def("integrate_by_summation",
      &make_summation_2d_bg<FloatType>, (
        arg("image"),
        arg("background"),
        arg("mask")));

    def("integrate_by_summation",
      &make_summation_3d<FloatType>, (
        arg("image"),
        arg("background")));

    def("integrate_by_summation",
      &make_summation_3d_bg<FloatType>, (
        arg("image"),
        arg("background"),
        arg("mask")));
  }

  void summation_with_reflection(Reflection &r) {

    af::const_ref< int, af::c_grid<3> > shoebox_mask =
      r.get_shoebox_mask().const_ref();
    af::versa< bool, af::c_grid<3> > mask(shoebox_mask.accessor(),
      af::init_functor_null<bool>());
    for (std::size_t i = 0; i < mask.size(); ++i) {
      mask[i] = (shoebox_mask[i] & shoebox::Valid &&
                 shoebox_mask[i] & shoebox::Foreground) ? true : false;
    }

    // Integrate the reflection
    Summation<Reflection::float_type> result(
      r.get_shoebox().const_ref(),
      r.get_shoebox_background().const_ref(),
      mask.const_ref());

    // Set the intensity and variance
    r.set_intensity(result.intensity());
    r.set_intensity_variance(result.variance());
  }

  void summation_with_reflection_list(af::ref<Reflection> reflections) {
    #pragma omp parallel for
    for (std::size_t i = 0; i < reflections.size(); ++i) {
      try {
        if (reflections[i].is_valid()) {
          summation_with_reflection(reflections[i]);
        }
      } catch (dials::error) {
        reflections[i].set_valid(false);
      }
    }
  }

  void export_summation() {
    summation_wrapper<float>("SummationFloat");
    summation_wrapper<double>("SummationDouble");

    summation_suite<float>();
    summation_suite<double>();

    def("integrate_by_summation", &summation_with_reflection);
    def("integrate_by_summation", &summation_with_reflection_list);
  }

}}} // namespace = dials::algorithms::boost_python
<|endoftext|>


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

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt 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 "itkExceptionObject.h"
#include "itkFixedArray.h"
#include "otbLandsatTMIndices.h"
#include <vector>
#include <algorithm>

int otbLandsatTMKernelSpectralRules(int argc, char * argv[])
{

  typedef double PrecisionType;
  typedef itk::FixedArray< PrecisionType, 8 >     InputPixelType;

  double TM1 = (::atof(argv[1]));
  double TM2 = (::atof(argv[2]));
  double TM3 = (::atof(argv[3]));
  double TM4 = (::atof(argv[4]));
  double TM5 = (::atof(argv[5]));
  double TM61 = (::atof(argv[6]));
  double TM62 = (::atof(argv[7]));
  double TM7 = (::atof(argv[8]));

  InputPixelType pixel;
  pixel[0] = TM1;
  pixel[1] = TM2;
  pixel[2] = TM3;
  pixel[3] = TM4;
  pixel[4] = TM5;
  pixel[5] = TM61;
  pixel[6] = TM62;
  pixel[7] = TM7;

  std::vector< PrecisionType > v123;
  v123.push_back(TM1);
  v123.push_back(TM2);
  v123.push_back(TM3);

  PrecisionType max123 = *(max_element ( v123.begin(), v123.end() ));
  PrecisionType min123 = *(min_element ( v123.begin(), v123.end() ));

  PrecisionType TV1 = 0.7;
  PrecisionType TV2 = 0.5;

  typedef otb::Functor::LandsatTM::ThickCloudsSpectralRule<InputPixelType> R1FunctorType;
  R1FunctorType r1Funct = R1FunctorType();
  bool result = r1Funct(pixel);
  bool goodResult = (min123 >= (TV1 * max123))
    and (max123 <= TV1 * TM4)
    and (TM5 <= TV1 * TM4)
    and (TM5 >= TV1 * max123)
    and (TM7 <= TV1 * TM4);

  std::cout << "Rule 1 " << goodResult << " " << result << std::endl;
  if( result!=goodResult ) return EXIT_FAILURE;

  typedef otb::Functor::LandsatTM::ThinCloudsSpectralRule<InputPixelType> R2FunctorType;
  R2FunctorType r2Funct = R2FunctorType();
  result = r2Funct(pixel);
  goodResult = (min123 >= (TV1 * max123))
    and (TM4 >= max123)
    and !((TM1<=TM2 and TM2<=TM3 and TM3<=TM4) and TM3 >= TV1*TM4)
    and (TM4 >= TV1*TM5) and (TM5 >= TV1*TM4)
    and (TM5 >= TV1*max123) and (TM5 >= TV1*TM7);

  std::cout << "Rule 2 " << goodResult << " " << result << std::endl;
  if( result!=goodResult ) return EXIT_FAILURE;

  typedef otb::Functor::LandsatTM::SnowOrIceSpectralRule<InputPixelType> R3FunctorType;
  R3FunctorType r3Funct = R3FunctorType();
  result = r3Funct(pixel);
  goodResult = (min123 >= (TV1 * max123))
    and (TM4 >= TV1 * max123)
    and (TM5 <= TV2 * TM4)
    and (TM5 <= TV1* min123)
    and (TM7 <= TV2 * TM4)
    and (TM7 <= TV1*min123);

  std::cout << "Rule 3 " << goodResult << " " << result << std::endl;
  if( result!=goodResult ) return EXIT_FAILURE;

  typedef otb::Functor::LandsatTM::WaterOrShadowSpectralRule<InputPixelType> R4FunctorType;
  R4FunctorType r4Funct = R4FunctorType();
  result = r4Funct(pixel);
  goodResult = (TM1 >= TM2) and (TM2 >= TM3) and (TM3 >= TM4) and (TM4 >= TM5) and (TM4 >= TM7);

  std::cout << "Rule 4 " << goodResult << " " << result << std::endl;
  if( result!=goodResult ) return EXIT_FAILURE;

  typedef otb::Functor::LandsatTM::PitbogOrGreenhouseSpectralRule<InputPixelType> R5FunctorType;
  R5FunctorType r5Funct = R5FunctorType();
  result = r5Funct(pixel);
  goodResult = (TM3 >= TV1 * TM1)
    and (TM1 >= TV1 * TM3)
    and (max123 <= TV1 * TM4)
    and (TM5 <= TV1 * TM4)
    and (TM3 >= TV2 * TM5)
    and (min123 >= TV1 * TM7);

  std::cout << "Rule 5 " << goodResult << " " << result << std::endl;
  if( result!=goodResult ) return EXIT_FAILURE;

  typedef otb::Functor::LandsatTM::DominantBlueSpectralRule<InputPixelType> R6FunctorType;
  R6FunctorType r6Funct = R6FunctorType();
  result = r6Funct(pixel);
  goodResult = (TM1 >= TV1 * TM2)
    and (TM1 >= TV1 * TM3)
    and (TM1 >= TV1 * TM4)
    and (TM1 >= TV1 * TM5)
    and (TM1 >= TV1 * TM7);

  std::cout << "Rule 6 " << goodResult << " " << result << std::endl;
  if( result!=goodResult ) return EXIT_FAILURE;

  return EXIT_SUCCESS;
}
<commit_msg>TEST: Landsat TM vegetation spectral rule<commit_after>/*=========================================================================

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt 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 "itkExceptionObject.h"
#include "itkFixedArray.h"
#include "otbLandsatTMIndices.h"
#include <vector>
#include <algorithm>

int otbLandsatTMKernelSpectralRules(int argc, char * argv[])
{

  typedef double PrecisionType;
  typedef itk::FixedArray< PrecisionType, 8 >     InputPixelType;

  double TM1 = (::atof(argv[1]));
  double TM2 = (::atof(argv[2]));
  double TM3 = (::atof(argv[3]));
  double TM4 = (::atof(argv[4]));
  double TM5 = (::atof(argv[5]));
  double TM61 = (::atof(argv[6]));
  double TM62 = (::atof(argv[7]));
  double TM7 = (::atof(argv[8]));

  InputPixelType pixel;
  pixel[0] = TM1;
  pixel[1] = TM2;
  pixel[2] = TM3;
  pixel[3] = TM4;
  pixel[4] = TM5;
  pixel[5] = TM61;
  pixel[6] = TM62;
  pixel[7] = TM7;

  std::vector< PrecisionType > v123;
  v123.push_back(TM1);
  v123.push_back(TM2);
  v123.push_back(TM3);

  PrecisionType max123 = *(max_element ( v123.begin(), v123.end() ));
  PrecisionType min123 = *(min_element ( v123.begin(), v123.end() ));

  PrecisionType TV1 = 0.7;
  PrecisionType TV2 = 0.5;

  typedef otb::Functor::LandsatTM::ThickCloudsSpectralRule<InputPixelType> R1FunctorType;
  R1FunctorType r1Funct = R1FunctorType();
  bool result = r1Funct(pixel);
  bool goodResult = (min123 >= (TV1 * max123))
    and (max123 <= TV1 * TM4)
    and (TM5 <= TV1 * TM4)
    and (TM5 >= TV1 * max123)
    and (TM7 <= TV1 * TM4);

  std::cout << "Rule 1 " << goodResult << " " << result << std::endl;
  if( result!=goodResult ) return EXIT_FAILURE;

  typedef otb::Functor::LandsatTM::ThinCloudsSpectralRule<InputPixelType> R2FunctorType;
  R2FunctorType r2Funct = R2FunctorType();
  result = r2Funct(pixel);
  goodResult = (min123 >= (TV1 * max123))
    and (TM4 >= max123)
    and !((TM1<=TM2 and TM2<=TM3 and TM3<=TM4) and TM3 >= TV1*TM4)
    and (TM4 >= TV1*TM5) and (TM5 >= TV1*TM4)
    and (TM5 >= TV1*max123) and (TM5 >= TV1*TM7);

  std::cout << "Rule 2 " << goodResult << " " << result << std::endl;
  if( result!=goodResult ) return EXIT_FAILURE;

  typedef otb::Functor::LandsatTM::SnowOrIceSpectralRule<InputPixelType> R3FunctorType;
  R3FunctorType r3Funct = R3FunctorType();
  result = r3Funct(pixel);
  goodResult = (min123 >= (TV1 * max123))
    and (TM4 >= TV1 * max123)
    and (TM5 <= TV2 * TM4)
    and (TM5 <= TV1* min123)
    and (TM7 <= TV2 * TM4)
    and (TM7 <= TV1*min123);

  std::cout << "Rule 3 " << goodResult << " " << result << std::endl;
  if( result!=goodResult ) return EXIT_FAILURE;

  typedef otb::Functor::LandsatTM::WaterOrShadowSpectralRule<InputPixelType> R4FunctorType;
  R4FunctorType r4Funct = R4FunctorType();
  result = r4Funct(pixel);
  goodResult = (TM1 >= TM2) and (TM2 >= TM3) and (TM3 >= TM4) and (TM4 >= TM5) and (TM4 >= TM7);

  std::cout << "Rule 4 " << goodResult << " " << result << std::endl;
  if( result!=goodResult ) return EXIT_FAILURE;

  typedef otb::Functor::LandsatTM::PitbogOrGreenhouseSpectralRule<InputPixelType> R5FunctorType;
  R5FunctorType r5Funct = R5FunctorType();
  result = r5Funct(pixel);
  goodResult = (TM3 >= TV1 * TM1)
    and (TM1 >= TV1 * TM3)
    and (max123 <= TV1 * TM4)
    and (TM5 <= TV1 * TM4)
    and (TM3 >= TV2 * TM5)
    and (min123 >= TV1 * TM7);

  std::cout << "Rule 5 " << goodResult << " " << result << std::endl;
  if( result!=goodResult ) return EXIT_FAILURE;

  typedef otb::Functor::LandsatTM::DominantBlueSpectralRule<InputPixelType> R6FunctorType;
  R6FunctorType r6Funct = R6FunctorType();
  result = r6Funct(pixel);
  goodResult = (TM1 >= TV1 * TM2)
    and (TM1 >= TV1 * TM3)
    and (TM1 >= TV1 * TM4)
    and (TM1 >= TV1 * TM5)
    and (TM1 >= TV1 * TM7);

  std::cout << "Rule 6 " << goodResult << " " << result << std::endl;
  if( result!=goodResult ) return EXIT_FAILURE;

  typedef otb::Functor::LandsatTM::VegetationSpectralRule<InputPixelType> R7FunctorType;
  R7FunctorType r7Funct = R7FunctorType();
  result = r7Funct(pixel);
  goodResult = (TM2 >= TV2 * TM1)
    and (TM2 >= TV1 * TM3)
    and (TM3 <= TV1 * TM4)
    and (TM4 >= max123)
    and (TM5 <= TV1 * TM4)
    and (TM5 >= TV1 * TM3)
    and (TM7 <= TV1 * TM5);

  std::cout << "Rule 7 " << goodResult << " " << result << std::endl;
  if( result!=goodResult ) return EXIT_FAILURE;

  return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before><commit_msg>Revert "tdf#92231 Potential regression curve calculation is wrong"<commit_after><|endoftext|>


<commit_before>////////////////////////////////////////////////////////////////////////////////
//
//  File: ProcessBoundaryExtract.cpp
//
//  For more information, please see: http://www.nektar.info/
//
//  The MIT License
//
//  Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
//  Department of Aeronautics, Imperial College London (UK), and Scientific
//  Computing and Imaging Institute, University of Utah (USA).
//
//  License for the specific language governing rights and limitations under
//  Permission is hereby granted, free of charge, to any person obtaining a
//  copy of this software and associated documentation files (the "Software"),
//  to deal in the Software without restriction, including without limitation
//  the rights to use, copy, modify, merge, publish, distribute, sublicense,
//  and/or sell copies of the Software, and to permit persons to whom the
//  Software is furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included
//  in all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
//  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
//  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
//  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
//  DEALINGS IN THE SOFTWARE.
//
//  Description: Set up boundary to be extracted when writing fld file.
//
////////////////////////////////////////////////////////////////////////////////

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

#include "ProcessBoundaryExtract.h"

#include <LibUtilities/BasicUtils/SharedArray.hpp>
#include <LibUtilities/BasicUtils/ParseUtils.hpp>

namespace Nektar
{
    namespace Utilities
    {
        ModuleKey ProcessBoundaryExtract::className =
            GetModuleFactory().RegisterCreatorFunction(
                ModuleKey(eProcessModule, "extract"),
                ProcessBoundaryExtract::create, "Extract Boundary field");

        ProcessBoundaryExtract::ProcessBoundaryExtract(FieldSharedPtr f) : ProcessModule(f)
        {
            // set up dafault values.
            m_config["bnd"] = ConfigOption(false,"All","Boundary to be extracted");
            m_config["fldtoboundary"] = ConfigOption(true,"1","Extract fld values to boundary");

            f->m_writeBndFld = true;

        }

        ProcessBoundaryExtract::~ProcessBoundaryExtract()
        {
        }

        void ProcessBoundaryExtract::Process(po::variables_map &vm)
        {
            if (m_f->m_verbose)
            {
                cout << "ProcessBoundaryExtract: Setting up boundary extraction..." << endl;
            }

            // Set up Field options to output boundary fld
            string bvalues =  m_config["bnd"].as<string>();

            if(bvalues.compare("All") == 0)
            {
                Array<OneD, const MultiRegions::ExpListSharedPtr>
                    BndExp = m_f->m_exp[0]->GetBndCondExpansions();

                for(int i = 0; i < BndExp.num_elements(); ++i)
                {
                    m_f->m_bndRegionsToWrite.push_back(i);
                }
            }
            else
            {
                ASSERTL0(ParseUtils::GenerateOrderedVector(bvalues.c_str(),
                                                           m_f->m_bndRegionsToWrite),"Failed to interpret range string");
            }

            if(m_config["fldtoboundary"].as<bool>())
            {
                m_f->m_fldToBnd = true;
            }

        }
    }
}

<commit_msg>Made keynames more consistent with meshconvert, i.e. extract rather than Extract<commit_after>////////////////////////////////////////////////////////////////////////////////
//
//  File: ProcessBoundaryExtract.cpp
//
//  For more information, please see: http://www.nektar.info/
//
//  The MIT License
//
//  Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
//  Department of Aeronautics, Imperial College London (UK), and Scientific
//  Computing and Imaging Institute, University of Utah (USA).
//
//  License for the specific language governing rights and limitations under
//  Permission is hereby granted, free of charge, to any person obtaining a
//  copy of this software and associated documentation files (the "Software"),
//  to deal in the Software without restriction, including without limitation
//  the rights to use, copy, modify, merge, publish, distribute, sublicense,
//  and/or sell copies of the Software, and to permit persons to whom the
//  Software is furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included
//  in all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
//  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
//  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
//  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
//  DEALINGS IN THE SOFTWARE.
//
//  Description: Set up boundary to be extracted when writing fld file.
//
////////////////////////////////////////////////////////////////////////////////

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

#include "ProcessBoundaryExtract.h"

#include <LibUtilities/BasicUtils/SharedArray.hpp>
#include <LibUtilities/BasicUtils/ParseUtils.hpp>

namespace Nektar
{
    namespace Utilities
    {
        ModuleKey ProcessBoundaryExtract::className =
            GetModuleFactory().RegisterCreatorFunction(
                ModuleKey(eProcessModule, "extract"),
                ProcessBoundaryExtract::create, "Extract Boundary field");

        ProcessBoundaryExtract::ProcessBoundaryExtract(FieldSharedPtr f) : ProcessModule(f)
        {
            // set up dafault values.
            m_config["bnd"] = ConfigOption(false,"All","Boundary to be extracted");
            m_config["fldtoboundary"] = ConfigOption(false,"1","Extract fld values to boundary");

            f->m_writeBndFld = true;

        }

        ProcessBoundaryExtract::~ProcessBoundaryExtract()
        {
        }

        void ProcessBoundaryExtract::Process(po::variables_map &vm)
        {
            if (m_f->m_verbose)
            {
                cout << "ProcessBoundaryExtract: Setting up boundary extraction..." << endl;
            }

            // Set up Field options to output boundary fld
            string bvalues =  m_config["bnd"].as<string>();

            if(bvalues.compare("All") == 0)
            {
                Array<OneD, const MultiRegions::ExpListSharedPtr>
                    BndExp = m_f->m_exp[0]->GetBndCondExpansions();

                for(int i = 0; i < BndExp.num_elements(); ++i)
                {
                    m_f->m_bndRegionsToWrite.push_back(i);
                }
            }
            else
            {
                ASSERTL0(ParseUtils::GenerateOrderedVector(bvalues.c_str(),
                                                           m_f->m_bndRegionsToWrite),"Failed to interpret range string");
            }

            if(m_config["fldtoboundary"].as<string>().compare("1") == 0)
            {
                m_f->m_fldToBnd = true;
            }
            else
            {
                m_f->m_fldToBnd = false;
            }

        }
    }
}

<|endoftext|>


<commit_before>/*
 * Copyright (C) 2017 Smirnov Vladimir mapron1@gmail.com
 * Source code licensed under the Apache License, Version 2.0 (the "License");
 * You may not use this file except in compliance with the License.
 * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 or in file COPYING-APACHE-2.0.txt
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.h
 */

#include "FileUtils.h"

#include "Compression.h"
#include "Syslogger.h"
#include "ThreadUtils.h"

#include <assert.h>
#include <stdio.h>
#include <algorithm>
#include <fstream>
#include <streambuf>

#ifdef HAS_BOOST
#include <boost/filesystem.hpp>
namespace fs = boost::filesystem;
#define u8string string
using fserr = boost::system::error_code;
#else
#include <experimental/filesystem>
namespace fs = std::experimental::filesystem;
using fserr = std::error_code;
#endif

#ifdef _MSC_VER
#define strtoull _strtoui64
#define getcwd _getcwd
#define PATH_MAX _MAX_PATH
#endif

#if defined( _WIN32)
#include <windows.h>
#include <io.h>
#include <share.h>
#include <direct.h>
#else
#include <unistd.h>
#include <errno.h>
inline int GetLastError() { return errno; }
#endif

namespace {
static const size_t CHUNK = 16384;
}

namespace Wuild {

class FileInfoPrivate
{
public:
	fs::path m_path;
};

std::string FileInfo::ToPlatformPath(std::string path)
{
#ifdef _WIN32
   std::replace(path.begin(), path.end(), '/', '\\');
   std::transform(path.begin(), path.end(), path.begin(), [](char c) { return ::tolower(c);});
#endif
   return path;
}

FileInfo::FileInfo(const FileInfo &rh)
	: m_impl(new FileInfoPrivate(*rh.m_impl))
{

}

FileInfo &FileInfo::operator =(const FileInfo &rh)
{
	m_impl.reset(new FileInfoPrivate(*rh.m_impl));
	return *this;
}

FileInfo::FileInfo(const std::string &filename)
	: m_impl(new FileInfoPrivate())
{
	m_impl->m_path = filename;
}

FileInfo::~FileInfo()
{

}

void FileInfo::SetPath(const std::string &path)
{
	m_impl->m_path = path;
}

std::string FileInfo::GetPath() const
{
	return m_impl->m_path.u8string();
}

std::string FileInfo::GetDir(bool ensureEndSlash) const
{
	auto ret = m_impl->m_path.parent_path().u8string();
	if (!ret.empty() && ensureEndSlash)
		ret += '/';
	return ret;
}

std::string FileInfo::GetFullname() const
{
	return m_impl->m_path.filename().u8string();
}

std::string FileInfo::GetNameWE() const
{
	const auto name = this->GetFullname();
	const auto dot = name.find('.');
	return name.substr(0, dot);
}

std::string FileInfo::GetFullExtension() const
{
	const auto name = this->GetFullname();
	const auto dot = name.find('.');
	return name.substr( dot );
}

std::string FileInfo::GetPlatformShortName() const
{
#ifdef _WIN32
	std::string result = GetPath();
	fserr code;
	result = fs::canonical(result, code).u8string();
	long length = 0;

	// First obtain the size needed by passing NULL and 0.
	length = GetShortPathNameA(result.c_str(), nullptr, 0);
	if (length == 0)
		return result;

	// Dynamically allocate the correct size
	// (terminating null char was included in length)
	std::vector<char> buffer(length + 1);

	// Now simply call again using same long path.
	length = GetShortPathNameA(result.c_str(), buffer.data(), length);
	if (length == 0)
		return result;

	return ToPlatformPath(std::string(buffer.data(), length));
#else
	return GetPath();
#endif
}

bool FileInfo::ReadCompressed(ByteArrayHolder &data, CompressionInfo compressionInfo)
{
	std::ifstream inFile;
	inFile.open(GetPath().c_str(), std::ios::binary | std::ios::in);
	if (!inFile)
		return false;

	try
	{
		ReadCompressedData(inFile, data, compressionInfo);
	}
	catch(std::exception &e)
	{
		Syslogger(Syslogger::Err) << "Error on reading:" << e.what() << " for " << GetPath();
		return false;
	}

	if (Syslogger::IsLogLevelEnabled(Syslogger::Debug))
		Syslogger() << "Compressed " << this->GetPath() << ": " << this->GetFileSize() << " -> " << data.size();

	return true;
}

bool FileInfo::WriteCompressed(const ByteArrayHolder & data, CompressionInfo compressionInfo, bool createTmpCopy)
{
	ByteArrayHolder uncompData;
	try
	{
		UncompressDataBuffer(data, uncompData, compressionInfo);
	}
	catch(std::exception &e)
	{
		Syslogger(Syslogger::Err) << "Error on uncompress:" << e.what() << " for " << GetPath();
		return false;
	}
	return this->WriteFile(uncompData, createTmpCopy);
}

bool FileInfo::ReadFile(ByteArrayHolder &data)
{
	FILE * f = fopen(GetPath().c_str(), "rb");
	if (!f)
		return false;

	ByteArray& dest = data.ref();

	unsigned char in[CHUNK];
	do {
		auto avail_in = fread(in, 1, CHUNK, f);
		if (!avail_in || ferror(f)) break;
		dest.insert(dest.end(), in, in + avail_in);
		if (feof(f)) break;

	} while (true);

	fclose(f);
	return true;
}

bool FileInfo::WriteFile(const ByteArrayHolder &data, bool createTmpCopy)
{
	fserr code;
	const std::string originalPath = fs::canonical(fs::absolute(m_impl->m_path), code).make_preferred().u8string();
	const std::string writePath = createTmpCopy ? originalPath + ".tmp" : originalPath;
	this->Remove();

	try
	{
#ifndef _WIN32
		std::ofstream outFile;
		outFile.open(writePath, std::ios::binary | std::ios::out);
		outFile.write((const char*)data.data(), data.size());
		outFile.close();
#else
		auto fileHandle = CreateFileA((LPTSTR) writePath.c_str(), // file name
							   GENERIC_WRITE,        // open for write
							   0,                    // do not share
							   NULL,                 // default security
							   CREATE_ALWAYS,        // overwrite existing
							   FILE_ATTRIBUTE_NORMAL,// normal file
							   NULL);                // no template
		if (fileHandle == INVALID_HANDLE_VALUE)
			throw std::runtime_error("Failed to open file");

		size_t bytesToWrite = data.size(); // <- lossy

		size_t totalWritten = 0;
		do {
			auto blockSize = std::min(bytesToWrite, size_t(32 * 1024 * 1024));
			DWORD bytesWritten;
			if (!::WriteFile(fileHandle, data.data() + totalWritten, blockSize, &bytesWritten, NULL)) {
				if (totalWritten == 0) {
					// Note: Only return error if the first WriteFile failed.
					throw std::runtime_error("Failed to write data");
				}
				break;
			}
			if (bytesWritten == 0)
				break;
			totalWritten += bytesWritten;
			bytesToWrite -= bytesWritten;
		} while (totalWritten < data.size());

		if (!::CloseHandle(fileHandle))
			throw std::runtime_error("Failed to close file");

#endif
	}
	catch(std::exception &e)
	{
		Syslogger(Syslogger::Err) << "Error on writing:" << e.what() << " for " << writePath ;
		return false;
	}
	if (createTmpCopy)
	{
		fserr code;
		fs::rename(writePath, originalPath, code);
		if (code)
		{
			Syslogger(Syslogger::Err) << "Failed to rename " << writePath << " -> " << originalPath << " :" << GetLastError();
			return false;
		}
	}
	return true;
}

bool FileInfo::Exists()
{
	fserr code;
	return fs::exists(m_impl->m_path, code);
}

size_t FileInfo::GetFileSize()
{
	if (!Exists())
		return 0;

	fserr code;
	return fs::file_size(m_impl->m_path, code);
}

void FileInfo::Remove()
{
	fserr code;
	if (fs::exists(m_impl->m_path, code))
		fs::remove(m_impl->m_path, code);
}

void FileInfo::Mkdirs()
{
	fserr code;
	fs::create_directories(m_impl->m_path, code);
}

StringVector FileInfo::GetDirFiles(bool sortByName)
{
	StringVector res;
	for(const fs::directory_entry& it : fs::directory_iterator(m_impl->m_path))
	{
		 const fs::path& p = it.path();
		 if (fs::is_regular_file(p))
			res.push_back( p.filename().u8string() );
	}
	if (sortByName)
		std::sort(res.begin(), res.end());
	return res;
}

TemporaryFile::~TemporaryFile()
{
	this->Remove();
}

std::string GetCWD()
{
	std::vector<char> cwd;
	std::string workingDir;
	do
	{
		cwd.resize(cwd.size() + 1024);
		errno = 0;
	} while (!getcwd(&cwd[0], cwd.size()) && errno == ERANGE);
	if (errno != 0 && errno != ERANGE)
	{
		workingDir = ".";
	}
	else
	{
		workingDir = cwd.data();
		if (workingDir.empty())
			workingDir = ".";
	}
	std::replace(workingDir.begin(), workingDir.end(), '\\', '/');
	if (*workingDir.rbegin() != '/')
		workingDir += '/';

	return workingDir;
}

void SetCWD(const std::string &cwd)
{
	chdir(cwd.c_str());
}

}

<commit_msg>Do not canonicalize path.<commit_after>/*
 * Copyright (C) 2017 Smirnov Vladimir mapron1@gmail.com
 * Source code licensed under the Apache License, Version 2.0 (the "License");
 * You may not use this file except in compliance with the License.
 * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 or in file COPYING-APACHE-2.0.txt
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.h
 */

#include "FileUtils.h"

#include "Compression.h"
#include "Syslogger.h"
#include "ThreadUtils.h"

#include <assert.h>
#include <stdio.h>
#include <algorithm>
#include <fstream>
#include <streambuf>

#ifdef HAS_BOOST
#include <boost/filesystem.hpp>
namespace fs = boost::filesystem;
#define u8string string
using fserr = boost::system::error_code;
#else
#include <experimental/filesystem>
namespace fs = std::experimental::filesystem;
using fserr = std::error_code;
#endif

#ifdef _MSC_VER
#define strtoull _strtoui64
#define getcwd _getcwd
#define PATH_MAX _MAX_PATH
#endif

#if defined( _WIN32)
#include <windows.h>
#include <io.h>
#include <share.h>
#include <direct.h>
#else
#include <unistd.h>
#include <errno.h>
inline int GetLastError() { return errno; }
#endif

namespace {
static const size_t CHUNK = 16384;
}

namespace Wuild {

class FileInfoPrivate
{
public:
	fs::path m_path;
};

std::string FileInfo::ToPlatformPath(std::string path)
{
#ifdef _WIN32
   std::replace(path.begin(), path.end(), '/', '\\');
   std::transform(path.begin(), path.end(), path.begin(), [](char c) { return ::tolower(c);});
#endif
   return path;
}

FileInfo::FileInfo(const FileInfo &rh)
	: m_impl(new FileInfoPrivate(*rh.m_impl))
{

}

FileInfo &FileInfo::operator =(const FileInfo &rh)
{
	m_impl.reset(new FileInfoPrivate(*rh.m_impl));
	return *this;
}

FileInfo::FileInfo(const std::string &filename)
	: m_impl(new FileInfoPrivate())
{
	m_impl->m_path = filename;
}

FileInfo::~FileInfo()
{

}

void FileInfo::SetPath(const std::string &path)
{
	m_impl->m_path = path;
}

std::string FileInfo::GetPath() const
{
	return m_impl->m_path.u8string();
}

std::string FileInfo::GetDir(bool ensureEndSlash) const
{
	auto ret = m_impl->m_path.parent_path().u8string();
	if (!ret.empty() && ensureEndSlash)
		ret += '/';
	return ret;
}

std::string FileInfo::GetFullname() const
{
	return m_impl->m_path.filename().u8string();
}

std::string FileInfo::GetNameWE() const
{
	const auto name = this->GetFullname();
	const auto dot = name.find('.');
	return name.substr(0, dot);
}

std::string FileInfo::GetFullExtension() const
{
	const auto name = this->GetFullname();
	const auto dot = name.find('.');
	return name.substr( dot );
}

std::string FileInfo::GetPlatformShortName() const
{
#ifdef _WIN32
	std::string result = GetPath();
	fserr code;
	result = fs::canonical(result, code).u8string();
	long length = 0;

	// First obtain the size needed by passing NULL and 0.
	length = GetShortPathNameA(result.c_str(), nullptr, 0);
	if (length == 0)
		return result;

	// Dynamically allocate the correct size
	// (terminating null char was included in length)
	std::vector<char> buffer(length + 1);

	// Now simply call again using same long path.
	length = GetShortPathNameA(result.c_str(), buffer.data(), length);
	if (length == 0)
		return result;

	return ToPlatformPath(std::string(buffer.data(), length));
#else
	return GetPath();
#endif
}

bool FileInfo::ReadCompressed(ByteArrayHolder &data, CompressionInfo compressionInfo)
{
	std::ifstream inFile;
	inFile.open(GetPath().c_str(), std::ios::binary | std::ios::in);
	if (!inFile)
		return false;

	try
	{
		ReadCompressedData(inFile, data, compressionInfo);
	}
	catch(std::exception &e)
	{
		Syslogger(Syslogger::Err) << "Error on reading:" << e.what() << " for " << GetPath();
		return false;
	}

	if (Syslogger::IsLogLevelEnabled(Syslogger::Debug))
		Syslogger() << "Compressed " << this->GetPath() << ": " << this->GetFileSize() << " -> " << data.size();

	return true;
}

bool FileInfo::WriteCompressed(const ByteArrayHolder & data, CompressionInfo compressionInfo, bool createTmpCopy)
{
	ByteArrayHolder uncompData;
	try
	{
		UncompressDataBuffer(data, uncompData, compressionInfo);
	}
	catch(std::exception &e)
	{
		Syslogger(Syslogger::Err) << "Error on uncompress:" << e.what() << " for " << GetPath();
		return false;
	}
	return this->WriteFile(uncompData, createTmpCopy);
}

bool FileInfo::ReadFile(ByteArrayHolder &data)
{
	FILE * f = fopen(GetPath().c_str(), "rb");
	if (!f)
		return false;

	ByteArray& dest = data.ref();

	unsigned char in[CHUNK];
	do {
		auto avail_in = fread(in, 1, CHUNK, f);
		if (!avail_in || ferror(f)) break;
		dest.insert(dest.end(), in, in + avail_in);
		if (feof(f)) break;

	} while (true);

	fclose(f);
	return true;
}

bool FileInfo::WriteFile(const ByteArrayHolder &data, bool createTmpCopy)
{
	const std::string originalPath = fs::absolute(m_impl->m_path).u8string();
	const std::string writePath = createTmpCopy ? originalPath + ".tmp" : originalPath;
	this->Remove();

	try
	{
#ifndef _WIN32
		std::ofstream outFile;
		outFile.open(writePath, std::ios::binary | std::ios::out);
		outFile.write((const char*)data.data(), data.size());
		outFile.close();
#else
		auto fileHandle = CreateFileA((LPTSTR) writePath.c_str(), // file name
							   GENERIC_WRITE,        // open for write
							   0,                    // do not share
							   NULL,                 // default security
							   CREATE_ALWAYS,        // overwrite existing
							   FILE_ATTRIBUTE_NORMAL,// normal file
							   NULL);                // no template
		if (fileHandle == INVALID_HANDLE_VALUE)
			throw std::runtime_error("Failed to open file");

		size_t bytesToWrite = data.size(); // <- lossy

		size_t totalWritten = 0;
		do {
			auto blockSize = std::min(bytesToWrite, size_t(32 * 1024 * 1024));
			DWORD bytesWritten;
			if (!::WriteFile(fileHandle, data.data() + totalWritten, blockSize, &bytesWritten, NULL)) {
				if (totalWritten == 0) {
					// Note: Only return error if the first WriteFile failed.
					throw std::runtime_error("Failed to write data");
				}
				break;
			}
			if (bytesWritten == 0)
				break;
			totalWritten += bytesWritten;
			bytesToWrite -= bytesWritten;
		} while (totalWritten < data.size());

		if (!::CloseHandle(fileHandle))
			throw std::runtime_error("Failed to close file");

#endif
	}
	catch(std::exception &e)
	{
		Syslogger(Syslogger::Err) << "Error on writing:" << e.what() << " for " << writePath ;
		return false;
	}
	if (createTmpCopy)
	{
		fserr code;
		fs::rename(writePath, originalPath, code);
		if (code)
		{
			Syslogger(Syslogger::Err) << "Failed to rename " << writePath << " -> " << originalPath << " :" << GetLastError();
			return false;
		}
	}
	return true;
}

bool FileInfo::Exists()
{
	fserr code;
	return fs::exists(m_impl->m_path, code);
}

size_t FileInfo::GetFileSize()
{
	if (!Exists())
		return 0;

	fserr code;
	return fs::file_size(m_impl->m_path, code);
}

void FileInfo::Remove()
{
	fserr code;
	if (fs::exists(m_impl->m_path, code))
		fs::remove(m_impl->m_path, code);
}

void FileInfo::Mkdirs()
{
	fserr code;
	fs::create_directories(m_impl->m_path, code);
}

StringVector FileInfo::GetDirFiles(bool sortByName)
{
	StringVector res;
	for(const fs::directory_entry& it : fs::directory_iterator(m_impl->m_path))
	{
		 const fs::path& p = it.path();
		 if (fs::is_regular_file(p))
			res.push_back( p.filename().u8string() );
	}
	if (sortByName)
		std::sort(res.begin(), res.end());
	return res;
}

TemporaryFile::~TemporaryFile()
{
	this->Remove();
}

std::string GetCWD()
{
	std::vector<char> cwd;
	std::string workingDir;
	do
	{
		cwd.resize(cwd.size() + 1024);
		errno = 0;
	} while (!getcwd(&cwd[0], cwd.size()) && errno == ERANGE);
	if (errno != 0 && errno != ERANGE)
	{
		workingDir = ".";
	}
	else
	{
		workingDir = cwd.data();
		if (workingDir.empty())
			workingDir = ".";
	}
	std::replace(workingDir.begin(), workingDir.end(), '\\', '/');
	if (*workingDir.rbegin() != '/')
		workingDir += '/';

	return workingDir;
}

void SetCWD(const std::string &cwd)
{
	chdir(cwd.c_str());
}

}

<|endoftext|>


<commit_before>/***************************************************************************
 *            benchmark_disks.cpp
 *
 *  Sat Aug 24 23:52:15 2002
 *  Copyright  2002  Roman Dementiev
 *  dementiev@mpi-sb.mpg.de
 ****************************************************************************/

#include "stxxl/io"
#include <cstdio>
#include <vector>
#include <iomanip>

#ifndef BOOST_MSVC
 #include <unistd.h>
#endif

#include "stxxl/bits/common/aligned_alloc.h"

using namespace stxxl;
#ifdef BLOCK_ALIGN
 #undef BLOCK_ALIGN
#endif

#define BLOCK_ALIGN  4096

//#define NOREAD

//#define DO_ONLY_READ

#define POLL_DELAY 1000

#define RAW_ACCESS

//#define WATCH_TIMES

#ifdef WATCH_TIMES
void watch_times(request_ptr reqs[], unsigned n, double * out)
{
    bool * finished = new bool[n];
    unsigned count = 0;
    unsigned i = 0;
    for (i = 0; i < n; i++)
        finished[i] = false;

    while (count != n)
    {
        usleep(POLL_DELAY);
        i = 0;
        for (i = 0; i < n; i++)
        {
            if (!finished[i])
                if (reqs[i]->poll())
                {
                    finished[i] = true;
                    out[i] = stxxl_timestamp();
                    count++;
                }
        }
    }
    delete [] finished;
}

void out_stat(double start, double end, double * times, unsigned n, const std::vector<std::string> & names)
{
    for (unsigned i = 0; i < n; i++)
    {
        std::cout << i << " " << names[i] << " took " <<
        100. * (times[i] - start) / (end - start) << " %" << std::endl;
    }
}
#endif

#define MB (1024 * 1024)
#define GB (1024 * 1024 * 1024)

int main(int argc, char * argv[])
{
    if (argc < 3) {
        std::cout << "Usage: " << argv[0] << " offset diskfile..." << std::endl;
        std::cout << "    offset is in GB" << std::endl;
        exit(0);
    }

    unsigned ndisks = 0;
    unsigned buffer_size = 256 * MB;
    unsigned buffer_size_int = buffer_size / sizeof(int);

    unsigned i = 0, j = 0;

    stxxl::int64 offset = stxxl::int64(GB) * stxxl::int64(atoi(argv[1]));
    std::vector<std::string> disks_arr;

    for (int i = 2; i < argc; i++)
    {
        std::cout << "Add disk: " << argv[i]
                  << std::endl;
        disks_arr.push_back(argv[i]);
    }
    ndisks = disks_arr.size();

    unsigned chunks = 32;
    request_ptr * reqs = new request_ptr [ndisks * chunks];
    file * * disks = new file *[ndisks];
    int * buffer = (int *)aligned_alloc<BLOCK_ALIGN>(buffer_size * ndisks);
#ifdef WATCH_TIMES
    double * r_finish_times = new double[ndisks];
    double * w_finish_times = new double[ndisks];
#endif

    int count = (70 * stxxl::int64(GB) - offset) / buffer_size;

    for (i = 0; i < ndisks * buffer_size_int; i++)
        buffer[i] = i;

    for (i = 0; i < ndisks; i++)
    {
#ifdef BOOST_MSVC
 #ifdef RAW_ACCESS
        disks[i] = new wincall_file(disks_arr[i],
                                    file::CREAT | file::RDWR | file::DIRECT, i);
 #else
        disks[i] = new wincall_file(disks_arr[i],
                                    file::CREAT | file::RDWR, i);
 #endif
#else
 #ifdef RAW_ACCESS
        disks[i] = new syscall_file(disks_arr[i],
                                    file::CREAT | file::RDWR | file::DIRECT, i);
 #else
        disks[i] = new syscall_file(disks_arr[i],
                                    file::CREAT | file::RDWR, i);
 #endif
#endif
    }

    try {
    while (count--)
    {
        std::cout << "Disk offset " << std::setw(5) << offset / MB << " MB: ";

        double begin = stxxl_timestamp(), end;

#ifndef DO_ONLY_READ
        for (i = 0; i < ndisks; i++)
        {
            for (j = 0; j < chunks; j++)
                reqs[i * chunks + j] =
                    disks[i]->awrite( buffer + buffer_size_int * i + buffer_size_int * j / chunks,
                                      offset + buffer_size * j / chunks,
                                      buffer_size / chunks,
                                      stxxl::default_completion_handler() );
        }

 #ifdef WATCH_TIMES
        watch_times(reqs, ndisks, w_finish_times);
 #else
        wait_all( reqs, ndisks * chunks );
 #endif

        end = stxxl_timestamp();

/*  std::cout << "WRITE\nDisks: " << ndisks
        <<" \nElapsed time: "<< end-begin
        << " \nThroughput: "<< int(1e-6*(buffer_size*ndisks)/(end-begin))
        << " Mb/s \nPer one disk:"
        << int(1e-6*(buffer_size)/(end-begin)) << " Mb/s"
        << std::endl;*/

 #ifdef WATCH_TIMES
        out_stat(begin, end, w_finish_times, ndisks, disks_arr);
 #endif
        std::cout << std::setw(2) << ndisks << " * " << std::setw(3) << int (1e-6 * (buffer_size) / (end - begin)) << " = " << std::setw(3) << int (1e-6 * (buffer_size * ndisks) / (end - begin)) << " MB/s write,";
#endif

#ifndef NOREAD
        begin = stxxl_timestamp();

        for (i = 0; i < ndisks; i++)
        {
            for (j = 0; j < chunks; j++)
                reqs[i * chunks + j] = disks[i]->aread(   buffer + buffer_size_int * i + buffer_size_int * j / chunks,
                                                          offset + buffer_size * j / chunks,
                                                          buffer_size / chunks,
                                                          stxxl::default_completion_handler() );
        }

 #ifdef WATCH_TIMES
        watch_times(reqs, ndisks, r_finish_times);
 #else
        wait_all( reqs, ndisks * chunks );
 #endif

        end = stxxl_timestamp();

/*  std::cout << "READ\nDisks: " << ndisks
        <<" \nElapsed time: "<< end-begin
        << " \nThroughput: "<< int(1e-6*(buffer_size*ndisks)/(end-begin))
        << " Mb/s \nPer one disk:"
        << int(1e-6*(buffer_size)/(end-begin)) << " Mb/s"
            << std::endl;*/

        std::cout << std::setw(2) << ndisks << " * " << std::setw(3) << int (1e-6 * (buffer_size) / (end - begin)) << " = " << std::setw(3) << int (1e-6 * (buffer_size * ndisks) / (end - begin)) << " MB/s read" << std::endl;
#else
        std::cout << std::endl;
#endif

#ifdef WATCH_TIMES
        out_stat(begin, end, r_finish_times, ndisks, disks_arr);
#endif
/*
   std::cout << "Checking..." <<std::endl;
   for(i=0;i<ndisks*buffer_size_int;i++)
   {
        if(buffer[i] != i)
        {
                int ibuf = i/buffer_size_int;
                int pos = i%buffer_size_int;
                i = (ibuf+1)*buffer_size_int; // jump to next

                std::cout << "Error on disk "<<ibuf<< " position"<< pos * sizeof(int) << std::endl;
        }
   } */

        offset += /* 4*stxxl::int64(GB); */ buffer_size;
    }
    }
    catch(const std::exception & ex)
    {
        std::cout << std::endl;
        STXXL_ERRMSG("Cought exception: " << ex.what());
    }

    delete [] reqs;
    delete [] disks;
    aligned_dealloc<BLOCK_ALIGN>(buffer);

#ifdef WATCH_TIMES
    delete [] r_finish_times;
    delete [] w_finish_times;
#endif

    return 0;
}
<commit_msg>increase disk benchmark details, add average<commit_after>/***************************************************************************
 *            benchmark_disks.cpp
 *
 *  Sat Aug 24 23:52:15 2002
 *  Copyright  2002  Roman Dementiev
 *  dementiev@mpi-sb.mpg.de
 ****************************************************************************/

/*
 example gnuplot command for the output of this program:
 (x-axis: disk offset in GB, y-axis: bandwidth in MB/s)

 plot \
        "disk.log" using ($3/1024):($16) w l title "read", \
        "disk.log" using ($3/1024):($9)  w l title "write"
 */

#include "stxxl/io"
#include <cstdio>
#include <vector>
#include <iomanip>

#ifndef BOOST_MSVC
 #include <unistd.h>
#endif

#include "stxxl/bits/common/aligned_alloc.h"

using namespace stxxl;
#ifdef BLOCK_ALIGN
 #undef BLOCK_ALIGN
#endif

#define BLOCK_ALIGN  4096

//#define NOREAD

//#define DO_ONLY_READ

#define POLL_DELAY 1000

#define RAW_ACCESS

//#define WATCH_TIMES

#ifdef WATCH_TIMES
void watch_times(request_ptr reqs[], unsigned n, double * out)
{
    bool * finished = new bool[n];
    unsigned count = 0;
    unsigned i = 0;
    for (i = 0; i < n; i++)
        finished[i] = false;

    while (count != n)
    {
        usleep(POLL_DELAY);
        i = 0;
        for (i = 0; i < n; i++)
        {
            if (!finished[i])
                if (reqs[i]->poll())
                {
                    finished[i] = true;
                    out[i] = stxxl_timestamp();
                    count++;
                }
        }
    }
    delete [] finished;
}

void out_stat(double start, double end, double * times, unsigned n, const std::vector<std::string> & names)
{
    for (unsigned i = 0; i < n; i++)
    {
        std::cout << i << " " << names[i] << " took " <<
        100. * (times[i] - start) / (end - start) << " %" << std::endl;
    }
}
#endif

#define MB (1024 * 1024)
#define GB (1024 * 1024 * 1024)

int main(int argc, char * argv[])
{
    if (argc < 3) {
        std::cout << "Usage: " << argv[0] << " offset diskfile..." << std::endl;
        std::cout << "    offset is in GB" << std::endl;
        exit(0);
    }

    unsigned ndisks = 0;
    unsigned buffer_size = 256 * MB;
    unsigned buffer_size_int = buffer_size / sizeof(int);
    double totaltimeread = 0, totaltimewrite = 0;
    stxxl::int64 totalsizeread = 0, totalsizewrite = 0;

    unsigned i = 0, j = 0;

    stxxl::int64 offset = stxxl::int64(GB) * stxxl::int64(atoi(argv[1]));
    std::vector<std::string> disks_arr;

    for (int i = 2; i < argc; i++)
    {
        std::cout << "# Add disk: " << argv[i] << std::endl;
        disks_arr.push_back(argv[i]);
    }
    ndisks = disks_arr.size();

    unsigned chunks = 32;
    request_ptr * reqs = new request_ptr [ndisks * chunks];
    file * * disks = new file *[ndisks];
    int * buffer = (int *)aligned_alloc<BLOCK_ALIGN>(buffer_size * ndisks);
#ifdef WATCH_TIMES
    double * r_finish_times = new double[ndisks];
    double * w_finish_times = new double[ndisks];
#endif

    int count = (70 * stxxl::int64(GB) - offset) / buffer_size;

    for (i = 0; i < ndisks * buffer_size_int; i++)
        buffer[i] = i;

    for (i = 0; i < ndisks; i++)
    {
#ifdef BOOST_MSVC
 #ifdef RAW_ACCESS
        disks[i] = new wincall_file(disks_arr[i],
                                    file::CREAT | file::RDWR | file::DIRECT, i);
 #else
        disks[i] = new wincall_file(disks_arr[i],
                                    file::CREAT | file::RDWR, i);
 #endif
#else
 #ifdef RAW_ACCESS
        disks[i] = new syscall_file(disks_arr[i],
                                    file::CREAT | file::RDWR | file::DIRECT, i);
 #else
        disks[i] = new syscall_file(disks_arr[i],
                                    file::CREAT | file::RDWR, i);
 #endif
#endif
    }

    std::cout << "# Buffer size: " << buffer_size << " bytes per disk" << std::endl;
    try {
    while (count--)
    {
        std::cout << "Disk offset " << std::setw(7) << offset / MB << " MB: " << std::fixed;

        double begin = stxxl_timestamp(), end;

#ifndef DO_ONLY_READ
        for (i = 0; i < ndisks; i++)
        {
            for (j = 0; j < chunks; j++)
                reqs[i * chunks + j] =
                    disks[i]->awrite( buffer + buffer_size_int * i + buffer_size_int * j / chunks,
                                      offset + buffer_size * j / chunks,
                                      buffer_size / chunks,
                                      stxxl::default_completion_handler() );
        }

 #ifdef WATCH_TIMES
        watch_times(reqs, ndisks, w_finish_times);
 #else
        wait_all( reqs, ndisks * chunks );
 #endif

        end = stxxl_timestamp();
        totalsizewrite += buffer_size;
        totaltimewrite += end - begin;

/*  std::cout << "WRITE\nDisks: " << ndisks
        <<" \nElapsed time: "<< end-begin
        << " \nThroughput: "<< int(1e-6*(buffer_size*ndisks)/(end-begin))
        << " Mb/s \nPer one disk:"
        << int(1e-6*(buffer_size)/(end-begin)) << " Mb/s"
        << std::endl;*/

 #ifdef WATCH_TIMES
        out_stat(begin, end, w_finish_times, ndisks, disks_arr);
 #endif
        std::cout << std::setw(2) << ndisks << " * "
            << std::setw(7) << std::setprecision(3) << (1e-6 * (buffer_size) / (end - begin)) << " = "
            << std::setw(7) << std::setprecision(3) << (1e-6 * (buffer_size * ndisks) / (end - begin)) << " MB/s write,";
#endif

#ifndef NOREAD
        begin = stxxl_timestamp();

        for (i = 0; i < ndisks; i++)
        {
            for (j = 0; j < chunks; j++)
                reqs[i * chunks + j] = disks[i]->aread(   buffer + buffer_size_int * i + buffer_size_int * j / chunks,
                                                          offset + buffer_size * j / chunks,
                                                          buffer_size / chunks,
                                                          stxxl::default_completion_handler() );
        }

 #ifdef WATCH_TIMES
        watch_times(reqs, ndisks, r_finish_times);
 #else
        wait_all( reqs, ndisks * chunks );
 #endif

        end = stxxl_timestamp();
        totalsizeread += buffer_size;
        totaltimeread += end - begin;

/*  std::cout << "READ\nDisks: " << ndisks
        <<" \nElapsed time: "<< end-begin
        << " \nThroughput: "<< int(1e-6*(buffer_size*ndisks)/(end-begin))
        << " Mb/s \nPer one disk:"
        << int(1e-6*(buffer_size)/(end-begin)) << " Mb/s"
            << std::endl;*/

        std::cout << std::setw(2) << ndisks << " * "
            << std::setw(7) << std::setprecision(3) << (1e-6 * (buffer_size) / (end - begin)) << " = "
            << std::setw(7) << std::setprecision(3) << (1e-6 * (buffer_size * ndisks) / (end - begin)) << " MB/s read" << std::endl;
#else
        std::cout << std::endl;
#endif

#ifdef WATCH_TIMES
        out_stat(begin, end, r_finish_times, ndisks, disks_arr);
#endif
/*
   std::cout << "Checking..." <<std::endl;
   for(i=0;i<ndisks*buffer_size_int;i++)
   {
        if(buffer[i] != i)
        {
                int ibuf = i/buffer_size_int;
                int pos = i%buffer_size_int;
                i = (ibuf+1)*buffer_size_int; // jump to next

                std::cout << "Error on disk "<<ibuf<< " position"<< pos * sizeof(int) << std::endl;
        }
   } */

        offset += /* 4*stxxl::int64(GB); */ buffer_size;
    }
    }
    catch(const std::exception & ex)
    {
        std::cout << std::endl;
        STXXL_ERRMSG(ex.what());
    }

    std::cout << "# Average over "<< std::setw(7) << totalsizewrite / MB << " MB: ";
    std::cout << std::setw(2) << ndisks << " * "
        << std::setw(7) << std::setprecision(3) << (1e-6 * (totalsizewrite) / totaltimewrite) << " = "
        << std::setw(7) << std::setprecision(3) << (1e-6 * (totalsizewrite * ndisks) / totaltimewrite) << " MB/s write,";
    std::cout << std::setw(2) << ndisks << " * "
        << std::setw(7) << std::setprecision(3) << (1e-6 * (totalsizeread) / totaltimeread) << " = "
        << std::setw(7) << std::setprecision(3) << (1e-6 * (totalsizeread * ndisks) / totaltimeread) << " MB/s read" << std::endl;

    delete [] reqs;
    delete [] disks;
    aligned_dealloc<BLOCK_ALIGN>(buffer);

#ifdef WATCH_TIMES
    delete [] r_finish_times;
    delete [] w_finish_times;
#endif

    return 0;
}
<|endoftext|>


<commit_before>// @(#)root/io:$Id$
// Author: Elvin Sindrilaru   19/05/2011

/*************************************************************************
 * Copyright (C) 1995-2011, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TFPBlock                                                             //
//                                                                      //
// This class represents the encapsulation of a block request.          //
// It contains the chunks to be prefetched and also serves as a         //
// container for the information read.                                  //
// These blocks are prefetch in a special reader thread by the          //
// TFilePrefetch class.                                                 //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TFPBlock.h"
#include "TStorage.h"
#include <cstdlib>

ClassImp(TFPBlock)

//__________________________________________________________________
TFPBlock::TFPBlock(Long64_t* offset, Int_t* length, Int_t nb)
{
   // Constructor.

   Int_t aux = 0;

   fNblock = nb;
   fPos = new Long64_t[nb];
   fLen = new Int_t[nb];

   for (Int_t i=0; i < nb; i++){
      fPos[i] = offset[i];
      fLen[i] = length[i];
      aux += length[i];
   }
   fFullSize = aux;
   fBuffer = new char[fFullSize];
}

//__________________________________________________________________
TFPBlock::~TFPBlock()
{
   // Destructor.

   delete[] fPos;
   delete[] fLen;
   delete[] fBuffer;
}

//__________________________________________________________________
Long64_t* TFPBlock::GetPos() const
{
   // Get pointer to the array of postions.

   return fPos;
}

//__________________________________________________________________
Int_t* TFPBlock::GetLen() const
{
   // Get pointer to the array of lengths.

   return fLen;
}

//__________________________________________________________________
Int_t TFPBlock::GetFullSize() const
{
   // Return size of the block.

   return fFullSize;
}

//__________________________________________________________________
Int_t TFPBlock::GetNoElem() const
{
   // Return number of elements in the block.

   return fNblock;
}

//__________________________________________________________________
Long64_t TFPBlock::GetPos(Int_t i) const
{
   // Get position of the element at index i.

   return fPos[i];
}

//__________________________________________________________________
Int_t TFPBlock::GetLen(Int_t i) const
{
  // Get length of the element at index i.

   return fLen[i];
}

//__________________________________________________________________
char* TFPBlock::GetBuffer() const
{
   // Get block buffer.

   return fBuffer;
}

//__________________________________________________________________
void TFPBlock::SetBuffer(char* buf)
{
   // Set block buffer.

   fBuffer = buf;
}

//__________________________________________________________________
void TFPBlock::ReallocBlock(Long64_t* offset, Int_t* length, Int_t nb)
{
   // Reallocate the block's buffer based on the length
   // of the elements it will contain.

   Int_t aux = 0;

   fNblock = nb;
   fPos = new Long64_t[nb];
   fLen = new Int_t[nb];

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

      fPos[i] = offset[i];
      fLen[i] = length[i];
      aux += fLen[i];
   }

   fBuffer = TStorage::ReAllocChar(fBuffer, aux, fFullSize);
   fFullSize = aux;
}
<commit_msg>From Elvin: fix memory leak<commit_after>// @(#)root/io:$Id$
// Author: Elvin Sindrilaru   19/05/2011

/*************************************************************************
 * Copyright (C) 1995-2011, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TFPBlock                                                             //
//                                                                      //
// This class represents the encapsulation of a block request.          //
// It contains the chunks to be prefetched and also serves as a         //
// container for the information read.                                  //
// These blocks are prefetch in a special reader thread by the          //
// TFilePrefetch class.                                                 //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TFPBlock.h"
#include "TStorage.h"
#include <cstdlib>

ClassImp(TFPBlock)

//__________________________________________________________________
TFPBlock::TFPBlock(Long64_t* offset, Int_t* length, Int_t nb)
{
   // Constructor.

   Int_t aux = 0;

   fNblock = nb;
   fPos = new Long64_t[nb];
   fLen = new Int_t[nb];

   for (Int_t i=0; i < nb; i++){
      fPos[i] = offset[i];
      fLen[i] = length[i];
      aux += length[i];
   }
   fFullSize = aux;
   fBuffer = new char[fFullSize];
}

//__________________________________________________________________
TFPBlock::~TFPBlock()
{
   // Destructor.

   delete[] fPos;
   delete[] fLen;
   delete[] fBuffer;
}

//__________________________________________________________________
Long64_t* TFPBlock::GetPos() const
{
   // Get pointer to the array of postions.

   return fPos;
}

//__________________________________________________________________
Int_t* TFPBlock::GetLen() const
{
   // Get pointer to the array of lengths.

   return fLen;
}

//__________________________________________________________________
Int_t TFPBlock::GetFullSize() const
{
   // Return size of the block.

   return fFullSize;
}

//__________________________________________________________________
Int_t TFPBlock::GetNoElem() const
{
   // Return number of elements in the block.

   return fNblock;
}

//__________________________________________________________________
Long64_t TFPBlock::GetPos(Int_t i) const
{
   // Get position of the element at index i.

   return fPos[i];
}

//__________________________________________________________________
Int_t TFPBlock::GetLen(Int_t i) const
{
  // Get length of the element at index i.

   return fLen[i];
}

//__________________________________________________________________
char* TFPBlock::GetBuffer() const
{
   // Get block buffer.

   return fBuffer;
}

//__________________________________________________________________
void TFPBlock::SetBuffer(char* buf)
{
   // Set block buffer.

   fBuffer = buf;
}

//__________________________________________________________________
void TFPBlock::ReallocBlock(Long64_t* offset, Int_t* length, Int_t nb)
{
   // Reallocate the block's buffer based on the length
   // of the elements it will contain.

   Int_t aux = 0;

   fPos = (Long64_t*) TStorage::ReAlloc(fPos, nb * sizeof(Long64_t), fNblock * sizeof(Long64_t));
   fLen = TStorage::ReAllocInt(fLen, nb, fNblock);
   fNblock = nb;

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

      fPos[i] = offset[i];
      fLen[i] = length[i];
      aux += fLen[i];
   }

   fBuffer = TStorage::ReAllocChar(fBuffer, aux, fFullSize);
   fFullSize = aux;
}
<|endoftext|>