Index: trunk/MagicSoft/Simulation/Detector/include-MTrigger/MTrigger.cxx
===================================================================
--- trunk/MagicSoft/Simulation/Detector/include-MTrigger/MTrigger.cxx	(revision 372)
+++ trunk/MagicSoft/Simulation/Detector/include-MTrigger/MTrigger.cxx	(revision 373)
@@ -14,9 +14,5 @@
 
 MTrigger::MTrigger() { 
-  
-  FILE *unit_mtrig ; 
-  Int_t endflag = 1  ; 
-  char   datac[256] ; 
-  char   dummy[50] ; 
+  // ============================================================
   //
   //  default constructor 
@@ -29,5 +25,12 @@
   //     this parameters of the trigger may be changed
   //  4. Then the all signals are set to zero
-  
+
+  FILE *unit_mtrig ; 
+  Int_t endflag = 1  ; 
+  char   datac[256] ; 
+  char   dummy[50] ; 
+  
+  Float_t threshold ; 
+ 
   // 
   //   allocate the memory for the 2dim arrays (a_sig, d_sig ) 
@@ -47,9 +50,12 @@
   fwhm_resp = RESPONSE_FWHM       ; 
   ampl_resp = RESPONSE_AMPLITUDE  ; 
-  
-  chan_thres    = CHANNEL_THRESHOLD  ; 
-  gate_leng     = TRIGGER_GATE       ; 
-  trigger_multi = TRIGGER_MULTI      ; 
- 
+    
+  threshold = CHANNEL_THRESHOLD  ; 
+  
+
+  gate_leng        = TRIGGER_GATE       ; 
+  trigger_multi    = TRIGGER_MULTI      ; 
+  trigger_geometry = TRIGGER_GEOM ; 
+
   //
   //  check if the file MTrigger.card exists
@@ -70,5 +76,5 @@
       
       if (      strncmp (datac, "channel_threshold", 17 ) == 0 ) {
-	sscanf (datac, "%s %f", dummy, &chan_thres ) ; 
+	sscanf (datac, "%s %f", dummy, &threshold ) ;
       }
       else if ( strncmp (datac, "gate_length", 11 ) == 0 ) {
@@ -80,4 +86,10 @@
       else if ( strncmp (datac, "response_ampl", 13 ) == 0 ) {
 	sscanf (datac, "%s %f", dummy, &ampl_resp ) ;
+      }
+      else if ( strncmp (datac, "multiplicity", 12 ) == 0 ) {
+	sscanf (datac, "%s %f", dummy, &trigger_multi ) ;
+      }
+      else if ( strncmp (datac, "topology", 8 ) == 0 ) {
+	sscanf (datac, "%s %i", dummy, &trigger_geometry ) ;
       }
 
@@ -97,5 +109,5 @@
        << "[MTrigger]  Setting up the MTrigger with this values "<< endl ; 
   cout << endl 
-       << "[MTrigger]    ChannelThreshold:   " << chan_thres << " mV" 
+       << "[MTrigger]    ChannelThreshold:   " << threshold << " mV" 
        << endl ; 
 
@@ -106,6 +118,19 @@
   cout << "[MTrigger]    Response Amplitude: " << ampl_resp  << " mV"
        << endl ; 
+  cout << "[MTrigger]    Trigger Multiplicity:      " << trigger_multi  << " pixels"
+       << endl ; 
+  cout << "[MTrigger]    Trigger Topology: " << trigger_geometry 
+       << endl ; 
   
   cout << endl ; 
+
+
+  //
+  //   we have introduced individual thresholds for all pixels
+  //
+  for (Int_t k=0; k<TRIGGER_PIXELS; k++ ) {
+    chan_thres[k] = threshold ; 
+  }
+
   //
   //    set up the response shape
@@ -132,5 +157,24 @@
     //  	 << endl ; 
 
-  } 
+  
+  }
+
+  //
+  //    look for the time between start of response function and the 
+  //    maximum value of the response function. This is needed by the
+  //    member functions FillNSB() and FillStar() 
+  //  
+
+  Int_t imax  = 0  ;
+  Float_t max = 0. ; 
+  for (i=0; i< RESPONSE_SLICES ; i++ ) {  
+    if ( sing_resp[i] > max ) {
+      imax = i ; 
+      max  = sing_resp[i] ; 
+    }
+  }
+ 
+  peak_time = ( (Float_t) imax )  / ( (Float_t) SLICES_PER_NSEC ) ;
+ 
 
   //
@@ -162,5 +206,4 @@
   GenElec = new TRandom() ; 
 
-
   //
   //  Read in the lookup table for NN trigger
@@ -169,5 +212,4 @@
   FILE *unit ;
   int id ;
-  float y ;
 
   i = 0 ; 
@@ -201,6 +243,11 @@
   for ( i =0 ; i <TRIGGER_PIXELS ; i++ ) { 
     used [i] = FALSE ;
-
-    nphot[i] = 0 ;
+    dknt [i] = FALSE ;
+
+    nphotshow[i] = 0 ;
+    nphotnsb [i] = 0 ;
+    nphotstar[i] = 0 ;
+
+    baseline[i] = 0 ; 
   }
 
@@ -209,4 +256,55 @@
   }
   
+  //
+  //   set the information about the Different Level Triggers to zero
+  //
+
+  nZero = nFirst = nSecond = 0 ; 
+
+  for (ii=0 ; ii<TRIGGER_TIME_SLICES; ii++ ) { 
+    SlicesZero[ii] = FALSE;
+  }
+  
+  for ( i = 0 ; i < 5 ; i++) {
+    SlicesFirst[i]  = 0 ; 
+    SlicesSecond[i] = 0 ; 
+  }
+  cout << " end of MTrigger::MTrigger()" << endl ; 
+} 
+
+MTrigger::~MTrigger() {
+  // ============================================================//
+  //   destructor
+  //
+  int i;
+  // delete histPmt ; 
+  for(i=0;i<TRIGGER_PIXELS;i++){
+    delete [] a_sig[i];
+    delete [] d_sig[i];
+  }
+  delete GenElec;
+}
+
+  
+void MTrigger::Reset() { 
+  // ============================================================
+  //
+  //  reset all values of the signals to zero
+  //
+  Int_t  i, ii ; 
+  
+  for ( i =0 ; i <TRIGGER_PIXELS ; i++ ) {
+    used [i] = FALSE ; 
+    dknt [i] = FALSE ; 
+    
+    nphotshow[i] = 0 ; 
+    nphotnsb [i] = 0 ; 
+    nphotstar[i] = 0 ; 
+    } 
+  
+  for ( ii=0 ; ii<TRIGGER_TIME_SLICES; ii++ ) { 
+    sum_d_sig[ii] = 0. ;  
+  }
+
   //
   //   set the information about the Different Level Triggers to zero
@@ -220,89 +318,121 @@
     SlicesSecond[i] = 0 ; 
   }
-  
-  cout << " end of MTrigger::MTrigger()" << endl ; 
-} 
-
-MTrigger::~MTrigger() {
-
-  delete histPmt ; 
-}
-  
-void MTrigger::Reset() { 
-  //
-  //  set all values of the signals to zero
-  //
-  Int_t  i, ii ; 
-  
-  for ( i =0 ; i <TRIGGER_PIXELS ; i++ ) {
-    used [i] = FALSE ; 
-    dknt [i] = FALSE ; 
-    
-    nphot[i] = 0 ; 
-    } 
-  
-  for ( ii=0 ; ii<TRIGGER_TIME_SLICES; ii++ ) { 
-    sum_d_sig[ii] = 0. ;  
-  }
-
-  //
-  //   set the information about the Different Level Triggers to zero
-  //
-
-  nZero = nFirst = nSecond = 0 ; 
-  
-  for ( i = 0 ; i < 5 ; i++) {
-    SlicesZero[i]   = 0 ; 
-    SlicesFirst[i]  = 0 ; 
-    SlicesSecond[i] = 0 ; 
-  }
-    
-}
-
-
-Float_t  MTrigger::Fill( Int_t iPix, Float_t time ) { 
-  //
-  // fills the information about one single Phe in the Trigger class
-  //
-  // parameter is the number of the pixel and the time-difference to the
-  // first particle
-  //
-  //
-
-  Int_t i, ichan ; 
-
-  Float_t NoiseAmp = 0 ;   //  Amplitude of the PMT signal (results from noise)
-
-  //
-  //   first we have to check if the pixel iPix is used or not until now
-  //   if this is the first use, reset all signal for that pixels
-  // 
-  if ( iPix >= CAMERA_PIXELS ) {
-    // 
-    //   the PixelID is greater than the CAMERA  
-    //
-    cout << " WARNING:  MTrigger::Fill() :  iPix (" << iPix
-	 <<")greater than CAMERA_PIXELS"
-	 << endl ; 
-    NoiseAmp = 0. ; 
-  }
-  else if ( iPix >=TRIGGER_PIXELS ) {
-    //
-    //   the pixel is inside the Camera, but outside of the TRIGGER-FIELD
-    //  
-    //   we just scramble the amplitude of the PMT-signal for the FADC
-    //
-    //   scramble the Amplitude of this single photo electron signal
-    //
-    NoiseAmp = (histPmt->GetRandom()/histMean) ; 
-  } 
-  else { 
-    //
-    //   the photoelectron is contributing to the trigger
-    //
+    
+}
+
+Float_t  MTrigger::FillShow(Int_t iPix, Float_t time) { 
+  // ============================================================
+  //
+  //     Fills the information of one single Phe electron that 
+  //     comes from the shower 
+  //
+  
+  //
+  //  First check the time 
+  //
+  
+  if ( time < 0. || time > TOTAL_TRIGGER_TIME ) {
+    cout << "     WARNING: time of phe out of time range: " << time << endl; 
+    return 0. ;      
+  }
+  else {
+    return ( Fill( iPix, time, CASE_SHOW ) )  ; 
+  }
+}
+
+Float_t  MTrigger::FillNSB(Int_t iPix, Float_t time) { 
+  // ============================================================
+  //
+  //     Fills the information of one single Phe electron that 
+  //     comes from the shower 
+  //
+
+  //
+  //  First check the time 
+  //
+
+  if ( time < 0. || time > TOTAL_TRIGGER_TIME ) {
+    cout << "     WARNING: time of phe out of time range: " << time << endl; 
+    return 0. ;      
+  }
+  else {
+    return ( Fill( iPix, time - peak_time, CASE_NSB ) )  ; 
+  }
+}
+
+Float_t  MTrigger::FillStar(Int_t iPix, Float_t time) { 
+  // ============================================================
+  //
+  //     Fills the information of one single Phe electron that 
+  //     comes from the shower 
+  //
+
+  //
+  //  First check the time 
+  //
+
+  if ( time < 0. || time > TOTAL_TRIGGER_TIME ) {
+    cout << "     WARNING: time of phe out of time range: " << time << endl; 
+    return 0. ;      
+  }
+  else {
+    return ( Fill( iPix, time - peak_time, CASE_STAR ) )  ; 
+  }
+}
+
+Float_t MTrigger::Fill( Int_t iPix, Float_t time, Int_t fall ) {
+  // ============================================================
+  //
+  //     Fills the information in the array for the analog signal
+  //
+
+  Float_t PmtAmp = 0 ;   //  Amplitude of the PMT signal (results from noise)
+
+  if ( iPix < 0 ) {
+    cout << "     ERROR: in MTrigger::Fill()    " << endl ; 
+    cout << "     ERROR: Pixel Id < 0 ---> Exit " << endl ; 
+    exit (1) ; 
+  }
+  else if ( iPix >= CAMERA_PIXELS ) {
+    cout << "     ERROR: in MTrigger::Fill()    " << endl ; 
+    cout << "     ERROR: Pixel Id > CAMERA_PIXELS ---> Exit " << endl ; 
+    exit (1) ; 
+  }
+  else if ( iPix >= TRIGGER_PIXELS ) {
+    //
+    //  We have not to fill information in the trigger part, 
+    //  but we must create the height of the puls going into 
+    //  the FADC simulation
+    //
+    PmtAmp =  (histPmt->GetRandom()/histMean) ; 
+    
+    //
+    //  But we fill the information in the counters of phe's
+    //
+    
+    if ( fall == CASE_SHOW )
+      nphotshow[iPix]++ ; 
+    else if ( fall == CASE_NSB ) 
+      nphotshow[iPix]++ ; 
+    else if ( fall == CASE_STAR ) 
+      nphotstar[iPix]++ ; 
+    
+      
+  }
+  else {  
+    //
+    // we have a trigger pixel and we fill it 
+    //
+    Int_t i ; 
+
+    //
+    //  but at the beginning we must check if this pixel is
+    //  hitted the first time
+    //
+    
     if ( used[iPix] == FALSE ) {
       used [iPix] = TRUE ; 
       //      baseline[iPix] = 0. ; 
-
+      
       for (i=0; i < TRIGGER_TIME_SLICES; i++ ) {
 	a_sig[iPix][i] = 0. ; 
@@ -312,119 +442,52 @@
     
     //
-    //   then select the time slice to use (ican) 
-    // 
-
-    
-    if ( time < 0. ) {
-      cout << "  WARNING!!   " << time << "  below ZERO!! Very strange!!" 
-	   << endl ; 
+    // get the randomized amplitude
+    //
+    PmtAmp =  (histPmt->GetRandom()/histMean) ; 
+
+    //
+    // select the first slice to fill
+    //
+
+    Int_t ichan = (Int_t) ( time * ((Float_t) SLICES_PER_NSEC) ) ; 
+
+    //
+    //  look over the response signal and put it in the signal line
+    //
+
+    for ( i = 0 ; i<RESPONSE_SLICES; i++ ) {
+      
+      if ( (ichan+i) >= 0  &&  
+	   (ichan+i)  < TRIGGER_TIME_SLICES ) {  
+	a_sig[iPix][ichan+i] += PmtAmp * sing_resp[i] ;
+      } 
     }
-    else if ( time < TOTAL_TRIGGER_TIME ) { 
-      nphot[iPix]++ ; 
-      //
-      ichan = (Int_t) ( time * ((Float_t) SLICES_PER_NSEC) ) ; 
-      
-      //
-      //   scramble the Amplitude of this single photo electron signal
-      //
-      NoiseAmp = (histPmt->GetRandom()/histMean) ; 
-      
-      for ( i = 0 ; i<RESPONSE_SLICES; i++ ) {
-	
-	if ( (ichan+i) < TRIGGER_TIME_SLICES ) {  
-	  a_sig[iPix][ichan+i] += NoiseAmp * sing_resp[i] ;
- 
-	} 
-      }
-    }
-    else {
-      cout << "  WARNING!!   " << time << "  out of TriggerTimeRange " 
-	   << TOTAL_TRIGGER_TIME << endl ; 
-    }
-  }
-  
-  return NoiseAmp ; 
-  
-}
-
-
-Float_t  MTrigger::FillNSB( Int_t iPix, Float_t time ) { 
-  //
-  // fills the information about one single Phe in the Trigger class
-  //
-  // parameter is the number of the pixel and the time-difference to the
-  // first particle
-  //
-  //
-
-  Int_t i, ichan ; 
-
-  Float_t NoiseAmp = 0 ;   //  Amplitude of the PMT signal (results from noise)
-
-  //
-  //   first we have to check if the pixel iPix is used or not until now
-  //   if this is the first use, reset all signal for that pixels
-  // 
-  if ( iPix >= CAMERA_PIXELS ) {
-    cout << " WARNING:  MTrigger::Fill() :  iPix greater than CAMERA_PIXELS"
-	 << endl ; 
-  }
-  else if ( iPix >= TRIGGER_PIXELS ) {
-    //
-    //   scramble the Amplitude of this single photo electron signal
-    //
-    NoiseAmp = (histPmt->GetRandom()/histMean) ; 
-  } 
-  
-  else {
-    if ( used[iPix] == FALSE ) {
-      used [iPix] = TRUE ; 
-      //      baseline[iPix] = 0. ; 
-
-      for (i=0; i < TRIGGER_TIME_SLICES; i++ ) {
-	a_sig[iPix][i] = 0. ; 
-	d_sig[iPix][i] = 0. ; 
-      }
-    }
-
-    //
-    //   then select the time slice to use (ican) 
-    // 
-    
-    if ( time < 0. ) {
-      cout << "  WARNING!!   " << time << "  below ZERO!! Very strange!!" 
-	   << endl ; 
-    }
-    else if ( time < TOTAL_TRIGGER_TIME ) { 
-      //
-      //  FillNSB doesn't add a photon to nphot[iPix] as the method Fill do!!
-      //
-      
-      ichan = (Int_t) ( time * ((Float_t) SLICES_PER_NSEC) ) ; 
-      
-      //
-      //   scramble the Amplitude of this single photo electron signal
-      //
-      NoiseAmp = (histPmt->GetRandom()/histMean) ; 
-      
-      for ( i = 0 ; i<RESPONSE_SLICES; i++ ) {
-	
-	if ( (ichan+i) < TRIGGER_TIME_SLICES ) {  
-	  a_sig[iPix][ichan+i] += NoiseAmp * sing_resp[i] ; 
-	} 
-      }
-    }
-    else {
-      cout << "  WARNING!!   " << time << "  out of TriggerTimeRange " 
-	   << TOTAL_TRIGGER_TIME << endl ; 
-    }
-  }
-  
-  return NoiseAmp ; 
-  
-}
+
+    //
+    //  we fill the information in the counters of phe's
+    //
+    
+    if ( fall == CASE_SHOW )
+      nphotshow[iPix]++ ; 
+    else if ( fall == CASE_NSB ) 
+      nphotshow[iPix]++ ; 
+    else if ( fall == CASE_STAR ) 
+      nphotstar[iPix]++ ; 
+
+    //
+    //
+    return PmtAmp ;
+  }
+  return PmtAmp ; 
+}
+
+
 
 void MTrigger::ElecNoise() {
-
+  // ============================================================
+  //
+  //    adds the noise due to optronic and electronic 
+  //    to the signal
+  //
   Float_t rausch ; 
 
@@ -442,17 +505,22 @@
     }
   }
-
-}
-
-
-Int_t MTrigger::Diskriminate() {
-
-  //  cout << " MTrigger::Diskriminate()" << flush ; 
-
+}
+
+void MTrigger::Diskriminate() {
+  // ============================================================
+  //
+  //    Diskriminates the analog signal
+  //
+  //    one very important part is the calucaltion of the baseline
+  //    shift. Because of the AC coupling of the PMT, only the 
+  //    fluctuations are interesting. If there are a lot of phe, 
+  //    a so-called shift of the baseline occurs.
+  //
+ 
   Int_t  iM = 0 ; 
   Int_t  i, ii  ; 
 
+
   Int_t  jmax = (Int_t) (gate_leng * SLICES_PER_NSEC )  ; 
-
 
   //
@@ -461,5 +529,4 @@
   // 
 
-
   for ( i=0 ; i < TRIGGER_PIXELS ; i++ ) {
     if ( used[i] == TRUE ) {
@@ -472,8 +539,9 @@
       baseline[i] = baseline[i] / ( (Float_t ) TRIGGER_TIME_SLICES)  ;
 
-      cout << "Pixel " << i 
-	   << " baseline " << baseline[i] 
-	   <<endl ; 
-
+      //   cout << "Pixel " << i << " baseline " << baseline[i] <<endl ; 
+
+      //
+      //  now correct the baseline shift in the analog signal!!
+      //
       for ( ii = 0 ;  ii < TRIGGER_TIME_SLICES ; ii++ ) {
 	a_sig[i][ii] = a_sig[i][ii] - baseline[i] ; 
@@ -482,4 +550,6 @@
   }
   
+  //  
+  //  now the diskrimination is coming
   //
   //  take only that pixel which are used
@@ -488,8 +558,6 @@
   for ( i=0 ; i < TRIGGER_PIXELS; i++  ) {
     if ( used [i] == TRUE ) {
-      //cout << "Pixel " << i << " used"  ; 
-       
+           
       for ( ii=1 ; ii<TRIGGER_TIME_SLICES; ii++ ) { 
-      
 	//
 	// first check if the signal is crossing the CHANNEL_THRESHOLD 
@@ -497,6 +565,6 @@
 	//
 	
-	if ( a_sig[i][ii-1] <   chan_thres  && 
-	     a_sig[i][ii]   >=  chan_thres  ) { 
+	if ( a_sig[i][ii-1] <   chan_thres[i]  && 
+	     a_sig[i][ii]   >=  chan_thres[i]  ) { 
 	  { 
 	    if ( dknt[i] == FALSE ) {
@@ -513,5 +581,4 @@
 	      if ( ii+j  < TRIGGER_TIME_SLICES ) { 
 		d_sig  [i][ii+j] = 1. ;  
-		sum_d_sig [ii+j] += 1. ;  
 	      } 
 	    } 
@@ -519,182 +586,13 @@
 	  }
 	}
-      }
-      //      cout << endl ; 
+	else d_sig[i][ii]=0.;
+      }
     }
-  }
-
-  //cout << "**  MTrigger::Diskriminate()  " << iM << endl ; 
-
-
-  //
-  //   determine the number of zero level triggers
-  //
-  //   zero level trigger = the sum of all diskriminated signals
-  //   is above the TRIGGER_MULTI value. 
-  //   only for this events it is neccessay to look for next neighbours!!!
-  // 
-  
-  if ( iM > TRIGGER_MULTI ) {
-    Int_t iReturn = 0 ; 
-
-    for ( ii=1 ; ii<TRIGGER_TIME_SLICES; ii++ ) { 
-      if ( sum_d_sig[ii] > TRIGGER_MULTI ) { 
-	iReturn++ ; 
-
-	SlicesZero[nZero++] = ii ; 
-	
-	//
-	//    if a trigger occurs we read out the next 50 nsec
-	//
-	//    -> don't study the next 50/0.25 = 200 slices
-	//
-	ii = ii + 200 ; 
-      }      
-    } 
-    
-    return ( iReturn ) ; 
-  }
-  else {
-    return ( 0 ) ; 
-  }
-
-  return ( 0 ) ; 
-  
-}  
-
-Int_t MTrigger::FirstLevel() {
-
-  Int_t iReturn = 0 ; 
-
-  Bool_t Muster[TRIGGER_PIXELS] ; 
-  Int_t  iMulti = 0 ; 
-
-  // cout << "#### MTrigger::FirstLevel()" << endl ; 
-  // cout << nZero << "  " << SlicesZero[0] <<  endl ; 
-  
-  if ( nZero > 1 ) { 
-    cout << " INFORMATION:  more than one Zero Level TRIGGER " << endl ; 
-  }
-
-  //
-  //   loop over all ZeroLevel Trigger
-  //
-  //   it is only neccessary to look after a ZeroLevel Trigger for
-  //   a FirstLevel (NextNeighbour) trigger. 
-  //
-  
-  for (Int_t iloop = 0; iloop < nZero ; iloop++ ) {
-    
-    //
-    //   Then run over all slices 
-    //   start at the ZeroLevelTrigger slices
-    //
-    
-    for ( Int_t iSli = SlicesZero[iloop];
-	  iSli < SlicesZero[iloop]+ 200; iSli++ ) {
-
-      //
-      //  then look in all pixel if the diskriminated signal is 1
-      //
-      iMulti = 0 ; 
-
-      for ( Int_t iPix = 0 ; iPix < TRIGGER_PIXELS; iPix++ ) {
-	Muster[iPix] = kFALSE ; 
-
-	if ( used [iPix] == TRUE ) {
-	  //
-	  //  now check the diskriminated signal
-	  //
-	  if ( d_sig [iPix][iSli] > 0. ) {
-
-	    iMulti++ ; 
-	    Muster[iPix] = kTRUE ; 
-	  } 
-	}
-      } // end of loop over the pixels
-      
-      //
-      //   here we have to look for next neighbours
-      //
-      
-      if ( PassNextNeighbour ( Muster ) ) { 
-	//
-	//   A NN-Trigger is detected at time Slice 
-	//
-	SlicesFirst[nFirst++] = iSli ; 
-	iReturn++ ;
-	break ; 
-      }   
-    } // end of loop over the slices  
-    
-  } // end of loop over zerolevelTriggers
-
-  //
-  //   return the Number of FirstLevel Triggers
-  //
-  return iReturn ; 
-}
-
-
-Bool_t MTrigger::PassNextNeighbour ( Bool_t m[] ) {
-  //
-  //  This method is looking for next neighbour triggers using a 
-  //  NNlookup table. This table is builded by the default constructor
-  //
-  
-  Int_t iNN ; 
-
-  //
-  //   loop over all trigger pixels
-  //
-  for ( Int_t i=0; i<TRIGGER_PIXELS; i++) { 
-    //
-    //  check if this pixel has a diskrminator signal 
-    //  (this is inside m[] ) 
-    //
-
-    if ( m[i] ) { 
-      iNN = 1 ; 
-      //      cout << "/ " << i  ; 
-      
-      //
-      //  look in the next neighbours from the lookuptable
-      //
-      for ( Int_t kk=0; kk<6; kk++ ) { 
-	//
-	//  if the nextneighbour is outside the triggerarea do nothing
-	//
-	if (NN[i][kk] >= TRIGGER_PIXELS ) {
-
-	} 
-	// the nextneighbout is inside the TRIGGER_PIXELS
-	else { 
-	  //
-	  //  look if the boolean of nn pixels is true
-	  //
-	  
-	  if ( m[ NN[i][kk] ] ) { 
-	    iNN++ ; 
-	  }  
-	}
-      } 
-      
-      //   cout << "   NN  " << iNN ; 
-      
-      if ( iNN >=4 ) { 
-	return ( kTRUE ) ; 
-      }  
-    } 
-  } 
-  return ( kFALSE ) ; 
-}
-
-Float_t MTrigger::GetFirstLevelTime(Int_t il ) {
-  return ( (Float_t)SlicesFirst[il]/ SLICES_PER_NSEC   ) ; 
-}
-
+  }  
+}
 
 
 void MTrigger::ShowSignal (MMcEvt *McEvt) { 
+  // ============================================================
   //
   //  This method is used to book the histogramm to show the signal in 
@@ -790,2 +688,361 @@
 }
   
+
+Int_t MTrigger::ZeroLevel() {
+  // ============================================================
+  //
+  //  This is a level introduced just to speed up the program. 
+  //  It makes sense to look for next neighbours only if there
+  //  are at least trigger_multi  pixels with a diskriminator 
+  //  signal. 
+  //
+  
+  //
+  //  first count the pixels with a diskriminator signal
+  //
+  Int_t iMul = 0 ; 
+  for ( Int_t iP =0 ; iP < TRIGGER_PIXELS; iP++ ) {
+    //
+    //
+    if ( dknt[iP] == TRUE ) {
+      iMul++ ; 
+    }
+  }
+
+  //
+  //   only if there are at least more pixels than requested 
+  //   it make sense to look into details
+  if ( iMul >= trigger_multi ) {
+    //
+    //  fill the sum signal of all diskriminator signals
+    // 
+    for ( Int_t iP =0 ; iP < TRIGGER_PIXELS; iP++ ) {
+      //
+      //
+      if ( dknt[iP] == TRUE ) {
+	//
+	// sum it up
+	//
+	for (Int_t iS=0; iS< TRIGGER_TIME_SLICES; iS++ ) {
+	  //
+	  //    
+	  sum_d_sig [iS] += d_sig[iP][iS] ; 
+	} 
+      }
+    }
+    //
+    //   run over the sum_d_sig and check each time slice
+    //
+    Int_t iReturn = 0 ; 
+  
+    for (Int_t iS=0; iS< TRIGGER_TIME_SLICES; iS++ ) {
+      
+      if ( sum_d_sig[iS] >= trigger_multi ) {
+	iReturn++ ; 
+	nZero++;
+	SlicesZero[iS] = TRUE ; 
+	
+      }
+      else SlicesZero[iS] = FALSE;
+    }
+
+    return ( iReturn ) ; 
+  }
+  else {
+    return 0 ; 
+  }
+}
+
+Int_t MTrigger::FirstLevel() {
+  //=================================================
+  //
+  // This is a level trigger which can look for several 
+  // multiplicities (trigger_multi) 
+  // and topologies (trigger_geometry)
+  //
+
+  Int_t iReturn = 0 ;  // Return value for this function 
+  
+  if ( nZero > 1 ) { 
+    cout << " INFORMATION:  more than one Zero Level TRIGGER " << endl ; 
+  }
+  
+  //   Definition of needed variables  
+  Bool_t Muster[TRIGGER_PIXELS] ; 
+  Bool_t Neighb[TRIGGER_PIXELS] ; 
+  Int_t  iMulti = 0 ; 
+
+  // We put several wrong topologies which we already know that they
+  // are not possible. It can save time.
+
+  if (trigger_geometry==0 &&  trigger_multi>7) {
+    cout <<"You are lookiny for a topology that needs more than six neighbours of the same pixel"<<endl;
+    cout <<" Topology   "<<trigger_geometry<<"   Multiplicity   "<<trigger_multi<<endl;;
+    return (kFALSE);
+  }
+
+  if (trigger_geometry==2 && trigger_multi<3) {
+    cout<<"Closed pack geometry with multiplicity "<<trigger_multi<<" does not make sense"<<endl;
+    return (kFALSE);
+  }
+  if (trigger_geometry>2) {
+    cout << "This trigger topology is not implemented"<<endl;
+    return (kFALSE);
+  }
+  
+  //
+  //   loop over all ZeroLevel Trigger
+  //
+  //   it is only neccessary to look after a ZeroLevel Trigger for
+  //   a FirstLevel (NextNeighbour) trigger. 
+  //  
+
+  if (nZero) {
+    
+    //
+    //   Then run over all slices 
+    //
+    
+    for ( Int_t iSli = 0;
+	  iSli < TRIGGER_TIME_SLICES; iSli++ ) {
+
+      //  Check if this time slice has more fired pixels than trigger_multi
+
+      if (SlicesZero[iSli]){
+	//
+	//  then look in all pixel if the diskriminated signal is 1
+	//
+	
+	for ( Int_t iPix = 0 ; iPix < TRIGGER_PIXELS; iPix++ ) {
+	  Muster[iPix] = kFALSE ; 
+	  Neighb[iPix] = kFALSE ;
+	  if ( used [iPix] == TRUE ) {
+	    //
+	    //  now check the diskriminated signal
+	    //
+	    if ( d_sig [iPix][iSli] > 0. ) {
+	      
+	      Muster[iPix] = kTRUE ; 
+	    } 
+	  }
+	} // end of loop over the pixels
+	
+	//
+	//   here we have to look for the topologies
+	//
+	
+	switch(trigger_geometry){
+	case 0:{
+	  
+	  // It looks for a pixel above threshold which has 
+	  // trigger_multi-1 neighbour pixels above threshold 
+
+	  Bool_t Dummy[TRIGGER_PIXELS] ;
+
+	  //  Loop over all pixels
+	  for (int j=0;j<TRIGGER_PIXELS;j++){
+	    Dummy=Muster;
+	    for (int k=0; k<TRIGGER_PIXELS; k++){
+	      Neighb[k]=kFALSE;
+	    }
+	    if(Muster[j]){
+	      //  If pixel is fired, it checks how many fired neighbours it has
+	      for (iMulti=1;iMulti<trigger_multi; iMulti++) {
+		Neighb[j] = kTRUE ;
+		Dummy[j] = kTRUE ;
+		if (!PassNextNeighbour(Dummy, &Neighb[0])){
+		  break;
+		} 
+		for (int k=0; k<TRIGGER_PIXELS; k++){
+		  if (Neighb[k]){
+		    Dummy[k]=kFALSE;
+		    Neighb[k]=kFALSE;
+		  }
+		}
+	      }
+	      if (iMulti==trigger_multi ) { 
+		//
+		//   A NN-Trigger is detected at time Slice 
+		//
+		SlicesFirst[nFirst++] = iSli ; // We save time when it triggers
+		iReturn++ ;
+		iSli+=(50*SLICES_PER_NSEC);  // We skip the following 50 ns (dead time)
+		break ; 
+	      }   
+	    }
+	  }
+	  break;
+	};
+	
+	case 1:{
+
+	  //   It looks for trigger_multi neighbour pixels above the 
+	  //   threshold.
+	  
+	  for (int j=0;j<TRIGGER_PIXELS;j++){
+	    if(Muster[j]){
+	      //  It checks if you can find 
+	      //  trigger_multi fired neighbour pixels
+	      Neighb[j] = kTRUE ;
+	      for (iMulti=1;iMulti<trigger_multi; iMulti++) {
+		if (!PassNextNeighbour(Muster, &Neighb[0]))
+		  break; 
+	      }
+	      if (iMulti==trigger_multi ) { 
+		//
+		//   A NN-Trigger is detected at time Slice 
+		//
+		SlicesFirst[nFirst++] = iSli ; //  We save when it triggers
+		iReturn++ ;
+		iSli+=(50*SLICES_PER_NSEC);  // We skip the following 50 ns (dead time)
+		break ; 
+	      }   
+	      else {
+		//  We put Neighb to kFALSE to check an other pixel
+		for (int k=0; k<TRIGGER_PIXELS; k++){
+		  if (Neighb[k]){
+		    Neighb[k]=kFALSE;
+		  }
+		}
+	      }
+	    }
+	  }
+	  break;
+	};
+	case 2:{
+	  
+	  // It looks for trigger_multi closed pack neighbours
+	  // above threshold
+	  // Closed pack means that you can take out any pixel
+	  // and you will still get a trigger for trigger_multi -1
+
+	  Int_t closed_pack = 1;
+
+	  for (int j=0;j<TRIGGER_PIXELS;j++){
+	    if(Muster[j]){
+	      //  It checks if there are trigger_multi
+	      //  neighbours above threshold
+	      Neighb[j] = kTRUE ;
+	      for (iMulti=1;iMulti<trigger_multi; iMulti++){
+		if (!PassNextNeighbour(Muster, &Neighb[0]))
+		  break; 
+	      }
+	      if (iMulti==trigger_multi ) { 
+		//
+		//   A NN-Trigger is detected at time Slice 
+		//
+
+		// Check if there is closed pack topology
+		Bool_t Aux1[TRIGGER_PIXELS];
+		Bool_t Aux2[TRIGGER_PIXELS];
+		for (int jj=0;jj<TRIGGER_PIXELS;jj++)
+			Aux2[jj]=kFALSE;
+		for (int i=0;i<TRIGGER_PIXELS;i++){
+		  if (Neighb[i]) {
+		    //  Loop over pixels that achive neighbouring condition
+		    Aux1=Neighb;
+		    Aux1[i]=kFALSE;
+		    for (int jj=0;jj<TRIGGER_PIXELS;jj++)
+		      Aux2[jj]=kFALSE;
+		    Aux2[j]=kTRUE;
+		    //  It checks if taking any of the pixels we lose
+		    //  neighbouring condition for trigger -1
+		    for (iMulti=1;iMulti<(trigger_multi-1);iMulti++){
+		      if (!PassNextNeighbour(Aux1, &Aux2[0]))
+			break; 
+		    }
+		    if (iMulti<(trigger_multi-1)){
+		      closed_pack=0;
+		      break;
+		    }
+
+		  }
+		}
+		if (closed_pack){
+		  SlicesFirst[nFirst++] = iSli ; //  We save time when it triggers
+		  iReturn++ ;
+		  iSli+=(50*SLICES_PER_NSEC);  // We skip the following 50 ns (dead time)
+		  break ; 
+		}
+		else {
+		  for (int k=0; k<TRIGGER_PIXELS; k++){
+		    if (Neighb[k]){
+		      Neighb[k]=kFALSE;
+		   }
+		  }
+		}
+	      }
+	      else
+		for (int k=0; k<TRIGGER_PIXELS; k++)
+		  Neighb[k]=kFALSE;		  
+	    }
+	  }
+	  break;
+	};
+	default:{
+	  cout << "This topology is not implemented yet"<<endl;
+	  break;
+	}
+	}
+      }
+    } // end of loop over the slices  
+  }   // end of conditional for a trigger Zero
+  
+  //
+  //   return the Number of FirstLevel Triggers
+  //
+  return iReturn ; 
+}
+
+
+Bool_t MTrigger::PassNextNeighbour ( Bool_t m[], Bool_t *n) {
+  //
+  //  This function is looking for a next neighbour of pixels in n[]
+  //  above triggers using a NNlookup table. 
+  //  This table is builded by the default constructor
+  //
+
+  //
+  //   loop over all trigger pixels
+  //
+  
+  Bool_t return_val = kFALSE;
+  
+  for ( Int_t i=0; i<TRIGGER_PIXELS; i++) { 
+    //
+    //  check if this pixel has a diskrminator signal 
+    //  (this is inside n[] ) 
+    //
+    
+    if ( n[i] && !return_val) { 
+      
+      //
+      //  look in the next neighbours from the lookuptable
+      //
+      
+      for ( Int_t kk=0; kk<6; kk++ ) { 
+	//
+	//  if the nextneighbour is outside the triggerarea do nothing
+	//
+	if (!return_val){
+	  if (NN[i][kk] >= TRIGGER_PIXELS ) {
+	    
+	  } 
+	  // the nextneighbour is not inside the TRIGGER_PIXELS
+	  else { 
+	    //
+	    //  look if the boolean of nn pixels is true
+	    //
+	    
+	    if ( m[ NN[i][kk] ] && !n[NN[i][kk]] ) { 
+	      n[NN[i][kk]]=kTRUE ;
+	      return_val =kTRUE;
+	    }  
+	  }
+	}
+	else break;
+      }
+    } 
+  }    
+  return(return_val);
+}
Index: trunk/MagicSoft/Simulation/Detector/include-MTrigger/MTrigger.hxx
===================================================================
--- trunk/MagicSoft/Simulation/Detector/include-MTrigger/MTrigger.hxx	(revision 372)
+++ trunk/MagicSoft/Simulation/Detector/include-MTrigger/MTrigger.hxx	(revision 373)
@@ -1,4 +1,8 @@
-#ifndef __MTrigger__
-#define __MTrigger__
+#ifndef __MTrigger__ 
+#define __MTrigger__ 
+
+#define    CASE_SHOW   0
+#define    CASE_NSB    1
+#define    CASE_STAR   2
 
 //     class MTrigger
@@ -6,11 +10,11 @@
 //     implemented by Harald Kornmayer
 //
-//     This is a class to simulate the trigger. 
-//     It assumes a special response of the PMT for one single Photo-electron. 
-//     
+//     This is a class to simulate the trigger.
+//     It assumes a special response of the PMT for one single Photo-electron.
+//
 //
 //
 #include <iostream.h>
-#include <math.h> 
+#include <math.h>
 
 #include "TROOT.h"
@@ -19,15 +23,16 @@
 #include "TH1.h"
 
-#include "Mdefine.h" 
+#include "Mdefine.h"
 #include "MMcEvt.h"
 
 #include "MTriggerDefine.h"
 
+
 //==========
 //  MTrigger
 //
-//  The simulation of the Trigger for MonteCarlo Events is using this 
+//  The simulation of the Trigger for MonteCarlo Events is using this
 //  class. So all methods concerning the trigger should be done inside this
-//  class. 
+//  class.
 //
 //  For a better understanding of the behavior of the trigger is here small
@@ -37,28 +42,28 @@
 //  We now from the camera program (This is the surrounding of the class 
 //  MTrigger.) that one photo electron leaves at time t the photo cathode 
-//  of the pixel number iPix). 
+//  of the pixel number iPix).
 //
 //  At the end of the PMT, the preamp, the optical fiber transmission we
-//  get a signal of a given shape. After some discussion with Eckart the 
-//  standard response function looks like this :    
-//                                  
-//  It is a gaussian Signal with a given FWHM. 
+//  get a signal of a given shape. After some discussion with Eckart the
+//  standard response function looks like this :
+//
+//  It is a gaussian Signal with a given FWHM.
 //
 //  So whenever a photo electron leaves the photo cathod, on has to add
-//  the standard response function to the analog signal of the pixel. 
+//  the standard response function to the analog signal of the pixel.
 //
-//  Each pixel of the camera has such an summed-up analog signal. It may 
-//  look like this picture: 
+//  Each pixel of the camera has such an summed-up analog signal. It may
+//  look like this picture:
 //
 //
 //  This is the input of the discriminator for the pixels. The output of
 //  the discriminator is a digital signal. The response of the diskriminator
-//  is not fixed at the moment. There are discussion about this topic. 
+//  is not fixed at the moment. There are discussion about this topic.
 //  
 //  At the moment the response is very simple. Whenever the analog signal
-//  is crossing a defined threshold from below to above, a digital signal 
-//  with a given length is created. 
+//  is crossing a defined threshold from below to above, a digital signal
+//  with a given length is created.
 // 
-//  Now one can start with the simulation of different trigger levels. 
+//  No one can start with the simulation of different trigger levels. 
 //  
 //  The TriggerLevelZero is a very easy one. It is just looking if there 
@@ -66,8 +71,8 @@
 //  a TriggerLevelZero signal is created.
 //
-//  The TriggerLevelOne is implemented now. This is be a kind of next 
+//  The TriggerLevelOne is not implemented now. This will be a kind of next 
 //  neighbour condition (i.e. four neigbouring analog signals at the same 
 //  time, but this requests at least four digital signals at level ON, what 
-//  is equivalent with a TriggerLevelZero.   
+//  is equivalent with a TriggerLevelZero.
 //  
 //  
@@ -76,8 +81,10 @@
  private:
   //
-  //    then for all pixels the shape of all the analog signals 
+  //    then for all pixels the shape of all the analog signals
   //
   Bool_t   used [TRIGGER_PIXELS] ;  //  a boolean to indicated if the pixels is used in this event
-  Int_t    nphot[TRIGGER_PIXELS];   //  count the photo electrons per pixel (NSB phe are not counted) 
+  Int_t    nphotshow[TRIGGER_PIXELS];   //  count the photo electrons per pixel coming from showers 
+  Int_t    nphotnsb[TRIGGER_PIXELS];   //  count the photo electrons per pixel  coming from NSB 
+  Int_t    nphotstar[TRIGGER_PIXELS];   //  count the photo electrons per pixel coming from stars
  
   Float_t  *a_sig[TRIGGER_PIXELS] ; //  the analog signal for pixels
@@ -96,5 +103,4 @@
   Float_t sum_d_sig[TRIGGER_TIME_SLICES] ; 
 
-
   //
   //    first the data for the response function
@@ -103,4 +109,5 @@
   Float_t ampl_resp ;                      // amplitude of the phe_response function (in mV)
   Float_t sing_resp[ RESPONSE_SLICES ] ;   // the shape of the phe_response function 
+  Float_t peak_time  ;                      // the time from the start of the response function to the maximum peak 
 
   TH1F     *histPmt ; 
@@ -112,9 +119,11 @@
   //
   
-  Float_t chan_thres ; // the threshold (in mV) for each individuel pixels
+  Float_t chan_thres[TRIGGER_PIXELS] ; // the threshold (in mV) for each individuel pixels
   Float_t gate_leng  ; // the length of the digital signal if analog signal is above threshold
 
   Float_t trigger_multi  ;  // Number of Pixels requested for a Trigger
-
+  Int_t trigger_geometry ;  // 0 means a pixel with trigger_multi-1 neighbours
+                            // 1 means trigger_multi neighbours
+                            // 2 means trigger_multi closed neighbours
   //
   //  The lookup table for the next neighbours
@@ -128,5 +137,5 @@
 
   Int_t  nZero ;         // how many ZeroLevel Trigger in one Event
-  Int_t  SlicesZero[5] ; // Times Slices at which the ZeroLevel Triggers occur
+  Bool_t  SlicesZero[TRIGGER_TIME_SLICES] ; // Times Slices at which the ZeroLevel Triggers occur
 
   Int_t  nFirst ;         // how many FirstLevel Trigger in one Event
@@ -136,5 +145,10 @@
   Int_t  SlicesSecond[5] ; // Times Slices at which the SecondLevel Triggers occur
 
+private: 
 
+  Float_t  Fill( Int_t, Float_t, Int_t ) ;  
+
+  Bool_t PassNextNeighbour( Bool_t m[], Bool_t *n) ; 
+ 
 public:
 
@@ -145,17 +159,23 @@
   void Reset() ; 
 
-  Float_t  Fill( Int_t, Float_t ) ;  
+  Float_t  FillShow( Int_t, Float_t ) ;  
 
   Float_t  FillNSB( Int_t, Float_t ) ;  
 
+  Float_t  FillStar( Int_t, Float_t ) ;  
+
   void ElecNoise() ;
 
-  Int_t Diskriminate() ;
+  void SetResponseShape();
+
+  void ReadParam(char name[]);
+
+  void Diskriminate() ;
+
+  void ShowSignal (MMcEvt *McEvt) ; 
+
+  Int_t ZeroLevel() ;
 
   Int_t FirstLevel() ;   
-
-  Bool_t PassNextNeighbour( Bool_t m[] ) ; 
- 
-  void ShowSignal (MMcEvt *McEvt) ; 
 
   Float_t GetFirstLevelTime( Int_t il ) ; 
Index: trunk/MagicSoft/Simulation/Detector/include-MTrigger/MTriggerDefine.h
===================================================================
--- trunk/MagicSoft/Simulation/Detector/include-MTrigger/MTriggerDefine.h	(revision 372)
+++ trunk/MagicSoft/Simulation/Detector/include-MTrigger/MTriggerDefine.h	(revision 373)
@@ -69,4 +69,10 @@
 //       channels with a diskrimiator signal at the same time 
 //
-
-
+#define TRIGGER_GEOM           0
+//
+//      This defines the geometry required for a trigger. There exists 
+//      different meaning for this behaviour: 
+//         0 means a pixel with trigger_multi-1 neighbours
+//         1 means trigger_multi neighbours
+//         2 means trigger_multi closed neighbours
+//
