AliRoot Core  v5-06-15 (45dab64)
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
AliMUONDigitizerV3.cxx
Go to the documentation of this file.
1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
15 
16 // $Id$
17 
18 
19 #include "AliMUONDigitizerV3.h"
20 
21 #include "AliMUON.h"
22 #include "AliMUONCalibrationData.h"
23 #include "AliMUONConstants.h"
24 #include "AliMUONDigit.h"
25 #include "AliMUONLogger.h"
27 #include "AliMUONTriggerStoreV1.h"
28 #include "AliMUONVCalibParam.h"
29 #include "AliMUONVDigitStore.h"
30 #include "AliMUONGeometryTransformer.h" //ADDED for trigger noise
31 #include "AliMUONRecoParam.h"
34 
35 #include "AliMpCDB.h"
36 #include "AliMpSegmentation.h"
37 #include "AliMpCathodType.h"
38 #include "AliMpConstants.h"
39 #include "AliMpDEIterator.h"
40 #include "AliMpDEManager.h"
41 #include "AliMpPad.h"
42 #include "AliMpStationType.h"
43 #include "AliMpVSegmentation.h"
44 #include "AliMpDDLStore.h"
45 
46 #include "AliCDBManager.h"
47 #include "AliCodeTimer.h"
48 #include "AliLog.h"
49 #include "AliRun.h"
50 #include "AliDigitizationInput.h"
51 #include "AliLoader.h"
52 #include "AliRunLoader.h"
53 
54 #include <Riostream.h>
55 #include <TF1.h>
56 #include <TFile.h>
57 #include <TMath.h>
58 #include <TRandom.h>
59 #include <TString.h>
60 #include <TSystem.h>
61 #include <TTree.h>
62 
63 //-----------------------------------------------------------------------------
90 //-----------------------------------------------------------------------------
91 
92 namespace
93 {
94  AliMUON* muon()
95  {
96  return static_cast<AliMUON*>(gAlice->GetModule("MUON"));
97  }
98 
99  //ADDED for trigger noise
100  const AliMUONGeometryTransformer* GetTransformer()
101  {
102  return muon()->GetGeometryTransformer();
103  }
104 }
105 
106 Double_t AliMUONDigitizerV3::fgNSigmas = 4.0;
107 
111 
112 //_____________________________________________________________________________
113 AliMUONDigitizerV3::AliMUONDigitizerV3(AliDigitizationInput* digInput,
114  Int_t generateNoisyDigits)
115 : AliDigitizer(digInput),
116 fIsInitialized(kFALSE),
117 fCalibrationData(0x0),
118 fTriggerProcessor(0x0),
119 fNoiseFunctionTrig(0x0),
120 fGenerateNoisyDigits(generateNoisyDigits),
121 fLogger(new AliMUONLogger(4207)), /* 4207 = 25% of the 16828 MCH manus */
122 fTriggerStore(new AliMUONTriggerStoreV1),
123 fDigitStore(0x0),
124 fOutputDigitStore(0x0),
125 fInputDigitStores(0x0),
126 fRecoParam(0x0),
127 fTriggerEfficiency(0x0),
128 fTriggerUtilities(0x0),
129 fEfficiencyResponse(2*AliMUONConstants::NTriggerCh()*AliMUONConstants::NTriggerCircuit())
130 {
132 
133  AliDebug(1,Form("AliDigitizationInput=%p",fDigInput));
134 
135 }
136 
137 //_____________________________________________________________________________
139 {
141 
142  AliDebug(1,"dtor");
143 
144  // delete fCalibrationData;
145  delete fTriggerProcessor;
146  delete fNoiseFunctionTrig;
147  delete fTriggerStore;
148  delete fDigitStore;
149  delete fOutputDigitStore;
150  delete fInputDigitStores;
151  delete fTriggerUtilities;
152 
153  AliInfo("Summary of messages");
154  fLogger->Print();
155 
156  delete fLogger;
157 }
158 
159 //_____________________________________________________________________________
160 void
162 {
169 
170  Float_t charge = digit.Charge();
171 
172  if (!digit.IsChargeInFC())
173  {
175  fLogger->Log("CHECK ME ! WAS NOT SUPPOSED TO BE HERE !!! ARE YOU RECONSTRUCTING OLD SIMULATIONS ? ");
176  AliError("CHECK ME ! WAS NOT SUPPOSED TO BE HERE !!! ARE YOU RECONSTRUCTING OLD SIMULATIONS ? ");
177  }
178 
179  // We set the charge to 0, as the only relevant piece of information
180  // after Digitization is the ADC value.
181  digit.SetCharge(0);
182 
183  Int_t detElemId = digit.DetElemId();
184  Int_t manuId = digit.ManuId();
185 
186  AliMUONVCalibParam* pedestal = fCalibrationData->Pedestals(detElemId,manuId);
187  if (!pedestal)
188  {
189  fLogger->Log(Form("%s:%d:Could not get pedestal for DE=%4d manuId=%4d. Disabling.",
190  __FILE__,__LINE__,
191  detElemId,manuId));
192  digit.SetADC(0);
193  return;
194  }
195 
196  Int_t manuChannel = digit.ManuChannel();
197 
198  if ( pedestal->ValueAsFloat(manuChannel,0) == AliMUONVCalibParam::InvalidFloatValue() ||
199  pedestal->ValueAsFloat(manuChannel,1) == AliMUONVCalibParam::InvalidFloatValue() )
200  {
201  // protection against invalid pedestal value
202  digit.SetADC(0);
203  return;
204  }
205 
206  TString calibrationMode(fRecoParam->GetCalibrationMode());
207  calibrationMode.ToUpper();
208 
209  AliMUONVCalibParam* gain = fCalibrationData->Gains(detElemId,manuId);
210  if (!gain)
211  {
212 
213  if (!calibrationMode.Contains("NOGAIN") )
214  {
215  fLogger->Log(Form("%s:%d:Could not get gain for DE=%4d manuId=%4d. Disabling.",
216  __FILE__,__LINE__,
217  detElemId,manuId));
218  digit.SetADC(0);
219  return;
220  }
221  }
222 
223  Int_t adc = DecalibrateTrackerDigit(*pedestal,gain,manuChannel,charge,addNoise,
224  digit.IsNoiseOnly(),
225  calibrationMode);
226 
227  digit.SetADC(adc);
228 }
229 
230 
231 //_____________________________________________________________________________
232 void
234 {
239 
240  Int_t detElemId = digit.DetElemId();
241  Int_t localCircuit = digit.ManuId();
242  Int_t strip = digit.ManuChannel();
243  Int_t cathode = digit.Cathode();
244  Int_t trigCh = detElemId/100 - 11;
245 
246  // Masked channels
247  Bool_t isMasked = fTriggerUtilities->IsMasked(digit);
248  AliDebug(1,Form("detElemId %i cath %i board %i strip %i is masked %i\n", detElemId, cathode, localCircuit, strip, isMasked));
249  if ( isMasked ) {
250  digit.SetCharge(0);
251  digit.SetADC(0);
252  //AliDebug(1,Form("ch %i cath %i board %i strip %i masked\n", trigCh, cathode, localCircuit, strip));
253  return;
254  }
255 
256 
257  Int_t arrayIndex = GetArrayIndex(cathode, trigCh, localCircuit);
258 
259  // Trigger chamber efficiency
260  if ( fTriggerEfficiency ) {
261  if ( fEfficiencyResponse[arrayIndex] < 0 ) {
262  Bool_t isTrig[2] = {kTRUE, kTRUE};
263  fTriggerEfficiency->IsTriggered(detElemId, localCircuit, isTrig[0], isTrig[1]);
264  Int_t arrayIndexBend = GetArrayIndex(0, trigCh, localCircuit);
265  Int_t arrayIndexNonBend = GetArrayIndex(1, trigCh, localCircuit);
266  fEfficiencyResponse[arrayIndexBend] = isTrig[0];
267  fEfficiencyResponse[arrayIndexNonBend] = isTrig[1];
268  }
269  AliDebug(1,Form("detElemId %i cath %i board %i strip %i efficiency %i\n", detElemId, cathode, localCircuit, strip, fEfficiencyResponse[arrayIndex]));
270  if ( fEfficiencyResponse[arrayIndex] == 0 ) {
271  digit.SetCharge(0);
272  digit.SetADC(0);
273  //AliDebug(1,Form("ch %i cath %i board %i strip %i NOT efficient\n", trigCh, cathode, localCircuit, strip));
274  return;
275  }
276  }
277 }
278 
279 
280 
281 //_____________________________________________________________________________
282 void
284  AliMUONVDigitStore& filteredStore)
285 {
288 
289  filteredStore.Clear();
290 
291  const Bool_t kAddNoise = kTRUE;
292 
293  TIter next(store.CreateIterator());
294  AliMUONVDigit* digit;
295 
296  if ( fTriggerEfficiency ) fEfficiencyResponse.Reset(-1);
297 
298  while ( ( digit = static_cast<AliMUONVDigit*>(next()) ) )
299  {
300  AliMp::StationType stationType = AliMpDEManager::GetStationType(digit->DetElemId());
301 
302  if ( stationType != AliMp::kStationTrigger )
303  {
304  Bool_t addNoise = kAddNoise;
305  if (digit->IsConverted()) addNoise = kFALSE; // No need to add extra noise to a converted real digit
306  ApplyResponseToTrackerDigit(*digit,addNoise);
307  }
308  else {
310  }
311 
312  if ( digit->ADC() > 0 || digit->Charge() > 0 )
313  {
314  filteredStore.Add(*digit,AliMUONVDigitStore::kIgnore);
315  }
316  }
317 }
318 
319 //_____________________________________________________________________________
320 Int_t
322  const AliMUONVCalibParam* gains,
323  Int_t channel,
324  Float_t charge,
325  Bool_t addNoise,
326  Bool_t noiseOnly,
327  const TString& calibrationMode)
328 {
338 
339  static const Int_t kMaxADC = (1<<12)-1; // We code the charge on a 12 bits ADC.
340 
341  Bool_t nogain = calibrationMode.Contains("NOGAIN");
342 
343  Float_t a1(0.0);
344  Int_t thres(4095);
345  Int_t qual(0xF);
346  Float_t capa(AliMUONConstants::DefaultCapa()); // capa = 0.2 and a0 = 1.25
347  Float_t a0(AliMUONConstants::DefaultA0()); // is equivalent to gain = 4 mV/fC
348  Float_t adc2mv(AliMUONConstants::DefaultADC2MV()); // 1 ADC channel = 0.61 mV
349 
350  if ( ! nogain )
351  {
352  if (!gains)
353  {
354  AliFatalClass("Cannot make gain decalibration without gain values !");
355  }
356  a0 = gains->ValueAsFloat(channel,0);
357  a1 = gains->ValueAsFloat(channel,1);
358  thres = gains->ValueAsInt(channel,2);
359  qual = gains->ValueAsInt(channel,3);
360  }
361 
362  Float_t pedestalMean = pedestals.ValueAsFloat(channel,0);
363  Float_t pedestalSigma = pedestals.ValueAsFloat(channel,1);
364 
365  AliDebugClass(2,Form("DE %04d MANU %04d CH %02d PEDMEAN %7.2f PEDSIGMA %7.2f",
366  pedestals.ID0(),pedestals.ID1(),channel,pedestalMean,pedestalSigma));
367 
368  if ( qual <= 0 ) return 0;
369 
370  Float_t chargeThres = a0*thres;
371 
372  Float_t padc(0); // (adc - ped) value
373 
374  if ( nogain || charge <= chargeThres || TMath::Abs(a1) < 1E-12 )
375  {
376  // linear part only
377 
378  if ( TMath::Abs(a0) > 1E-12 )
379  {
380  padc = charge/a0;
381  }
382  }
383  else
384  {
385  // FIXME: when we'll use capacitances and real gains, revise this part
386  // to take capa properly into account...
387 
388  AliWarningClass("YOU PROBABLY NEED TO REVISE THIS PART OF CODE !!!");
389 
390  // linear + parabolic part
391  Double_t qt = chargeThres - charge;
392  Double_t delta = a0*a0-4*a1*qt;
393  if ( delta < 0 )
394  {
395  AliErrorClass(Form("delta=%e DE %d Manu %d Channel %d "
396  " charge %e a0 %e a1 %e thres %d ped %e pedsig %e",
397  delta,pedestals.ID0(),pedestals.ID1(),
398  channel, charge, a0, a1, thres, pedestalMean,
399  pedestalSigma));
400  }
401  else
402  {
403  delta = TMath::Sqrt(delta);
404 
405  padc = ( ( -a0 + delta ) > 0 ? ( -a0 + delta ) : ( -a0 - delta ) );
406 
407  padc /= 2*a1;
408 
409  if ( padc < 0 )
410  {
411  if ( TMath::Abs(padc) > 1E-3)
412  {
413  // this is more than a precision problem : let's signal it !
414  AliErrorClass(Form("padc=%e DE %d Manu %d Channel %d "
415  " charge %e a0 %e a1 %e thres %d ped %e pedsig %e delta %e",
416  padc,pedestals.ID0(),pedestals.ID1(),
417  channel, charge, a0, a1, thres, pedestalMean,
418  pedestalSigma,delta));
419  }
420 
421  // ok. consider we're just at thres, let it be zero.
422  padc = 0;
423  }
424 
425  padc += thres;
426 
427  }
428  }
429 
430  padc /= capa*adc2mv;
431 
432  Int_t adc(0);
433 
434  Float_t adcNoise = 0.0;
435 
436  if ( addNoise )
437  {
438  if ( noiseOnly )
439  {
440  adcNoise = NoiseFunction()->GetRandom()*pedestalSigma;
441  }
442  else
443  {
444  adcNoise = gRandom->Gaus(0.0,pedestalSigma);
445  }
446  }
447 
448  adc = TMath::Nint(padc + pedestalMean + adcNoise + 0.5);
449 
450  if ( adc < TMath::Nint(pedestalMean + fgNSigmas*pedestalSigma + 0.5) )
451  {
452  // this is an error only in specific cases
453  if ( !addNoise || (addNoise && noiseOnly) )
454  {
455  AliDebugClass(1,Form(" DE %04d Manu %04d Channel %02d "
456  " a0 %7.2f a1 %7.2f thres %04d ped %7.2f pedsig %7.2f adcNoise %7.2f "
457  " charge=%7.2f padc=%7.2f adc=%04d ZS=%04d fgNSigmas=%e addNoise %d noiseOnly %d ",
458  pedestals.ID0(),pedestals.ID1(),channel,
459  a0, a1, thres, pedestalMean, pedestalSigma, adcNoise,
460  charge, padc, adc,
461  TMath::Nint(pedestalMean + fgNSigmas*pedestalSigma + 0.5),
462  fgNSigmas,addNoise,noiseOnly));
463  }
464 
465  adc = 0;
466  }
467 
468  // be sure we stick to 12 bits.
469  if ( adc > kMaxADC )
470  {
471  adc = kMaxADC;
472  }
473 
474  return adc;
475 }
476 
477 //_____________________________________________________________________________
478 void
480 {
483 
484  if (fInputDigitStores)
485  {
486  AliFatal("Should be called only once !");
487  }
488 
490 
491  fInputDigitStores->SetOwner(kTRUE);
492 
493  for ( Int_t iFile = 0; iFile < fDigInput->GetNinputs(); ++iFile )
494  {
495  AliLoader* inputLoader = GetLoader(fDigInput->GetInputFolderName(iFile));
496 
497  inputLoader->LoadSDigits("READ");
498 
499  TTree* iTreeS = inputLoader->TreeS();
500  if (!iTreeS)
501  {
502  AliFatal(Form("Could not get access to input file #%d",iFile));
503  }
504 
505  fInputDigitStores->AddAt(AliMUONVDigitStore::Create(*iTreeS),iFile);
506  }
507 }
508 
509 //_____________________________________________________________________________
510 void
512 {
518 
519  AliCodeTimerAuto("",0)
520 
521  if ( fDigInput->GetNinputs() == 0 )
522  {
523  AliWarning("No input set. Nothing to do.");
524  return;
525  }
526 
527  if ( !fIsInitialized )
528  {
529  AliError("Not initialized. Cannot perform the work. Sorry");
530  return;
531  }
532 
533  Int_t nInputFiles = fDigInput->GetNinputs();
534 
535  AliLoader* outputLoader = GetLoader(fDigInput->GetOutputFolderName());
536 
537  outputLoader->MakeDigitsContainer();
538 
539  TTree* oTreeD = outputLoader->TreeD();
540 
541  if (!oTreeD)
542  {
543  AliFatal("Cannot create output TreeD");
544  }
545 
546  // Loop over all the input files, and merge the sdigits found in those
547  // files.
548 
549  for ( Int_t iFile = 0; iFile < nInputFiles; ++iFile )
550  {
551  AliLoader* inputLoader = GetLoader(fDigInput->GetInputFolderName(iFile));
552 
553  inputLoader->LoadSDigits("READ");
554 
555  TTree* iTreeS = inputLoader->TreeS();
556  if (!iTreeS)
557  {
558  AliFatal(Form("Could not get access to input file #%d",iFile));
559  }
560 
561  if (!fInputDigitStores)
562  {
564  }
565 
566  AliMUONVDigitStore* dstore = static_cast<AliMUONVDigitStore*>(fInputDigitStores->At(iFile));
567 
568  dstore->Connect(*iTreeS);
569 
570  iTreeS->GetEvent(0);
571 
572  MergeWithSDigits(fDigitStore,*dstore,fDigInput->GetMask(iFile));
573 
574  inputLoader->UnloadSDigits();
575 
576  dstore->Clear();
577  }
578 
579 
580  // At this point, we do have digit arrays (one per chamber) which contains
581  // the merging of all the sdigits of the input file(s).
582  // We now massage them to apply the detector response, i.e. this
583  // is here that we do the "digitization" work.
584 
585  if (!fOutputDigitStore)
586  {
588  }
589 
590  if ( fGenerateNoisyDigits>=2 )
591  {
592  // Generate noise-only digits for trigger.
594  }
596 
597  if ( fGenerateNoisyDigits )
598  {
599  // Generate noise-only digits for tracker.
601  }
602 
603  // We generate the global and local trigger decisions.
605 
606  // Prepare output tree
607  Bool_t okD = fOutputDigitStore->Connect(*oTreeD,kFALSE);
608  Bool_t okT = fTriggerStore->Connect(*oTreeD,kFALSE);
609  if (!okD || !okT)
610  {
611  AliError(Form("Could not make branch : Digit %d Trigger %d",okD,okT));
612  return;
613  }
614 
615  // Fill the output treeD
616  oTreeD->Fill();
617 
618  // Write to the output tree(D).
619  // Please note that as GlobalTrigger, LocalTrigger and Digits are in the same
620  // tree (=TreeD) in different branches, this WriteDigits in fact writes all of
621  // the 3 branches.
622  outputLoader->WriteDigits("OVERWRITE");
623 
624  outputLoader->UnloadDigits();
625 
626  // Finally, we clean up after ourselves.
627  fTriggerStore->Clear();
628  fDigitStore->Clear();
630 }
631 
632 
633 //_____________________________________________________________________________
634 void
636 {
640 
641  AliCodeTimerAuto("",0)
642 
643  for ( Int_t i = 0; i < AliMUONConstants::NTrackingCh(); ++i )
644  {
645  AliMpDEIterator it;
646 
647  it.First(i);
648 
649  while ( !it.IsDone() )
650  {
651  for ( Int_t cathode = 0; cathode < 2; ++cathode )
652  {
653  GenerateNoisyDigitsForOneCathode(digitStore,it.CurrentDEId(),cathode);
654  }
655  it.Next();
656  }
657  }
658 }
659 
660 //_____________________________________________________________________________
661 void
663  Int_t detElemId, Int_t cathode)
664 {
667 
668  const AliMpVSegmentation* seg
670  Int_t nofPads = seg->NofPads();
671 
672  Int_t maxIx = seg->MaxPadIndexX();
673  Int_t maxIy = seg->MaxPadIndexY();
674 
675  static const Double_t kProbToBeOutsideNsigmas = TMath::Erfc(fgNSigmas/TMath::Sqrt(2.0)) / 2. ;
676 
677  Int_t nofNoisyPads = TMath::Nint(kProbToBeOutsideNsigmas*nofPads);
678  if ( !nofNoisyPads ) return;
679 
680  nofNoisyPads =
681  TMath::Nint(gRandom->Gaus(nofNoisyPads,
682  nofNoisyPads/TMath::Sqrt(nofNoisyPads)));
683 
684  AliDebug(3,Form("DE %d cath %d nofNoisyPads %d",detElemId,cathode,nofNoisyPads));
685 
686  for ( Int_t i = 0; i < nofNoisyPads; ++i )
687  {
688  Int_t ix(-1);
689  Int_t iy(-1);
690  AliMpPad pad;
691 
692  do {
693  ix = gRandom->Integer(maxIx+1);
694  iy = gRandom->Integer(maxIy+1);
695  pad = seg->PadByIndices(ix,iy,kFALSE);
696  } while ( !pad.IsValid() );
697 
698  Int_t manuId = pad.GetManuId();
699  Int_t manuChannel = pad.GetManuChannel();
700 
701  AliMUONVCalibParam* pedestals = fCalibrationData->Pedestals(detElemId,manuId);
702 
703  if (!pedestals)
704  {
705  // no pedestal available for this channel, simply give up
706  continue;
707  }
708 
709  AliMUONVDigit* d = digitStore.CreateDigit(detElemId,manuId,manuChannel,cathode);
710 
711  d->SetPadXY(ix,iy);
712 
713  d->SetCharge(0.0); // charge is zero, the ApplyResponseToTrackerDigit will add the noise
714  d->NoiseOnly(kTRUE);
715  ApplyResponseToTrackerDigit(*d,kTRUE);
716  if ( d->ADC() > 0 )
717  {
718  Bool_t ok = digitStore.Add(*d,AliMUONVDigitStore::kDeny);
719  // this can happen (that we randomly chose a digit that is
720  // already there). We simply ignore this, but log the occurence
721  // to cross-check that it's not too frequent.
722  if (!ok)
723  {
724  fLogger->Log("Collision while adding noiseOnly digit");
725  }
726  else
727  {
728  fLogger->Log("Added noiseOnly digit");
729  }
730  }
731  delete d;
732  }
733 }
734 
735 
736 //_____________________________________________________________________________
737 void
739 {
742 
743  if ( !fNoiseFunctionTrig )
744  {
745  fNoiseFunctionTrig = new TF1("AliMUONDigitizerV3::fNoiseFunctionTrig","landau",
746  50.,270.);
747 
748  fNoiseFunctionTrig->SetParameters(3.91070e+02, 9.85026, 9.35881e-02);
749  }
750 
751  AliMpPad pad[2];
752  AliMUONVDigit *d[2]={0x0};
753 
754  for ( Int_t chamberId = AliMUONConstants::NTrackingCh(); chamberId < AliMUONConstants::NCh(); ++chamberId )
755  {
756 
757  Int_t nofNoisyPads = 50;
758 
759  Float_t r=-1, fi = 0., gx, gy, x, y, z, xg01, yg01, zg, xg02, yg02;
760  AliMpDEIterator it;
761 
762  AliDebug(3,Form("Chamber %d nofNoisyPads %d",chamberId,nofNoisyPads));
763 
764  for ( Int_t i = 0; i < nofNoisyPads; ++i )
765  {
766  //printf("Generating noise %i\n",i);
767  Int_t ix(-1);
768  Int_t iy(-1);
769  Bool_t isOk = kFALSE;
770  Int_t detElemId = -1;
771  do {
772  //r = gRandom->Landau(9.85026, 9.35881e-02);
773  r = fNoiseFunctionTrig->GetRandom();
774  fi = 2. * TMath::Pi() * gRandom->Rndm();
775  //printf("r = %f\tfi = %f\n", r, fi);
776  gx = r * TMath::Cos(fi);
777  gy = r * TMath::Sin(fi);
778 
779  for ( it.First(chamberId); ! it.IsDone(); it.Next() ){
780  Int_t currDetElemId = it.CurrentDEId();
781  const AliMpVSegmentation* seg
783  if (!seg) continue;
784  Float_t deltax = seg->GetDimensionX();
785  Float_t deltay = seg->GetDimensionY();
786  GetTransformer()->Local2Global(currDetElemId, -deltax, -deltay, 0, xg01, yg01, zg);
787  GetTransformer()->Local2Global(currDetElemId, deltax, deltay, 0, xg02, yg02, zg);
788  Float_t xg1 = xg01, xg2 = xg02, yg1 = yg01, yg2 = yg02;
789  if(xg01>xg02){
790  xg1 = xg02;
791  xg2 = xg01;
792  }
793  if(yg01>yg02){
794  yg1 = yg02;
795  yg2 = yg01;
796  }
797  if(gx>=xg1 && gx<=xg2 && gy>=yg1 && gy<=yg2){
798  detElemId = currDetElemId;
799  GetTransformer()->Global2Local(detElemId, gx, gy, 0, x, y, z);
800  pad[0] = seg->PadByPosition(x,y,kFALSE);
801  if(!pad[0].IsValid()) continue;
802  isOk = kTRUE;
803  break;
804  }
805  } // loop on slats
806  } while ( !isOk );
807 
808  const AliMpVSegmentation* seg1
810  pad[1] = seg1->PadByPosition(x,y,kFALSE);
811 
812  for ( Int_t cathode = 0; cathode < 2; ++cathode ){
813  Int_t manuId = pad[cathode].GetLocalBoardId(0);
814  Int_t manuChannel = pad[cathode].GetLocalBoardChannel(0);
815  d[cathode] = digitStore.CreateDigit(detElemId,manuId,manuChannel,cathode);
816  ix = pad[cathode].GetIx();
817  iy = pad[cathode].GetIy();
818  d[cathode]->SetPadXY(ix,iy);
819  //d[cathode].SetSignal(1);
820  //d[cathode].SetPhysicsSignal(0);
821  d[cathode]->SetCharge(1);
822  d[cathode]->NoiseOnly(kTRUE);
823  AliDebug(3,Form("Adding a pure noise digit :"));
824 
825  Bool_t ok = digitStore.Add(*d[cathode],AliMUONVDigitStore::kDeny);
826  if (!ok)
827  {
828  fLogger->Log("Collision while adding TriggerNoise digit");
829  }
830  else
831  {
832  fLogger->Log("Added triggerNoise digit");
833  }
834  } //loop on cathodes
835  } // loop on noisy pads
836  } // loop on chambers
837 }
838 
839 
840 //_____________________________________________________________________________
841 AliLoader*
842 AliMUONDigitizerV3::GetLoader(const TString& folderName)
843 {
845 
846  AliDebug(2,Form("Getting access to folder %s",folderName.Data()));
847  AliLoader* loader = AliRunLoader::GetDetectorLoader("MUON",folderName.Data());
848  if (!loader)
849  {
850  AliError(Form("Could not get MuonLoader from folder %s",folderName.Data()));
851  return 0x0;
852  }
853  return loader;
854 }
855 
856 //_____________________________________________________________________________
857 Bool_t
859 {
863 
864  AliDebug(2,"");
865 
866  if ( fIsInitialized )
867  {
868  AliError("Object already initialized.");
869  return kFALSE;
870  }
871 
872  if (!fDigInput)
873  {
874  AliError("fDigInput is null !");
875  return kFALSE;
876  }
877 
878  // Load mapping
879  if ( ! AliMpCDB::LoadDDLStore() ) {
880  AliFatal("Could not access mapping from OCDB !");
881  }
882 
883  if (!fCalibrationData)
884  AliFatal("Calibration data object not defined");
885 
886  if ( !fCalibrationData->Pedestals() )
887  {
888  AliFatal("Could not access pedestals from OCDB !");
889  }
890  if ( !fCalibrationData->Gains() )
891  {
892  AliFatal("Could not access gains from OCDB !");
893  }
894 
895 
896  AliInfo("Using trigger configuration from CDB");
897 
899 
900  AliDebug(1, Form("Will %s generate noise-only digits for tracker",
901  (fGenerateNoisyDigits ? "":"NOT")));
902 
904 
905  if ( muon()->GetTriggerEffCells() ) {
906  // Apply trigger efficiency
907  AliDebug(1, "Will apply trigger efficiency");
909  }
910 
911  fIsInitialized = kTRUE;
912  return kTRUE;
913 }
914 
915 
916 //_____________________________________________________________________________
917 Int_t AliMUONDigitizerV3::GetArrayIndex(Int_t cathode, Int_t trigCh, Int_t localCircuit)
918 {
920  return
922  AliMUONConstants::NTriggerCircuit() * trigCh + localCircuit-1;
923 }
924 
925 
926 //_____________________________________________________________________________
927 void
929  const AliMUONVDigitStore& input,
930  Int_t mask)
931 {
933 
934  if ( !outputStore ) outputStore = input.Create();
935 
936  TIter next(input.CreateIterator());
937  AliMUONVDigit* sdigit;
938 
939  while ( ( sdigit = static_cast<AliMUONVDigit*>(next()) ) )
940  {
941  // Update the track references using the mask.
942  // FIXME: this is dirty, for backward compatibility only.
943  // Should re-design all this way of keeping track of MC information...
944  if ( mask ) sdigit->PatchTracks(mask);
945  // Then add or update the digit to the output.
946  AliMUONVDigit* added = outputStore->Add(*sdigit,AliMUONVDigitStore::kMerge);
947  if (!added)
948  {
949  AliError("Could not add digit in merge mode");
950  }
951  }
952 }
953 
954 //_____________________________________________________________________________
955 TF1*
957 {
959  static TF1* f = 0x0;
960  if (!f)
961  {
962  f = new TF1("AliMUONDigitizerV3::NoiseFunction","gaus",fgNSigmas,fgNSigmas*10);
963  f->SetParameters(1,0,1);
964  }
965  return f;
966 }
967 
968 //_____________________________________________________________________________
970  AliMUONRecoParam* recoParam)
971 {
972  fCalibrationData = calibrationData;
973  fRecoParam = recoParam;
974  if (!fRecoParam)
975  {
976  AliError("Cannot work (e.g. decalibrate) without recoparams !");
977  }
978 }
979 
virtual Int_t ManuChannel() const =0
The channel within ManuId() this digit belongs to (manuChannel for tracker, localBoardChannel for tri...
The iterator over detection elements.
static Float_t InvalidFloatValue()
Return 1E38 as invalid float value.
TF1 * fNoiseFunctionTrig
! function to get noise disribution on trig. chambers
const AliMpVSegmentation * GetMpSegmentation(Int_t detElemId, AliMp::CathodType cath, Bool_t warn=true) const
Interface for a digit container.
void Print(Option_t *opt="") const
Implementation of AliMUONVTriggerStore.
static AliMpSegmentation * Instance(Bool_t warn=true)
virtual Float_t ValueAsFloat(Int_t i, Int_t j=0) const =0
#define TObjArray
static Int_t NTrackingCh()
Return number of tracking chambers.
Int_t GetIy() const
Definition: AliMpPad.cxx:280
virtual Int_t NofPads() const =0
Return the number of pads in the detection element.
Int_t fGenerateNoisyDigits
! whether or not we should generate noise-only digits for tracker (1) and trigger (2) ...
Top container class for geometry transformations.
Int_t GetManuId() const
Definition: AliMpPad.cxx:256
Bool_t IsDone() const
TFile f("CalibObjects.root")
virtual Int_t ADC() const =0
Raw ADC value of this digit.
Int_t Log(const char *message)
AliMUONRecoParam * fRecoParam
! reco params (to know how to decalibrate) (not owner)
virtual void Digitize(Option_t *opt="")
Bool_t fIsInitialized
are we initialized ?
AliMUONLogger * fLogger
for noise-only digit generation and zero-suppression
static Bool_t LoadDDLStore(Bool_t warn=false)
Definition: AliMpCDB.cxx:149
Int_t CurrentDEId() const
AliDetector class for MUON subsystem providing simulation data management.
Definition: AliMUON.h:37
Int_t GetArrayIndex(Int_t cathode, Int_t trigCh, Int_t localCircuit)
Class with MUON reconstruction parameters.
static Int_t DecalibrateTrackerDigit(const AliMUONVCalibParam &pedestals, const AliMUONVCalibParam *gains, Int_t channel, Float_t charge, Bool_t addNoise=kFALSE, Bool_t noiseOnly=kFALSE, const TString &calibrationMode="NOGAIN")
Utilities for trigger (check if pad is masked)
void ApplyResponseToTriggerDigit(AliMUONVDigit &digit)
virtual Bool_t IsChargeInFC() const
Whether this digit has charge in femto coulomb (see note 1 in AliMUONVDigit.cxx)
Definition: AliMUONVDigit.h:73
virtual void SetCharge(Float_t q)=0
Set the charge of this digit.
virtual Float_t Charge() const =0
The charge of this digit, calibrated or not depending on IsCalibrated()
static Float_t DefaultA0()
virtual AliMpPad PadByIndices(Int_t ix, Int_t iy, Bool_t warning=true) const =0
Find pad by indices.
virtual Int_t DetElemId() const =0
The detection element this digit belongs to.
virtual Double_t GetDimensionY() const =0
Return the y half-sizes of the detection element.
virtual void NoiseOnly(Bool_t=kTRUE)
Set the noiseOnly status.
Definition: AliMUONVDigit.h:60
virtual TIterator * CreateIterator() const =0
Create an iterator to loop over all our digits.
Option_t * GetCalibrationMode() const
AliMUONVDigitStore * fDigitStore
! temporary digits
ClassImp(TPCGenInfo)
Definition: AliTPCCmpNG.C:254
AliMUONTriggerChamberEfficiency * fTriggerEfficiency
! trigger efficiency map
Int_t GetManuChannel() const
Definition: AliMpPad.cxx:264
Manager class for muon trigger electronics.
A logger that keeps track of the number of times a message appeared.
Definition: AliMUONLogger.h:29
Container of calibration values for a given number of channels.
void ApplyResponse(const AliMUONVDigitStore &store, AliMUONVDigitStore &filteredStore)
void IsTriggered(Int_t detElemId, Int_t localBoard, Bool_t &trigBend, Bool_t &trigNonBend) const
virtual AliMUONVDigitStore * Create() const =0
Create an (empty) object of the same concrete class as *this.
virtual void SetADC(Int_t adc)=0
Set the ADC value.
void MergeWithSDigits(AliMUONVDigitStore *&digitStore, const AliMUONVDigitStore &input, Int_t mask)
virtual Int_t MaxPadIndexY() const =0
Return maximum pad index in Y direction.
virtual Int_t Cathode() const =0
Cathode number this digit is on (0 or 1)
Bool_t IsMasked(const AliMUONVDigit &digit) const
MUON global constants.
virtual Int_t ID0() const
First id of this object.
virtual Int_t ID1() const
Second id of this object (might not be required)
AliMUONTriggerUtilities * fTriggerUtilities
! Trigger utilities for masks
static Float_t DefaultCapa()
static AliMp::StationType GetStationType(Int_t detElemId)
void GenerateNoisyDigitsForTrigger(AliMUONVDigitStore &digitStore)
const AliMUONGeometryTransformer * GetGeometryTransformer() const
Definition: AliMUON.cxx:243
static Float_t DefaultADC2MV()
virtual Double_t GetDimensionX() const =0
Return the x half-sizes of the detection element.
virtual void SetPadXY(Int_t padx, Int_t pady)=0
Set the ix and iy of this digit.
AliMp::CathodType GetCathodType(Int_t cathodNumber)
Convert integer number in enum;.
static Int_t NTriggerCh()
Return number of trigger chambers.
AliRun * gAlice
Int_t GetLocalBoardId(Int_t i) const
Definition: AliMpPad.cxx:347
AliMUONVStore * Pedestals() const
Get the pedestal store.
AliMUONTriggerEfficiencyCells * TriggerEfficiency() const
Get the trigger efficiency map.
virtual Int_t ValueAsInt(Int_t i, Int_t j=0) const =0
virtual Bool_t IsNoiseOnly() const =0
Whether this (simulated) digit is purely noise.
TObjArray * fInputDigitStores
! input digit stores (one per input file
static Int_t NCh()
Return number of chambers.
Bool_t IsValid() const
Return validity.
Definition: AliMpPad.h:89
void GenerateNoisyDigits(AliMUONVDigitStore &digitStore)
static Double_t fgNSigmas
number of sigmas above ped to use
virtual AliMpPad PadByPosition(Double_t x, Double_t y, Bool_t warning=true) const =0
Find pad by position.
Single entry point to access MUON calibration data.
Int_t GetIx() const
Definition: AliMpPad.cxx:272
AliMUON * muon()
AliMUONCalibrationData * fCalibrationData
! pointer to access calib parameters
The abstract base class for the segmentation.
trigger stations (slats)
AliMUONVTriggerStore * fTriggerStore
! trigger objects
virtual Int_t MaxPadIndexX() const =0
Return maximum pad index in X direction.
AliLoader * GetLoader(const TString &foldername)
virtual Int_t ManuId() const =0
The electronic card id this digit belongs to (manuId for tracker, localboardId for trigger) ...
ABC of a MUON digit.
Definition: AliMUONVDigit.h:18
TArrayI fEfficiencyResponse
! Local board efficiency response
Class which encapsuate all information about a pad.
Definition: AliMpPad.h:22
Calculate, apply and possibly draw trigger chamber efficiency.
virtual void Clear(Option_t *opt="")=0
Clear ourselves (i.e. Reset)
virtual void Digits2Trigger(const AliMUONVDigitStore &digitStore, AliMUONVTriggerStore &triggerStore)
virtual AliMUONVDigit * CreateDigit(Int_t detElemId, Int_t manuId, Int_t manuChannel, Int_t cathode) const =0
Create a digit.
Digitizer (from SDigit to Digit), performing digit de-calibration.
static TF1 * NoiseFunction()
static Int_t NTriggerCircuit()
Return number of trigger circuits.
Int_t GetLocalBoardChannel(Int_t i) const
Definition: AliMpPad.cxx:358
virtual Bool_t Connect(TTree &tree, Bool_t alone=kTRUE) const
Connect us to a TTree (only valid if CanConnect()==kTRUE)
AliMUONVStore * Gains() const
Get all the gains.
void SetCalibrationData(AliMUONCalibrationData *calibrationData, AliMUONRecoParam *recoParam)
Set calibration (and recoparam) data.
void GenerateNoisyDigitsForOneCathode(AliMUONVDigitStore &digitStore, Int_t detElemId, Int_t cathode)
virtual Bool_t Add(TObject *object)
Add an object, if it is of the right class.
void ApplyResponseToTrackerDigit(AliMUONVDigit &digit, Bool_t addNoise)
AliMUONTriggerElectronics * fTriggerProcessor
pointer to the trigger part of the job
virtual void PatchTracks(Int_t)
Patch track with a mask.
AliMUONVDigitStore * fOutputDigitStore
! digits we'll output to disk