//////////////////////////////////////////////////////////////// // // MFadc // // #include "MFadc.hxx" #include "MMcEvt.hxx" #include "TROOT.h" #include #include #include #include "TH1.h" #include "TObjArray.h" #include "MGFadcSignal.hxx" 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. 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: // 1. some parameters of the trigger are set to default. // this parameters of the trigger may be changed // 3. Then the all signals are set to zero numpix=pix; fwhm_resp = fwhm; integ_resp = integral; fwhm_resp_outer = fwhmout; integ_resp_outer = integralout; cout<< "[MFadc] Setting up the MFadc with this values "<< endl ; cout<< "[MFadc] - Inner pixels : "<< endl ; cout<< "[MFadc] Response Area : "< numpix ) { cout << " WARNING: MFadc::Fill() : iPix greater than Pixels in Camera = " << numpix << endl ; exit(987) ; } if ( used[iPix] == FALSE ) { used [iPix] = TRUE ; for (i=0; i < (Int_t) SLICES_MFADC; i++ ) { sig[iPix][i] = 0. ; } } // // then select the time slice to use (ican) // if ( time < TOTAL_TRIGGER_TIME+fadc_time_offset ) { // // 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 )); // // putting the response slices in the right sig slices. // Be carefull, because both slices have different widths. // // // 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+fadc_time_offset << endl ; } } void MFadc::FillOuter( Int_t iPix, Float_t time, Float_t amplitude ) { // // fills the information about one single Phe in the Trigger class // for an outer pixel // // parameter is the number of the pixel and the time-difference to the // first particle // // Int_t i, ichan, ichanfadc ; // // 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::FillOuter() : iPix greater than CAMERA_PIXELS" << endl ; exit(987) ; } if ( used[iPix] == FALSE ) { used [iPix] = TRUE ; for (i=0; i < (Int_t) SLICES_MFADC; i++ ) { sig[iPix][i] = 0. ; } } // // then select the time slice to use (ican) // if ( time < TOTAL_TRIGGER_TIME+fadc_time_offset ) { // // determine the slices number assuming the WIDTH_RESPONSE_MFADC // ichan = (Int_t) ( time / ((Float_t) WIDTH_RESPONSE_MFADC )); // // putting the response slices in the right sig slices. // Be carefull, because both slices have different widths. // // // 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+fadc_time_offset << endl ; } } void MFadc::Set( Int_t iPix, Float_t resp[(Int_t) SLICES_MFADC]) { // // Sets the information about fadc reponse from a given array // // parameter is the number of the pixel and the values to be set // // 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)SLICES_MFADC; i++ ) { sig[iPix][i] = 0. ; } } for ( i = 0 ; i<(Int_t)SLICES_MFADC; i++ ) { sig[iPix][i] = resp[i] ; } } void MFadc::AddSignal( Int_t iPix, Float_t resp[(Int_t) SLICES_MFADC]) { // // Adds signals to the fadc reponse from a given array // // parameter is 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)SLICES_MFADC; i++ ) { sig[iPix][i] = 0. ; } } for ( i = 0 ; i<(Int_t)SLICES_MFADC; i++ ) { sig[iPix][i] += resp[i] ; } } void MFadc::SetPedestals( Int_t ped) { // It sets pedestal for each pixel flat randomly dstributed between 0 and ped // It uses the instance of TRandom GenElec. Int_t i; for(i=0;iRndm()); } } void MFadc::SetPedestals( Float_t *ped) { // It sets pedestal for each pixel from ped array Int_t i; for(i=0;iRndm()); for(j=0;j<(Int_t) SLICES_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) SLICES_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;iGaus(0., value ); } cout<<"MFadc::SetElecNoise ... done"<Integer(((Int_t)SLICES_MFADC)*1000); if ( used[i] == FALSE ) { used [i] = TRUE ; memcpy( (Float_t*)&sig[i][0], (Float_t*)&noise[startslice], ((Int_t) SLICES_MFADC)*sizeof(Float_t)); for ( Int_t is=0 ; is< (Int_t)SLICES_MFADC ; is++ ) { } } // // Then the noise is introduced for each time slice // else for ( Int_t is=0 ; is< (Int_t)SLICES_MFADC ; is++ ) { sig[i][is] += noise[startslice+is] ; } } } void MFadc::SetDigitalNoise(Float_t value){ UInt_t i; Float_t xrdm; cout<<"MFadc::SetDigitalNoise ... generating database for electronic noise." <Gaus(0., value); digital_noise[i]=(xrdm>0?Int_t(xrdm+0.5):Int_t(xrdm-0.5)); } cout<<"MFadc::SetDigitalNoise ... done"<Integer((Int_t) SLICES_MFADC*999); // // Then the noise is introduced for each time slice // for ( Int_t is=0 ; is< FADC_SLICES; is++ ) { if(digital_noise[startslice+is]+Int_t(output[i][is])<0) output[i][is] = 0; else output[i][is] = (digital_noise[startslice+is]+Int_t(output[i][is])>255 ? 255 : UChar_t(digital_noise[startslice+is]+Int_t(output[i][is]))); if(digital_noise[startslice+FADC_SLICES+is]+Int_t(output_lowgain[i][is])<0) output_lowgain[i][is] = 0; else output_lowgain[i][is] = (digital_noise[startslice+FADC_SLICES+is] +Int_t(output_lowgain[i][is])>255? 255: UChar_t(digital_noise[startslice+FADC_SLICES+is] +Int_t(output_lowgain[i][is]))); } } } } void MFadc::Scan() { for ( Int_t ip=0; ip 0. ) { printf (" %4.1f/", sig[ip][is] ) ; } else { printf ("----/" ) ; } } printf ("\n"); } } } void MFadc::Scan(Float_t time) { // // first of all we subtract from the time a offset (8 ns) // Float_t t ; (0 > time - TIME_BEFORE_TRIGGER)? t=fadc_time_offset: t=(time-TIME_BEFORE_TRIGGER+fadc_time_offset) ; // 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 // Int_t iFirstSlice ; iFirstSlice = (Int_t) ( t / WIDTH_FADC_TIMESLICE ) ; for ( Int_t ip=0; ipInteger((Int_t) SLICES_MFADC*999); for ( Int_t is=0; is < (Int_t)SLICES_MFADC ; is++ ) { if (pedestal[pix]+(sig[pix][is]-pedestal[pix])/factor>0.0){ value=(pedestal[pix]+(sig[pix][is]-pedestal[pix])/factor > 255. ? 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; else value=(Int_t(value)+digital_noise[startslice+is]>255 ?255 :UChar_t(Int_t(value)+digital_noise[startslice+is])); } else { value= 0; if(Int_t(value)+digital_noise[startslice+is]<0.0) value=0; else value=(Int_t(value)+digital_noise[startslice+is]>255 ?255 :UChar_t(Int_t(value)+digital_noise[startslice+is])); } sigma+=((Float_t)value-pedestal[pix])*((Float_t)value-pedestal[pix]); } sigma=sqrt(sigma/(SLICES_MFADC-1)); return sigma; } void MFadc::TriggeredFadc(Float_t time) { // // calculate the first slice to write out, according to trigger time: // Int_t iFirstSlice ; Int_t i; // // We had 0.5 for the correct rounding: // iFirstSlice = (Int_t) ( 0.5 + time / WIDTH_FADC_TIMESLICE ) ; for ( Int_t ip=0; ip0.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++; } 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 // 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); } } } } void MFadc::ShowSignal (MMcEvt *McEvt, Float_t trigTime) { // ============================================================ // // This method is used to book the histogram 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 ; Char_t dumm[10]; Char_t name[256]; TObjArray *AList ; AList = 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 < numpix; i++ ) { if ( used [i] == TRUE ) { sprintf (dumm, "FADC_%d", i ) ; sprintf (name, "fadc signal %d", i ) ; hist = new TH1F(dumm, name, SLICES_MFADC, fadc_time_offset, TOTAL_TRIGGER_TIME+fadc_time_offset); // // fill the histogram // for (Int_t ibin=1; ibin <=(Int_t)SLICES_MFADC; ibin++) { hist->SetBinContent (ibin, sig[i][ibin-1]) ; } // hist->SetMaximum( 5.); // hist->SetMinimum(-10.); hist->SetStats(kFALSE); // hist->SetAxisRange(0., 80. ) ; AList->Add(hist) ; ic++ ; } } // // create the Gui Tool // // new MGFadcSignal(McEvt, AList, trigTime, gClient->GetRoot(), gClient->GetRoot(), 400, 400 ) ; // // delete the List of histogramms // AList->Delete() ; delete AList ; } UChar_t MFadc::GetFadcSignal(Int_t pixel, Int_t slice){ // It returns the analog signal for a given pixel and a given FADC // time slice which would be read. return (output[pixel][slice]); } UChar_t MFadc::GetFadcLowGainSignal(Int_t pixel, Int_t slice){ // It returns the analog signal for a given pixel and a given FADC // time slice which would be read. return (output_lowgain[pixel][slice]); }