/*
 * RefitTrackAction.h
 *
 *  Created on: 10/may/2010
 *      Author: N. Mori
 */

#ifndef REFITTRACKACTION_H_
#define REFITTRACKACTION_H_

#include "../CollectionAction/CollectionAction.h"
#include <TRandom3.h>

/*! @brief Track refitting.
 *
 * This action refits the TRK track using only level 2 data. This means that it will use the same
 * clusters which are associated to the track, with the possibility to mask or shift some of them.
 * If a refit fails the event will not be discarded (since this is not a cut) but chi2 will be negative,
 * and the event will be subsequently discarded by an eventual TrkPhSinCut.
 * This action can be used also before TrkPhSinCut, since it checks for the existence of at least
 * one track before refitting. The refitted track is always the first "physical" track; the ordering
 * criterion can be set using #SetSortingMethod(). If, instead, this action is placed after a TrkPhsinCut
 * it is not necessary to set this parameter, since the value used for TrkPhSinCut will be automatically
 * used (of course, it can be used as well if a different ordering may be needed).
 * Before fitting, the track parameters (measured impact positions and "good" flags) are reset to the
 * original values. This means that if two or more RefitTrackAction objects are used, each of them will
 * try to refit the original track of the current event (applying its own mask and spreads), regardless of
 * what was obtained with previous refits.
 * For a complete reprocess and fit use #ReprocessTrackAction.
 */
class RefitTrackAction: public CollectionAction {
public:

  /*! @brief Constructor
   *
   * @param actionName The action's name.
   * @param spreadX The width of the gaussian spread applied to all the X view coordinates, in cm.
   * @param spreadY The width of the gaussian spread applied to all the Y view coordinates, in cm.
   * @param maskedViews The excluded views. 0 means that all the views will be used, while #T6X means that the
   *                    X view of the last tracker plane will be ignored. For other combinations, sum up the values
   *                    defined in #TRKLAYERS: T1X + T1Y will exclude the whole first plane, for example.
   * @param trkParamsFile The file containing the tracker alignment parameters to be used. Default value corresponds to
   *                      the values contained in the official software calibration directory.
   */
  RefitTrackAction(const char *actionName, float spreadX = 0., float spreadY = 0., int maskedViews = 0,
      TString trkParamsFile = "") :
    CollectionAction(actionName), _spreadX(spreadX), _spreadY(spreadY), _maskedViews(maskedViews), _trkParamsFile(
        trkParamsFile), _sortingMethod(NULL) {

  }

  /*! @brief Destructor. */
  ~RefitTrackAction() {
  }

  /* @brief The refitting procedure.
   *
   * This will refit the tracker track introducing the mask and spreads defined in the constructor.
   *
   * @param  event The event to analyze.
   */
  void OnGood(PamLevel2 *event);

  /*! @brief The finalization procedure. */
  void Finalize() {

  }

  /*! @brief Sets the track sorting criterion.
   *
   * The action refits the first track, which is the one obtained with PamLevel2::GetTrack(0). This method can
   * be used to set the sorting criterion used to determine which track is the first.
   *
   * @param sortingMethod The sorting method. Format has to be compatible with the argument of PamLevel2::SetSortingMethod.
   */
  void SetSortingMethod(const char *sortingMethod) {
    _sortingMethod = sortingMethod;
  }

private:

  float _spreadX, _spreadY;
  int _maskedViews;

  static TRandom3 *_r3;
  static long int _currEvent;

  static float _xmBackup[], _ymBackup[];
  static int _layerXBackup[], _layerYBackup[];

  TString _trkParamsFile;
  static TString _currTrkParamsFile;

  const char *_sortingMethod;
};

#endif /* REFITTRACKACTION_H_ */
