]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - PWG/EMCAL/AliEmcalTriggerMaker.cxx
Merge remote-tracking branch 'origin/flatdev' into mergeFlat2Master
[u/mrichter/AliRoot.git] / PWG / EMCAL / AliEmcalTriggerMaker.cxx
index a12ba3ded615c6ae55faf2b1186ce0863173badf..d76b70d798dae540a76cc5a63ff08709f5f55f6d 100644 (file)
@@ -1,4 +1,4 @@
-// $Id$
+// $Id: AliEmcalTriggerMaker.cxx 64593 2013-10-18 10:23:58Z loizides $
 //
 // Class to make emcal particles in AOD/ESD events.
 //
@@ -33,7 +33,8 @@ AliEmcalTriggerMaker::AliEmcalTriggerMaker() :
   fCaloTriggersOut(0),
   fCaloTriggerSetupOut(0),
   fSimpleOfflineTriggers(0),
-  fV0(0)
+  fV0(0),
+  fITrigger(0)
 {
   // Constructor.
   for( int i = 0; i < 4; i++ )
@@ -50,7 +51,8 @@ AliEmcalTriggerMaker::AliEmcalTriggerMaker(const char *name) :
   fCaloTriggersOut(0),
   fCaloTriggerSetupOut(0),
   fSimpleOfflineTriggers(0),
-  fV0(0)
+  fV0(0),
+  fITrigger(0)
 {
   // Constructor.
   for( int i = 0; i < 4; i++ )
@@ -117,18 +119,15 @@ Bool_t AliEmcalTriggerMaker::Run()
   // Create the emcal particles
 
   Short_t cellId;
-  Int_t globCol, globRow, tBits, cellAbsId[4], v0[2];
-  Int_t absId, adcAmp;
-  Int_t i, j, k, iMain, iMainSimple, cmCol, cmRow, cmiCellCol, cmiCellRow, nCell, iCell;
-  Int_t jetTrigger, iTriggers;
-       Int_t patchADC[48][64];
-  Double_t amp, ca, eMain, eMainSimple, cmiCol, cmiRow;
+  Int_t globCol, globRow, v0[2];
+  Int_t absId, adcAmp, tBits;
+  Int_t i, j, nCell, iCell;
+  Double_t amp;
   ULong64_t v0S, thresh;
   Bool_t isOfflineSimple;
   
-  TVector3 centerGeo, center1, center2, centerMass, edge1, edge2, vertex;
-  
-  AliEmcalTriggerPatchInfo *trigger;
+  AliEmcalTriggerPatchInfo *trigger, *triggerMainJet, *triggerMainGamma;
+  AliEmcalTriggerPatchInfo *triggerMainJetSimple, *triggerMainGammaSimple;
 
   // delete patch array, clear setup object
   fCaloTriggersOut->Delete();
@@ -146,26 +145,30 @@ Bool_t AliEmcalTriggerMaker::Run()
     AliError(Form("V0 container %s not available.", fV0InName.Data()));
     return kTRUE;
   }
-
+  
+  // do not process, if sooner than 11h period
+  // 160683 ??
+  if( InputEvent()->GetRunNumber() < 167693 )
+    return kTRUE;
+//   // do not process any MC, since no MC was generated with correct
+//   // EMCal trigger L1 jet trigger simulation, yet
+//   // productions will be enabled, once some correct once are produced
+//   if( MCEvent() != 0 )
+//     return kTRUE;
+  
   // must reset before usage, or the class will fail 
   fCaloTriggers->Reset();
-  for (i=0; i<2; i++) {
-    fEGA[i] = 0;
-    fEJE[i] = 0;
-  }
-  // first run over the patch array to compose a map of 2x2 patch energies
+
+       // first run over the patch array to compose a map of 2x2 patch energies
   // which is then needed to construct the full patch ADC energy
   // class is not empty
-  Int_t isMC = 0;
-  if (MCEvent()) isMC = 1;
-  Int_t offSet = (1 - isMC) * kTriggerTypeEnd;
-
   if( fCaloTriggers->GetEntries() > 0 ){
                
-    // zero the array
-    for( i = 0; i < 48; i++ )
-      for( j = 0; j < 64; j++ )
-       patchADC[i][j] = 0;
+               // zero the array
+               for( i = 0; i < 48; i++ )
+                       for( j = 0; j < 64; j++ )
+                               fPatchADC[i][j] = 0;
                
     // go throuth the trigger channels
     while( fCaloTriggers->Next() ){
@@ -177,18 +180,10 @@ Bool_t AliEmcalTriggerMaker::Run()
       // as -1, neglect those :\\ wth
       fCaloTriggers->GetL1TimeSum( adcAmp );
                        if( adcAmp > -1 )
-                               patchADC[globCol][globRow] = adcAmp;
-      
-      fCaloTriggers->GetTriggerBits( tBits );
+                               fPatchADC[globCol][globRow] = adcAmp;
       
-      if (tBits) {
-        if ((tBits >> (offSet + kL1GammaHigh)) & 1 ) fEGA[0] = 1;
-        if ((tBits >> (offSet + kL1GammaLow )) & 1 ) fEGA[1] = 1;
-        if ((tBits >> (offSet + kL1JetHigh  )) & 1 ) fEJE[0] = 1;
-        if ((tBits >> (offSet + kL1JetLow   )) & 1 ) fEJE[1] = 1;
-      }
-    } // patches
-  } // array not empty
+               } // patches
+       } // array not empty
   
   // fill the array for offline trigger processing
   // using calibrated cell energies
@@ -251,162 +246,91 @@ Bool_t AliEmcalTriggerMaker::Run()
   // class is not empty
   if( fCaloTriggers->GetEntries() > 0 ||  fSimpleOfflineTriggers->GetEntries() > 0 ){
  
-    iTriggers = 0;
-    iMain = -1;
-    eMain = -1;
-    iMainSimple = -1;
-    eMainSimple = -1;
-
-    // save primary vertex in vector
-    vertex.SetXYZ( fVertex[0], fVertex[1], fVertex[2] );
+    fITrigger = 0;
+               triggerMainGamma = 0;
+               triggerMainJet = 0;
+               triggerMainGammaSimple = 0;
+               triggerMainJetSimple = 0;
 
     // go throuth the trigger channels, real first, then offline
     while( NextTrigger( isOfflineSimple ) ){
-      // check if jet trigger low or high
-      if( ! isOfflineSimple )
-       fCaloTriggers->GetTriggerBits( tBits );
-      else
-        fSimpleOfflineTriggers->GetTriggerBits( tBits );
       
-      jetTrigger = 0;
-      if(( tBits >> ( offSet + kL1JetLow )) & 1 )
-        jetTrigger = 1;
-      if(( tBits >> ( offSet + kL1JetHigh )) & 1)
-        jetTrigger = jetTrigger | 2;
+                       // process jet
+                       trigger = ProcessPatch( 0, isOfflineSimple );
+                       
+                       // save main jet triggers in event
+                       if( trigger != 0 ){
+                               // check if more energetic than others for main patch marking
+                               if( ! isOfflineSimple ){
+                                       if( triggerMainJet == 0 )
+                                               triggerMainJet = trigger;
+                                       else if( triggerMainJet->GetPatchE() < trigger->GetPatchE() )
+                                               triggerMainJet = trigger;
+                               }
+                               else{
+                                       if( triggerMainJetSimple == 0 )
+                                               triggerMainJetSimple = trigger;
+                                       else if( triggerMainJetSimple->GetPatchE() < trigger->GetPatchE() )
+                                               triggerMainJetSimple = trigger;
+                               }
+                       }
       
-      if( jetTrigger == 0 )
-        continue;
+                       // process gamma
+                       trigger = ProcessPatch( 1, isOfflineSimple );
+                       
+                       // save main gamma triggers in event
+                       if( trigger != 0 ){
+                               // check if more energetic than others for main patch marking
+                               if( ! isOfflineSimple ){
+                                       if( triggerMainGamma == 0 )
+                                               triggerMainGamma = trigger;
+                                       else if( triggerMainGamma->GetPatchE() < trigger->GetPatchE() )
+                                               triggerMainGamma = trigger;
+                               }
+                               else{
+                                       if( triggerMainGammaSimple == 0 )
+                                               triggerMainGammaSimple = trigger;
+                                       else if( triggerMainGammaSimple->GetPatchE() < trigger->GetPatchE() )
+                                               triggerMainGammaSimple = trigger;
+                               }
+                       }
+
+//       cout << " pi:" << trigger->GetPhiMin() << " px:" << trigger->GetPhiMax();
+//       cout << " pg:" << trigger->GetPhiGeo() << " " << (trigger->GetPhiMin()+trigger->GetPhiMax()) / 2.;
+//       cout << " pc:" << trigger->GetPhiCM();
+//       cout << " ei:" << trigger->GetEtaMin() << " ex:" << trigger->GetEtaMax();
+//       cout << " eg:" << trigger->GetEtaGeo() << " " << (trigger->GetEtaMin()+trigger->GetEtaMax()) / 2.;
+//       cout << " ec:" << trigger->GetEtaCM();
+//       cout << " e:" << trigger->GetPatchE();
+//       cout << " jl:" << trigger->IsJetLow() << " jh:" << trigger->IsJetHigh() << endl;
       
-      // get position in global 2x2 tower coordinates
-      // A0 left bottom (0,0)
-      if( ! isOfflineSimple )
-       fCaloTriggers->GetPosition( globCol, globRow );
-      else
-        fSimpleOfflineTriggers->GetPosition( globCol, globRow );
-
-      // get the absolute trigger ID
-      fGeom->GetAbsFastORIndexFromPositionInEMCAL( globCol, globRow, absId );
-      // convert to the 4 absId of the cells composing the trigger channel
-      fGeom->GetCellIndexFromFastORIndex( absId, cellAbsId );
-      
-      // get low left edge (eta max, phi min)
-      fGeom->GetGlobal( cellAbsId[0], edge1 );
-      
-      // sum the available energy in the 32/32 window of cells
-      // step over trigger channels and get all the corresponding cells
-      // make CM
-      amp = 0;
-      cmiCol = 0;
-      cmiRow = 0;
-      adcAmp = 0;
-      for( i = 0; i < 16; i++ ){
-        for( j = 0; j < 16; j++ ){
-          // get the 4 cells composing the trigger channel
-          fGeom->GetAbsFastORIndexFromPositionInEMCAL( globCol+i, globRow+j, absId );
-          fGeom->GetCellIndexFromFastORIndex( absId, cellAbsId );
-          // add amplitudes and find patch edges
-          for( k = 0; k < 4; k++ ){
-            ca = fCaloCells->GetCellAmplitude( cellAbsId[k] );
-            amp += ca;
-            cmiCol += ca*(Double_t)i;
-            cmiRow += ca*(Double_t)j;
-          }
-          // add the STU ADCs in the patch
-          if( ! isOfflineSimple )
-          adcAmp += patchADC[globCol+i][globRow+j];
-          else
-            adcAmp += fPatchADCSimple[globCol+i][globRow+j];
-        }
-      } // 32x32 cell window
-      if( amp == 0 ){
-        AliDebug(2,"EMCal trigger patch with 0 energy.");
-        continue;
-      }
-      
-      // get the CM and patch index
-      cmiCol /= amp;
-      cmiRow /= amp;
-      cmCol = globCol + (Int_t)cmiCol;
-      cmRow = globRow + (Int_t)cmiRow;
-
-      // get the patch and corresponding cells
-      fGeom->GetAbsFastORIndexFromPositionInEMCAL( cmCol, cmRow, absId );
-      fGeom->GetCellIndexFromFastORIndex( absId, cellAbsId );
-
-      // find which out of the 4 cells is closest to CM and get it's position
-      cmiCellCol = TMath::Nint( cmiCol * 2. );
-      cmiCellRow = TMath::Nint( cmiRow * 2. );
-      fGeom->GetGlobal( cellAbsId[(cmiCellRow%2)*2 + cmiCellCol%2], centerMass );
-      
-      // get up right edge (eta min, phi max)
-      // get the absolute trigger ID
-      fGeom->GetAbsFastORIndexFromPositionInEMCAL( globCol+15, globRow+15, absId );
-      // convert to the 4 absId of the cells composing the trigger channel
-      fGeom->GetCellIndexFromFastORIndex( absId, cellAbsId );
-
-      fGeom->GetGlobal( cellAbsId[3], edge2 );
-      
-      // get the geometrical center as an average of two diagonally
-      // adjacent patches in the center
-      // picking two diagonally closest cells from the patches
-      fGeom->GetAbsFastORIndexFromPositionInEMCAL( globCol+7, globRow+7, absId );
-      fGeom->GetCellIndexFromFastORIndex( absId, cellAbsId );
-      fGeom->GetGlobal( cellAbsId[3], center1 );
-      
-      fGeom->GetAbsFastORIndexFromPositionInEMCAL( globCol+8, globRow+8, absId );
-      fGeom->GetCellIndexFromFastORIndex( absId, cellAbsId );
-      fGeom->GetGlobal( cellAbsId[0], center2 );
-      
-      centerGeo = center1;
-      centerGeo += center2;
-      centerGeo *= 0.5;
-      
-      // relate all to primary vertex
-      centerGeo -= vertex;
-      centerMass -= vertex;
-      edge1 -= vertex;
-      edge2 -= vertex;
-    
-      // save the trigger object
-      new ((*fCaloTriggersOut)[iTriggers])AliEmcalTriggerPatchInfo();
-      trigger = (AliEmcalTriggerPatchInfo*)fCaloTriggersOut->At( iTriggers );
-      iTriggers++;
-      
-      trigger->SetCenterGeo( centerGeo, amp );
-      trigger->SetCenterMass( centerMass, amp );
-      trigger->SetEdge1( edge1, amp );
-      trigger->SetEdge2( edge2, amp );
-      trigger->SetADCAmp( adcAmp );
-      trigger->SetTriggerBits( tBits );
-      trigger->SetEdgeCell( globCol*2, globRow*2 ); // from triggers to cells
-      trigger->SetOffSet(offSet);
-
-      // check if more energetic than others for main patch marking
-      if( ! isOfflineSimple && eMain < amp ){
-        eMain = amp;
-        iMain = iTriggers - 1;
-      }
-      if( isOfflineSimple && eMainSimple < amp ){
-        eMainSimple = amp;
-        iMainSimple = iTriggers - 1;
-      }
     } // triggers
     
     // mark the most energetic patch as main
     // for real and also simple offline
-    if( iMain > -1 ){
-      trigger = (AliEmcalTriggerPatchInfo*)fCaloTriggersOut->At( iMain );
-      tBits = trigger->GetTriggerBits();
+    if( triggerMainJet != 0 ){
+      tBits = triggerMainJet->GetTriggerBits();
+      // main trigger flag
+      tBits = tBits | ( 1 << 24 );
+      triggerMainJet->SetTriggerBits( tBits );
+    }
+    if( triggerMainJetSimple != 0 ){
+      tBits = triggerMainJetSimple->GetTriggerBits();
       // main trigger flag
       tBits = tBits | ( 1 << 24 );
-      trigger->SetTriggerBits( tBits );
+      triggerMainJetSimple->SetTriggerBits( tBits );
     }
-    if( iMainSimple > -1 ){
-      trigger = (AliEmcalTriggerPatchInfo*)fCaloTriggersOut->At( iMainSimple );
-      tBits = trigger->GetTriggerBits();
+    if( triggerMainGamma != 0 ){
+      tBits = triggerMainGamma->GetTriggerBits();
       // main trigger flag
       tBits = tBits | ( 1 << 24 );
-      trigger->SetTriggerBits( tBits );
+      triggerMainGamma->SetTriggerBits( tBits );
+    }
+    if( triggerMainGammaSimple != 0 ){
+      tBits = triggerMainGammaSimple->GetTriggerBits();
+      // main trigger flag
+      tBits = tBits | ( 1 << 24 );
+      triggerMainGammaSimple->SetTriggerBits( tBits );
     }
     
   } // there are some triggers
@@ -414,18 +338,198 @@ Bool_t AliEmcalTriggerMaker::Run()
   return kTRUE;
 }
 
+//________________________________________________________________________
+AliEmcalTriggerPatchInfo* AliEmcalTriggerMaker::ProcessPatch( Int_t type, Bool_t isOfflineSimple ){
+
+       
+  Int_t globCol, globRow, tBits, cellAbsId[4];
+  Int_t absId, adcAmp;
+  Int_t i, j, k, cmCol, cmRow, cmiCellCol, cmiCellRow;
+  Double_t amp, ca, cmiCol, cmiRow;
+  
+  TVector3 centerGeo, center1, center2, centerMass, edge1, edge2, vertex, cellCoor;
+  
+  AliEmcalTriggerPatchInfo *trigger;
+
+       // check if jet trigger low or high
+       if( ! isOfflineSimple )
+               fCaloTriggers->GetTriggerBits( tBits );
+       else
+               fSimpleOfflineTriggers->GetTriggerBits( tBits );
+       
+       if(( type == 0 && ! IsEJE( tBits )) || ( type == 1 && ! IsEGA( tBits )))
+               return 0;
+       
+       // save primary vertex in vector
+       vertex.SetXYZ( fVertex[0], fVertex[1], fVertex[2] );
+
+       // get position in global 2x2 tower coordinates
+       // A0 left bottom (0,0)
+       if( ! isOfflineSimple )
+               fCaloTriggers->GetPosition( globCol, globRow );
+       else
+               fSimpleOfflineTriggers->GetPosition( globCol, globRow );
+
+       // get the absolute trigger ID
+       fGeom->GetAbsFastORIndexFromPositionInEMCAL( globCol, globRow, absId );
+       // convert to the 4 absId of the cells composing the trigger channel
+       fGeom->GetCellIndexFromFastORIndex( absId, cellAbsId );
+       
+       // get low left edge (eta max, phi min)
+       fGeom->GetGlobal( cellAbsId[0], edge1 );
+       
+       // sum the available energy in the 32/32 window of cells
+       // step over trigger channels and get all the corresponding cells
+       // make CM
+       amp = 0;
+       cmiCol = 0;
+       cmiRow = 0;
+       adcAmp = 0;
+       if( IsEJE( tBits ) && type == 0 ){
+               for( i = 0; i < 16; i++ ){
+                       for( j = 0; j < 16; j++ ){
+                               // get the 4 cells composing the trigger channel
+                               fGeom->GetAbsFastORIndexFromPositionInEMCAL( globCol+i, globRow+j, absId );
+                               fGeom->GetCellIndexFromFastORIndex( absId, cellAbsId );
+                               // add amplitudes and find patch edges
+                               for( k = 0; k < 4; k++ ){
+                                       ca = fCaloCells->GetCellAmplitude( cellAbsId[k] );
+                                       fGeom->GetGlobal( cellAbsId[k], cellCoor );
+                                       amp += ca;
+                                       cmiCol += ca*(Double_t)i;
+                                       cmiRow += ca*(Double_t)j;
+                               }
+                               // add the STU ADCs in the patch
+                               if( ! isOfflineSimple )
+                                       adcAmp += fPatchADC[globCol+i][globRow+j];
+                               else
+                                       adcAmp += fPatchADCSimple[globCol+i][globRow+j];
+                       }
+               } // 32x32 cell window
+       }
+       
+       if( IsEGA( tBits ) && type == 1 ){
+               for( i = 0; i < 2; i++ ){
+                       for( j = 0; j < 2; j++ ){
+                               // get the 4 cells composing the trigger channel
+                               fGeom->GetAbsFastORIndexFromPositionInEMCAL( globCol+i, globRow+j, absId );
+                               fGeom->GetCellIndexFromFastORIndex( absId, cellAbsId );
+                               // add amplitudes and find patch edges
+                               for( k = 0; k < 4; k++ ){
+                                       ca = fCaloCells->GetCellAmplitude( cellAbsId[k] );
+                                       fGeom->GetGlobal( cellAbsId[k], cellCoor );
+                                       amp += ca;
+                                       cmiCol += ca*(Double_t)i;
+                                       cmiRow += ca*(Double_t)j;
+                               }
+                               // add the STU ADCs in the patch
+                               if( ! isOfflineSimple )
+                                       adcAmp += fPatchADC[globCol+i][globRow+j];
+                               else
+                                       adcAmp += fPatchADCSimple[globCol+i][globRow+j];
+                       }
+               } // 4x4 cell window
+       }
+       if( amp == 0 ){
+               AliDebug(2,"EMCal trigger patch with 0 energy.");
+               return 0;
+       }
+       
+       // get the CM and patch index
+       cmiCol /= amp;
+       cmiRow /= amp;
+       cmCol = globCol + (Int_t)cmiCol;
+       cmRow = globRow + (Int_t)cmiRow;
+
+       // get the patch and corresponding cells
+       fGeom->GetAbsFastORIndexFromPositionInEMCAL( cmCol, cmRow, absId );
+       fGeom->GetCellIndexFromFastORIndex( absId, cellAbsId );
+
+       // find which out of the 4 cells is closest to CM and get it's position
+       cmiCellCol = TMath::Nint( cmiCol * 2. );
+       cmiCellRow = TMath::Nint( cmiRow * 2. );
+       fGeom->GetGlobal( cellAbsId[(cmiCellRow%2)*2 + cmiCellCol%2], centerMass );
+       
+       // get up right edge (eta min, phi max)
+       // get the absolute trigger ID
+       if( type == 0 )
+               fGeom->GetAbsFastORIndexFromPositionInEMCAL( globCol+15, globRow+15, absId );
+       else if( type == 1)
+               fGeom->GetAbsFastORIndexFromPositionInEMCAL( globCol+1, globRow+1, absId );
+       // convert to the 4 absId of the cells composing the trigger channel
+       fGeom->GetCellIndexFromFastORIndex( absId, cellAbsId );
+
+       fGeom->GetGlobal( cellAbsId[3], edge2 );
+       
+       // get the geometrical center as an average of two diagonally
+       // adjacent patches in the center
+       // picking two diagonally closest cells from the patches
+       if( type == 0 )
+               fGeom->GetAbsFastORIndexFromPositionInEMCAL( globCol+7, globRow+7, absId );
+       else if( type == 1 )
+               fGeom->GetAbsFastORIndexFromPositionInEMCAL( globCol, globRow, absId );
+
+       fGeom->GetCellIndexFromFastORIndex( absId, cellAbsId );
+       fGeom->GetGlobal( cellAbsId[3], center1 );
+       
+       if( type == 0 )
+               fGeom->GetAbsFastORIndexFromPositionInEMCAL( globCol+8, globRow+8, absId );
+       else if( type == 1 )
+               fGeom->GetAbsFastORIndexFromPositionInEMCAL( globCol+1, globRow+1, absId );
+
+       fGeom->GetCellIndexFromFastORIndex( absId, cellAbsId );
+       fGeom->GetGlobal( cellAbsId[0], center2 );
+       
+       centerGeo = center1;
+       centerGeo += center2;
+       centerGeo *= 0.5;
+       
+       // relate all to primary vertex
+       centerGeo -= vertex;
+       centerMass -= vertex;
+       edge1 -= vertex;
+       edge2 -= vertex;
+       
+       // fix tbits .. remove the unwanted type triggers
+       if( type == 0 )
+               tBits = tBits & ~( 1 << (kTriggerTypeEnd + kL1GammaLow) | 1 << (kTriggerTypeEnd + kL1GammaHigh) | 1 << (kL1GammaLow) | 1 << (kL1GammaHigh));
+       else if( type == 1 )
+               tBits = tBits & ~( 1 << (kTriggerTypeEnd + kL1JetLow) | 1 << (kTriggerTypeEnd + kL1JetHigh) | 1 << (kL1JetLow) | 1 << (kL1JetHigh));
+
+       // save the trigger object
+       new ((*fCaloTriggersOut)[fITrigger])AliEmcalTriggerPatchInfo();
+       trigger = (AliEmcalTriggerPatchInfo*)fCaloTriggersOut->At( fITrigger );
+       fITrigger++;
+       
+       Int_t isMC = MCEvent() ? 1 : 0;
+       Int_t offSet = (1 - isMC) * kTriggerTypeEnd;
+
+       trigger->SetCenterGeo( centerGeo, amp );
+       trigger->SetCenterMass( centerMass, amp );
+       trigger->SetEdge1( edge1, amp );
+       trigger->SetEdge2( edge2, amp );
+       trigger->SetADCAmp( adcAmp );
+       trigger->SetTriggerBits( tBits );
+       trigger->SetOffSet(offSet);
+       trigger->SetEdgeCell( globCol*2, globRow*2 ); // from triggers to cells
+       
+       return trigger;
+       
+}
+
+
 //________________________________________________________________________
 void AliEmcalTriggerMaker::RunSimpleOfflineTrigger() 
 {
   // runs simple offline trigger algorithm
+  
+  // it creates separate patches for jet and gamma triggers
+  // on the same positions (different from STU reconstruction behavior)
+  // TODO:: change to merge
 
   Int_t i, j, k, l, tBits, tSum;
   TArrayI tBitsArray, rowArray, colArray;
   
-  Int_t isMC = 0;
-  if (MCEvent()) isMC = 1;
-  Int_t offSet = (1 - isMC) * kTriggerTypeEnd;
-
   // 0 thresholds = no processing
   if( fCaloTriggerSetupOut->GetThresholdJetLowSimple() == 0 &&
     fCaloTriggerSetupOut->GetThresholdJetHighSimple() == 0 )
@@ -445,9 +549,9 @@ void AliEmcalTriggerMaker::RunSimpleOfflineTrigger()
       
       // check thresholds
       if( tSum > fCaloTriggerSetupOut->GetThresholdJetLowSimple() )
-        tBits = tBits | ( 1 << ( offSet + kL1JetLow ));
+        tBits = tBits | ( 1 << ( kTriggerTypeEnd + kL1JetLow ));
       if( tSum > fCaloTriggerSetupOut->GetThresholdJetHighSimple() )
-        tBits = tBits | ( 1 << ( offSet + kL1JetHigh ));
+        tBits = tBits | ( 1 << ( kTriggerTypeEnd + kL1JetHigh ));
       
       // add trigger values
       if( tBits != 0 ){
@@ -465,6 +569,41 @@ void AliEmcalTriggerMaker::RunSimpleOfflineTrigger()
     }
   } // trigger algo
   
+  // 4x4 trigger algo, stepping by 2 towers (= 1 trigger channel)
+  for( i = 0; i < 46; i ++ ){
+    for( j = 0; j < 62; j ++ ){
+      
+      tSum = 0;
+      tBits = 0;
+      
+      // window
+      for( k = 0; k < 2; k++ )
+        for( l = 0; l < 2; l++ )
+          tSum += (ULong64_t)fPatchADCSimple[i+k][j+l];
+      
+      // check thresholds
+      if( tSum > fCaloTriggerSetupOut->GetThresholdGammaLowSimple() )
+        tBits = tBits | ( 1 << ( kTriggerTypeEnd + kL1GammaLow ));
+      if( tSum > fCaloTriggerSetupOut->GetThresholdGammaHighSimple() )
+        tBits = tBits | ( 1 << ( kTriggerTypeEnd + kL1GammaHigh ));
+      
+      // add trigger values
+      if( tBits != 0 ){
+        // add offline bit
+        tBits = tBits | ( 1 << 25 );
+        
+        tBitsArray.Set( tBitsArray.GetSize() + 1 );
+        colArray.Set( colArray.GetSize() + 1 );
+        rowArray.Set( rowArray.GetSize() + 1 );
+        
+        tBitsArray[tBitsArray.GetSize()-1] = tBits;
+        colArray[colArray.GetSize()-1] = i;
+        rowArray[rowArray.GetSize()-1] = j;
+      }
+    }
+  } // trigger algo
+  
+  
   // save in object
   fSimpleOfflineTriggers->DeAllocate();
   fSimpleOfflineTriggers->Allocate( tBitsArray.GetSize() );