Index: trunk/MagicSoft/Simulation/Detector/include-MFadc/MFadc.cxx
===================================================================
--- trunk/MagicSoft/Simulation/Detector/include-MFadc/MFadc.cxx	(revision 6588)
+++ trunk/MagicSoft/Simulation/Detector/include-MFadc/MFadc.cxx	(revision 6692)
@@ -60,5 +60,8 @@
 
   for (Int_t i = 0; i < CAMERA_PIXELS; i++)
-    sig[i] = new Float_t[fSlices_mFadc];
+    {
+      sig[i] = new Float_t[fSlices_mFadc];
+      sig_LG[i] = new Float_t[fSlices_mFadc];
+    }
 
   noise = new Float_t[fSlices_mFadc*1001];
@@ -125,4 +128,27 @@
   sing_resp_outer = new Float_t[fResponseSlicesFadc];
 
+  sing_resp_lowgain = new Float_t[fResponseSlicesFadc];
+  sing_resp_outer_lowgain = new Float_t[fResponseSlicesFadc];
+
+
+  // Parameters for real pulse shaped as measured with the Pulpo device:
+  fPulseParameters[0] = 2.066; 
+  fPulseParameters[1] = 1.568; 
+  fPulseParameters[2] = 3;     // This will set the peak of the pulse at x ~ 3*3.3 = 10 ns
+                               // It is just a safe value so that the pulse is well contained.
+  fPulseParameters[3] = 0.00282; 
+  fPulseParameters[4] = 0.04093; 
+  fPulseParameters[5] = 0.2411; 
+  fPulseParameters[6] = -0.009442;
+
+  // Now for the low gain:
+  fPulseParametersLG[0] = 0.7;
+  fPulseParametersLG[1] = 0.88;
+  fPulseParametersLG[2] = 3.4;
+  fPulseParametersLG[3] = 0.00282; 
+  fPulseParametersLG[4] = 0.04093; 
+  fPulseParametersLG[5] = 0.2411; 
+  fPulseParametersLG[6] = -0.009442;
+
   Int_t  i ;
   
@@ -132,6 +158,10 @@
 
   Float_t   response_sum_inner, response_sum_outer;
+  Float_t   response_sum_inner_LG, response_sum_outer_LG;
+
   response_sum_inner = 0.;
   response_sum_outer = 0.;
+  response_sum_inner_LG = 0.;
+  response_sum_outer_LG = 0.;
 
   dX  = 1. / fFadcSlicesPerNanosec / SUBBINS ;   // Units: ns
@@ -144,5 +174,5 @@
     x0 = 3*sigma;
     fadc_time_offset = trigger_delay-x0; // ns
-  
+
     for (i = 0; i < fResponseSlicesFadc ; i++ ) 
       {  
@@ -150,11 +180,16 @@
       
 	sing_resp[i] = (Float_t)(expf(-0.5*(x-x0)*(x-x0)/(sigma*sigma))); 
-
+	sing_resp_lowgain[i] = sing_resp[i]; 
+
+	// Use the same pulse for high and low gain in case of gaussian shape
+	// FIXME: it would be nice to be able to choose a different shape for 
+	// high and low gain:
 	response_sum_inner += sing_resp[i];
+	response_sum_inner_LG += sing_resp_lowgain[i];
       }
 
     break;
   case 1:
-    float p1,p2,p3,p4,p5,p6,p7;
+    float p0,p1,p2,p3,p4,p5,p6;
     float d;
     float zed_slices;
@@ -162,12 +197,21 @@
     // gaussian electronic pulse passed through the whole chain from 
     // transmitter boards to FADC.
-    p1 = 2.066; 
-    p2 = 1.568; 
-    p3 = 3; // This will set the peak of the pulse at x ~ 3*3.3 = 10 ns
-            // It is just a safe value so that the pulse is well contained.
-    p4 = 0.00282; 
-    p5 = 0.04093; 
-    p6 = 0.2411; 
-    p7 = -0.009442;
+    p0 = fPulseParameters[0];
+    p1 = fPulseParameters[1];
+    p2 = fPulseParameters[2];
+    p3 = fPulseParameters[3];
+    p4 = fPulseParameters[4];
+    p5 = fPulseParameters[5];
+    p6 = fPulseParameters[6];
+
+    float p0_LG, p1_LG, p2_LG, p3_LG, p4_LG, p5_LG, p6_LG;
+    p0_LG = fPulseParametersLG[0];
+    p1_LG = fPulseParametersLG[1];
+    p2_LG = fPulseParametersLG[2];
+    p3_LG = fPulseParametersLG[3];
+    p4_LG = fPulseParametersLG[4];
+    p5_LG = fPulseParametersLG[5];
+    p6_LG = fPulseParametersLG[6];
+
 
     // Now define the time before trigger to read FADC signal when it
@@ -181,5 +225,5 @@
     // frequency we are simulating!
 
-    fadc_time_offset = trigger_delay - p3 / FADC_SLICES_PER_NSEC; // ns
+    fadc_time_offset = trigger_delay - p2 / FADC_SLICES_PER_NSEC; // ns
 
     for (i=0; i< fResponseSlicesFadc ; i++ )
@@ -191,12 +235,19 @@
 	// are using another sampling frequency!):
 	//
-	zed_slices = x * FADC_SLICES_PER_NSEC - p3;
-	d=(zed_slices>0)?0.5:-0.5;
-
-	sing_resp[i] =  (Float_t) (p1*exp(-p2*(exp(-p2*zed_slices)+zed_slices))+
-				   p4+p5*exp(-p2*(exp(-p2*zed_slices)+
-						  p6*zed_slices))+p7*d);
+	zed_slices = x * FADC_SLICES_PER_NSEC - p2;
+	d = (zed_slices>0)? 0.5 : -0.5;
+
+	sing_resp[i] =  (Float_t) (p0*exp(-p1*(exp(-p1*zed_slices)+zed_slices))+
+				   p3+p4*exp(-p1*(exp(-p1*zed_slices)+
+						  p5*zed_slices))+p6*d);
+
+	zed_slices = x * FADC_SLICES_PER_NSEC - p2_LG;
+	d = (zed_slices>0)? 0.5 : -0.5;
+	sing_resp_lowgain[i] =  (Float_t) (p0_LG*exp(-p1_LG*(exp(-p1_LG*zed_slices)+zed_slices))+
+					   p3+p4*exp(-p1_LG*(exp(-p1_LG*zed_slices)+
+							  p5*zed_slices))+p6*d);
 
 	response_sum_inner += sing_resp[i];
+	response_sum_inner_LG += sing_resp_lowgain[i];
       }
 
@@ -234,5 +285,5 @@
     break;
   case 1:
-    float p1,p2,p3,p4,p5,p6,p7;
+    float p0,p1,p2,p3,p4,p5,p6;
     float d;
     float zed_slices;
@@ -240,12 +291,21 @@
     // gaussian electronic pulse passed through the whole chain from 
     // transmitter boards to FADC.
-    p1 = 2.066; 
-    p2 = 1.568; 
-    p3 = 3; // This sets the peak of the pulse at x ~ 3*3.3 = 10 nanosec
-            // It is just a safe value so that the pulse is well contained.
-    p4 = 0.00282; 
-    p5 = 0.04093; 
-    p6 = 0.2411; 
-    p7 = -0.009442;
+
+    p0 = fPulseParameters[0];
+    p1 = fPulseParameters[1];
+    p2 = fPulseParameters[2];
+    p3 = fPulseParameters[3];
+    p4 = fPulseParameters[4];
+    p5 = fPulseParameters[5];
+    p6 = fPulseParameters[6];
+
+    float p0_LG, p1_LG, p2_LG, p3_LG, p4_LG, p5_LG, p6_LG;
+    p0_LG = fPulseParametersLG[0];
+    p1_LG = fPulseParametersLG[1];
+    p2_LG = fPulseParametersLG[2];
+    p3_LG = fPulseParametersLG[3];
+    p4_LG = fPulseParametersLG[4];
+    p5_LG = fPulseParametersLG[5];
+    p6_LG = fPulseParametersLG[6];
 
     // Now define the time before trigger to read FADC signal when it
@@ -259,5 +319,5 @@
     // frequency we are simulating!
 
-    fadc_time_offset = trigger_delay - p3 / FADC_SLICES_PER_NSEC; // ns
+    fadc_time_offset = trigger_delay - p2 / FADC_SLICES_PER_NSEC; // ns
 
     for (i=0; i< fResponseSlicesFadc ; i++ )
@@ -269,12 +329,20 @@
 	// are using another sampling frequency!):
 	//
-	zed_slices = x * FADC_SLICES_PER_NSEC - p3;
-	d=(zed_slices>0)?0.5:-0.5;
-
-	sing_resp_outer[i] = (Float_t) (p1*exp(-p2*(exp(-p2*zed_slices)+
-						    zed_slices))+p4+
-					p5*exp(-p2*(exp(-p2*zed_slices)+
-						    p6*zed_slices))+p7*d);
+	zed_slices = x * FADC_SLICES_PER_NSEC - p2;
+	d = (zed_slices>0)? 0.5 : -0.5;
+
+	sing_resp_outer[i] = (Float_t) (p0*exp(-p1*(exp(-p1*zed_slices)+
+						    zed_slices))+p3+
+					p4*exp(-p1*(exp(-p1*zed_slices)+
+						    p5*zed_slices))+p6*d);
+
+	zed_slices = x * FADC_SLICES_PER_NSEC - p2_LG;
+	d = (zed_slices>0)? 0.5 : -0.5;
+	sing_resp_outer_lowgain[i] =  (Float_t) (p0_LG*exp(-p1_LG*(exp(-p1_LG*zed_slices)+zed_slices))+
+						 p3+p4*exp(-p1_LG*(exp(-p1_LG*zed_slices)+
+								   p5*zed_slices))+p6*d);
+
 	response_sum_outer += sing_resp_outer[i];
+	response_sum_outer_LG += sing_resp_outer_lowgain[i];
       }
     break;
@@ -288,5 +356,5 @@
 
   //   
-  // Normalize responses to values set trhough input card: (= set gain of electronic chain)
+  // Normalize responses to values set through input card: (= set gain of electronic chain)
   // Take into account that only 1 of every SUBBINS bins of sing_resp[] will be "sampled" by 
   // the FADC, so we have to correct for this to get the right "FADC integral" (=integ_resp) 
@@ -294,12 +362,17 @@
   //
 
-  for (i=0; i< fResponseSlicesFadc ; i++ )
+  for (i = 0; i < fResponseSlicesFadc ; i++ )
     {  
       sing_resp[i] *= integ_resp / response_sum_inner * SUBBINS;
       sing_resp_outer[i] *= integ_resp_outer / response_sum_outer * SUBBINS;
-    }
-
-  //
-  //    init the Random Generator for Electonic Noise
+
+      // The low gain will be further scaled down later; for now we normalize it with to same
+      // integral as the high gain.
+      sing_resp_lowgain[i] *= integ_resp / response_sum_inner_LG * SUBBINS;
+      sing_resp_outer_lowgain[i] *= integ_resp_outer / response_sum_outer_LG * SUBBINS;
+    }
+
+  //
+  // init the Random Generator for Electronic Noise
   //
 
@@ -333,8 +406,11 @@
 
     // 
-    // Added 15 01 2004, AM:
+    
     //
     for (Int_t i = 0; i < CAMERA_PIXELS; i++)
-      memset(sig[i], 0, (Int_t)(fSlices_mFadc*sizeof(Float_t)));
+      {
+	memset(sig[i], 0, (Int_t)(fSlices_mFadc*sizeof(Float_t)));    // Added 15 01 2004, AM
+	memset(sig_LG[i], 0, (Int_t)(fSlices_mFadc*sizeof(Float_t))); // Added 01 03 2005, AM
+      }
 }
 void MFadc::Fill( Int_t iPix, Float_t time, 
@@ -385,6 +461,9 @@
       used [iPix] = TRUE; 
     
-      for (i=0; i < (Int_t) fSlices_mFadc; i++ ) 
-	sig[iPix][i] = 0.; 
+      for (i=0; i < (Int_t) fSlices_mFadc; i++ )
+	{
+	  sig[iPix][i] = 0.;
+	  sig_LG[iPix][i] = 0.;
+	}
     }
 
@@ -429,11 +508,13 @@
 
 	//
-	// fSlices_mFadc is by default 48. sig[][] is not the true FADC, which
-	// is filled (from sig[][]) in MFadc::TriggeredFadc()
+	// fSlices_mFadc is by default 48. sig[][] is not the final FADC output; that 
+	// will be later filled (from sig[][]) in MFadc::TriggeredFadc()
 	//
-	if ( (ichanfadc) < (Int_t) fSlices_mFadc )  
-	  sig[iPix][ichanfadc] += (amplitude * sing_resp[i] ); 
+	if ( (ichanfadc) < (Int_t) fSlices_mFadc )
+	  {
+	    sig[iPix][ichanfadc] += (amplitude * sing_resp[i] ); 
+	    sig_LG[iPix][ichanfadc] += (amplitude * sing_resp_lowgain[i] );
+	  }
       }
-
   }
   else
@@ -466,5 +547,8 @@
     
       for (i=0; i < (Int_t) fSlices_mFadc; i++)
-	sig[iPix][i] = 0.;
+	{
+	  sig[iPix][i] = 0.;
+	  sig_LG[iPix][i] = 0.;
+	}
     }
 
@@ -485,5 +569,9 @@
 
 	if ( (ichanfadc) < (Int_t)fSlices_mFadc )
-	  sig[iPix][ichanfadc] += (amplitude * sing_resp_outer[i] ); 
+	  {
+	    sig[iPix][ichanfadc] += (amplitude * sing_resp_outer[i] );
+	    sig_LG[iPix][ichanfadc] += (amplitude * sing_resp_outer_lowgain[i] );
+	  }
+
       }
     
@@ -496,11 +584,11 @@
 }
 
-void MFadc::Set( Int_t iPix, Float_t *resp) { 
-  
-  //
-  // Sets the information about fadc reponse from a given array
-  //
-  // parameter is the number of the pixel and the values to be set
-  //
+void MFadc::AddSignal( Int_t iPix, Float_t *resp) { 
+  
+  //
+  // Adds signals to the fadc reponse from a given array
+  // Parameters are the number of the pixel and the values to be added
+  // With add the signal equally to the high and low gain branch. The low
+  // gain branch is not yet scaled down!!
   //
 
@@ -511,54 +599,26 @@
   //   if this is the first use, reset all signal for that pixels
   // 
-  if ( iPix > numpix ) {
-    cout << " WARNING:  MFadc::Fill() :  iPix greater than CAMERA_PIXELS"
-	 << endl ;
-    exit(987) ; 
-  }
-
-  if ( used[iPix] == FALSE ) {
-    used [iPix] = TRUE ; 
+  if ( iPix > numpix ) 
+    {
+      cout << " WARNING:  MFadc::Fill() :  iPix greater than CAMERA_PIXELS"
+	   << endl ;
+      exit(987) ; 
+    }
+
+  if ( used[iPix] == FALSE ) 
+    {
+      used [iPix] = TRUE ; 
     
-    for (i=0; i < (Int_t)fSlices_mFadc; i++ ) {
-      sig[iPix][i] = 0. ; 
-    }
-  }
-  for ( i = 0 ; i<(Int_t)fSlices_mFadc; i++ ) {
-    sig[iPix][i] = resp[i] ; 
-  }
-
-}
-
-void MFadc::AddSignal( Int_t iPix, Float_t *resp) { 
-  
-  //
-  // Adds signals to the fadc reponse from a given array
-  //
-  // parameters are the number of the pixel and the values to be added
-  //
-  //
-
-  Int_t i ; 
-  
-  //
-  //   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 > numpix ) {
-    cout << " WARNING:  MFadc::Fill() :  iPix greater than CAMERA_PIXELS"
-	 << endl ;
-    exit(987) ; 
-  }
-
-  if ( used[iPix] == FALSE ) {
-    used [iPix] = TRUE ; 
-    
-    for (i=0; i < (Int_t)fSlices_mFadc; i++ ) {
-      sig[iPix][i] = 0. ; 
-    }
-  }
-  for ( i = 0 ; i<(Int_t)fSlices_mFadc; i++ ) {
-    sig[iPix][i] += resp[i] ; 
-  }
+      for (i=0; i < (Int_t)fSlices_mFadc; i++ )
+	{
+	  sig[iPix][i] = 0. ; 
+	  sig_LG[iPix][i] = 0. ; 
+	}
+    }
+  for ( i = 0 ; i<(Int_t)fSlices_mFadc; i++ ) 
+    {
+      sig[iPix][i] += resp[i] ; 
+      sig_LG[iPix][i] += resp[i] ; 
+    }
 
 }
@@ -584,24 +644,5 @@
   }
 }
-  
-
-void MFadc::Baseline(){
-  //  
-  //  It simulates the AC behaviour
-
-  int i,j;
-  Float_t baseline;
-
-  for(j=0;j<numpix;j++){
-    baseline=0.0;
-    for(i=0;i<(Int_t) fSlices_mFadc;i++){
-      baseline+=sig[j][i];
-    }
-    baseline=baseline/fSlices_mFadc;
-    for(i=0;i<(Int_t) fSlices_mFadc;i++){
-      sig[j][i]=-baseline;
-    }
-  }
-}
+
 
 void MFadc::Pedestals(){
@@ -616,5 +657,9 @@
   for(i=0;i<numpix;i++)
     for(j=0;j<(Int_t)fSlices_mFadc;j++)
-        sig[i][j]+=pedestal[i];
+      {
+        sig[i][j] += pedestal[i];
+	sig_LG[i][j] += pedestal[i];
+      }
+
   //
   // AM 15 01 2003: Formerly the above operation was performed only 
@@ -625,60 +670,4 @@
 }
 
-void MFadc::Offset(Float_t offset, Int_t pixel){
-  // 
-  //  It puts an offset in the FADC signal
-  //
-
-  int i,j;
-  float fdum;
-  TRandom *GenOff = new TRandom () ; 
-
-  if (offset<0) {
-    //  It cannot be, so the program assumes that 
-    //  it should generate random values for the offset.
-
-    if (pixel<0) {
-      // It does not exist, so all pixels will have the same offset
-
-      for(i=0;i<numpix;i++){
-	if (used[i]){
-	  fdum=(10*GenOff->Rndm());
-	  for(j=0;j<(Int_t) fSlices_mFadc;j++)
-	    sig[i][j]+=fdum;
-	}
-      }
-    } else {
-      // The program will put the specifies offset to the pixel "pixel".
-
-      if (used[pixel]){
-	fdum=(10*GenOff->Rndm());
-	for(j=0;j<(Int_t) fSlices_mFadc;j++)
-	  sig[pixel][j]+=fdum;
-	}
-
-    }
-  }else {
-    //  The "offset" will be the offset for the FADC
-
-    if (pixel<0) {
-      // It does not exist, so all pixels will have the same offset
-
-      for(i=0;i<numpix;i++){
-	if (used[i]){
-	  for(j=0;j<(Int_t) fSlices_mFadc;j++)
-	    sig[i][j]+=offset;
-	}
-      }
-    } else {
-      // The program will put the specifies offset to the pixel "pixel".
-
-      if (used[pixel]){
-	for(j=0;j<(Int_t) fSlices_mFadc;j++)
-	  sig[pixel][j]+=offset;
-      }
-    }
-  }
-  delete GenOff;
-}
 
 void MFadc::SetElecNoise(Float_t value1, Float_t value2, UInt_t n_in_pix){
@@ -716,5 +705,5 @@
     //
 
-    startslice=GenElec->Integer(((Int_t)fSlices_mFadc)*1000);
+    startslice = GenElec->Integer(((Int_t)fSlices_mFadc)*1000);
 
     if ( used[i] == FALSE )
@@ -722,11 +711,22 @@
 	used [i] = TRUE ; 
 	if (i < fInnerPixelsNum)
+	  {
 	    memcpy( (Float_t*)&sig[i][0],
 		    (Float_t*)&noise[startslice], 
 		    ((Int_t) fSlices_mFadc)*sizeof(Float_t));
+	    memcpy( (Float_t*)&sig_LG[i][0],
+		    (Float_t*)&noise[startslice], 
+		    ((Int_t) fSlices_mFadc)*sizeof(Float_t));
+	  }
+
 	else
+	  {
 	    memcpy( (Float_t*)&sig[i][0],
 		    (Float_t*)&noise_outer[startslice], 
 		    ((Int_t) fSlices_mFadc)*sizeof(Float_t));
+	    memcpy( (Float_t*)&sig_LG[i][0],
+		    (Float_t*)&noise_outer[startslice], 
+		    ((Int_t) fSlices_mFadc)*sizeof(Float_t));
+	  }
     }
 
@@ -737,9 +737,15 @@
     {
 	if (i < fInnerPixelsNum)
-	    for ( Int_t is=0 ; is< (Int_t)fSlices_mFadc ; is++ ) 
+	    for ( Int_t is = 0 ; is < (Int_t)fSlices_mFadc ; is++ ) 
+	      {
 		sig[i][is] += noise[startslice+is];
+		sig_LG[i][is] += noise[startslice+is];
+	      }
 	else
-	    for ( Int_t is=0 ; is< (Int_t)fSlices_mFadc ; is++ ) 
+	    for ( Int_t is = 0 ; is < (Int_t)fSlices_mFadc ; is++ ) 
+	      {
 		sig[i][is] += noise_outer[startslice+is];
+		sig_LG[i][is] += noise_outer[startslice+is];
+	      }
     }
   }
@@ -888,19 +894,10 @@
 Float_t MFadc::AddNoiseInSlices( Int_t pix, Int_t ishigh, Int_t n_slices) {
 
-  Float_t sum=0;
+  Float_t sum = 0;
   Float_t fvalue = 0.;
-  UChar_t value=0;
-  
-  Float_t factor;
+  UChar_t value = 0;
   UInt_t startslice;
 
   //
-  // If we deal with low gain, we have to scale the values in sig[][] by
-  // the gain ratio (high2low_gain), since "sig" contains here the noise 
-  // produced before the receiver boards (for instance NSB noise)
-  //
-  factor=(ishigh?1.0:high2low_gain);
-
-  //
   // Get at random a point in the FADC presimulated digital noise:
   //
@@ -909,12 +906,19 @@
   for ( Int_t is=0; is < n_slices ; is++ ) 
     {
-	fvalue = pedestal[pix]+(sig[pix][is]-pedestal[pix])/factor;
-	fvalue += digital_noise[startslice+is];
-
-	fvalue = fvalue < 0? fvalue-0.5 : fvalue+0.5;
-
-	value = fvalue < 0.? (UChar_t) 0 :
-	  (fvalue > 255.? 255 : (UChar_t) fvalue);
-
+      if (ishigh)
+	fvalue = sig[pix][is];
+      else 
+	// If we deal with low gain, we have to scale the values in sig_LG[][] by
+	// the gain ratio (high2low_gain), since "sig_LG" contains at this point the 
+	// noise produced before the receiver boards (for instance NSB noise).
+	//
+	fvalue = pedestal[pix]+(sig_LG[pix][is]-pedestal[pix]) / high2low_gain;
+
+      fvalue += digital_noise[startslice+is]; // We add the noise intrinsic to FADC
+
+      fvalue = fvalue < 0? fvalue-0.5 : fvalue+0.5;
+
+      value = fvalue < 0.? (UChar_t) 0 :
+	(fvalue > 255.? 255 : (UChar_t) fvalue);
 
       // Add up slices:
@@ -933,5 +937,5 @@
   // is NOT done here (it is already done in MFadc::Fill). This procedure only
   // selects which FADC slices to write out, out of those contained in the sig[][]
-  // array.
+  // and sig_LG[][] arrays.
   //
 
@@ -998,5 +1002,5 @@
 	      if (switch_i > 0 && (i+fFadcSlices) >= switch_i)
 		output_lowgain[ip][i] = pedestal[ip] + 
-		  (sig[ip][is-(fHi2LoGainPeak-fFadcSlices)]-pedestal[ip])/high2low_gain;
+		  (sig_LG[ip][is-(fHi2LoGainPeak-fFadcSlices)]-pedestal[ip])/high2low_gain;
 	      // Once the shift occurs, low gain is filled with the high
 	      // gain signal scaled down by the factor high2low_gain
@@ -1010,5 +1014,5 @@
 	  else // We are beyond the simulated signal history in sig[][]! Put just mean pedestal!
 	    {
-	      output_lowgain[ip][i]= pedestal[ip];
+	      output_lowgain[ip][i] = pedestal[ip];
 	    }
 	  i++;
