Index: trunk/MagicSoft/Simulation/Detector/include-MFadc/MFadc.cxx
===================================================================
--- trunk/MagicSoft/Simulation/Detector/include-MFadc/MFadc.cxx	(revision 2984)
+++ trunk/MagicSoft/Simulation/Detector/include-MFadc/MFadc.cxx	(revision 2985)
@@ -18,12 +18,17 @@
 #include "MGFadcSignal.hxx"
 
-MFadc::MFadc(Int_t pix, Float_t ampl, Float_t fwhm, Float_t amplout, Float_t fwhmout) {
+MFadc::MFadc(Int_t pix, Float_t integral, Float_t fwhm, Float_t integralout, Float_t fwhmout, Float_t trigger_delay) {
   //
   //  Constructor overloaded II 
   //  
   //  Input variables:
-  //  1. ampl(out) = integration of the single phe response (outer pixels)
-  //  2. fwhm(out) = width at half high of the single phe 
-  //  response(outer pixels)
+  //  1. integral(out) = integration of the single phe response for inner 
+  // (outer) pixels.
+  //  2. fwhm(out) = width at half high of the single phe response for
+  // inner (outer) pixels.
+  //
+  // trigger_delay: shift of signals towards later times in FADC, in order
+  // to center the signals in a good range. It acts as a sort of delay of 
+  // the signals (before being sent to the FADC) with respect to the trigger.
   //
   //  The procedure is the following: 
@@ -31,17 +36,18 @@
   //     this parameters of the trigger may be changed
   //  3. Then the all signals are set to zero
+
   numpix=pix;
   
   fwhm_resp = fwhm; 
-  ampl_resp = ampl; 
+  integ_resp = integral; 
   fwhm_resp_outer = fwhmout; 
-  ampl_resp_outer = amplout; 
+  integ_resp_outer = integralout; 
 
   cout<< "[MFadc]  Setting up the MFadc with this values "<< endl ; 
   cout<< "[MFadc]    - Inner pixels :  "<< endl ; 
-  cout<< "[MFadc]       Response Are : "<<ampl<<" adc counts"<< endl ; 
+  cout<< "[MFadc]       Response Area : "<<integral<<" adc counts"<< endl ; 
   cout<< "[MFadc]       Response FWHM : "<<fwhm<<" ns"<< endl ; 
-  cout<< "[MFadc]    - Outer pixels :  "<< endl ; 
-  cout<< "[MFadc]       Response Are : "<<amplout<<" adc counts"<< endl ; 
+  cout<< "[MFadc]    - Inner pixels :  "<< endl ; 
+  cout<< "[MFadc]       Response Area : "<<integralout<<" adc counts"<< endl ; 
   cout<< "[MFadc]       Response FWHM : "<<fwhmout<<" ns"<< endl ; 
   
@@ -57,4 +63,7 @@
   x0 = 3*sigma;
   
+  fadc_time_offset = trigger_delay-x0; // ns
+
+
   Float_t   dX, dX2 ; 
 
@@ -70,8 +79,21 @@
     //
     //   the value 1/(2*Pi*sigma^2) was introduced to normalize 
-    //   the area at the input value
-    //
-    sing_resp[i] = ampl_resp / sqrt(2*3.1415926*sigma*sigma)*  
+    //   the area at the input value. After this, the integral
+    //   of the response will be integ_resp.
+    //
+    sing_resp[i] = integ_resp / sqrt(2*3.1415926*sigma*sigma)*  
        expf(-0.5 * (x-x0)*(x-x0) / (sigma*sigma) ) ; 
+
+    //   
+    //   The integral of the response above would be the sum of all
+    //   sing_resp[i] values times the bin width WIDTH_RESPONSE_MFADC,
+    //   and it would now equal "integ_resp". 
+    //   We want however that our actual measurement, the sum of FADC 
+    //   slices contents, is equal to integ_resp. Since in each FADC 
+    //   slice we will put the content of just one response bin, and 
+    //   there are a number SUBBINS of such response bins within 1 FADC 
+    //   slice, the needed factor is then:
+    //
+    sing_resp[i] *= (WIDTH_RESPONSE_MFADC*SUBBINS);
 
   } 
@@ -90,9 +112,21 @@
     //
     //   the value 1/(2*Pi*sigma^2) was introduced to normalize 
-    //   the area at the input value
-    //
-    sing_resp_outer[i] = ampl_resp_outer / sqrt(2*3.1415926*sigma*sigma)*  
+    //   the area at the input value After this, the integral
+    //   of the response will be integ_resp.
+    //
+    sing_resp_outer[i] = integ_resp_outer / sqrt(2*3.1415926*sigma*sigma)*  
        expf(-0.5 * (x-x0)*(x-x0) / (sigma*sigma) ) ; 
 
+    //   
+    //   The integral of the response above would be the sum of all
+    //   sing_resp[i] values times the bin width WIDTH_RESPONSE_MFADC,
+    //   and it would now equal "integ_resp". 
+    //   We want however that our actual measurement, the sum of FADC 
+    //   slices contents, is equal to integ_resp. Since in each FADC 
+    //   slice we will put the content of just one response bin, and 
+    //   there are a number SUBBINS of such response bins within 1 FADC 
+    //   slice, the needed factor is then:
+    //  
+    sing_resp_outer[i] *= (WIDTH_RESPONSE_MFADC*SUBBINS);
   } 
 
@@ -119,12 +153,22 @@
     //
     //  set all values of the signals to zero
-    //  set tha values of FADC slices that would be read after trigger to zero
+    //  set the values of FADC slices that would be read after trigger to zero
     //
     memset(used, 0, CAMERA_PIXELS*sizeof(Bool_t));
     memset(output, 0, CAMERA_PIXELS*FADC_SLICES*sizeof(UChar_t));
     memset(output_lowgain, 0, CAMERA_PIXELS*FADC_SLICES*sizeof(UChar_t));
+    // 
+    // Added 15 01 2004, AM:
+    //
+    memset(sig, 0, (Int_t)(CAMERA_PIXELS*SLICES_MFADC*sizeof(Float_t)));
 }
 void MFadc::Fill( Int_t iPix, Float_t time, 
 		  Float_t amplitude, Int_t isinner ) { 
+
+    // AM, Jan 2004 : added delay to shift the signal peak to the desired
+    // range in the FADC window (indicated through the trigger_delay command
+    // in the camera input card.
+
+  time += fadc_time_offset;
 
   if(isinner)
@@ -169,13 +213,12 @@
   // 
 
-  
-  if ( time < 0. ) {
-    cout << "  WARNING! Fadc::Fill  " << time << "  below ZERO!! Very strange!!" 
-	 << endl ; 
-  }
-  else if ( time < TOTAL_TRIGGER_TIME ) { 
+  if ( time < TOTAL_TRIGGER_TIME+trigger_delay ) { 
     //
     //   determine the slices number assuming the WIDTH_RESPONSE_MFADC
-    //
+    //   ichan marks the start of the pulse, in number of bins of width  
+    //   WIDTH_RESPONSE_MFADC (2/3 of a ns), measured from the start of the 
+    //   FADC.
+    //
+
     ichan = (Int_t) ( time / ((Float_t) WIDTH_RESPONSE_MFADC )); 
 
@@ -185,14 +228,35 @@
     //
 
-    for ( i = 0 ; i<RESPONSE_SLICES; i++ ) {
+    //
+    // AM, Jan 2004: Replaced former FADC simulation (integration of signal)
+    // with a more realistic one (measuring signal height at discrete points).
+    //
+
+    // We take the pulse height in the middle of FADC slices, we start in the
+    // first such point after the time "time" (=ichan in response bins). Each
+    // FADC slice corresponds to SUBBINS response bins (SUBBINS=5 by default).
+
+    Int_t first_i =  Int_t(SUBBINS/2) - ichan%(Int_t)SUBBINS;
+    first_i = first_i < 0 ? (Int_t)SUBBINS+first_i : first_i;
+
+
+    for ( i = first_i ; i < (Int_t)RESPONSE_SLICES; i += (Int_t)SUBBINS) {	
       ichanfadc = (Int_t) ((ichan+i)/SUBBINS) ; 
+      if ( ichanfadc < 0 )
+	  continue;
+
+      //
+      // SLICES_MFADC is by default 48. sig[][] is not the true FADC, which
+      // is filled from sig[][] in MFadc::TriggeredFadc()
+      //
       if ( (ichanfadc) < (Int_t)SLICES_MFADC ) {  
 	sig[iPix][ichanfadc] += (amplitude * sing_resp[i] )  ; 
       } 
     }
+
   }
   else {
     cout << "  WARNING!  Fadc::Fill " << time << "  out of TriggerTimeRange " 
-	 << TOTAL_TRIGGER_TIME << endl ; 
+	 << TOTAL_TRIGGER_TIME+trigger_delay << endl ; 
   }
 
@@ -234,10 +298,6 @@
   // 
 
-  
-  if ( time < 0. ) {
-    cout << "  WARNING! Fadc::FillOuter  " << time << "  below ZERO!! Very strange!!" 
-	 << endl ; 
-  }
-  else if ( time < TOTAL_TRIGGER_TIME ) { 
+
+  if ( time < TOTAL_TRIGGER_TIME+trigger_delay ) { 
     //
     //   determine the slices number assuming the WIDTH_RESPONSE_MFADC
@@ -250,14 +310,31 @@
     //
 
-    for ( i = 0 ; i<RESPONSE_SLICES; i++ ) {
+    //
+    // AM, Jan 2004: Replaced former FADC simulation (integration of signal)
+    // with a more realistic one (measuring signal height at discrete points).
+    //
+
+    // We take the pulse height in the middle of FADC slices, we start in the
+    // first such point after the time "time" (=ichan in response bins). Each
+    // FADC slice corresponds to SUBBINS response bins (SUBBINS=5 by default).
+
+    Int_t first_i =  Int_t(SUBBINS/2) - ichan%(Int_t)SUBBINS;
+    first_i = first_i < 0 ? (Int_t)SUBBINS+first_i : first_i;
+
+    for ( i = first_i ; i < (Int_t)RESPONSE_SLICES; i += (Int_t)SUBBINS) {
       ichanfadc = (Int_t) ((ichan+i)/SUBBINS) ; 
+
+      if ( ichanfadc < 0 )
+	  continue;
+
       if ( (ichanfadc) < (Int_t)SLICES_MFADC ) {  
 	sig[iPix][ichanfadc] += (amplitude * sing_resp_outer[i] )  ; 
       } 
     }
+
   }
   else {
     cout << "  WARNING!  Fadc::FillOuter " << time << "  out of TriggerTimeRange " 
-	 << TOTAL_TRIGGER_TIME << endl ; 
+	 << TOTAL_TRIGGER_TIME+trigger_delay << endl ; 
   }
 
@@ -364,5 +441,5 @@
     baseline=0.0;
     for(i=0;i<(Int_t) SLICES_MFADC;i++){
-      baseline=+sig[j][i];
+      baseline+=sig[j][i];
     }
     baseline=baseline/SLICES_MFADC;
@@ -383,10 +460,13 @@
 
   for(i=0;i<numpix;i++)
-    for(j=0;j<(Int_t)SLICES_MFADC;j++){
-      if(used[i])
-      	sig[i][j]+=pedestal[i];
-      else
-      	sig[i][j]=pedestal[i];
-    }
+    for(j=0;j<(Int_t)SLICES_MFADC;j++)
+        sig[i][j]+=pedestal[i];
+  //
+  // AM 15 01 2003: Formerly the above operation was performed only 
+  // for pixels in which used[] was true. But to run camera with no noise
+  // and get the right baseline on the pixels with no C-photons, we have 
+  // to do it for all pixels.
+  //
+
 
 }
@@ -412,5 +492,5 @@
 	  fdum=(10*GenOff->Rndm());
 	  for(j=0;j<(Int_t) SLICES_MFADC;j++)
-	    sig[i][j]=+fdum;
+	    sig[i][j]+=fdum;
 	}
       }
@@ -421,5 +501,5 @@
 	fdum=(10*GenOff->Rndm());
 	for(j=0;j<(Int_t) SLICES_MFADC;j++)
-	  sig[pixel][j]=+fdum;
+	  sig[pixel][j]+=fdum;
 	}
 
@@ -434,5 +514,5 @@
 	if (used[i]){
 	  for(j=0;j<(Int_t) SLICES_MFADC;j++)
-	    sig[i][j]=+offset;
+	    sig[i][j]+=offset;
 	}
       }
@@ -442,5 +522,5 @@
       if (used[pixel]){
 	for(j=0;j<(Int_t) SLICES_MFADC;j++)
-	  sig[pixel][j]=+offset;
+	  sig[pixel][j]+=offset;
       }
     }
@@ -593,5 +673,5 @@
   Float_t t ; 
 
-  (0 > time - TIME_BEFORE_TRIGGER)? t=0: t=(time-TIME_BEFORE_TRIGGER) ; // to show also the start of the pulse before the trigger time
+  (0 > time - TIME_BEFORE_TRIGGER)? t=trigger_delay: t=(time-TIME_BEFORE_TRIGGER+trigger_delay) ; // to show also the start of the pulse before the trigger time
 
   if ( t < 0. ) {
@@ -666,4 +746,5 @@
 	     ? 255 
 	     :UChar_t(pedestal[pix]+(sig[pix][is]-pedestal[pix])/factor+0.5));
+
       if(Int_t(value)+digital_noise[startslice+is]<0.0)
 	 value=0;
@@ -683,6 +764,6 @@
     }
     sigma+=((Float_t)value-pedestal[pix])*((Float_t)value-pedestal[pix]);
-  }
-
+
+  }
 
   sigma=sqrt(sigma/(SLICES_MFADC-1));
@@ -694,18 +775,5 @@
   
   //
-  //    first of all we subtract from the time a offset (8 ns) 
-  // 
-  
-  Float_t t ; 
-
-  (0>time-TIME_BEFORE_TRIGGER)? t=0: t=(time-TIME_BEFORE_TRIGGER) ; // to show also the start of the pulse before the trigger time
-
-  if ( t < 0. ) {
-    cout << " WARNING!! FROM MFADC::SCAN(t) " << endl ; 
-    exit (776) ;  
-  }
-
-  //
-  //  calculate the first slice to write out
+  //  calculate the first slice to write out, according to trigger time: 
   // 
   
@@ -713,39 +781,54 @@
   Int_t i;
 
-  iFirstSlice = (Int_t) ( t /  WIDTH_FADC_TIMESLICE ) ; 
+  //
+  // We had 0.5 for the correct rounding:
+  //
+  iFirstSlice = (Int_t) ( 0.5 + time /  WIDTH_FADC_TIMESLICE ) ; 
 
   for ( Int_t ip=0; ip<numpix; ip++ ) {
     
-    if ( used[ip] == kTRUE ) { 
-      i=0;
-      for ( Int_t is=iFirstSlice ; is < (iFirstSlice+FADC_SLICES) ; is++ ) {
-	if (is< (Int_t)SLICES_MFADC && sig[ip][is]>0.0)
+      if ( used[ip] == kTRUE ) { 
+	  i=0;
+	  for ( Int_t is=iFirstSlice ; is < (iFirstSlice+FADC_SLICES) ; is++ ) 
 	  {
+	      if (is< (Int_t)SLICES_MFADC && sig[ip][is]>0.0)
+	      {
 	    
-	    output[ip][i]=(sig[ip][is] > 255. ? 255 :(UChar_t) (sig[ip][is]+0.5));
-	    output_lowgain[ip][i]= 
-	      (Int_t)(pedestal[ip]+(sig[ip][is]-pedestal[ip])/high2low_gain+0.5) > 255. ? 255 :
-	      (UChar_t)(pedestal[ip]+(sig[ip][is]-pedestal[ip])/high2low_gain+0.5);
-	    i++;
+		  output[ip][i]=(sig[ip][is] > 255. ? 255 :(UChar_t) (sig[ip][is]+0.5));
+		  output_lowgain[ip][i]= 
+		      (Int_t)(pedestal[ip]+(sig[ip][is]-pedestal[ip])/high2low_gain+0.5) > 255. ? 255 :
+		      (UChar_t)(pedestal[ip]+(sig[ip][is]-pedestal[ip])/high2low_gain+0.5);
+		  i++;
 	    
+	      }
+	      else if(sig[ip][is]>=0.0)
+	      {
+		  output[ip][i]= (UChar_t)(pedestal[ip]+0.5);
+		  output_lowgain[ip][i]= (UChar_t)(pedestal[ip]+0.5);
+		  i++;
+	      }
+	      else 
+	      {
+		  output[ip][i]= 0;
+		  if((pedestal[ip]+(sig[ip][is]-pedestal[ip])/high2low_gain)<0)
+		      output_lowgain[ip][i]= 0;
+		  else
+		      output_lowgain[ip][i]=(UChar_t)(pedestal[ip]+(sig[ip][is]-pedestal[ip])/high2low_gain+0.5);
+		  i++;
+	      }
 	  }
-	else if(sig[ip][is]>=0.0)
+      }
+      else  
+	  // Pixels with no C-photons in the case that camera is run with
+	  // no noise (nor NSB neither electronic)
+      {
+	  for ( Int_t i=0 ; i < FADC_SLICES ; i++ ) 
 	  {
- 	    output[ip][i]= (UChar_t)(pedestal[ip]+0.5);
- 	    output_lowgain[ip][i]= (UChar_t)(pedestal[ip]+0.5);
-	    i++;
-	  }
-	else 
- 	  {
- 	    output[ip][i]= 0;
-	    if((pedestal[ip]+(sig[ip][is]-pedestal[ip])/high2low_gain)<0)
-	      output_lowgain[ip][i]= 0;
-	    else
-	      output_lowgain[ip][i]=(UChar_t)(pedestal[ip]+(sig[ip][is]-pedestal[ip])/high2low_gain+0.5);
-	    i++;
- 	  }
+	      output[ip][i]= (UChar_t)(pedestal[ip]+0.5);
+	      output_lowgain[ip][i]= (UChar_t)(pedestal[ip]+0.5);
+	  } 
       }
-    }
-  }  
+  }
+
 } 
 
@@ -782,5 +865,5 @@
       sprintf (name, "fadc signal %d", i ) ; 
       
-      hist = new TH1F(dumm, name, SLICES_MFADC, 0., TOTAL_TRIGGER_TIME); 
+      hist = new TH1F(dumm, name, SLICES_MFADC, trigger_delay, TOTAL_TRIGGER_TIME+trigger_delay); 
       //
       //  fill the histogram
