/* $Id$ */
+/* History of cvs commits:
+ *
+ * $Log$
+ * Revision 1.111 2007/07/24 09:41:19 morsch
+ * AliStack included for kKeepBit.
+ *
+ * Revision 1.110 2007/03/10 08:58:52 kharlov
+ * Protection for noCPV geometry
+ *
+ * Revision 1.109 2007/03/01 11:37:37 kharlov
+ * Strip units changed from 8x1 to 8x2 (T.Pocheptsov)
+ *
+ * Revision 1.108 2007/02/02 09:40:50 alibrary
+ * Includes required by ROOT head
+ *
+ * Revision 1.107 2007/02/01 10:34:47 hristov
+ * Removing warnings on Solaris x86
+ *
+ * Revision 1.106 2006/11/14 17:11:15 hristov
+ * Removing inheritances from TAttLine, TAttMarker and AliRndm in AliModule. The copy constructor and assignment operators are moved to the private part of the class and not implemented. The corresponding changes are propagated to the detectors
+ *
+ * Revision 1.105 2006/09/13 07:31:01 kharlov
+ * Effective C++ corrections (T.Pocheptsov)
+ *
+ * Revision 1.104 2005/05/28 14:19:05 schutz
+ * Compilation warnings fixed by T.P.
+ *
+ */
+
//_________________________________________________________________________
// Implementation version v1 of PHOS Manager class
//---
// --- ROOT system ---
+#include <TClonesArray.h>
#include <TParticle.h>
#include <TVirtualMC.h>
#include "AliPHOSCPVDigit.h"
#include "AliPHOSGeometry.h"
#include "AliPHOSHit.h"
-#include "AliPHOSQAFloatCheckable.h"
-#include "AliPHOSQAIntCheckable.h"
-#include "AliPHOSQAMeanChecker.h"
#include "AliPHOSv1.h"
#include "AliRun.h"
#include "AliMC.h"
+#include "AliStack.h"
ClassImp(AliPHOSv1)
//____________________________________________________________________________
AliPHOSv1::AliPHOSv1():
-AliPHOSv0()
+ fLightYieldMean(0.),
+ fIntrinsicPINEfficiency(0.),
+ fLightYieldAttenuation(0.),
+ fRecalibrationFactor(0.),
+ fElectronsPerGeV(0.),
+ fAPDGain(0.),
+ fLightFactor(0.),
+ fAPDFactor(0.)
{
- // default ctor: initialze data memebers
- fQAHitsMul = 0 ;
- fQAHitsMulB = 0 ;
- fQATotEner = 0 ;
- fQATotEnerB = 0 ;
-
- fLightYieldMean = 0. ;
- fIntrinsicPINEfficiency = 0. ;
- fLightYieldAttenuation = 0. ;
- fRecalibrationFactor = 0. ;
- fElectronsPerGeV = 0. ;
- fAPDGain = 0. ;
- fLightFactor = 0. ;
- fAPDFactor = 0. ;
-
+ //Def ctor.
}
//____________________________________________________________________________
AliPHOSv1::AliPHOSv1(const char *name, const char *title):
- AliPHOSv0(name,title)
+ AliPHOSv0(name,title),
+ fLightYieldMean(0.),
+ fIntrinsicPINEfficiency(0.),
+ fLightYieldAttenuation(0.),
+ fRecalibrationFactor(0.),
+ fElectronsPerGeV(0.),
+ fAPDGain(0.),
+ fLightFactor(0.),
+ fAPDFactor(0.)
{
//
// We store hits :
fElectronsPerGeV = 2.77e+8 ;
fAPDGain = 300. ;
fLightFactor = fLightYieldMean * fIntrinsicPINEfficiency ;
- fAPDFactor = (fRecalibrationFactor/100.) * fAPDGain ;
-
-
- Int_t nb = GetGeometry()->GetNModules() ;
-
- // create checkables
- fQAHitsMul = new AliPHOSQAIntCheckable("HitsM") ;
- fQATotEner = new AliPHOSQAFloatCheckable("TotEn") ;
- fQAHitsMulB = new TClonesArray("AliPHOSQAIntCheckable",nb) ;
- fQAHitsMulB->SetOwner() ;
- fQATotEnerB = new TClonesArray("AliPHOSQAFloatCheckable", nb);
- fQATotEnerB->SetOwner() ;
- char tempo[20] ;
- Int_t i ;
- for ( i = 0 ; i < nb ; i++ ) {
- sprintf(tempo, "HitsMB%d", i+1) ;
- new( (*fQAHitsMulB)[i]) AliPHOSQAIntCheckable(tempo) ;
- sprintf(tempo, "TotEnB%d", i+1) ;
- new( (*fQATotEnerB)[i] ) AliPHOSQAFloatCheckable(tempo) ;
- }
-
- AliPHOSQAMeanChecker * hmc = new AliPHOSQAMeanChecker("HitsMul", 100. ,25.) ;
- AliPHOSQAMeanChecker * emc = new AliPHOSQAMeanChecker("TotEner", 10. ,5.) ;
- AliPHOSQAMeanChecker * bhmc = new AliPHOSQAMeanChecker("HitsMulB", 100. ,5.) ;
- AliPHOSQAMeanChecker * bemc = new AliPHOSQAMeanChecker("TotEnerB", 2. ,.5) ;
-
- // associate checkables and checkers
- fQAHitsMul->AddChecker(hmc) ;
- fQATotEner->AddChecker(emc) ;
- for ( i = 0 ; i < nb ; i++ ) {
- (static_cast<AliPHOSQAIntCheckable*>((*fQAHitsMulB)[i]))->AddChecker(bhmc) ;
- (static_cast<AliPHOSQAFloatCheckable*>((*fQATotEnerB)[i]))->AddChecker(bemc) ;
- }
-
+ fAPDFactor = (fRecalibrationFactor/100.) * fAPDGain ;
}
//____________________________________________________________________________
fHits->Delete() ;
delete fHits ;
fHits = 0 ;
- }
-
- if ( fQAHitsMulB ) {
- fQAHitsMulB->Delete() ;
- delete fQAHitsMulB ;
- }
-
- if ( fQATotEnerB ) {
- fQATotEnerB->Delete() ;
- delete fQATotEnerB ;
- }
-
+ }
}
//____________________________________________________________________________
-void AliPHOSv1::Copy(AliPHOSv1 & phos)
-{
- TObject::Copy(phos) ;
- AliPHOSv0::Copy(phos) ;
- phos.fLightYieldMean = fLightYieldMean ;
- phos.fIntrinsicPINEfficiency = fIntrinsicPINEfficiency ;
- phos.fLightYieldAttenuation = fLightYieldAttenuation ;
- phos.fRecalibrationFactor = fRecalibrationFactor ;
- phos.fElectronsPerGeV = fElectronsPerGeV ;
- phos.fAPDGain = fAPDGain ;
- phos.fLightFactor = fLightFactor ;
- phos.fAPDFactor = fAPDFactor ;
-}
-
-//____________________________________________________________________________
-void AliPHOSv1::AddHit(Int_t shunt, Int_t primary, Int_t tracknumber, Int_t Id, Float_t * hits)
+void AliPHOSv1::AddHit(Int_t shunt, Int_t primary, Int_t Id, Float_t * hits)
{
// Add a hit to the hit list.
// A PHOS hit is the sum of all hits in a single crystal from one primary and within some time gate
Bool_t deja = kFALSE ;
AliPHOSGeometry * geom = GetGeometry() ;
- newHit = new AliPHOSHit(shunt, primary, tracknumber, Id, hits) ;
+ newHit = new AliPHOSHit(shunt, primary, Id, hits) ;
for ( hitCounter = fNhits-1 ; hitCounter >= 0 && !deja ; hitCounter-- ) {
curHit = dynamic_cast<AliPHOSHit*>((*fHits)[hitCounter]) ;
// get the block Id number
Int_t relid[4] ;
geom->AbsToRelNumbering(Id, relid) ;
- // and fill the relevant QA checkable (only if in PbW04)
- if ( relid[1] == 0 ) {
- fQAHitsMul->Update(1) ;
- (static_cast<AliPHOSQAIntCheckable*>((*fQAHitsMulB)[relid[0]-1]))->Update(1) ;
- }
+
fNhits++ ;
}
-
+
delete newHit;
}
// called at the end of each track (primary) by AliRun
// hits are reset for each new track
// accumulate the total hit-multiplicity
-// if ( fQAHitsMul )
-// fQAHitsMul->Update( fHits->GetEntriesFast() ) ;
}
// accumulate the hit-multiplicity and total energy per block
// if the values have been updated check it
-
- if ( fQATotEner ) {
- if ( fQATotEner->HasChanged() ) {
- fQATotEner->CheckMe() ;
- fQATotEner->Reset() ;
- }
- }
-
- Int_t i ;
- if ( fQAHitsMulB && fQATotEnerB ) {
- for (i = 0 ; i < GetGeometry()->GetNModules() ; i++) {
- AliPHOSQAIntCheckable * ci = static_cast<AliPHOSQAIntCheckable*>((*fQAHitsMulB)[i]) ;
- AliPHOSQAFloatCheckable* cf = static_cast<AliPHOSQAFloatCheckable*>((*fQATotEnerB)[i]) ;
- if ( ci->HasChanged() ) {
- ci->CheckMe() ;
- ci->Reset() ;
- }
- if ( cf->HasChanged() ) {
- cf->CheckMe() ;
- cf->Reset() ;
- }
- }
- }
-
- // check the total multiplicity
-
- if ( fQAHitsMul ) {
- if ( fQAHitsMul->HasChanged() ) {
- fQAHitsMul->CheckMe() ;
- fQAHitsMul->Reset() ;
- }
- }
-
AliDetector::FinishEvent();
}
//____________________________________________________________________________
TLorentzVector pos ; // Lorentz vector of the track current position
Int_t copy ;
- Int_t tracknumber = gAlice->GetMCApp()->GetCurrentTrackNumber() ;
- TString name = GetGeometry()->GetName() ;
-
Int_t moduleNumber ;
- if( gMC->CurrentVolID(copy) == gMC->VolId("PCPQ") &&
+ static Int_t idPCPQ = -1;
+ if (strstr(fTitle.Data(),"noCPV") == 0)
+ idPCPQ = gMC->VolId("PCPQ");
+
+ if( gMC->CurrentVolID(copy) == idPCPQ &&
(gMC->IsTrackEntering() ) &&
gMC->TrackCharge() != 0) {
gMC -> TrackPosition(pos);
-
+
Float_t xyzm[3], xyzd[3] ;
Int_t i;
for (i=0; i<3; i++) xyzm[i] = pos[i];
- gMC -> Gmtod (xyzm, xyzd, 1); // transform coordinate from master to daughter system
-
+ gMC -> Gmtod (xyzm, xyzd, 1); // transform coordinate from master to daughter system
+
+
Float_t xyd[3]={0,0,0} ; //local position of the entering
xyd[0] = xyzd[0];
xyd[1] =-xyzd[2];
Float_t x2 = cpvDigit2->GetXpad() ;
Float_t z2 = cpvDigit2->GetYpad() ;
if (x1==x2 && z1==z2) {
- Float_t qsum = cpvDigit1->GetQpad() + cpvDigit2->GetQpad() ;
- cpvDigit2->SetQpad(qsum) ;
+ Float_t qsumpad = cpvDigit1->GetQpad() + cpvDigit2->GetQpad() ;
+ cpvDigit2->SetQpad(qsumpad) ;
cpvDigits->RemoveAt(idigit) ;
}
}
xyzte[3] = gMC->TrackTime() ;
xyzte[4] = cpvDigit->GetQpad() ; // amplitude in a pad
- AddHit(fIshunt, -1, tracknumber, absid, xyzte); // -1: No need in primary for CPV
+
+ Int_t primary = gAlice->GetMCApp()->GetPrimary( gAlice->GetMCApp()->GetCurrentTrackNumber() );
+ AddHit(fIshunt, primary, absid, xyzte);
if (cpvDigit->GetQpad() > 0.02) {
xmean += cpvDigit->GetQpad() * (cpvDigit->GetXpad() + 0.5);
}
-
- if(gMC->CurrentVolID(copy) == gMC->VolId("PXTL") ) { // We are inside a PBWO crystal
+ static Int_t idPXTL = gMC->VolId("PXTL");
+ if(gMC->CurrentVolID(copy) == idPXTL ) { // We are inside a PBWO crystal
gMC->TrackPosition(pos) ;
xyzte[0] = pos[0] ;
xyzte[1] = pos[1] ;
xyzte[2] = pos[2] ;
- Float_t global[3], local[3] ;
- global[0] = pos[0] ;
- global[1] = pos[1] ;
- global[2] = pos[2] ;
Float_t lostenergy = gMC->Edep();
//Put in the TreeK particle entering PHOS and all its parents
vert[1]=part->Vy() ;
vert[2]=part->Vz() ;
gMC -> Gmtod (vert, vertd, 1); // transform coordinate from master to daughter system
- if(vertd[1]<-GetGeometry()->GetCrystalSize(1)/2.-0.1){ //Particle is created in foront of PHOS 0.1 to get rid of numerical errors
+ if(vertd[1]<-GetGeometry()->GetCrystalSize(1)/2.-0.1){ //Particle is created in foront of PHOS
+ //0.1 to get rid of numerical errors
+ part->SetBit(kKeepBit);
while ( parent != -1 ) {
part = gAlice->GetMCApp()->Particle(parent) ;
- part->Print() ;
part->SetBit(kKeepBit);
parent = part->GetFirstMother() ;
}
gMC->CurrentVolOffID(3, strip);
Int_t cell ;
gMC->CurrentVolOffID(2, cell);
-
- Int_t row = 1 + GetGeometry()->GetNZ() - strip % GetGeometry()->GetNZ() ;
- Int_t col = (Int_t) TMath::Ceil((Double_t) strip/GetGeometry()->GetNZ()) -1 ;
-
+
+ //Old formula for row is wrong. For example, I have strip 56 (28 for 2 x 8), row must be 1.
+ //But row == 1 + 56 - 56 % 56 == 57 (row == 1 + 28 - 28 % 28 == 29)
+ //Int_t row = 1 + GetGeometry()->GetEMCAGeometry()->GetNStripZ() - strip % (GetGeometry()->GetEMCAGeometry()->GetNStripZ()) ;
+ Int_t row = GetGeometry()->GetEMCAGeometry()->GetNStripZ() - (strip - 1) % (GetGeometry()->GetEMCAGeometry()->GetNStripZ()) ;
+ Int_t col = (Int_t) TMath::Ceil((Double_t) strip/(GetGeometry()->GetEMCAGeometry()->GetNStripZ())) -1 ;
+
+ // Absid for 8x2-strips. Looks nice :)
absid = (moduleNumber-1)*GetGeometry()->GetNCristalsInModule() +
- row + (col*GetGeometry()->GetEMCAGeometry()->GetNCellsInStrip() + cell-1)*GetGeometry()->GetNZ() ;
-
- gMC->Gmtod(global, local, 1) ;
+ row * 2 + (col*GetGeometry()->GetEMCAGeometry()->GetNCellsXInStrip() + (cell - 1) / 2)*GetGeometry()->GetNZ() - (cell & 1 ? 1 : 0);
+
//Calculates the light yield, the number of photons produced in the
//crystal
- Float_t lightYield = gRandom->Poisson(fLightFactor * lostenergy *
- exp(-fLightYieldAttenuation *
- (local[1]+GetGeometry()->GetCrystalSize(1)/2.0 ))
- ) ;
+ //There is no dependence of reponce on distance from energy deposition to APD
+ Float_t lightYield = gRandom->Poisson(fLightFactor * lostenergy) ;
//Calculates de energy deposited in the crystal
- xyzte[4] = fAPDFactor * lightYield ;
+ xyzte[4] = fAPDFactor * lightYield ;
- Int_t primary =-1 ;
- if(fIshunt == 1)
- primary = gAlice->GetMCApp()->GetPrimary( gAlice->GetMCApp()->GetCurrentTrackNumber() );
- else if(fIshunt == 2){
- primary = gAlice->GetMCApp()->GetCurrentTrackNumber() ;
- TParticle * part = gAlice->GetMCApp()->Particle(primary) ;
- while ( !part->TestBit(kKeepBit) ) {
- primary = part->GetFirstMother() ;
- if(primary == -1) break ; //there is a possibility that particle passed e.g. thermal isulator and hits a side
- //surface of the crystal. In this case it may have no primary at all.
- //We can not easily separate this case from the case when this is part of the shower,
- //developed in the neighboring crystal.
- part = gAlice->GetMCApp()->Particle(primary) ;
- }
+ Int_t primary ;
+ if(fIshunt == 2){
+ primary = gAlice->GetMCApp()->GetCurrentTrackNumber() ;
+ TParticle * part = gAlice->GetMCApp()->Particle(primary) ;
+ while ( !part->TestBit(kKeepBit) ) {
+ primary = part->GetFirstMother() ;
+ if(primary == -1){
+ primary = gAlice->GetMCApp()->GetPrimary( gAlice->GetMCApp()->GetCurrentTrackNumber() );
+ break ; //there is a possibility that particle passed e.g. thermal isulator and hits a side
+ //surface of the crystal. In this case it may have no primary at all.
+ //We can not easily separate this case from the case when this is part of the shower,
+ //developed in the neighboring crystal.
+ }
+ part = gAlice->GetMCApp()->Particle(primary) ;
+ }
}
+ else
+ primary = gAlice->GetMCApp()->GetPrimary( gAlice->GetMCApp()->GetCurrentTrackNumber() );
-
- // add current hit to the hit list
- // Info("StepManager","%d %d", primary, tracknumber) ;
- AddHit(fIshunt, primary,tracknumber, absid, xyzte);
- // fill the relevant QA Checkables
- fQATotEner->Update( xyzte[4] ) ; // total energy in PHOS
- (static_cast<AliPHOSQAFloatCheckable*>((*fQATotEnerB)[moduleNumber-1]))->Update( xyzte[4] ) ; // energy in this block
+ // add current hit to the hit list
+ // Info("StepManager","%d %d", primary, tracknumber) ;
+ AddHit(fIshunt, primary, absid, xyzte);
+
} // there is deposited energy
} // we are inside a PHOS Xtal