ROOT logo
/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/* $Id$ */
//-------------------------------------------
// Class : AliVZEROTriggerMask
//
// Fill up the trigger mask word.
//

#include <Riostream.h>
#include <TGeoManager.h>
#include <TGeoMatrix.h>
#include <TGeoPhysicalNode.h>
#include <TF1.h>
#include <TMath.h>

#include <AliGeomManager.h>
#include "AliLog.h"
#include "AliVZEROTriggerMask.h"
#include "AliVZEROConst.h"
#include "AliVZEROCalibData.h"
#include "AliESDVZERO.h"
#include "AliVZEROReconstructor.h"

//______________________________________________________________________
ClassImp(AliVZEROTriggerMask)

//______________________________________________________________________

AliVZEROTriggerMask::AliVZEROTriggerMask()
  :TObject(),
   fV0ADist(0),
   fV0CDist(0),
   fRecoParam(NULL)
{
  // Default constructor
  //
  Float_t zV0A = TMath::Abs(GetZPosition("VZERO/V0A"));
  Float_t zV0C = TMath::Abs(GetZPosition("VZERO/V0C"));

  // distance in time units from nominal vertex to V0
  fV0ADist = zV0A/TMath::Ccgs()*1e9;
  fV0CDist = zV0C/TMath::Ccgs()*1e9;
}

//________________________________________________________________________________
Double_t AliVZEROTriggerMask::GetZPosition(const char* symname){
// Get the global z coordinate of the given V0 alignable volume
//
  Double_t *tr;
  TGeoPNEntry *pne = gGeoManager->GetAlignableEntry(symname);
  if (!pne) {
    AliFatalClass(Form("TGeoPNEntry with symbolic name %s does not exist!",symname));
    return 0;
  }

  TGeoPhysicalNode *pnode = pne->GetPhysicalNode();
  if(pnode){
          TGeoHMatrix* hm = pnode->GetMatrix();
           tr = hm->GetTranslation();
  }else{
          const char* path = pne->GetTitle();
          if(!gGeoManager->cd(path)){
                  AliFatalClass(Form("Volume path %s not valid!",path));
                  return 0;
          }
         tr = gGeoManager->GetCurrentMatrix()->GetTranslation();
  }
  return tr[2];

}

//________________________________________________________________________________


void AliVZEROTriggerMask::FillMasks(AliESDVZERO *esdV0,
				    AliVZEROCalibData *cal,
				    TF1 *slewing)
{
  // Fill up the trigger mask word
  // using the TDC data (already corrected for
  // slewing and misalignment between channels)

  esdV0->SetBit(AliESDVZERO::kTriggerBitsFilled,kTRUE);
  esdV0->SetBit(AliESDVZERO::kDecisionFilled,kTRUE);

  const Float_t p1 = 2.50; // photostatistics term in the time resolution
  const Float_t p2 = 3.00; // slewing related term in the time resolution

  // loop over vzero channels
  Float_t timeAW = 0,timeCW = 0;
  Float_t weightA = 0,weightC = 0;
  Int_t ntimeA = 0, ntimeC = 0;
  Double_t timesA[32], timesC[32];
  Double_t wA[32],wC[32];
  Int_t indA[32], indC[32];
  for (Int_t i = 0; i < 64; ++i) {
    Float_t adc = esdV0->GetAdc(i);
    if (adc > GetRecoParam()->GetAdcThresHold()) {
      Float_t tdc = esdV0->GetTime(i);
      if (tdc > (AliVZEROReconstructor::kInvalidTime + 1e-6)) {
	Float_t nphe = adc*kChargePerADC/(cal->GetGain(i)*TMath::Qe());
	Float_t timeErr = TMath::Sqrt(kIntTimeRes*kIntTimeRes+
				      p1*p1/nphe+
				      p2*p2*(slewing->GetParameter(0)*slewing->GetParameter(1))*(slewing->GetParameter(0)*slewing->GetParameter(1))*
				      TMath::Power(adc/cal->GetCalibDiscriThr(i,kTRUE),2.*(slewing->GetParameter(1)-1.))/
				      (cal->GetCalibDiscriThr(i,kTRUE)*cal->GetCalibDiscriThr(i,kTRUE)));

	if (i < 32) { // in V0C
	  timesC[ntimeC] = tdc;
	  wC[ntimeC] = 1.0/(timeErr*timeErr);
	  indC[ntimeC] = i;
	  ntimeC++;
	  timeCW += tdc/(timeErr*timeErr);
	  weightC += 1.0/(timeErr*timeErr);
	}
	else { // in V0A
	  timesA[ntimeA] = tdc;
	  wA[ntimeA] = 1.0/(timeErr*timeErr);
	  indA[ntimeA] = i - 32;
	  ntimeA++;
	  timeAW += tdc/(timeErr*timeErr);
	  weightA += 1.0/(timeErr*timeErr);
	}
      }
    }
  } // end of loop over channels

  if (weightA > 0) timeAW = timeAW/weightA;
  else timeAW = AliVZEROReconstructor::kInvalidTime;

  if (weightC > 0) timeCW = timeCW/weightC;
  else timeCW = AliVZEROReconstructor::kInvalidTime;

  esdV0->SetBit(AliESDVZERO::kRobustMeanTime,kTRUE);

  Double_t medianTimeA = AliVZEROReconstructor::kInvalidTime;
  if (ntimeA > 0) medianTimeA = TMath::Median(ntimeA,timesA,wA);
  Double_t medianTimeC = AliVZEROReconstructor::kInvalidTime;
  if (ntimeC > 0) medianTimeC = TMath::Median(ntimeC,timesC,wC);

  Float_t robTimeAW = 0,robTimeCW = 0;
  Float_t robWeightA = 0,robWeightC = 0;
  Int_t nrobTimeA = 0, nrobTimeC = 0;
  Int_t robIndA[32], robIndC[32];
  for(Int_t i = 0; i < ntimeA; ++i) {
    AliDebug(1,Form("ChannelsAResiduals %f %f %d",timesA[i]-medianTimeA,1./TMath::Sqrt(wA[i]),ntimeA));
    if (TMath::Abs(timesA[i]-medianTimeA) < GetRecoParam()->GetMaxResid()/TMath::Sqrt(wA[i])) {
      robIndA[nrobTimeA] = indA[i];
      nrobTimeA++;
      robTimeAW += timesA[i]*wA[i];
      robWeightA += wA[i];
    }
  }
  for(Int_t i = 0; i < ntimeC; ++i) {
    AliDebug(1,Form("ChannelsCResiduals %f %f %d",timesC[i]-medianTimeC,1./TMath::Sqrt(wC[i]),ntimeC));
    if (TMath::Abs(timesC[i]-medianTimeC) < GetRecoParam()->GetMaxResid()/TMath::Sqrt(wC[i])) {
      robIndC[nrobTimeC] = indC[i];
      nrobTimeC++;
      robTimeCW += timesC[i]*wC[i];
      robWeightC += wC[i];
    }
  }

  if (robWeightA > 0) robTimeAW = robTimeAW/robWeightA;
  else robTimeAW = AliVZEROReconstructor::kInvalidTime;

  if (robWeightC > 0) robTimeCW = robTimeCW/robWeightC;
  else robTimeCW = AliVZEROReconstructor::kInvalidTime;

  AliDebug(1,Form("V0timesA %f %f %f %f %d",timeAW,(weightA > 0) ? (1./TMath::Sqrt(weightA)) : 0,
		  medianTimeA,robTimeAW,ntimeA));
  AliDebug(1,Form("V0timesC %f %f %f %f %d",timeCW,(weightC > 0) ? (1./TMath::Sqrt(weightC)) : 0,
		  medianTimeC,robTimeCW,ntimeC));

  esdV0->SetV0ATime(robTimeAW);
  esdV0->SetV0CTime(robTimeCW);
  esdV0->SetV0ATimeError((robWeightA > 0) ? (1./TMath::Sqrt(robWeightA)) : 0);
  esdV0->SetV0CTimeError((robWeightC > 0) ? (1./TMath::Sqrt(robWeightC)) : 0);

  esdV0->SetV0ADecision(AliESDVZERO::kV0Empty);
  esdV0->SetV0CDecision(AliESDVZERO::kV0Empty);

  if (robTimeAW > (fV0ADist + GetRecoParam()->GetTimeWindowBBALow()) &&
      robTimeAW < (fV0ADist + GetRecoParam()->GetTimeWindowBBAUp())) 
    esdV0->SetV0ADecision(AliESDVZERO::kV0BB);
  else if (robTimeAW > (-fV0ADist + GetRecoParam()->GetTimeWindowBGALow()) &&
	   robTimeAW < (-fV0ADist + GetRecoParam()->GetTimeWindowBGAUp()))
    esdV0->SetV0ADecision(AliESDVZERO::kV0BG);
  else if (robTimeAW > (AliVZEROReconstructor::kInvalidTime + 1e-6))
    esdV0->SetV0ADecision(AliESDVZERO::kV0Fake);

  if (robTimeCW > (fV0CDist + GetRecoParam()->GetTimeWindowBBCLow()) &&
      robTimeCW < (fV0CDist + GetRecoParam()->GetTimeWindowBBCUp())) 
    esdV0->SetV0CDecision(AliESDVZERO::kV0BB);
  else if (robTimeCW > (-fV0CDist + GetRecoParam()->GetTimeWindowBGCLow()) &&
	   robTimeCW < (-fV0CDist + GetRecoParam()->GetTimeWindowBGCUp()))
    esdV0->SetV0CDecision(AliESDVZERO::kV0BG);
  else if (robTimeCW > (AliVZEROReconstructor::kInvalidTime + 1e-6))
    esdV0->SetV0CDecision(AliESDVZERO::kV0Fake);

  UInt_t aBBtriggerV0A = 0; // bit mask for Beam-Beam trigger in V0A
  UInt_t aBGtriggerV0A = 0; // bit mask for Beam-Gas trigger in V0A
  UInt_t aBBtriggerV0C = 0; // bit mask for Beam-Beam trigger in V0C
  UInt_t aBGtriggerV0C = 0; // bit mask for Beam-Gas trigger in V0C

  for(Int_t i = 0; i < nrobTimeA; ++i) {
    if (esdV0->GetV0ADecision() == AliESDVZERO::kV0BB)
      aBBtriggerV0A |= (1 << (robIndA[i]));
    else if (esdV0->GetV0ADecision() == AliESDVZERO::kV0BG)
      aBGtriggerV0A |= (1 << (robIndA[i]));
  }

  for(Int_t i = 0; i < nrobTimeC; ++i) {
    if (esdV0->GetV0CDecision() == AliESDVZERO::kV0BB)
      aBBtriggerV0C |= (1 << (robIndC[i]));
    else if (esdV0->GetV0CDecision() == AliESDVZERO::kV0BG)
      aBGtriggerV0C |= (1 << (robIndC[i]));
  }

  esdV0->SetBBtriggerV0A(aBBtriggerV0A);
  esdV0->SetBGtriggerV0A(aBGtriggerV0A);
  esdV0->SetBBtriggerV0C(aBBtriggerV0C);
  esdV0->SetBGtriggerV0C(aBGtriggerV0C);
}
 AliVZEROTriggerMask.cxx:1
 AliVZEROTriggerMask.cxx:2
 AliVZEROTriggerMask.cxx:3
 AliVZEROTriggerMask.cxx:4
 AliVZEROTriggerMask.cxx:5
 AliVZEROTriggerMask.cxx:6
 AliVZEROTriggerMask.cxx:7
 AliVZEROTriggerMask.cxx:8
 AliVZEROTriggerMask.cxx:9
 AliVZEROTriggerMask.cxx:10
 AliVZEROTriggerMask.cxx:11
 AliVZEROTriggerMask.cxx:12
 AliVZEROTriggerMask.cxx:13
 AliVZEROTriggerMask.cxx:14
 AliVZEROTriggerMask.cxx:15
 AliVZEROTriggerMask.cxx:16
 AliVZEROTriggerMask.cxx:17
 AliVZEROTriggerMask.cxx:18
 AliVZEROTriggerMask.cxx:19
 AliVZEROTriggerMask.cxx:20
 AliVZEROTriggerMask.cxx:21
 AliVZEROTriggerMask.cxx:22
 AliVZEROTriggerMask.cxx:23
 AliVZEROTriggerMask.cxx:24
 AliVZEROTriggerMask.cxx:25
 AliVZEROTriggerMask.cxx:26
 AliVZEROTriggerMask.cxx:27
 AliVZEROTriggerMask.cxx:28
 AliVZEROTriggerMask.cxx:29
 AliVZEROTriggerMask.cxx:30
 AliVZEROTriggerMask.cxx:31
 AliVZEROTriggerMask.cxx:32
 AliVZEROTriggerMask.cxx:33
 AliVZEROTriggerMask.cxx:34
 AliVZEROTriggerMask.cxx:35
 AliVZEROTriggerMask.cxx:36
 AliVZEROTriggerMask.cxx:37
 AliVZEROTriggerMask.cxx:38
 AliVZEROTriggerMask.cxx:39
 AliVZEROTriggerMask.cxx:40
 AliVZEROTriggerMask.cxx:41
 AliVZEROTriggerMask.cxx:42
 AliVZEROTriggerMask.cxx:43
 AliVZEROTriggerMask.cxx:44
 AliVZEROTriggerMask.cxx:45
 AliVZEROTriggerMask.cxx:46
 AliVZEROTriggerMask.cxx:47
 AliVZEROTriggerMask.cxx:48
 AliVZEROTriggerMask.cxx:49
 AliVZEROTriggerMask.cxx:50
 AliVZEROTriggerMask.cxx:51
 AliVZEROTriggerMask.cxx:52
 AliVZEROTriggerMask.cxx:53
 AliVZEROTriggerMask.cxx:54
 AliVZEROTriggerMask.cxx:55
 AliVZEROTriggerMask.cxx:56
 AliVZEROTriggerMask.cxx:57
 AliVZEROTriggerMask.cxx:58
 AliVZEROTriggerMask.cxx:59
 AliVZEROTriggerMask.cxx:60
 AliVZEROTriggerMask.cxx:61
 AliVZEROTriggerMask.cxx:62
 AliVZEROTriggerMask.cxx:63
 AliVZEROTriggerMask.cxx:64
 AliVZEROTriggerMask.cxx:65
 AliVZEROTriggerMask.cxx:66
 AliVZEROTriggerMask.cxx:67
 AliVZEROTriggerMask.cxx:68
 AliVZEROTriggerMask.cxx:69
 AliVZEROTriggerMask.cxx:70
 AliVZEROTriggerMask.cxx:71
 AliVZEROTriggerMask.cxx:72
 AliVZEROTriggerMask.cxx:73
 AliVZEROTriggerMask.cxx:74
 AliVZEROTriggerMask.cxx:75
 AliVZEROTriggerMask.cxx:76
 AliVZEROTriggerMask.cxx:77
 AliVZEROTriggerMask.cxx:78
 AliVZEROTriggerMask.cxx:79
 AliVZEROTriggerMask.cxx:80
 AliVZEROTriggerMask.cxx:81
 AliVZEROTriggerMask.cxx:82
 AliVZEROTriggerMask.cxx:83
 AliVZEROTriggerMask.cxx:84
 AliVZEROTriggerMask.cxx:85
 AliVZEROTriggerMask.cxx:86
 AliVZEROTriggerMask.cxx:87
 AliVZEROTriggerMask.cxx:88
 AliVZEROTriggerMask.cxx:89
 AliVZEROTriggerMask.cxx:90
 AliVZEROTriggerMask.cxx:91
 AliVZEROTriggerMask.cxx:92
 AliVZEROTriggerMask.cxx:93
 AliVZEROTriggerMask.cxx:94
 AliVZEROTriggerMask.cxx:95
 AliVZEROTriggerMask.cxx:96
 AliVZEROTriggerMask.cxx:97
 AliVZEROTriggerMask.cxx:98
 AliVZEROTriggerMask.cxx:99
 AliVZEROTriggerMask.cxx:100
 AliVZEROTriggerMask.cxx:101
 AliVZEROTriggerMask.cxx:102
 AliVZEROTriggerMask.cxx:103
 AliVZEROTriggerMask.cxx:104
 AliVZEROTriggerMask.cxx:105
 AliVZEROTriggerMask.cxx:106
 AliVZEROTriggerMask.cxx:107
 AliVZEROTriggerMask.cxx:108
 AliVZEROTriggerMask.cxx:109
 AliVZEROTriggerMask.cxx:110
 AliVZEROTriggerMask.cxx:111
 AliVZEROTriggerMask.cxx:112
 AliVZEROTriggerMask.cxx:113
 AliVZEROTriggerMask.cxx:114
 AliVZEROTriggerMask.cxx:115
 AliVZEROTriggerMask.cxx:116
 AliVZEROTriggerMask.cxx:117
 AliVZEROTriggerMask.cxx:118
 AliVZEROTriggerMask.cxx:119
 AliVZEROTriggerMask.cxx:120
 AliVZEROTriggerMask.cxx:121
 AliVZEROTriggerMask.cxx:122
 AliVZEROTriggerMask.cxx:123
 AliVZEROTriggerMask.cxx:124
 AliVZEROTriggerMask.cxx:125
 AliVZEROTriggerMask.cxx:126
 AliVZEROTriggerMask.cxx:127
 AliVZEROTriggerMask.cxx:128
 AliVZEROTriggerMask.cxx:129
 AliVZEROTriggerMask.cxx:130
 AliVZEROTriggerMask.cxx:131
 AliVZEROTriggerMask.cxx:132
 AliVZEROTriggerMask.cxx:133
 AliVZEROTriggerMask.cxx:134
 AliVZEROTriggerMask.cxx:135
 AliVZEROTriggerMask.cxx:136
 AliVZEROTriggerMask.cxx:137
 AliVZEROTriggerMask.cxx:138
 AliVZEROTriggerMask.cxx:139
 AliVZEROTriggerMask.cxx:140
 AliVZEROTriggerMask.cxx:141
 AliVZEROTriggerMask.cxx:142
 AliVZEROTriggerMask.cxx:143
 AliVZEROTriggerMask.cxx:144
 AliVZEROTriggerMask.cxx:145
 AliVZEROTriggerMask.cxx:146
 AliVZEROTriggerMask.cxx:147
 AliVZEROTriggerMask.cxx:148
 AliVZEROTriggerMask.cxx:149
 AliVZEROTriggerMask.cxx:150
 AliVZEROTriggerMask.cxx:151
 AliVZEROTriggerMask.cxx:152
 AliVZEROTriggerMask.cxx:153
 AliVZEROTriggerMask.cxx:154
 AliVZEROTriggerMask.cxx:155
 AliVZEROTriggerMask.cxx:156
 AliVZEROTriggerMask.cxx:157
 AliVZEROTriggerMask.cxx:158
 AliVZEROTriggerMask.cxx:159
 AliVZEROTriggerMask.cxx:160
 AliVZEROTriggerMask.cxx:161
 AliVZEROTriggerMask.cxx:162
 AliVZEROTriggerMask.cxx:163
 AliVZEROTriggerMask.cxx:164
 AliVZEROTriggerMask.cxx:165
 AliVZEROTriggerMask.cxx:166
 AliVZEROTriggerMask.cxx:167
 AliVZEROTriggerMask.cxx:168
 AliVZEROTriggerMask.cxx:169
 AliVZEROTriggerMask.cxx:170
 AliVZEROTriggerMask.cxx:171
 AliVZEROTriggerMask.cxx:172
 AliVZEROTriggerMask.cxx:173
 AliVZEROTriggerMask.cxx:174
 AliVZEROTriggerMask.cxx:175
 AliVZEROTriggerMask.cxx:176
 AliVZEROTriggerMask.cxx:177
 AliVZEROTriggerMask.cxx:178
 AliVZEROTriggerMask.cxx:179
 AliVZEROTriggerMask.cxx:180
 AliVZEROTriggerMask.cxx:181
 AliVZEROTriggerMask.cxx:182
 AliVZEROTriggerMask.cxx:183
 AliVZEROTriggerMask.cxx:184
 AliVZEROTriggerMask.cxx:185
 AliVZEROTriggerMask.cxx:186
 AliVZEROTriggerMask.cxx:187
 AliVZEROTriggerMask.cxx:188
 AliVZEROTriggerMask.cxx:189
 AliVZEROTriggerMask.cxx:190
 AliVZEROTriggerMask.cxx:191
 AliVZEROTriggerMask.cxx:192
 AliVZEROTriggerMask.cxx:193
 AliVZEROTriggerMask.cxx:194
 AliVZEROTriggerMask.cxx:195
 AliVZEROTriggerMask.cxx:196
 AliVZEROTriggerMask.cxx:197
 AliVZEROTriggerMask.cxx:198
 AliVZEROTriggerMask.cxx:199
 AliVZEROTriggerMask.cxx:200
 AliVZEROTriggerMask.cxx:201
 AliVZEROTriggerMask.cxx:202
 AliVZEROTriggerMask.cxx:203
 AliVZEROTriggerMask.cxx:204
 AliVZEROTriggerMask.cxx:205
 AliVZEROTriggerMask.cxx:206
 AliVZEROTriggerMask.cxx:207
 AliVZEROTriggerMask.cxx:208
 AliVZEROTriggerMask.cxx:209
 AliVZEROTriggerMask.cxx:210
 AliVZEROTriggerMask.cxx:211
 AliVZEROTriggerMask.cxx:212
 AliVZEROTriggerMask.cxx:213
 AliVZEROTriggerMask.cxx:214
 AliVZEROTriggerMask.cxx:215
 AliVZEROTriggerMask.cxx:216
 AliVZEROTriggerMask.cxx:217
 AliVZEROTriggerMask.cxx:218
 AliVZEROTriggerMask.cxx:219
 AliVZEROTriggerMask.cxx:220
 AliVZEROTriggerMask.cxx:221
 AliVZEROTriggerMask.cxx:222
 AliVZEROTriggerMask.cxx:223
 AliVZEROTriggerMask.cxx:224
 AliVZEROTriggerMask.cxx:225
 AliVZEROTriggerMask.cxx:226
 AliVZEROTriggerMask.cxx:227
 AliVZEROTriggerMask.cxx:228
 AliVZEROTriggerMask.cxx:229
 AliVZEROTriggerMask.cxx:230
 AliVZEROTriggerMask.cxx:231
 AliVZEROTriggerMask.cxx:232
 AliVZEROTriggerMask.cxx:233
 AliVZEROTriggerMask.cxx:234
 AliVZEROTriggerMask.cxx:235
 AliVZEROTriggerMask.cxx:236
 AliVZEROTriggerMask.cxx:237
 AliVZEROTriggerMask.cxx:238