Index: trunk/MagicSoft/Simulation/Detector/include-MTrigger/MTrigger.cxx
===================================================================
--- trunk/MagicSoft/Simulation/Detector/include-MTrigger/MTrigger.cxx	(revision 350)
+++ trunk/MagicSoft/Simulation/Detector/include-MTrigger/MTrigger.cxx	(revision 351)
@@ -6,2 +6,781 @@
 #include "MTrigger.hxx"
 
+#include "TROOT.h"
+#include "TFile.h"
+#include "TH1.h"
+#include "TObjArray.h"
+#include "MGTriggerSignal.hxx"
+
+
+MTrigger::MTrigger() { 
+  
+  FILE *unit_mtrig ; 
+  Int_t endflag = 1  ; 
+  char   datac[256] ; 
+  char   dummy[50] ; 
+  //
+  //  default constructor 
+  //  
+  //  The procedure is the following: 
+  //
+  //  1. Allocation of some memory needed
+  //  2. some parameters of the trigger are set to default.   
+  //  3. if a File MTrigger.card exists in the current directory, 
+  //     this parameters of the trigger may be changed
+  //  4. Then the all signals are set to zero
+  
+  // 
+  //   allocate the memory for the 2dim arrays (a_sig, d_sig ) 
+  //
+
+  for( Int_t j=0; j<TRIGGER_PIXELS; j++ ) { 
+
+    a_sig[j] = new Float_t[TRIGGER_TIME_SLICES] ; 
+
+    d_sig[j] = new Float_t[TRIGGER_TIME_SLICES] ; 
+  } 
+
+  //
+  //   set the values for the standard response pulse
+  //
+
+  fwhm_resp = RESPONSE_FWHM       ; 
+  ampl_resp = RESPONSE_AMPLITUDE  ; 
+  
+  chan_thres    = CHANNEL_THRESHOLD  ; 
+  gate_leng     = TRIGGER_GATE       ; 
+  trigger_multi = TRIGGER_MULTI      ; 
+ 
+  //
+  //  check if the file MTrigger.card exists
+  //
+
+  if ( (unit_mtrig = fopen ("MTrigger.card", "r")) != 0 ) {
+    cout << "[MTrigger]  use the values from MTrigger.card "<< endl ; 
+    
+    while ( endflag == 1  ) {
+      //
+      //
+      fgets (datac, 255, unit_mtrig) ;
+      //      printf ("--> %s <--", datac ) ;
+      
+      //
+      //   now compare the line with controlcard words
+      //
+      
+      if (      strncmp (datac, "channel_threshold", 17 ) == 0 ) {
+	sscanf (datac, "%s %f", dummy, &chan_thres ) ; 
+      }
+      else if ( strncmp (datac, "gate_length", 11 ) == 0 ) {
+	sscanf (datac, "%s %f", dummy, &gate_leng ) ;
+      }
+      else if ( strncmp (datac, "response_fwhm", 13 ) == 0 ) {
+	sscanf (datac, "%s %f", dummy, &fwhm_resp ) ;
+      }
+      else if ( strncmp (datac, "response_ampl", 13 ) == 0 ) {
+	sscanf (datac, "%s %f", dummy, &ampl_resp ) ;
+      }
+
+      if ( feof(unit_mtrig) != 0 ) {
+	endflag = 0 ;
+      }
+      
+    }
+
+    fclose ( unit_mtrig ) ; 
+  }
+  else {
+    cout << "[MTrigger]  use the standard values for MTrigger "<< endl ; 
+  }
+
+  cout << endl
+       << "[MTrigger]  Setting up the MTrigger with this values "<< endl ; 
+  cout << endl 
+       << "[MTrigger]    ChannelThreshold:   " << chan_thres << " mV" 
+       << endl ; 
+
+  cout << "[MTrigger]    Gate Length:        " << gate_leng  << " ns"
+       << endl ; 
+  cout << "[MTrigger]    Response FWHM:      " << fwhm_resp  << " ns"
+       << endl ; 
+  cout << "[MTrigger]    Response Amplitude: " << ampl_resp  << " mV"
+       << endl ; 
+  
+  cout << endl ; 
+  //
+  //    set up the response shape
+  // 
+  Int_t  i, ii ; 
+     
+  Float_t   sigma ; 
+  Float_t   x, x0 ; 
+
+  sigma = fwhm_resp / 2.35 ; 
+  x0 = 3*sigma ; 
+  
+  for (i=0; i< RESPONSE_SLICES ; i++ ) {  
+
+    x = i * (1./((Float_t)SLICES_PER_NSEC)) 
+      + (1./( 2 * (Float_t)SLICES_PER_NSEC ))  ; 
+    
+    sing_resp[i] = 
+      ampl_resp * expf(-0.5 * (x-x0)*(x-x0) / (sigma*sigma) ) ; 
+
+    //      cout << i << "  "
+    //  	 << x << "  "
+    //  	 << sing_resp[i] 
+    //  	 << endl ; 
+
+  } 
+
+  //
+  //   the amplitude of one single photo electron is not a constant. 
+  //   There exists a measured distribution from Razmik. This distribution
+  //   is used to simulate the noise of the amplitude. 
+  //   For this a histogramm (histPmt) is created and filled with the
+  //   values. 
+  // 
+
+  histPmt = new TH1F ("histPmt","Noise of PMT", 40, 0., 40.) ;
+  
+  Stat_t ValRazmik[41] = { 0., 2.14, 2.06, 2.05, 2.05, 2.06, 2.07, 2.08,  2.15,
+			   2.27, 2.40, 2.48, 2.55, 2.50, 2.35, 2.20,  2.10,
+			   1.90, 1.65, 1.40, 1.25, 1.00, 0.80, 0.65,  0.50,
+			   0.35, 0.27, 0.20, 0.18, 0.16, 0.14, 0.12,  0.10, 
+			   0.08, 0.06, 0.04, 0.02, 0.01, 0.005,0.003, 0.001} ; 
+
+  histMean =  histPmt->GetMean() ;   
+  
+  histPmt->SetContent( ValRazmik) ; 
+
+  histMean =  histPmt->GetMean() ; 
+
+  //
+  //   create the random generator for the Electronic Noise
+  // 
+
+  GenElec = new TRandom() ; 
+
+
+  //
+  //  Read in the lookup table for NN trigger
+  //
+  
+  FILE *unit ;
+  int id ;
+  float y ;
+
+  i = 0 ; 
+
+  if ( (unit = fopen("../include-MTrigger/TABLE_NEXT_NEIGHBOUR", "r" )) == 0 ) { 
+    cout << "ERROR: not able to read ../include-MTrigger/TABLE_NEXT_NEIGHBOUR"
+	 << endl ; 
+    exit(123) ; 
+  }  
+  else { 
+    while ( i < TRIGGER_PIXELS )
+      {
+	fscanf ( unit, " %d", &id ) ;
+	
+	for ( Int_t k=0; k<6; k++ ) { 
+	  fscanf ( unit, "%d ", &NN[i][k]  ) ; 
+	}
+	i++ ;
+      }
+    
+    fclose (unit) ;
+  }
+
+
+  //
+  //
+  //  set all the booleans used to FALSE, indicating that the pixel is not 
+  //  used in this event. 
+  //
+  
+  for ( i =0 ; i <TRIGGER_PIXELS ; i++ ) { 
+    used [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 ; 
+  }
+  
+  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 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
+    //
+    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 ) { 
+      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 ; 
+  
+}
+
+void MTrigger::ElecNoise() {
+
+  Float_t rausch ; 
+
+  rausch = RESPONSE_AMPLITUDE * 0.3 ; 
+ 
+  for ( Int_t i=0 ; i < TRIGGER_PIXELS; i++  ) {
+    if ( used [i] == TRUE ) {
+      //cout << "Pixel " << i << " used"  ; 
+       
+      for ( Int_t ii=1 ; ii<TRIGGER_TIME_SLICES; ii++ ) { 
+
+	a_sig [i][ii] +=  GenElec->Gaus(0., rausch  ) ; 
+
+      }
+    }
+  }
+
+}
+
+
+Int_t MTrigger::Diskriminate() {
+
+  cout << " MTrigger::Diskriminate()" << flush ; 
+
+  Int_t  iM = 0 ; 
+  Int_t  i, ii  ; 
+
+  Int_t  jmax = (Int_t) (gate_leng * SLICES_PER_NSEC )  ; 
+
+
+  //
+  //    first of all determine the integral of all signals to get
+  //    the baseline shift. 
+  // 
+
+
+  for ( i=0 ; i < TRIGGER_PIXELS ; i++ ) {
+    if ( used[i] == TRUE ) {
+      baseline[i] = 0. ; 
+
+      for ( ii = 0 ;  ii < TRIGGER_TIME_SLICES ; ii++ ) {
+	baseline[i] += a_sig[i][ii] ; 
+      } 
+
+      baseline[i] = baseline[i] / ( (Float_t ) TRIGGER_TIME_SLICES)  ;
+
+      //cout << "Pixel " << i 
+      //   << " baseline " << baseline[i] 
+      //   <<endl ; 
+
+    }
+  }
+  
+  //
+  //  take only that pixel which are used
+  //
+
+  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 
+	// form low to big signals
+	//
+	
+	if ( a_sig[i][ii-1] <   chan_thres  && 
+	     a_sig[i][ii]   >=  chan_thres  ) { 
+	  { 
+	    if ( dknt[i] == FALSE ) {
+	      dknt [i] = TRUE ; 
+	      iM++ ; 
+	    }
+	    //    cout << " disk " << ii  ; 
+	    // 
+	    //   put the standard diskriminator signal in 
+	    //   the diskriminated signal 
+	    //
+	    for ( Int_t j=0 ; j < jmax ; j++ ) { 
+	      
+	      if ( ii+j  < TRIGGER_TIME_SLICES ) { 
+		d_sig  [i][ii+j] = 1. ;  
+		sum_d_sig [ii+j] += 1. ;  
+	      } 
+	    } 
+	    ii = ii + jmax ; 
+	  }
+	}
+      }
+      //      cout << endl ; 
+    }
+  }
+
+  //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 
+  //  a special gui frame (class MGTriggerSignal). After the look onto the
+  //  signals for a better understanding of the things we will expect 
+  //  the gui frame and all histogramms will be destroyed.   
+  //
+  
+  //
+  //  first of all create a list of the histograms to show
+  //
+  //  take only that one with a entry
+  
+  TH1F *hist ; 
+  TH1F *dhist ; 
+  Char_t dumm[10]; 
+  Char_t name[256]; 
+  
+  TObjArray  *AList ;
+  AList = new TObjArray(10) ; 
+
+  TObjArray  *DList ;
+  DList = new TObjArray(10) ; 
+
+  // the list of analog signal histograms
+  // at the beginning we initalise 10 elements
+  // but this array expand automaticly if neccessay
+  
+  Int_t ic = 0 ; 
+  for ( Int_t i=0 ; i < TRIGGER_PIXELS; i++  ) {
+    if ( used [i] == TRUE ) {
+
+      sprintf (dumm, "A_%d", i ) ; 
+      sprintf (name, "analog %d", i ) ; 
+      
+      hist = new TH1F(dumm, name, TRIGGER_TIME_SLICES, 0., TOTAL_TRIGGER_TIME); 
+      //
+      //  fill the histogram
+      //
+
+      for (Int_t ibin=1; ibin <=TRIGGER_TIME_SLICES; ibin++) {
+	hist->SetBinContent (ibin, a_sig[i][ibin-1]) ;
+      }
+      hist->SetMaximum(8.); 
+      hist->SetStats(kFALSE); 
+  
+      AList->Add(hist) ; 
+      
+      sprintf (dumm, "D_%d", i ) ; 
+      sprintf (name, "digital %d", i ) ; 
+      
+      dhist = new TH1F(dumm, name, TRIGGER_TIME_SLICES, 0., TOTAL_TRIGGER_TIME); 
+      if ( dknt[i] == TRUE ) {
+	//
+	//   fill the histogram of digital signal
+	//
+	for (Int_t ibin=1; ibin <=TRIGGER_TIME_SLICES; ibin++) {
+	  dhist->SetBinContent (ibin, d_sig[i][ibin-1]) ;
+	  dhist->SetStats(kFALSE); 
+	} 
+      }
+      dhist->SetMaximum(1.5);
+	
+      DList->Add(dhist); 
+      
+      ic++ ; 
+
+    }
+  }  
+
+  //
+  //   create the Gui Tool
+  //
+  //
+
+  new MGTriggerSignal(McEvt,
+		      AList,
+ 		      DList,
+		      gClient->GetRoot(), 
+ 		      gClient->GetRoot(), 
+ 		      400, 400 ) ; 
+  
+  //
+  //   delete the List of histogramms
+  //
+
+  AList->Delete() ; 
+  DList->Delete() ; 
+  
+  delete AList ; 
+  delete DList ; 
+}
+  
Index: trunk/MagicSoft/Simulation/Detector/include-MTrigger/MTrigger.hxx
===================================================================
--- trunk/MagicSoft/Simulation/Detector/include-MTrigger/MTrigger.hxx	(revision 350)
+++ trunk/MagicSoft/Simulation/Detector/include-MTrigger/MTrigger.hxx	(revision 351)
@@ -1,3 +1,5 @@
-//
+#ifndef __MTrigger__
+#define __MTrigger__
+
 //     class MTrigger
 //
@@ -12,43 +14,154 @@
 #include <math.h> 
 
+#include "TROOT.h"
 #include "TObject.h"
+#include "TRandom.h"
+#include "TH1.h"
 
 #include "Mdefine.h" 
+#include "MMcEvt.h"
 
-#define TRIGGER_TIME_SLICES    400
+#include "MTriggerDefine.h"
+
+
+//==========
+//  MTrigger
 //
-//      We need 400 Time Slices of 0.25 nsec width. 
-//      So the whole Time range we studies is 100 nsec. 
+//  The simulation of the Trigger for MonteCarlo Events is using this 
+//  class. So all methods concerning the trigger should be done inside this
+//  class. 
 //
-#define RESPONSE_SLICES        40
+//  For a better understanding of the behavior of the trigger is here small
+//  abstract of the trigger. This may change in the future. 
 //
-//       This is for the standard response Signal to 1 Photoelectron
-//       that leaves the Photocathode
-//       The whole Timescale for the signal is 10 nsec
+//  
+//  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). 
+//
+//  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. 
+//
+//  So whenever a photo electron leaves the photo cathod, on has to add
+//  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: 
 //
 //
-//       These values are discussed with Eckart. We start from this point. 
-#define RESPONSE_FWHM          2. 
-#define RESPONSE_AMPLITUDE     1. 
+//  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. 
+//  
+//  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. 
+// 
+//  No one can start with the simulation of different trigger levels. 
+//  
+//  The TriggerLevelZero is a very easy one. It is just looking if there 
+//  are more then N digital signals at level ON (=1). If this is the case,
+//  a TriggerLevelZero signal is created.
 //
-//       This are the Standard values of the response function for
-//       1 photo electron. 
-//       We assume a gaussian pulse with FWHM 2.5 nsec. 
-//
+//  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.   
+//  
+//  
+class MTrigger {
 
-#define CHANNEL_THRESHOLD      2. 
-//
-//       This is the diskriminator threshold for each individual channel
-//       First we set the value to 2 unit of the RESPONSE_AMPLITUDE 
-//
-#define TRIGGER_GATE           3. 
-// 
-//       Here we set the width of the digital signal we get if the signal
-//       passes the diskriminator
-//
-#define TRIGGER_MULTI          4.  
-//
-//       We get a Level Zero Trigger, if we have a least TRIGGER_MULTI
-//       channels with a diskrimiator signal at the same time 
-//
+ private:
+  //
+  //    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) 
+ 
+  Float_t  *a_sig[TRIGGER_PIXELS] ; //  the analog signal for pixels
 
+  Float_t  baseline[TRIGGER_PIXELS] ; //  for the baseline shift
+
+  //
+  //    then for all pixels the shape of the digital signal
+  //
+  Bool_t  dknt [TRIGGER_PIXELS] ;  //  a boolean to indicated if the pixels has passed the diskrminator 
+  Float_t *d_sig[TRIGGER_PIXELS] ; //  the digital signal for all pixels
+
+  //
+  //    and the sum of all digital signals
+  // 
+  Float_t sum_d_sig[TRIGGER_TIME_SLICES] ; 
+
+
+  //
+  //    first the data for the response function
+  //
+  Float_t fwhm_resp ;                      // fwhm of the phe_response function 
+  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 
+
+  TH1F     *histPmt ; 
+  Float_t  histMean ;    // Mean value of the distribution of Rasmik (stored in histPmt) 
+  TRandom  *GenElec  ;   // RandomGenerator for the Electronic Noise
+
+  //
+  //    some values for the trigger settings
+  //
+  
+  Float_t chan_thres ; // 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
+
+  //
+  //  The lookup table for the next neighbours
+  // 
+
+  Int_t NN[TRIGGER_PIXELS][6] ; 
+ 
+  //
+  //    some information about the different TriggerLevels in each Event
+  // 
+
+  Int_t  nZero ;         // how many ZeroLevel Trigger in one Event
+  Int_t  SlicesZero[5] ; // Times Slices at which the ZeroLevel Triggers occur
+
+  Int_t  nFirst ;         // how many FirstLevel Trigger in one Event
+  Int_t  SlicesFirst[5] ; // Times Slices at which the FirstLevel Triggers occur
+
+  Int_t  nSecond ;         // how many SecondLevel Trigger in one Event
+  Int_t  SlicesSecond[5] ; // Times Slices at which the SecondLevel Triggers occur
+
+
+public:
+
+  MTrigger() ; 
+
+  ~MTrigger() ; 
+
+  void Reset() ; 
+
+  Float_t  Fill( Int_t, Float_t ) ;  
+
+  Float_t  FillNSB( Int_t, Float_t ) ;  
+
+  void ElecNoise() ;
+
+  Int_t Diskriminate() ;
+
+  Int_t FirstLevel() ;   
+
+  Bool_t PassNextNeighbour( Bool_t m[] ) ; 
+ 
+  void ShowSignal (MMcEvt *McEvt) ; 
+
+  Float_t GetFirstLevelTime( Int_t il ) ; 
+
+} ; 
+
+#endif
+
