ROOT logo
// $Id$
// Main authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007

/**************************************************************************
 * Copyright(c) 1998-2008, ALICE Experiment at CERN, all rights reserved. *
 * See http://aliceinfo.cern.ch/Offline/AliRoot/License.html for          *
 * full copyright notice.                                                 *
 **************************************************************************/

#include "AliEveTPCSector3D.h"
#include <EveDet/AliEveTPCSectorData.h>

#include <TEveTrans.h>

#include <TBuffer3D.h>
#include <TBuffer3DTypes.h>
#include <TVirtualPad.h>
#include <TVirtualViewer3D.h>

#include <TStyle.h>

//==============================================================================
//==============================================================================
// AliEveTPCSector3D
//==============================================================================

//______________________________________________________________________________
//
// Visualization of TPC raw-data in 3D.

ClassImp(AliEveTPCSector3D)

AliEveTPCSector3D::AliEveTPCSector3D(const Text_t* n, const Text_t* t) :
  AliEveTPCSectorViz(n, t),

  fBoxSet       (n, t),
  fPointSetArray(n, t),
  fPointFrac    (0.25),
  fPointSize    (3),

  fPointSetOn     (0),
  fPointSetMaxVal (0),

  fDriftVel  (1.07),
  fZStep     (250.0/900),
  fCutOnEta  (kFALSE),
  fEtaMin    (-1.5),
  fEtaMax    (1.5)

{
  // Constructor.

  fRnrFrame = kTRUE;
  ComputeBBox();
}

/******************************************************************************/

void AliEveTPCSector3D::SetRnrFrame(Bool_t rf)
{
  // Setter for fRnrFrame.

  if(fRnrFrame != rf) {
    fRnrFrame = rf;
    IncRTS();
  }
}

/******************************************************************************/

void AliEveTPCSector3D::ComputeBBox()
{
  // Compute bounding box containing whole sector.

  const AliEveTPCSectorData::SegmentInfo&  iSeg = AliEveTPCSectorData::GetInnSeg();
  const AliEveTPCSectorData::SegmentInfo& o2Seg = AliEveTPCSectorData::GetOut2Seg();

  BBoxInit();

  Float_t w = 0.5*o2Seg.GetNMaxPads()*o2Seg.GetPadWidth();
  fBBox[0] = -w;
  fBBox[1] =  w;
  fBBox[2] =  iSeg.GetRLow();
  fBBox[3] =  o2Seg.GetRLow() + o2Seg.GetNRows()*o2Seg.GetPadHeight();
  fBBox[4] =  0;
  fBBox[5] =  AliEveTPCSectorData::GetZLength();
  Float_t* b = fBoxSet.AssertBBox();
  for (Int_t i=0; i<6; ++i) { b[i] = fBBox[i]; }
}

void AliEveTPCSector3D::Paint(Option_t* /*option*/)
{
  // Paint object.

  if(fRnrSelf == kFALSE)
    return;

  TBuffer3D buffer(TBuffer3DTypes::kGeneric);

  SetMainColor(36);
  SetMainTransparency(100);

  // Section kCore
  buffer.fID           = this;
  buffer.fColor        = GetMainColor();
  buffer.fTransparency = GetMainTransparency();
  if (HasMainTrans()) RefMainTrans().SetBuffer3D(buffer);
  buffer.SetSectionsValid(TBuffer3D::kCore);

  Int_t reqSections = gPad->GetViewer3D()->AddObject(buffer);
  if (reqSections == TBuffer3D::kNone) {
    return;
  }

  Error("AliEveTPCSector3D::Paint", "only direct OpenGL rendering supported.");
  return;
}

/******************************************************************************/

void AliEveTPCSector3D::LoadPadrow(AliEveTPCSectorData::RowIterator& iter,
                                   Float_t xs, Float_t ys,
                                   Float_t pw, Float_t ph)
{
  // Load data of one padrow. Fill internal boxset and pointset objects.

  Short_t pad, time, val;
  Float_t x0, z0;
  Float_t ym = ys + 0.5*ph;
  Float_t zs = fZStep/fDriftVel;
  Float_t eta, x1, y1, z1, x, y, z, c, s, zL;

  while (iter.NextPad())
  {
    pad = iter.TEvePad();
    while (iter.Next())
    {
      time = iter.Time();
      val  = iter.Signal();

      if (val <= fThreshold || time < fMinTime || time > fMaxTime)
	continue;

      if (fCutOnEta)
      {

        x1 = xs + (pad+0.5)*pw;
        y1 = ym;
        z1 = (time+0.5)*zs;

        c = TMath::Cos((fSectorID + 0.5)*20*TMath::Pi()/180 - TMath::PiOver2());
        s = TMath::Sin((fSectorID + 0.5)*20*TMath::Pi()/180 - TMath::PiOver2());
        zL = AliEveTPCSectorData::GetZLength();

        if (fSectorID < 18)
        {
          x = -c*x1-s*y1;
          y = -s*x1+c*y1;
          z = -z1+zL;
        } 
        else
        {
          x = c*x1+s*y1;
          y = -s*x1+c*y1;
          z = z1-zL;
        }

        eta = -TMath::Log(TMath::Tan(0.5*TMath::ACos(z/TMath::Sqrt(x*x + y*y + z*z))));

        if(!(eta < fEtaMax && eta > fEtaMin) && !(-eta < fEtaMax && -eta > fEtaMin))
	  continue;

      }

      if (fPointSetOn && val <= fPointSetMaxVal)
      {
	fPointSetArray.Fill(xs + (pad+0.5)*pw, ym, (time+0.5)*zs, val);
      }
      else
      {
	x0 = xs + pad*pw;
	z0 = time*zs;
	fBoxSet.AddBox(x0, ys, z0, pw, ph, zs);
        fBoxSet.DigitColor(ColorFromArray(val));
      }
    }
  }
}

void AliEveTPCSector3D::UpdateBoxesAndPoints()
{
  // Populate BoxSet and PointSet with digit information.

  // printf("AliEveTPCSector3D update boxes\n");

  fBoxSet.Reset(TEveBoxSet::kBT_AABox, kTRUE, 16384);
  // Brutally delete sub-pointsets so that destruction via TEveManager is
  // avoided. This only works because fPointSetArray is never published.
  for (Int_t i = 0; i < fPointSetArray.GetNBins(); ++i)
    delete fPointSetArray.GetBin(i);
  fPointSetArray.RemoveElementsLocal();

  AliEveTPCSectorData* data = GetSectorData();
  if (data != 0) {
    Bool_t isOn[3];
    isOn[0] = fRnrInn;
    isOn[1] = fRnrOut1;
    isOn[2] = fRnrOut2;

    SetupColorArray();
    SetupPointSetArray();

    // Loop over 3 main segments
    for (Int_t sId = 0; sId <= 2; ++sId)
    {
      if (isOn[sId] == kFALSE)
        continue;
      const AliEveTPCSectorData::SegmentInfo& sInfo = AliEveTPCSectorData::GetSeg(sId);
      Float_t sy = sInfo.GetRLow();
      for (Int_t row=sInfo.GetFirstRow(); row<=sInfo.GetLastRow(); ++row)
      {
        AliEveTPCSectorData::RowIterator i = data->MakeRowIterator(row);
        Float_t sx = -0.5*AliEveTPCSectorData::GetNPadsInRow(row)*sInfo.GetPadWidth();
        LoadPadrow(i, sx, sy, sInfo.GetPadWidth(), sInfo.GetPadHeight());
        sy += sInfo.GetPadHeight();
      }
    }

    fBoxSet.RefitPlex();
    if (fPointSetOn)
      fPointSetArray.CloseBins();
  }
}

void AliEveTPCSector3D::SetupPointSetArray()
{
  // Setup fPointSetArray for current settings.

  Int_t nBins = (Int_t) TMath::Nint(fPointFrac*gStyle->GetNumberOfColors());
  if (nBins > 0) {
    fPointSetOn = kTRUE;
    fPointSetMaxVal = fThreshold + (Int_t) TMath::Nint(fPointFrac*(fMaxVal - fThreshold));
    // printf("SetupPointSetArray frac=%f nbins=%d psmv=%d (%d,%d)\n", fPointFrac, nBins, fPointSetMaxVal, fThreshold, fMaxVal);
    fPointSetArray.InitBins("", nBins, fThreshold, fPointSetMaxVal);
    for (Int_t b=0; b<nBins; ++b) {
      fPointSetArray.GetBin(b)->SetMarkerColor(gStyle->GetColorPalette(b));
    }
  } else {
    fPointSetOn = kFALSE;
  }
}
 AliEveTPCSector3D.cxx:1
 AliEveTPCSector3D.cxx:2
 AliEveTPCSector3D.cxx:3
 AliEveTPCSector3D.cxx:4
 AliEveTPCSector3D.cxx:5
 AliEveTPCSector3D.cxx:6
 AliEveTPCSector3D.cxx:7
 AliEveTPCSector3D.cxx:8
 AliEveTPCSector3D.cxx:9
 AliEveTPCSector3D.cxx:10
 AliEveTPCSector3D.cxx:11
 AliEveTPCSector3D.cxx:12
 AliEveTPCSector3D.cxx:13
 AliEveTPCSector3D.cxx:14
 AliEveTPCSector3D.cxx:15
 AliEveTPCSector3D.cxx:16
 AliEveTPCSector3D.cxx:17
 AliEveTPCSector3D.cxx:18
 AliEveTPCSector3D.cxx:19
 AliEveTPCSector3D.cxx:20
 AliEveTPCSector3D.cxx:21
 AliEveTPCSector3D.cxx:22
 AliEveTPCSector3D.cxx:23
 AliEveTPCSector3D.cxx:24
 AliEveTPCSector3D.cxx:25
 AliEveTPCSector3D.cxx:26
 AliEveTPCSector3D.cxx:27
 AliEveTPCSector3D.cxx:28
 AliEveTPCSector3D.cxx:29
 AliEveTPCSector3D.cxx:30
 AliEveTPCSector3D.cxx:31
 AliEveTPCSector3D.cxx:32
 AliEveTPCSector3D.cxx:33
 AliEveTPCSector3D.cxx:34
 AliEveTPCSector3D.cxx:35
 AliEveTPCSector3D.cxx:36
 AliEveTPCSector3D.cxx:37
 AliEveTPCSector3D.cxx:38
 AliEveTPCSector3D.cxx:39
 AliEveTPCSector3D.cxx:40
 AliEveTPCSector3D.cxx:41
 AliEveTPCSector3D.cxx:42
 AliEveTPCSector3D.cxx:43
 AliEveTPCSector3D.cxx:44
 AliEveTPCSector3D.cxx:45
 AliEveTPCSector3D.cxx:46
 AliEveTPCSector3D.cxx:47
 AliEveTPCSector3D.cxx:48
 AliEveTPCSector3D.cxx:49
 AliEveTPCSector3D.cxx:50
 AliEveTPCSector3D.cxx:51
 AliEveTPCSector3D.cxx:52
 AliEveTPCSector3D.cxx:53
 AliEveTPCSector3D.cxx:54
 AliEveTPCSector3D.cxx:55
 AliEveTPCSector3D.cxx:56
 AliEveTPCSector3D.cxx:57
 AliEveTPCSector3D.cxx:58
 AliEveTPCSector3D.cxx:59
 AliEveTPCSector3D.cxx:60
 AliEveTPCSector3D.cxx:61
 AliEveTPCSector3D.cxx:62
 AliEveTPCSector3D.cxx:63
 AliEveTPCSector3D.cxx:64
 AliEveTPCSector3D.cxx:65
 AliEveTPCSector3D.cxx:66
 AliEveTPCSector3D.cxx:67
 AliEveTPCSector3D.cxx:68
 AliEveTPCSector3D.cxx:69
 AliEveTPCSector3D.cxx:70
 AliEveTPCSector3D.cxx:71
 AliEveTPCSector3D.cxx:72
 AliEveTPCSector3D.cxx:73
 AliEveTPCSector3D.cxx:74
 AliEveTPCSector3D.cxx:75
 AliEveTPCSector3D.cxx:76
 AliEveTPCSector3D.cxx:77
 AliEveTPCSector3D.cxx:78
 AliEveTPCSector3D.cxx:79
 AliEveTPCSector3D.cxx:80
 AliEveTPCSector3D.cxx:81
 AliEveTPCSector3D.cxx:82
 AliEveTPCSector3D.cxx:83
 AliEveTPCSector3D.cxx:84
 AliEveTPCSector3D.cxx:85
 AliEveTPCSector3D.cxx:86
 AliEveTPCSector3D.cxx:87
 AliEveTPCSector3D.cxx:88
 AliEveTPCSector3D.cxx:89
 AliEveTPCSector3D.cxx:90
 AliEveTPCSector3D.cxx:91
 AliEveTPCSector3D.cxx:92
 AliEveTPCSector3D.cxx:93
 AliEveTPCSector3D.cxx:94
 AliEveTPCSector3D.cxx:95
 AliEveTPCSector3D.cxx:96
 AliEveTPCSector3D.cxx:97
 AliEveTPCSector3D.cxx:98
 AliEveTPCSector3D.cxx:99
 AliEveTPCSector3D.cxx:100
 AliEveTPCSector3D.cxx:101
 AliEveTPCSector3D.cxx:102
 AliEveTPCSector3D.cxx:103
 AliEveTPCSector3D.cxx:104
 AliEveTPCSector3D.cxx:105
 AliEveTPCSector3D.cxx:106
 AliEveTPCSector3D.cxx:107
 AliEveTPCSector3D.cxx:108
 AliEveTPCSector3D.cxx:109
 AliEveTPCSector3D.cxx:110
 AliEveTPCSector3D.cxx:111
 AliEveTPCSector3D.cxx:112
 AliEveTPCSector3D.cxx:113
 AliEveTPCSector3D.cxx:114
 AliEveTPCSector3D.cxx:115
 AliEveTPCSector3D.cxx:116
 AliEveTPCSector3D.cxx:117
 AliEveTPCSector3D.cxx:118
 AliEveTPCSector3D.cxx:119
 AliEveTPCSector3D.cxx:120
 AliEveTPCSector3D.cxx:121
 AliEveTPCSector3D.cxx:122
 AliEveTPCSector3D.cxx:123
 AliEveTPCSector3D.cxx:124
 AliEveTPCSector3D.cxx:125
 AliEveTPCSector3D.cxx:126
 AliEveTPCSector3D.cxx:127
 AliEveTPCSector3D.cxx:128
 AliEveTPCSector3D.cxx:129
 AliEveTPCSector3D.cxx:130
 AliEveTPCSector3D.cxx:131
 AliEveTPCSector3D.cxx:132
 AliEveTPCSector3D.cxx:133
 AliEveTPCSector3D.cxx:134
 AliEveTPCSector3D.cxx:135
 AliEveTPCSector3D.cxx:136
 AliEveTPCSector3D.cxx:137
 AliEveTPCSector3D.cxx:138
 AliEveTPCSector3D.cxx:139
 AliEveTPCSector3D.cxx:140
 AliEveTPCSector3D.cxx:141
 AliEveTPCSector3D.cxx:142
 AliEveTPCSector3D.cxx:143
 AliEveTPCSector3D.cxx:144
 AliEveTPCSector3D.cxx:145
 AliEveTPCSector3D.cxx:146
 AliEveTPCSector3D.cxx:147
 AliEveTPCSector3D.cxx:148
 AliEveTPCSector3D.cxx:149
 AliEveTPCSector3D.cxx:150
 AliEveTPCSector3D.cxx:151
 AliEveTPCSector3D.cxx:152
 AliEveTPCSector3D.cxx:153
 AliEveTPCSector3D.cxx:154
 AliEveTPCSector3D.cxx:155
 AliEveTPCSector3D.cxx:156
 AliEveTPCSector3D.cxx:157
 AliEveTPCSector3D.cxx:158
 AliEveTPCSector3D.cxx:159
 AliEveTPCSector3D.cxx:160
 AliEveTPCSector3D.cxx:161
 AliEveTPCSector3D.cxx:162
 AliEveTPCSector3D.cxx:163
 AliEveTPCSector3D.cxx:164
 AliEveTPCSector3D.cxx:165
 AliEveTPCSector3D.cxx:166
 AliEveTPCSector3D.cxx:167
 AliEveTPCSector3D.cxx:168
 AliEveTPCSector3D.cxx:169
 AliEveTPCSector3D.cxx:170
 AliEveTPCSector3D.cxx:171
 AliEveTPCSector3D.cxx:172
 AliEveTPCSector3D.cxx:173
 AliEveTPCSector3D.cxx:174
 AliEveTPCSector3D.cxx:175
 AliEveTPCSector3D.cxx:176
 AliEveTPCSector3D.cxx:177
 AliEveTPCSector3D.cxx:178
 AliEveTPCSector3D.cxx:179
 AliEveTPCSector3D.cxx:180
 AliEveTPCSector3D.cxx:181
 AliEveTPCSector3D.cxx:182
 AliEveTPCSector3D.cxx:183
 AliEveTPCSector3D.cxx:184
 AliEveTPCSector3D.cxx:185
 AliEveTPCSector3D.cxx:186
 AliEveTPCSector3D.cxx:187
 AliEveTPCSector3D.cxx:188
 AliEveTPCSector3D.cxx:189
 AliEveTPCSector3D.cxx:190
 AliEveTPCSector3D.cxx:191
 AliEveTPCSector3D.cxx:192
 AliEveTPCSector3D.cxx:193
 AliEveTPCSector3D.cxx:194
 AliEveTPCSector3D.cxx:195
 AliEveTPCSector3D.cxx:196
 AliEveTPCSector3D.cxx:197
 AliEveTPCSector3D.cxx:198
 AliEveTPCSector3D.cxx:199
 AliEveTPCSector3D.cxx:200
 AliEveTPCSector3D.cxx:201
 AliEveTPCSector3D.cxx:202
 AliEveTPCSector3D.cxx:203
 AliEveTPCSector3D.cxx:204
 AliEveTPCSector3D.cxx:205
 AliEveTPCSector3D.cxx:206
 AliEveTPCSector3D.cxx:207
 AliEveTPCSector3D.cxx:208
 AliEveTPCSector3D.cxx:209
 AliEveTPCSector3D.cxx:210
 AliEveTPCSector3D.cxx:211
 AliEveTPCSector3D.cxx:212
 AliEveTPCSector3D.cxx:213
 AliEveTPCSector3D.cxx:214
 AliEveTPCSector3D.cxx:215
 AliEveTPCSector3D.cxx:216
 AliEveTPCSector3D.cxx:217
 AliEveTPCSector3D.cxx:218
 AliEveTPCSector3D.cxx:219
 AliEveTPCSector3D.cxx:220
 AliEveTPCSector3D.cxx:221
 AliEveTPCSector3D.cxx:222
 AliEveTPCSector3D.cxx:223
 AliEveTPCSector3D.cxx:224
 AliEveTPCSector3D.cxx:225
 AliEveTPCSector3D.cxx:226
 AliEveTPCSector3D.cxx:227
 AliEveTPCSector3D.cxx:228
 AliEveTPCSector3D.cxx:229
 AliEveTPCSector3D.cxx:230
 AliEveTPCSector3D.cxx:231
 AliEveTPCSector3D.cxx:232
 AliEveTPCSector3D.cxx:233
 AliEveTPCSector3D.cxx:234
 AliEveTPCSector3D.cxx:235
 AliEveTPCSector3D.cxx:236
 AliEveTPCSector3D.cxx:237
 AliEveTPCSector3D.cxx:238
 AliEveTPCSector3D.cxx:239
 AliEveTPCSector3D.cxx:240
 AliEveTPCSector3D.cxx:241
 AliEveTPCSector3D.cxx:242
 AliEveTPCSector3D.cxx:243
 AliEveTPCSector3D.cxx:244
 AliEveTPCSector3D.cxx:245
 AliEveTPCSector3D.cxx:246
 AliEveTPCSector3D.cxx:247
 AliEveTPCSector3D.cxx:248
 AliEveTPCSector3D.cxx:249
 AliEveTPCSector3D.cxx:250
 AliEveTPCSector3D.cxx:251