source: trunk/MagicSoft/Simulation/Detector/Camera/camera.cxx@ 1223

Last change on this file since 1223 was 1223, checked in by blanch, 23 years ago
A small back has been solved. Before, while not using the option writte_all_images, not all triggered showers were stored. Now it is solved. For that it is importatn taht the less restrictive trigger option is checked first. A new facility has been introduced and now one can choose the step size in trigger loop mode for the discriminator threshold. The close-compact topology for less than 3 pixels does not make sense. Before the program was ignoring that, now it switch to simple neighbour condition.
File size: 100.3 KB
Line 
1//!/////////////////////////////////////////////////////////////////////
2//
3// camera
4//
5// @file camera.cxx
6// @title Camera simulation
7// @subtitle Code for the simulation of the camera phase
8// @desc Code for the simulation of the camera of CT1 and MAGIC
9// @author J C Gonzalez
10// @email gonzalez@mppmu.mpg.de
11// @date Thu May 7 16:24:22 1998
12//
13//----------------------------------------------------------------------
14//
15// Created: Thu May 7 16:24:22 1998
16// Author: Jose Carlos Gonzalez
17// Purpose: Program for reflector simulation
18// Notes: See files README for details
19//
20//----------------------------------------------------------------------
21//
22// $RCSfile: camera.cxx,v $
23// $Revision: 1.32 $
24// $Author: blanch $
25// $Date: 2002-02-28 15:04:52 $
26//
27////////////////////////////////////////////////////////////////////////
28// @tableofcontents @coverpage
29
30//=-----------------------------------------------------------
31//!@section Source code of |camera.cxx|.
32
33/*!@"
34
35 In this section we show the (commented) code of the program for the
36 read-out of the output files generated by the simulator of the
37 reflector, |reflector 0.3|.
38
39 @"*/
40
41//=-----------------------------------------------------------
42//!@subsection Includes and Global variables definition.
43
44//!@{
45
46// includes for ROOT
47// BEWARE: the order matters!
48
49#include "TROOT.h"
50
51#include "TRandom.h"
52#include "TApplication.h"
53
54#include "TFile.h"
55#include "TTree.h"
56#include "TBranch.h"
57#include "TCanvas.h"
58
59#include "TArrayC.h"
60
61#include "MTrigger.hxx"
62#include "MFadc.hxx"
63#include "MLons.hxx"
64
65#include "MRawRunHeader.h"
66#include "MRawEvtData.h"
67#include "MRawEvtHeader.h"
68#include "MRawCrateData.h"
69#include "MMcEvt.hxx"
70#include "MMcTrig.hxx"
71#include "MMcRunHeader.hxx"
72#include "MMcTrigHeader.hxx"
73#include "MMcFadcHeader.hxx"
74
75/*!@"
76
77 All the defines are located in the file |camera.h|.
78
79 @"*/
80
81#include "camera.h"
82
83//!@}
84
85/*!@"
86
87 The following set of flags are used in time of compilation. They do
88 not affect directly the behaviour of the program at run-time
89 (though, of course, if you disconnected the option for
90 implementation of the Trigger logic, you will not be able to use any
91 trigger at all. The 'default' values mean default in the sense of
92 what you got from the server when you obtained this program.
93
94 @"*/
95
96//!@{
97
98// flag for debugging (default: OFF )
99#define __DEBUG__
100#undef __DEBUG__
101
102
103//!@}
104
105//=-----------------------------------------------------------
106//!@subsection Definition of global variables.
107
108/*!@"
109
110 Now we define some global variables with data about the telescope,
111 such as "focal distance", number of pixels/mirrors,
112 "size of the camera", and so on.
113
114 @"*/
115
116/*!@"
117
118 Depending on the telescope we are using (CT1 or MAGIC), the
119 information stored in the definition file is different.
120 The variable |ct_Type| has the value 0 when we use
121 CT1, and 1 when we use MAGIC.
122
123 @"*/
124
125//!@{
126static int ct_Type; //@< Type of telescope: 0:CT1, 1:MAGIC
127//!@}
128
129/*!@"
130
131 And this is the information about the whole telescope.
132
133 @"*/
134
135//!@{
136
137// parameters of the CT (from the CT definition file)
138
139////@: Focal distances [cm]
140//static float *ct_Focal;
141
142//@: Mean Focal distances [cm]
143static float ct_Focal_mean;
144
145//@: STDev. Focal distances [cm]
146static float ct_Focal_std;
147
148//@: Mean Point Spread function [cm]
149static float ct_PSpread_mean;
150
151//@: STDev. Point Spread function [cm]
152static float ct_PSpread_std;
153
154//@: STDev. Adjustmente deviation [cm]
155static float ct_Adjustment_std;
156
157//@: Radius of the Black Spot in mirror [cm]
158static float ct_BlackSpot_rad;
159
160//@: Radius of one mirror [cm]
161static float ct_RMirror;
162
163//@: Camera width [cm]
164static float ct_CameraWidth;
165
166//@: Pixel width [cm]
167static float ct_PixelWidth;
168
169//@: ct_PixelWidth_corner_2_corner = ct_PixelWidth / cos(60)
170static float ct_PixelWidth_corner_2_corner;
171
172//@: ct_PixelWidth_corner_2_corner / 2
173static float ct_PixelWidth_corner_2_corner_half;
174
175//@: Number of mirrors
176static int ct_NMirrors = 0;
177
178//@: Number of pixels
179static int ct_NPixels;
180
181//@: Number of pixels
182static int ct_NCentralPixels;
183
184//@: Number of pixels
185static int ct_NGapPixels;
186
187//@: ct_Apot = ct_PixelWidth / 2
188static float ct_Apot;
189
190//@: ct_2Apot = 2 * ct_Apot = ct_PixelWidth
191static float ct_2Apot;
192
193//@: name of the CT definition file to use
194static char ct_filename[256];
195
196//@: list of showers to be skipped
197static int *Skip;
198
199//@: number of showers to be skipped
200static int nSkip=0;
201
202//@: flag: TRUE: data come from STDIN; FALSE: from file
203static int Data_From_STDIN = FALSE;
204
205//@: flag: TRUE: write all images to output; FALSE: only triggered showers
206static int Write_All_Images = FALSE;
207
208//@: flag: TRUE: write all data to output; FALSE: only triggered showers
209static int Write_All_Data = FALSE;
210
211static int Write_McEvt = TRUE;
212static int Write_McTrig = TRUE;
213static int Write_McFADC = TRUE;
214static int Write_RawEvt = FALSE;
215
216//@: flag: TRUE: selection on the energy
217static int Select_Energy = TRUE;
218
219//@: Lower edge of the selected energy range (in GeV)
220static float Select_Energy_le = 0.0;
221
222//@: Upper edge of the selected energy range (in GeV)
223static float Select_Energy_ue = 100000.0;
224
225//@: flag: TRUE: show all fadc singnal in the screen; FALSE: don't
226static int FADC_Scan = FALSE;
227
228//@: flag: TRUE: show all trigger singnal in the screen; FALSE: don't
229static int Trigger_Scan = FALSE;
230
231//@: flag: TRUE: loop trigger analysis over several thresholds, multiplicities and topologies; FALSE: a single trigger configuration
232static int Trigger_Loop = FALSE;
233
234//@: flag: TRUE: Different threshold for each pixel ; FALSE: same threshold for all pixels
235static int Individual_Thres_Pixel = FALSE;
236
237//@: Properties of the trigger
238static float Trigger_gate_length = 6.0;
239static float Trigger_response_ampl = 1.0;
240static float Trigger_response_fwhm = 2.0;
241static float Trigger_overlaping_time= 0.25;
242static float Trigger_noise= 0.3;
243
244//@: Properties of the FADC
245static float FADC_response_ampl = MFADC_RESPONSE_AMPLITUDE;
246static float FADC_response_fwhm = MFADC_RESPONSE_FWHM;
247static float FADC_noise = 2.0;
248
249//@: Trigger conditions for a single trigger mode
250static float qThreshold[TRIGGER_PIXELS];
251static int Trigger_multiplicity = 4;
252static int Trigger_topology = 2;
253
254//@: Upper and lower edges of the trigger loop
255static float Trigger_loop_lthres = 2.0;
256static float Trigger_loop_uthres = 10.0;
257static float Trigger_loop_sthres = 1.0;
258static int Trigger_loop_lmult = 2;
259static int Trigger_loop_umult = 10;
260static int Trigger_loop_ltop = 0;
261static int Trigger_loop_utop = 2;
262
263//!@}
264
265/*!@"
266
267 The following double-pointer is a 2-dimensional table with information
268 about each pixel. The routine read_pixels will generate
269 the information for filling it using igen_pixel_coordinates().
270
271 @"*/
272
273//!@{
274// Pointer to a tables/Arrays with information about the pixels
275// and data stored on them with information about the pixels
276
277
278//@: coordinates x,y for each pixel
279static float **pixary;
280
281//@: indexes of pixels neighbours of a given one
282static int **pixneig;
283
284//@: number of neighbours a pixel have
285static int *npixneig;
286
287//@: contents of the pixels (ph.e.)
288static float *fnpix;
289
290
291//!@}
292
293/*!@"
294
295 The following double-pointer is a 2-dimensional table with the
296 Quantum Efficiency @$QE@$ of each pixel in the camera, as a function
297 of the wavelength @$\lambda@$. The routine |read_pixels()| will read
298 also this information from the file |qe.dat|.
299
300 @"*/
301
302//!@{
303// Pointer to a table with QE, number of datapoints, and wavelengths
304
305//@: table of QE
306static float ***QE;
307
308//@: number of datapoints for the QE curve
309static int pointsQE;
310
311//@: table of QE
312static float *QElambda;
313//!@}
314
315/*!@"
316
317 The following double-pointer is a 2-dimensional table with information
318 about each mirror in the dish. The routine |read_ct_file()| will read
319 this information from the CT definition file.
320
321 @"*/
322
323//!@{
324// Pointer to a table with the following info.:
325
326static float **ct_data;
327
328/*
329 * TYPE=0 (CT1)
330 * i s rho theta x y z thetan phin xn yn zn
331 *
332 * i : number of the mirror
333 * s : arc length [cm]
334 * rho : polar rho of the position of the center of the mirror [cm]
335 * theta : polar angle of the position of the center of the mirror [cm]
336 * x : x coordinate of the center of the mirror [cm]
337 * y : y coordinate of the center of the mirror [cm]
338 * z : z coordinate of the center of the mirror [cm]
339 * thetan : polar theta angle of the direction where the mirror points to
340 * phin : polar phi angle of the direction where the mirror points to
341 * xn : xn coordinate of the normal vector in the center (normalized)
342 * yn : yn coordinate of the normal vector in the center (normalized)
343 * zn : zn coordinate of the normal vector in the center (normalized)
344 *
345 * TYPE=1 (MAGIC)
346 * i f sx sy x y z thetan phin
347 *
348 * i : number of the mirror
349 * f : focal distance of that mirror
350 * sx : curvilinear coordinate of mirror's center in X[cm]
351 * sy : curvilinear coordinate of mirror's center in X[cm]
352 * x : x coordinate of the center of the mirror [cm]
353 * y : y coordinate of the center of the mirror [cm]
354 * z : z coordinate of the center of the mirror [cm]
355 * thetan : polar theta angle of the direction where the mirror points to
356 * phin : polar phi angle of the direction where the mirror points to
357 * xn : xn coordinate of the normal vector in the center (normalized)
358 * yn : yn coordinate of the normal vector in the center (normalized)
359 * zn : zn coordinate of the normal vector in the center (normalized)
360 */
361//!@}
362
363/*!@"
364
365 We define a table into where random numbers will be stored.
366 The routines used for random number generation are provided by
367 |RANLIB| (taken from NETLIB, |www.netlib.org|), and by
368 the routine |double drand48(void)| (prototype defined in
369 |stdlib.h|) through the macro |RandomNumber| defined in
370 |camera.h|.
371
372 @"*/
373
374
375//!@}
376
377extern char FileName[];
378
379
380//=-----------------------------------------------------------
381// @subsection Main program.
382
383//!@{
384
385//++++++++++++++++++++++++++++++++++++++++
386// MAIN PROGRAM
387//----------------------------------------
388
389int main(int argc, char **argv)
390{
391
392 //!@' @#### Definition of variables.
393 //@'
394
395 char inname[256]; //@< input file name
396 char starfieldname[256]; //@< starfield input file name
397
398 char datname[256]; //@< data (ASCII) output file name
399
400 char rootname[256] ; //@< ROOT file name
401 char rootname_loop[256] ; //@< ROOT file name
402
403 char parname[256]; //@< parameters file name
404
405 char nsbpathname[256]; //@< directory with the dataabse for th NSB
406
407 char flag[SIZE_OF_FLAGS + 1]; //@< flags in the .rfl file
408
409 FILE *inputfile; //@< stream for the input file
410 ofstream datafile; //@< stream for the data file
411
412 MCEventHeader mcevth; //@< Event Header class (MC)
413 MCCphoton cphoton; //@< Cherenkov Photon class (MC)
414
415 int inumphe; //@< number of photoelectrons in an event from showers
416 float inumphensb; //@< number of photoelectrons in an event from nsb
417
418 float arrtmin_ns; //@ arrival time of the first photoelectron
419 float arrtmax_ns; //@ arrival time of the last photoelectron
420
421 float thetaCT, phiCT; //@< parameters of a given shower
422 float thetashw, phishw; //@< parameters of a given shower
423 float coreD, coreX, coreY; //@< core position
424 float impactD; //@< impact parameter
425 float l1, m1, n1; //@< auxiliary variables
426 float l2, m2, n2; //@< auxiliary variables
427 float num, den; //@< auxiliary variables
428
429 int nshow=0; //@< partial number of shower in a given run
430 int ntshow=0; //@< total number of showers
431 int ncph=0; //@< partial number of photons in a given run
432 int ntcph=0; //@< total number of photons
433
434 int i, j, k; //@< simple counters
435
436 int addElecNoise; //@< Will we add ElecNoise?
437
438 int simulateNSB; //@< Will we simulate NSB?
439 int nphe2NSB; //@< From how many phe will we simulate NSB?
440 float meanNSB; //@< diffuse NSB mean value (phe per ns per central pixel)
441 float diffnsb_phepns[iMAXNUMPIX]; //@< diffuse NSB values for each pixel
442 //@< derived from meanNSB
443 float nsbrate_phepns[iMAXNUMPIX][iNUMWAVEBANDS]; //@< non-diffuse nsb
444 //@< photoelectron rates
445 float nsb_phepns[iMAXNUMPIX]; //@< NSB values for each pixel
446
447 Float_t nsb_trigresp[TRIGGER_TIME_SLICES]; //@< array to write the trigger
448 //@< response from the database
449 Float_t nsb_fadcresp[(Int_t) SLICES_MFADC]; //@< array to write the fadc
450 //@< response from the database
451 Byte_t trigger_map[((Int_t)(TRIGGER_PIXELS/8))+1];//@< Pixels on when the
452 //@< camera triggers
453 Float_t fadc_elecnoise[CAMERA_PIXELS]; //@< Electronic niose for each pixel
454 Float_t fadc_pedestals[CAMERA_PIXELS]; //@< array for fadc pedestals values
455
456 float ext[iNUMWAVEBANDS] = { //@< average atmospheric extinction in each waveband
457 EXTWAVEBAND1,
458 EXTWAVEBAND2,
459 EXTWAVEBAND3,
460 EXTWAVEBAND4,
461 EXTWAVEBAND5
462 };
463 float zenfactor=1.0; // correction factor calculated from the extinction
464
465 float qTailCut; //@< Tail Cut value
466 int nIslandsCut; //@< Islands Cut value
467 int countIslands=FALSE; //@< Will we count the islands?
468 int anaPixels;
469
470 float fCorrection; //@< Factor to apply to pixel values (def. 1.)
471
472 int ntrigger = 0; //@< number of triggers in the whole file
473 int btrigger = 0; //@< trigger flag
474 int ithrescount; //@< counter for loop over threshold trigger
475 float fthrescount; //@< value for loop over threshold trigger
476 int imulticount; //@< counter for loop over multiplicity trigger
477 int itopocount; //@< counter for loop over topology trigger
478 int isorttopo[3]; //@< sorting the topologies
479 int icontrigger; //@< number of trigger conditions to be analised
480 UShort_t numPix; //@< number of sets of fadc written counts
481
482 float fpixelthres[TRIGGER_PIXELS]; //@< Threshold values
483
484 TArrayC *fadcValues; //@< the analog Fadc signal for pixels
485
486 float plateScale_cm2deg; //@< plate scale (deg/cm)
487 float degTriggerZone; //@< trigger area in the camera (radius, in deg.)
488
489 int still_in_loop = FALSE;
490
491 //@< Variables to fill the McRunHeader
492 Int_t sfRaH = 5;
493 Int_t sfRaM = 34;
494 Int_t sfRaS = 32;
495 Int_t sfDeD = 22;
496 Int_t sfDeM = 00;
497 Int_t sfDeS = 52;
498 Float_t shthetamax = 0.0;
499 Float_t shthetamin = 0.0;
500 Float_t shphimax = 0.0;
501 Float_t shphimin = 0.0;
502 Float_t telestheta = 0.0;
503 Float_t telesphi = 0.0;
504 Float_t sofftheta = 0.0;
505 Float_t soffphi = 0.0;
506 UInt_t corsika = 5200 ;
507
508
509 struct camera cam; // structure holding the camera definition
510
511
512 //!@' @#### Definition of variables for |getopt()|.
513 //@'
514
515 int ch, errflg = 0; //@< used by getopt
516
517 //!@' @#### Initialisation of some variables
518 //@'
519
520 for(i=0;i<iMAXNUMPIX;i++){
521 nsb_phepns[i]=0;
522 for(j=0;j<iNUMWAVEBANDS;j++)
523 nsbrate_phepns[i][j]=0.0; //@< Starlight rates initialised at 0.0
524 }
525 /*!@'
526
527 @#### Beginning of the program.
528
529 We start with the main program. First we (could) make some
530 presentation, and follows the reading of the parameters file (now
531 from the |stdin|), the reading of the CT parameters file, and the
532 creation of the output file, where the processed data will be
533 stored.
534
535 */
536
537 //++
538 // START
539 //--
540
541 // make unbuffered output
542
543 cout.setf ( ios::stdio );
544
545 // parse command line options (see reflector.h)
546
547 parname[0] = '\0';
548
549 optarg = NULL;
550 while ( !errflg && ((ch = getopt(argc, argv, COMMAND_LINE_OPTIONS)) != -1) )
551 switch (ch) {
552 case 'f':
553 strcpy(parname, optarg);
554 break;
555 case 'h':
556 usage();
557 break;
558 default :
559 errflg++;
560 }
561
562 // show help if error
563
564 if ( errflg>0 )
565 usage();
566
567 // make some sort of presentation
568
569 present();
570
571 // read parameters file
572
573 if ( strlen(parname) < 1 )
574 readparam(NULL);
575 else
576 readparam(parname);
577
578 // read data from file or from STDIN?
579
580 Data_From_STDIN = get_data_from_stdin();
581
582 // write all images, even those without trigger?
583
584 Write_All_Images = get_write_all_images();
585
586 // write all data (i.e., ph.e.s in pixels)
587
588 Write_All_Data = get_write_all_data();
589
590 Write_McEvt = get_write_McEvt() ;
591 Write_McTrig = get_write_McTrig() ;
592 Write_McFADC = get_write_McFadc() ;
593 Write_RawEvt = get_write_RawEvt() ;
594
595 FADC_Scan = get_FADC_Scan();
596 Trigger_Scan = get_Trigger_Scan();
597
598 Individual_Thres_Pixel = get_indi_thres_pixel();
599
600 get_FADC_properties( &FADC_response_ampl, &FADC_response_fwhm);
601
602 get_Trigger_properties( &Trigger_gate_length, &Trigger_overlaping_time, &Trigger_response_ampl, &Trigger_response_fwhm);
603
604 Trigger_Loop = get_Trigger_Loop(&Trigger_loop_lthres, &Trigger_loop_uthres, &Trigger_loop_sthres, &Trigger_loop_lmult, &Trigger_loop_umult, &Trigger_loop_ltop, &Trigger_loop_utop);
605
606 icontrigger =((int)((Trigger_loop_uthres-Trigger_loop_lthres)
607 /Trigger_loop_sthres)+1)*
608 (Trigger_loop_umult-Trigger_loop_lmult+1)*
609 (Trigger_loop_utop-Trigger_loop_ltop+1);
610
611 if (!Trigger_Loop){
612 get_Trigger_Single (qThreshold, &Trigger_multiplicity, &Trigger_topology);
613 icontrigger=1;
614 }
615 else
616 get_threshold(qThreshold);
617
618 // get filenames
619
620 strcpy( inname, get_input_filename() );
621 strcpy( starfieldname, get_starfield_filename() );
622 strcpy( datname, get_data_filename() );
623 strcpy( rootname, get_root_filename() );
624 strcpy( rootname_loop, get_loop_filename() );
625 strcpy( ct_filename, get_ct_filename() );
626 strcpy( nsbpathname, get_nsb_directory() );
627
628 // get different parameters of the simulation
629
630 qTailCut = get_tail_cut();
631 addElecNoise = add_elec_noise(&FADC_noise, &Trigger_noise);
632 simulateNSB = get_nsb( &meanNSB, &nphe2NSB );
633 countIslands = get_islands_cut( &nIslandsCut );
634
635 // get selections on the parameters
636
637 Select_Energy = get_select_energy( &Select_Energy_le, &Select_Energy_ue);
638
639 // log filenames information
640
641 log(SIGNATURE,
642 "%s:\n\t%20s:\t%s\n\t%20s:\t%s\n\t%20s:\t%s\n\t%20s:\t%s\n\t%20s:\t%s\n\t%20s:\t%s\n",
643 "Filenames",
644 "In", inname,
645 "Stars", starfieldname,
646 "NSB database", nsbpathname,
647 "CT", ct_filename,
648 "Data", datname,
649 "ROOT", rootname
650 );
651
652 // log Trigger information
653
654 if (Trigger_Loop) {
655 log(SIGNATURE,
656 "%s:\n\t%20s: from %5.2f to %5.2f by %5.2f step\n\t%20s: %i - %i\n\t%20s: %i - %i\n\t%20s\n",
657 "Trigger Loop mode",
658 "Threshold",Trigger_loop_lthres,Trigger_loop_uthres,Trigger_loop_sthres,
659 "Multiplicity",Trigger_loop_lmult,Trigger_loop_umult,
660 "Topology",Trigger_loop_ltop,Trigger_loop_utop,
661 rootname_loop);
662 }
663 else if (Individual_Thres_Pixel == FALSE){
664 log(SIGNATURE,
665 "%s:\n\t%20s: %f\n\t%20s: %i\n\t%20s: %i\n",
666 "Single Trigger mode",
667 "Threshold",qThreshold[0],
668 "Multiplicity",Trigger_multiplicity,
669 "Topology",Trigger_topology);
670 }
671 else{
672 log(SIGNATURE,
673 "%s:\n\t%20s: %s\n\t%20s: %i\n\t%20s: %i\n",
674 "Single Trigger mode",
675 "Threshold","Different for each pixel",
676 "Multiplicity",Trigger_multiplicity,
677 "Topology",Trigger_topology);
678 }
679 // log flags information
680
681 log(SIGNATURE,
682 "%s:\n\t%20s: %s\n\t%20s: %s\n\t%20s: %s\n",
683 "Flags",
684 "Data_From_STDIN", ONoff(Data_From_STDIN),
685 "Write_All_Images", ONoff(Write_All_Images),
686 "Write_All_Data", ONoff(Write_All_Data));
687
688 // log flags information
689
690 log(SIGNATURE,
691 "%s:\n\t%20s: %s\n\t%20s: %s\n\t%20s: %s\n",
692 "Root output",
693 "Write_McEvt", ONoff(Write_McEvt),
694 "Write_McTrig", ONoff(Write_McTrig),
695 "Write_McFADC", ONoff(Write_McFADC),
696 "Write_RawEvt", ONoff(Write_RawEvt));
697
698 // log parameters information
699
700 log(SIGNATURE,
701 "%s:\n\t%20s: %f\n\t%20s: %f %s\n",
702 "Parameters",
703 "t0 (Tail-cut)", qTailCut,
704 "NSB (phes/pixel)", meanNSB, ONoff(simulateNSB));
705
706 // log selections
707
708 log(SIGNATURE,
709 "%s:\n\t%20s: %s (%f:%f)\n",
710 "Selections:",
711 "Energy", ONoff(Select_Energy), Select_Energy_le, Select_Energy_ue);
712
713 // Definition and initialization of array to save trigger statistics
714
715 int ***ntriggerloop;
716
717 ntriggerloop= new int ** [(int)((Trigger_loop_uthres-Trigger_loop_lthres)
718 /Trigger_loop_sthres)];
719 for (ithrescount=0, fthrescount=Trigger_loop_lthres;fthrescount<=Trigger_loop_uthres;fthrescount+=Trigger_loop_sthres, ithrescount++){
720 ntriggerloop[ithrescount]= new int * [Trigger_loop_umult-Trigger_loop_lmult+1];
721 for (imulticount=0;imulticount<=Trigger_loop_umult-Trigger_loop_lmult;imulticount++){
722 ntriggerloop[ithrescount][imulticount]= new int [Trigger_loop_utop-Trigger_loop_ltop+1];
723 for(itopocount=0;itopocount<=Trigger_loop_utop-Trigger_loop_ltop;itopocount++){
724 ntriggerloop[ithrescount][imulticount][itopocount]=0;
725 }
726 }
727 }
728
729 // We should be careful that topologies are sort from
730 // the less to the more restrictive one.
731
732 if (Trigger_loop_utop==Trigger_loop_ltop)
733 for(int is=0; is<3;is++)
734 isorttopo[is]=is;
735 else {
736 isorttopo[0]=1;
737 isorttopo[1]=0;
738 isorttopo[2]=2;
739 }
740
741 // set all random numbers seeds
742
743 setall( get_seeds(0), get_seeds(1) );
744
745 // get list of showers to evt. skip
746
747 nSkip = get_nskip_showers();
748
749 if (nSkip > 0) {
750 Skip = new int[ nSkip ];
751 get_skip_showers( Skip );
752
753 log(SIGNATURE, "There are some showers to skip:\n");
754 for (i=0; i<nSkip; ++i)
755 log(SIGNATURE, "\tshower # %d\n", Skip[i]);
756 }
757
758
759 // read parameters from the ct.def file
760
761 read_ct_file();
762
763 // read camera setup
764
765 read_pixels(&cam);
766
767 Int_t Lev0, Lev1, Lev2 ;
768
769 fadcValues = new TArrayC(FADC_SLICES);
770
771 // number of pixels for parameters
772
773 anaPixels = get_ana_pixels();
774 anaPixels = (anaPixels == -1) ? ct_NPixels : anaPixels;
775
776 // initialise ROOT
777
778 TROOT simple("simple", "MAGIC Telescope Monte Carlo");
779
780 // initialise instance of Trigger and FADC classes
781
782 MTrigger Trigger(Trigger_gate_length, Trigger_overlaping_time,
783 Trigger_response_ampl, Trigger_response_fwhm); //@< A instance of the Class MTrigger
784
785 // Initialise McTrig information class if we want to save trigger informtion
786
787 MMcTrig **McTrig = NULL;
788 MMcTrigHeader **HeaderTrig = NULL;
789 MMcFadcHeader **HeaderFadc = NULL;
790
791
792 if (Write_McTrig){
793
794 McTrig = new MMcTrig * [icontrigger];
795
796 for (i=0;i<icontrigger;i++) {
797 McTrig[i] = new MMcTrig();
798 }
799
800 HeaderTrig = new MMcTrigHeader * [icontrigger];
801
802 for (i=0;i<icontrigger;i++) {
803 HeaderTrig[i] = new MMcTrigHeader();
804 }
805 }
806
807 if (Write_McFADC){
808
809 HeaderFadc = new MMcFadcHeader * [icontrigger];
810
811 for (i=0;i<icontrigger;i++) {
812 HeaderFadc[i] = new MMcFadcHeader();
813 }
814 }
815
816 MFadc fadc(FADC_response_ampl,FADC_response_fwhm) ; //@< A instance of the Class MFadc
817
818 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
819 //
820 // Set the FADC pedestals for that run
821 // Some modifications
822 // mut be done to simulate a more realistic distribution of the pedestals.
823 // This simualtion is done int the SetPedestals methode inside the
824 // class MFadc
825 // Currentlly a input_pedestal array is declared with the pedestals.
826 // Thy can also be set randomly following a flat distribution.
827 //
828 /////////////////////////////////////////////////////////////////////
829
830 Float_t input_pedestals[CAMERA_PIXELS];
831
832 for(i=0;i<CAMERA_PIXELS;i++)
833 input_pedestals[i]=10.5;
834
835 fadc.SetPedestals(input_pedestals);
836
837 // Prepare the raw data output
838
839 // Header Tree
840
841 MRawRunHeader *RunHeader= new MRawRunHeader();
842 MMcRunHeader *McRunHeader = new MMcRunHeader();
843
844 // Header branch
845
846 MRawEvtHeader **EvtHeader = NULL;
847
848 if (Write_RawEvt) {
849 EvtHeader = new MRawEvtHeader * [icontrigger];
850
851 for (i=0;i<icontrigger;i++) {
852 EvtHeader[i] = new MRawEvtHeader();
853 }
854 }
855
856 // Data branch
857
858 MRawEvtData **EvtData = NULL; // Data branch
859
860 if (Write_RawEvt) {
861 EvtData = new MRawEvtData * [icontrigger];
862
863 for (i=0;i<icontrigger;i++) {
864 EvtData[i] = new MRawEvtData();
865 EvtData[i]->Init(RunHeader); // We need thr RunHeader to read
866 // number of pixels
867 }
868 }
869
870 MMcEvt *McEvt = new MMcEvt ();
871
872 //
873 // initalize a temporal ROOT file
874 //
875
876 TFile outfile_temp ( rootname , "RECREATE" );
877
878 // create a Tree for the Header Event
879 TTree HeaderTree("RunHeaders","Headers of Run");
880
881 // define branches of Header Tree
882
883 char help[4];
884
885 HeaderTree.Branch("MRawRunHeader","MRawRunHeader",
886 &RunHeader);
887
888 HeaderTree.Branch("MMcRunHeader","MMcRunHeader",
889 &McRunHeader);
890
891 if(!Trigger_Loop && Write_McTrig){
892
893 HeaderTree.Branch("MMcTrigHeader","MMcTrigHeader",
894 &HeaderTrig[0]);
895 }
896 if (Trigger_Loop && Write_McTrig){
897 for(char branchname[20],i=0;i<icontrigger;i++){
898
899 sprintf(help,"%i",i+1);
900 strcpy (branchname, "MMcTrigHeader;");
901 strcat (branchname, & help[0]);
902 strcat (branchname, ".");
903 HeaderTree.Branch(branchname,"MMcTrigHeader",
904 &HeaderTrig[i]);
905 }
906 }
907
908 if(!Trigger_Loop && Write_McFADC){
909
910 HeaderTree.Branch("MMcFadcHeader","MMcFadcHeader",
911 &HeaderFadc[0]);
912 }
913 if (Trigger_Loop && Write_McFADC){
914 for(char branchname[20],i=0;i<icontrigger;i++){
915
916 sprintf(help,"%i",i+1);
917 strcpy (branchname, "MMcFadcHeader;");
918 strcat (branchname, & help[0]);
919 strcat (branchname, ".");
920 HeaderTree.Branch(branchname,"MMcFadcHeader",
921 &HeaderFadc[i]);
922 }
923 }
924
925 // Fill branches for MRawRunHeader
926
927 RunHeader->SetMagicNumber(kMagicNumber);
928 RunHeader->SetFormatVersion(2);
929 RunHeader->SetSoftVersion((UShort_t) (VERSION*10));
930 RunHeader->SetRunType(256);
931 RunHeader->SetRunNumber(0);
932 RunHeader->SetNumSamples(0,FADC_SLICES);
933 RunHeader->SetNumCrates(1);
934 RunHeader->SetNumPixInCrate(CAMERA_PIXELS);
935
936
937 // Fill branches for MMcTrigHeader
938
939 if(!Trigger_Loop && Write_McTrig){
940
941 HeaderTrig[0]->SetTopology((Short_t) Trigger_topology);
942 HeaderTrig[0]->SetMultiplicity((Short_t) Trigger_multiplicity);
943 HeaderTrig[0]->SetThreshold(qThreshold);
944 HeaderTrig[0]->SetAmplitud(Trigger_response_ampl);
945 HeaderTrig[0]->SetFwhm(Trigger_response_fwhm);
946 HeaderTrig[0]->SetOverlap(Trigger_overlaping_time);
947 HeaderTrig[0]->SetGate(Trigger_gate_length);
948 }
949 if(Trigger_Loop && Write_McTrig){
950
951 int iconcount;
952 for (iconcount=0,ithrescount=0,fthrescount=Trigger_loop_lthres;fthrescount<=Trigger_loop_uthres;ithrescount++,fthrescount+=Trigger_loop_sthres){
953 for (imulticount=0;imulticount<=Trigger_loop_umult-Trigger_loop_lmult;imulticount++){
954 for(itopocount=0;itopocount<=Trigger_loop_utop-Trigger_loop_ltop;itopocount++){
955 HeaderTrig[iconcount]->SetTopology((Short_t) isorttopo[itopocount+Trigger_loop_ltop]);
956 HeaderTrig[iconcount]->SetMultiplicity((Short_t) imulticount+Trigger_loop_lmult);
957 for(int i=0;i<TRIGGER_PIXELS;i++){
958 fpixelthres[i]=
959 ((Float_t)(fthrescount)>=qThreshold[i])?
960 (Float_t)(fthrescount):qThreshold[i];
961 }
962 HeaderTrig[iconcount]->SetThreshold( fpixelthres);
963 HeaderTrig[iconcount]->SetAmplitud(Trigger_response_ampl);
964 HeaderTrig[iconcount]->SetFwhm(Trigger_response_fwhm);
965 HeaderTrig[iconcount]->SetOverlap(Trigger_overlaping_time);
966 HeaderTrig[iconcount]->SetGate(Trigger_gate_length);
967 iconcount++;
968 }
969 }
970 }
971 }
972
973 // Fill branches for MMcFadcHeader
974
975 for(i=0;i<CAMERA_PIXELS;i++){
976 fadc_elecnoise[i]=FADC_noise;
977 }
978
979 fadc.GetPedestals(&fadc_pedestals[0]);
980
981 if(!Trigger_Loop && Write_McFADC){
982
983 HeaderFadc[0]->SetShape(0.0);
984 HeaderFadc[0]->SetAmplitud(FADC_response_ampl);
985 HeaderFadc[0]->SetFwhm(FADC_response_fwhm);
986 HeaderFadc[0]->SetPedestal(&fadc_pedestals[0],anaPixels);
987 HeaderFadc[0]->SetElecNoise(&fadc_elecnoise[0],anaPixels);
988 }
989 if(Trigger_Loop && Write_McFADC){
990 int iconcount;
991 for (iconcount=0,ithrescount=0,fthrescount=Trigger_loop_lthres;fthrescount<=Trigger_loop_uthres;ithrescount++, fthrescount+=Trigger_loop_sthres){
992 for (imulticount=0;imulticount<=Trigger_loop_umult-Trigger_loop_lmult;imulticount++){
993 for(itopocount=0;itopocount<=Trigger_loop_utop-Trigger_loop_ltop;itopocount++){
994 HeaderFadc[iconcount]->SetShape(0.0);
995 HeaderFadc[iconcount]->SetAmplitud(Trigger_response_ampl);
996 HeaderFadc[iconcount]->SetFwhm(Trigger_response_fwhm);
997 HeaderFadc[iconcount]->SetPedestal(&fadc_pedestals[0],anaPixels);
998 HeaderFadc[iconcount]->SetElecNoise(&fadc_elecnoise[0],anaPixels);
999 iconcount++;
1000 }
1001 }
1002 }
1003 }
1004
1005 // Fill the Header Tree with the current leaves of each branch
1006 // HeaderTree.Fill() ;
1007
1008
1009 // create a Tree for the Event data stream
1010 TTree EvtTree("Events","Normal Triggered Events");
1011
1012 if (Write_McEvt){
1013
1014 EvtTree.Branch("MMcEvt","MMcEvt",
1015 &McEvt);
1016 }
1017
1018 if(!Trigger_Loop){
1019
1020 if (Write_RawEvt){
1021 EvtTree.Branch("MRawEvtHeader","MRawEvtHeader",
1022 &EvtHeader[0]);
1023 EvtTree.Branch("MRawEvtData","MRawEvtData",
1024 &EvtData[0]);
1025 }
1026 if (Write_McTrig){
1027 EvtTree.Branch("MMcTrig","MMcTrig",
1028 &McTrig[0]);
1029 }
1030 }
1031 else{
1032 if (Write_McTrig){
1033 for(char branchname[10],i=0;i<icontrigger;i++){
1034
1035 sprintf(help,"%i",i+1);
1036 strcpy (branchname, "MMcTrig;");
1037 strcat (branchname, & help[0]);
1038 strcat (branchname, ".");
1039 EvtTree.Branch(branchname,"MMcTrig",
1040 &McTrig[i]);
1041 }
1042 }
1043 }
1044
1045 if (Trigger_Loop && Write_RawEvt){
1046 for(char branchname[15],i=0;i<icontrigger;i++){
1047
1048 sprintf(help,"%i",i+1);
1049 strcpy (branchname, "MRawEvtHeader;");
1050 strcat (branchname, & help[0]);
1051 strcat (branchname, ".");
1052 EvtTree.Branch(branchname,"MRawEvtHeader",
1053 &EvtHeader[i]);
1054 }
1055 for(char branchname[15],i=0;i<icontrigger;i++){
1056
1057 sprintf(help,"%i",i+1);
1058 strcpy (branchname, "MRawEvtData;");
1059 strcat (branchname, & help[0]);
1060 strcat (branchname, ".");
1061 EvtTree.Branch(branchname,"MRawEvtData",
1062 &EvtData[i]);
1063 }
1064 }
1065
1066 TApplication theAppTrigger("App", &argc, argv);
1067
1068 if(FADC_Scan){
1069 if (gROOT->IsBatch()) {
1070 fprintf(stderr, "%s: cannot run in batch mode\n", argv[0]);
1071 // return 1;
1072 }
1073 }
1074 if(FADC_Scan){
1075 //TApplication theAppFadc("App", &argc, argv);
1076
1077 if (gROOT->IsBatch()) {
1078 fprintf(stderr, "%s: cannot run in batch mode\n", argv[0]);
1079 // return 1;
1080 }
1081 }
1082
1083 // set plate scale (deg/cm) and trigger area (deg)
1084
1085 plateScale_cm2deg = ( ct_Type == 0 ) ? (0.244/2.1) : 0.030952381;
1086
1087 if ( ! get_trigger_radius( &degTriggerZone ) )
1088 degTriggerZone = ( ct_Type == 0 ) ? (5.0) : (5.0);
1089
1090 if ( ! get_correction( &fCorrection ) )
1091 fCorrection = 1.0;
1092
1093 // prepare the NSB simulation
1094
1095 // Instance of the Mlons class
1096 MLons lons(Trigger_response_ampl, Trigger_response_fwhm,
1097 MFADC_RESPONSE_AMPLITUDE, MFADC_RESPONSE_FWHM);
1098
1099 lons.SetPath(nsbpathname);
1100
1101 if( simulateNSB ){
1102
1103 //
1104 // Calculate the non-diffuse NSB photoelectron rates
1105 //
1106
1107 k = produce_nsbrates( starfieldname,
1108 &cam,
1109 nsbrate_phepns);
1110
1111 if (k != 0){
1112 cout << "Error when reading starfield... \nExiting.\n";
1113 exit(1);
1114 }
1115
1116 // calculate diffuse rate correcting for the pixel size
1117
1118 for(i=0; i<cam.inumpixels; i++){
1119 diffnsb_phepns[i] = meanNSB *
1120 cam.dpixsizefactor[i] * cam.dpixsizefactor[i];
1121 }
1122
1123 // calculate nsb rate including diffuse and starlight
1124 // we also include the extinction effect
1125 for(j=0;j<iNUMWAVEBANDS;j++){
1126 // calculate the effect of the atmospheric extinction
1127
1128 zenfactor = pow(10., -0.4 * ext[j] );
1129
1130 for(i=0; i<cam.inumpixels;i++){
1131 nsb_phepns[i]+=diffnsb_phepns[i]/iNUMWAVEBANDS + zenfactor *nsbrate_phepns[i][j];
1132 }
1133 }
1134 }
1135
1136 //
1137 // Read the reflector file with the Cherenkov data
1138 //
1139
1140 // select input file
1141
1142 if ( Data_From_STDIN ) {
1143
1144 inputfile = stdin;
1145
1146 }
1147 else{
1148
1149 log( SIGNATURE, "Opening input \"rfl\" file %s\n", inname );
1150 inputfile = fopen( inname, "r" );
1151 if ( inputfile == NULL )
1152 error( SIGNATURE, "Cannot open input file: %s\n", inname );
1153
1154 }
1155
1156 // get signature, and check it
1157
1158 if(check_reflector_file( inputfile )==FALSE){
1159 exit(1);
1160 }
1161
1162 // open data file
1163
1164 log( SIGNATURE, "Opening data \"dat\" file %s\n", datname );
1165 datafile.open( datname );
1166
1167 if ( datafile.bad() )
1168 error( SIGNATURE, "Cannot open data file: %s\n", datname );
1169
1170 // initializes flag
1171
1172 strcpy( flag, " \0" );
1173
1174 // allocate space for PMTs numbers of pixels
1175
1176 fnpix = new float [ ct_NPixels ];
1177
1178
1179 //!@' @#### Main loop.
1180 //@'
1181
1182 // get flag
1183
1184 fread( flag, SIZE_OF_FLAGS, 1, inputfile );
1185
1186 // loop over the file
1187
1188 still_in_loop = TRUE;
1189
1190 while (
1191 ((! Data_From_STDIN) && ( !feof(inputfile) ))
1192 ||
1193 (Data_From_STDIN && still_in_loop)
1194 ) {
1195
1196 // reading .rfl files
1197 if(!isA( flag, FLAG_START_OF_RUN )){
1198
1199 // We exit
1200 //error( SIGNATURE, "Expected start of run flag, but found: %s\n", flag );
1201 // We break the main loop
1202 cout<<"Warning: Expected start of run flag, but found:"<<flag<<endl;
1203 cout<<" We break the main loop"<<endl;
1204 break;
1205 }
1206 else { // found start of run
1207
1208 nshow=0;
1209
1210 fread( flag, SIZE_OF_FLAGS, 1, inputfile );
1211
1212 while( isA( flag, FLAG_START_OF_EVENT )){ // while there is a next event
1213 //
1214 // Clear Trigger and Fadc
1215 //
1216 Trigger.Reset() ;
1217 Trigger.ClearFirst();
1218 Trigger.ClearZero();
1219 fadc.Reset() ;
1220
1221 ++nshow;
1222 log(SIGNATURE, "Event %d(+%d)\n", nshow, ntshow);
1223
1224 // get MCEventHeader
1225 fread( (char*)&mcevth, mcevth.mysize(), 1, inputfile );
1226
1227 // calculate core distance and impact parameter
1228
1229 coreD = mcevth.get_core(&coreX, &coreY);
1230
1231 // calculate impact parameter (shortest distance betwee the original
1232 // trajectory of the primary (assumed shower-axis) and the
1233 // direction where the telescope points to
1234 //
1235 // we use the following equation, given that the shower core position
1236 // is (x1,y1,z1)=(x,y,0),the trajectory is given by (l1,m1,n1),
1237 // and the telescope position and orientation are (x2,y2,z2)=(0,0,0)
1238 // and (l2,m2,n2)
1239 //
1240 // | |
1241 // | x1-x2 y1-y2 z1-z2 |
1242 // | |
1243 // + | l1 m1 n1 |
1244 // - | |
1245 // | l2 m2 n2 |
1246 // | |
1247 // dist = ------------------------------------ ( > 0 )
1248 // [ |l1 m1|2 |m1 n1|2 |n1 l1|2 ]1/2
1249 // [ | | + | | + | | ]
1250 // [ |l2 m2| |m2 n2| |n2 l2| ]
1251 //
1252 // playing a little bit, we get this reduced for in our case:
1253 //
1254 //
1255 // dist = (- m2 n1 x + m1 n2 x + l2 n1 y - l1 n2 y - l2 m1 z + l1 m2 z) /
1256 // [(l2^2 (m1^2 + n1^2) + (m2 n1 - m1 n2)^2 -
1257 // 2 l1 l2 (m1 m2 + n1 n2) + l1^2 (m2^2 + n2^2) ] ^(1/2)
1258
1259 // read the direction of the incoming shower
1260
1261 thetashw = mcevth.get_theta();
1262 phishw = mcevth.get_phi();
1263
1264 // calculate vector for shower
1265
1266 l1 = sin(thetashw)*cos(phishw);
1267 m1 = sin(thetashw)*sin(phishw);
1268 n1 = cos(thetashw);
1269
1270 // read the deviation of the telescope with respect to the shower
1271
1272 mcevth.get_deviations ( &thetaCT, &phiCT );
1273
1274 if ( (thetaCT == 0.) && (phiCT == 0.) ) {
1275
1276 // CT was looking to the source (both lines are parallel)
1277 // therefore, we calculate the impact parameter as the distance
1278 // between the CT axis and the core position
1279
1280 impactD = dist_r_P( 0., 0., 0., l1, m1, n1, coreX, coreY, 0. );
1281
1282 } else {
1283
1284 // the shower comes off-axis
1285
1286 // obtain with this the final direction of the CT
1287
1288 thetaCT += thetashw;
1289 phiCT += phishw;
1290
1291 // calculate vector for telescope
1292
1293 l2 = sin(thetaCT)*cos(phiCT);
1294 m2 = sin(thetaCT)*sin(phiCT);
1295 n2 = cos(thetaCT);
1296
1297 num = (m1*n2*coreX - m2*n1*coreX + l2*n1*coreY - l1*n2*coreY);
1298 den = (SQR(l1*m2 - l2*m1) +
1299 SQR(m1*n2 - m2*n1) +
1300 SQR(n1*l2 - n2*l1));
1301 den = sqrt(den);
1302
1303 impactD = fabs(num)/den;
1304
1305 }
1306
1307 // energy cut
1308
1309 if ( Select_Energy ) {
1310 if (( mcevth.get_energy() < Select_Energy_le ) ||
1311 ( mcevth.get_energy() > Select_Energy_ue )) {
1312 log(SIGNATURE, "select_energy: shower rejected.\n");
1313 continue;
1314 }
1315 }
1316
1317 // Read first and last time and put inumphe to 0
1318
1319 mcevth.get_times(&arrtmin_ns,&arrtmax_ns);
1320 inumphe=0;
1321
1322 // read the photons and produce the photoelectrons
1323
1324 k = produce_phes( inputfile,
1325 &cam,
1326 WAVEBANDBOUND1,
1327 WAVEBANDBOUND6,
1328 &Trigger, // will be changed by the function!
1329 &fadc, // will be changed by the function!
1330 &inumphe, // important for later: the size of photoe[]
1331 fnpix, // will be changed by the function!
1332 &ncph, // will be changed by the function!
1333 &arrtmin_ns, // will be changed by the function!
1334 &arrtmax_ns // will be changed by the function!
1335 );
1336
1337 if( k != 0 ){ // non-zero returnvalue means error
1338 cout << "Exiting.\n";
1339 exit(1);
1340 }
1341
1342 // NSB simulation
1343
1344 if(simulateNSB && nphe2NSB<=inumphe){
1345
1346 // Fill trigger and fadc response in the trigger class from the database
1347 for(i=0;i<cam.inumpixels;i++)
1348 if(nsb_phepns[i]>0.0){
1349 k=lons.GetResponse(nsb_phepns[i],0.1,
1350 & nsb_trigresp[0],& nsb_fadcresp[0]);
1351 if(k==0){
1352 cout << "Exiting.\n";
1353 exit(1);
1354 }
1355 Trigger.AddNSB(i,nsb_trigresp);
1356 fadc.AddSignal(i,nsb_fadcresp);
1357 }
1358 }// end if(simulateNSB && nphe2NSB<=inumphe) ...
1359
1360 log(SIGNATURE, "End of this event: %d cphs(+%d). . .\n",
1361 ncph, ntcph);
1362
1363 ntcph += ncph;
1364
1365 // skip it ?
1366
1367 for ( i=0; i<nSkip; ++i ) {
1368 if (Skip[i] == (nshow+ntshow)) {
1369 i = -1;
1370 break;
1371 }
1372 }
1373
1374 // if after the previous loop, the exit value of i is -1
1375 // then the shower number is in the list of showers to be
1376 // skipped
1377
1378 if (i == -1) {
1379 log(SIGNATURE, "\t\tskipped!\n");
1380 continue;
1381 }
1382
1383 cout << "Total number of phes: " << inumphe<<" + ";
1384 inumphensb=0;
1385 for (i=0;i<cam.inumpixels;i++){
1386 inumphensb+=nsb_phepns[i]*TOTAL_TRIGGER_TIME;
1387 }
1388 cout<<inumphensb<<endl;
1389
1390 //++++++++++++++++++++++++++++++++++++++++++++++++++
1391 // at this point we have a camera full of
1392 // ph.e.s
1393 // we should first apply the trigger condition,
1394 // and if there's trigger, then clean the image,
1395 // calculate the islands statistics and the
1396 // other parameters of the image (Hillas' parameters
1397 // and so on).
1398 //--------------------------------------------------
1399
1400 // TRIGGER HERE
1401
1402 //
1403 // now the noise of the electronic
1404 // (preamps, optical transmission,..) is introduced.
1405 // This is done inside the class MTrigger by the method ElecNoise.
1406 //
1407 if (addElecNoise){
1408 Trigger.ElecNoise(Trigger_noise) ;
1409
1410 fadc.ElecNoise(FADC_noise) ;
1411 }
1412
1413 // We should simulate the AC coupling behaviour:
1414 // For the FADC it is only done for the NSB while producinr
1415 // the StarResponse database.
1416 // For the trigger is done in the Trigger.Diskriminate(), which
1417 // is called later (it should be seperated to speed up the program
1418
1419 // now a shift in the fadc signal due to the pedestlas is
1420 // intorduced
1421 // This is done inside the class MFadc by the method Pedestals
1422 fadc.Pedestals();
1423
1424 // We study several trigger conditons
1425 if(Trigger_Loop){
1426
1427 // Set to zero the flag to know if some conditon has triggered
1428 btrigger=0;
1429 // Loop over trigger threshold
1430 int iconcount;
1431 for (iconcount=0, ithrescount=0, fthrescount=Trigger_loop_lthres;fthrescount<=Trigger_loop_uthres;ithrescount++, fthrescount+=Trigger_loop_sthres){
1432 for (i=0;i<TRIGGER_PIXELS;i++)
1433 fpixelthres[i]=
1434 ((Float_t)(fthrescount)>=qThreshold[i])?
1435 (Float_t)(fthrescount):qThreshold[i];
1436 Trigger.SetThreshold(fpixelthres);
1437
1438 Trigger.Diskriminate();
1439 //
1440 // look if in all the signals in the trigger signal branch
1441 // is a possible Trigger. Therefore we habe to diskriminate all
1442 // the simulated analog signals (Method Diskriminate in class
1443 // MTrigger). We look simultanously for the moments at which
1444 // there are more than TRIGGER_MULTI pixels above the
1445 // CHANNEL_THRESHOLD.
1446 //
1447
1448 // Set trigger flags to zero
1449 Lev1=Lev2=0;
1450
1451 // loop over multiplicity of trigger configuration
1452 for (imulticount=Trigger_loop_lmult;imulticount<=Trigger_loop_umult;imulticount++){
1453 Trigger.SetMultiplicity(imulticount);
1454 Trigger.ClearZero();
1455
1456 Lev0=(Short_t) Trigger.ZeroLevel();
1457 if (Lev0>0 || Write_All_Images || btrigger){
1458
1459 // loop over topologies
1460 for(itopocount=Trigger_loop_ltop;itopocount<=Trigger_loop_utop;itopocount++){
1461 Lev1=Lev2=0;
1462
1463 if(itopocount==0 && imulticount>7) continue;
1464 //COBB if(itopocount==2 && imulticount<3) continue;
1465 // It only makes to look for a different topology
1466 // if there are 3 or more N pixels.
1467 if(imulticount<3)
1468 Trigger.SetTopology(1);
1469 else
1470 {
1471 // We should be careful that topologies are sort from
1472 // the less to the more restrictive one.
1473 Trigger.SetTopology(isorttopo[itopocount]);
1474 }
1475 Trigger.ClearFirst();
1476
1477 //
1478 // Start the First Level Trigger simulation
1479 //
1480 if(Lev0!=0)
1481 Lev1=Trigger.FirstLevel();
1482 if(Lev1>0) {
1483 btrigger= 1;
1484 ntriggerloop[ithrescount][imulticount-Trigger_loop_lmult][itopocount-Trigger_loop_ltop]++;
1485 }
1486
1487 Lev0=1;
1488 if(Lev1==0 && (Write_All_Images || btrigger)){
1489 btrigger= 1;
1490 Lev1=1;
1491 Lev0=0;
1492 }
1493 numPix=0;
1494 for (Int_t ii=0;ii<Lev1;ii++){
1495 if (Write_McTrig){
1496 McTrig[iconcount]->SetFirstLevel ((ii+1)*Lev0);
1497 McTrig[iconcount]->SetTime(Trigger.GetFirstLevelTime(ii),ii+1);
1498 Trigger.GetMapDiskriminator(trigger_map);
1499 McTrig[iconcount]->SetMapPixels(trigger_map,ii);
1500 }
1501 //
1502 // fill inside the class fadc the member output
1503 //
1504
1505 fadc.TriggeredFadc(Trigger.GetFirstLevelTime(ii));
1506
1507 if( Write_RawEvt ){
1508 //
1509 // Fill the header of this event
1510 //
1511
1512 EvtHeader[iconcount]->FillHeader ( (UInt_t) (ntshow + nshow),0);
1513 // fill pixel information
1514 for(int i=0;i<ct_NPixels;i++){
1515 for (j=0;j<FADC_SLICES;j++){
1516 fadcValues->AddAt(fadc.GetFadcSignal(i,j),j);
1517 }
1518 EvtData[iconcount]->AddPixel(i,fadcValues,0);
1519 }
1520 }
1521 }
1522 //
1523 // Increase counter of analised trigger conditions
1524 //
1525 iconcount++;
1526 }
1527 }
1528 else{
1529 break;
1530 }
1531 }
1532 if (!btrigger) break;
1533 }
1534 if (btrigger){
1535
1536 //
1537 // fill the MMcEvt with all information
1538 //
1539
1540 if (Write_McEvt) {
1541 McEvt->Fill( (UShort_t) mcevth.get_primary() ,
1542 mcevth.get_energy(),
1543 mcevth.get_theta(),
1544 mcevth.get_phi(),
1545 mcevth.get_core(),
1546 mcevth.get_coreX(),
1547 mcevth.get_coreY(),
1548 impactD,
1549 (UInt_t)mcevth.get_CORSIKA(),
1550 (UInt_t)mcevth.get_AtmAbs(),
1551 (UInt_t)mcevth.get_MirrAbs()+mcevth.get_OutOfMirr()+mcevth.get_BlackSpot(),
1552 (UInt_t) ncph,
1553 (UInt_t) inumphe,
1554 (UInt_t) inumphensb+inumphe);
1555 }
1556 // Fill the Tree with the current leaves of each branch
1557 i=EvtTree.Fill() ;
1558
1559 // Clear the branches
1560 if(Write_McTrig){
1561 for(i=0;i<icontrigger;i++){
1562 McTrig[i]->Clear() ;
1563 }
1564 }
1565 if( Write_RawEvt ){
1566 for(i=0;i<icontrigger;i++){
1567 EvtHeader[i]->Clear() ;
1568 EvtData[i]->DeletePixels();
1569 }
1570 }
1571 if (Write_McEvt)
1572 McEvt->Clear() ;
1573 }
1574 }
1575 // We study a single trigger condition
1576 else {
1577
1578 // Setting trigger conditions
1579 Trigger.SetMultiplicity(Trigger_multiplicity);
1580 Trigger.SetTopology(Trigger_topology);
1581 for (int i=0;i<TRIGGER_PIXELS;i++)
1582 fpixelthres[i]=qThreshold[i];
1583 Trigger.SetThreshold(fpixelthres);
1584
1585 Trigger.Diskriminate() ;
1586
1587 //
1588 // look if in all the signals in the trigger signal branch
1589 // is a possible Trigger. Therefore we habe to diskriminate all
1590 // the simulated analog signals (Method Diskriminate in class
1591 // MTrigger). We look simultanously for the moments at which
1592 // there are more than TRIGGER_MULTI pixels above the
1593 // CHANNEL_THRESHOLD.
1594 //
1595
1596 Lev0 = (Short_t) Trigger.ZeroLevel() ;
1597
1598 Lev1 = Lev2 = 0 ;
1599
1600 //
1601 // Start the First Level Trigger simulation
1602 //
1603
1604 if ( Lev0 > 0 || Write_All_Images) {
1605 Lev1= Trigger.FirstLevel();
1606 }
1607 if (Lev1>0){
1608 ++ntrigger;
1609 }
1610 Lev0=1;
1611 if (Lev1==0 && Write_All_Images){
1612 Lev1=1;
1613 Lev0=0;
1614 }
1615
1616 numPix=0;
1617 for(Int_t ii=0;ii<Lev1;ii++){
1618 // Loop over different level one triggers
1619
1620 //
1621 // fill inside class fadc the member output
1622 //
1623 fadc.TriggeredFadc(Trigger.GetFirstLevelTime(ii));
1624
1625 if (Write_McTrig){
1626 McTrig[0]->SetFirstLevel ((ii+1)*Lev0);
1627 McTrig[0]->SetTime(Trigger.GetFirstLevelTime(ii),ii+1);
1628 Trigger.GetMapDiskriminator(trigger_map);
1629 McTrig[0]->SetMapPixels(trigger_map,ii);
1630 }
1631
1632 // Fill Evt information
1633
1634 if (Write_RawEvt){
1635
1636 //
1637 // Fill the header of this event
1638 //
1639
1640 EvtHeader[0]->FillHeader ( (UShort_t) (ntshow + nshow) , 20 ) ;
1641
1642 // fill pixel information
1643
1644 for(int i=0;i<ct_NPixels;i++){
1645 for (j=0;j<FADC_SLICES;j++){
1646 fadcValues->AddAt(fadc.GetFadcSignal(i,j),j);
1647 }
1648 EvtData[0]->AddPixel(i,fadcValues,0);
1649 }
1650 }
1651 //
1652 // fill the MMcEvt with all information
1653 //
1654
1655 if (Write_McEvt){
1656 McEvt->Fill( (UShort_t) mcevth.get_primary() ,
1657 mcevth.get_energy(),
1658 mcevth.get_theta(),
1659 mcevth.get_phi(),
1660 mcevth.get_core(),
1661 mcevth.get_coreX(),
1662 mcevth.get_coreY(),
1663 impactD,
1664 (UInt_t)mcevth.get_CORSIKA(),
1665 (UInt_t)mcevth.get_AtmAbs(),
1666 (UInt_t)mcevth.get_MirrAbs()+mcevth.get_OutOfMirr()+mcevth.get_BlackSpot(),
1667 (UInt_t) ncph,
1668 (UInt_t) inumphe,
1669 (UInt_t) inumphensb+inumphe);
1670 }
1671 // We don not count photons out of the camera.
1672
1673
1674 //
1675 // write it out to the file outfile
1676 //
1677
1678 EvtTree.Fill() ;
1679
1680 //
1681 // if a first level trigger occurred, then
1682 // 1. do some other stuff (not implemented)
1683 // 2. start the gui tool
1684
1685 if(FADC_Scan){
1686 if ( Lev0 > 0 ) {
1687 fadc.ShowSignal( McEvt, (Float_t) 60. ) ;
1688 }
1689 }
1690
1691 if(Trigger_Scan){
1692 if ( Lev0 > 0 ) {
1693 Trigger.ShowSignal(McEvt) ;
1694 }
1695 }
1696
1697 // clear all
1698 if (Write_RawEvt) EvtHeader[0]->Clear() ;
1699 if (Write_RawEvt) EvtData[0]->DeletePixels();
1700 if (Write_McEvt) McEvt->Clear() ;
1701 }
1702 if (Write_McTrig) McTrig[0]->Clear() ;
1703 }
1704
1705#ifdef __DEBUG__
1706 printf("\n");
1707
1708 for ( ici=0; ici<PIX_ARRAY_SIDE; ++ici ) {
1709
1710 for ( icj=0; icj<PIX_ARRAY_SIDE; ++icj ) {
1711
1712 if ( (int)pixels[ici][icj][PIXNUM] > -1 ) {
1713
1714 if ( fnpix[(int)pixels[ici][icj][PIXNUM]] > 0. ) {
1715
1716 printf ("@@ %4d %4d %10f %10f %4f (%4d %4d)\n", nshow,
1717 (int)pixels[ici][icj][PIXNUM],
1718 pixels[ici][icj][PIXX],
1719 pixels[ici][icj][PIXY],
1720 fnpix[(int)pixels[ici][icj][PIXNUM]], ici, icj);
1721
1722 }
1723 }
1724 }
1725 }
1726
1727 for (int i=0; i<ct_NPixels; ++i) {
1728 printf("%d (%d): ", i, npixneig[i]);
1729 for (j=0; j<npixneig[i]; ++i)
1730 printf(" %d", pixneig[i][j]);
1731 printf("\n");
1732 }
1733
1734#endif // __DEBUG__
1735
1736
1737 // look for the next event
1738
1739 fread( flag, SIZE_OF_FLAGS, 1, inputfile );
1740
1741 } // end while there is a next event
1742
1743 if( !isA( flag, FLAG_END_OF_RUN )){
1744 error( SIGNATURE, "Expected end of run flag, but found: %s\n", flag );
1745 }
1746 else { // found end of run
1747 ntshow += nshow;
1748 log(SIGNATURE, "End of this run with %d events . . .\n", nshow);
1749
1750 fread( flag, SIZE_OF_FLAGS, 1, inputfile );
1751
1752 if( isA( flag, FLAG_END_OF_FILE ) ){ // end of file
1753 log(SIGNATURE, "End of file . . .\n");
1754 still_in_loop = FALSE;
1755
1756 if ((! Data_From_STDIN) && ( !feof(inputfile) )){
1757
1758 // we have concatenated input files.
1759 // get signature of the next part and check it.
1760
1761 if(check_reflector_file( inputfile )==FALSE){
1762 exit(1);
1763 }
1764
1765 }
1766
1767 fread( flag, SIZE_OF_FLAGS, 1, inputfile );
1768
1769 } // end if found end of file
1770 } // end if found end of run
1771
1772 } // end if else found start of run
1773 } // end big while loop
1774
1775 //<@ Finally we should fill th McRunHeader
1776
1777
1778 get_starfield_center(&sfRaH,&sfRaM,&sfRaS,&sfDeD,&sfDeM,&sfDeS);
1779 get_teles_axis(&telestheta,&telesphi);
1780 get_source_off(&sofftheta,&soffphi);
1781 mcevth.get_theta_range(&shthetamin, &shthetamax);
1782 mcevth.get_phi_range(&shphimin,&shphimax);
1783 corsika=get_corsika_ver();
1784 if(!Trigger_Loop) icontrigger=0;
1785 McRunHeader->Fill(icontrigger,
1786 !Write_All_Images,
1787 Write_McEvt,
1788 Write_McTrig,
1789 Write_McFADC,
1790 CAMERA_PIXELS,
1791 (UInt_t)ntshow,
1792 (UInt_t)ntrigger,
1793 sfRaH,
1794 sfRaM,
1795 sfRaS,
1796 sfDeD,
1797 sfDeM,
1798 sfDeS,
1799 meanNSB,
1800 telestheta,
1801 telesphi,
1802 sofftheta,
1803 soffphi,
1804 shthetamax,
1805 shthetamin,
1806 shphimax,
1807 shphimin,
1808 corsika,
1809 (UInt_t)(REFL_VERSION*100),
1810 (UInt_t)(VERSION*100));
1811
1812 // Fill the Header Tree with the current leaves of each branch
1813 HeaderTree.Fill() ;
1814
1815 //++
1816 // put the Event to the root file
1817 //--
1818
1819 outfile_temp.Write() ;
1820 outfile_temp.Close() ;
1821
1822
1823 // close input file
1824
1825 log( SIGNATURE, "%d event(s), with a total of %d C.photons\n",
1826 ntshow, ntcph );
1827 datafile<<ntshow<<" event(s), with a total of "<<ntcph<<" C.photons"<<endl;
1828 if (Trigger_Loop){
1829 log( SIGNATURE, "Trigger Mode. \n");
1830 log( SIGNATURE, "Fraction of triggers: \n");
1831 datafile<<"Fraction of triggers: "<<endl;
1832 for (ithrescount=0, fthrescount=Trigger_loop_lthres;fthrescount<=Trigger_loop_uthres;ithrescount++, fthrescount+=Trigger_loop_sthres){
1833 for (imulticount=Trigger_loop_lmult;imulticount<=Trigger_loop_umult;imulticount++){
1834 for(itopocount=Trigger_loop_ltop;itopocount<=Trigger_loop_utop;itopocount++){
1835 log( SIGNATURE, "Thres %5.1f, Multi %d, Topo %d: %5.1f%% (%d out of %d)\n",
1836 fthrescount,imulticount,isorttopo[itopocount],((float)ntriggerloop[ithrescount][imulticount-Trigger_loop_lmult][itopocount-Trigger_loop_ltop] / ((float)ntshow) * 100.0), ntriggerloop[ithrescount][imulticount-Trigger_loop_lmult][itopocount-Trigger_loop_ltop], ntshow);
1837 datafile<<"Thres "<<fthrescount<<", Multi "<<imulticount<<", Topo"<<isorttopo[itopocount]<<": ";
1838 datafile<<((float)ntriggerloop[ithrescount][imulticount-Trigger_loop_lmult][itopocount-Trigger_loop_ltop] / ((float)ntshow) * 100.0)<<"% ("<<ntriggerloop[ithrescount][imulticount-Trigger_loop_lmult][itopocount-Trigger_loop_ltop]<<" out of "<<ntshow<<")"<<endl;
1839 }
1840 }
1841 }
1842 }
1843 else{
1844 log( SIGNATURE, "Fraction of triggers: %5.1f%% (%d out of %d)\n",
1845 ((float)ntrigger) / ((float)ntshow) * 100.0, ntrigger, ntshow);
1846 datafile<<"Fraction of triggers: "<<((float)ntrigger) / ((float)ntshow) * 100.0<<" ("<<ntrigger<<" out of "<<ntshow<<" )"<<endl;
1847 }
1848
1849 // close files
1850
1851 log( SIGNATURE, "Closing files\n" );
1852
1853 if( ! Data_From_STDIN ){
1854 fclose( inputfile );
1855 }
1856 datafile.close();
1857
1858 // program finished
1859
1860 log( SIGNATURE, "Done.\n");
1861
1862 return( 0 );
1863}
1864//!@}
1865
1866// @T \newpage
1867
1868//!@subsection Functions definition.
1869
1870//!-----------------------------------------------------------
1871// @name present
1872//
1873// @desc Make some presentation
1874//
1875// @date Sat Jun 27 05:58:56 MET DST 1998
1876//------------------------------------------------------------
1877// @function
1878
1879//!@{
1880void
1881present(void)
1882{
1883 cout << "##################################################\n"
1884 << SIGNATURE << '\n' << '\n'
1885 << "Processor of the reflector output\n"
1886 << "J C Gonzalez, Jun 1998\n"
1887 << "##################################################\n\n"
1888 << flush ;
1889}
1890//!@}
1891
1892
1893//!-----------------------------------------------------------
1894// @name usage
1895//
1896// @desc show help
1897//
1898// @date Tue Dec 15 16:23:30 MET 1998
1899//------------------------------------------------------------
1900// @function
1901
1902//!@{
1903void
1904usage(void)
1905{
1906 present();
1907 cout << "\nusage ::\n\n"
1908 << "\t camera "
1909 << " [ -@ paramfile ] "
1910 << " [ -h ] "
1911 << "\n\n or \n\n"
1912 << "\t camera < paramfile"
1913 << "\n\n";
1914 exit(0);
1915}
1916//!@}
1917
1918
1919//!-----------------------------------------------------------
1920// @name log
1921//
1922// @desc function to send log information
1923//
1924// @var funct Name of the caller function
1925// @var fmt Format to be used (message)
1926// @var ... Other information to be shown
1927//
1928// @date Sat Jun 27 05:58:56 MET DST 1998
1929//------------------------------------------------------------
1930// @function
1931
1932//!@{
1933void
1934log(const char *funct, char *fmt, ...)
1935{
1936 va_list args;
1937
1938 // Display the name of the function that called error
1939 printf("[%s]: ", funct);
1940
1941 // Display the remainder of the message
1942 va_start(args, fmt);
1943 vprintf(fmt, args);
1944 va_end(args);
1945}
1946//!@}
1947
1948
1949//!-----------------------------------------------------------
1950// @name error
1951//
1952// @desc function to send an error message, and abort the program
1953//
1954// @var funct Name of the caller function
1955// @var fmt Format to be used (message)
1956// @var ... Other information to be shown
1957//
1958// @date Sat Jun 27 05:58:56 MET DST 1998
1959//------------------------------------------------------------
1960// @function
1961
1962//!@{
1963void
1964error(const char *funct, char *fmt, ...)
1965{
1966 va_list args;
1967
1968 // Display the name of the function that called error
1969 fprintf(stdout, "ERROR in %s: ", funct);
1970
1971 // Display the remainder of the message
1972 va_start(args, fmt);
1973 vfprintf(stdout, fmt, args);
1974 va_end(args);
1975
1976 perror(funct);
1977
1978 exit(1);
1979}
1980//!@}
1981
1982
1983//!-----------------------------------------------------------
1984// @name isA
1985//
1986// @desc returns TRUE(FALSE), if the flag is(is not) the given
1987//
1988// @var s1 String to be searched
1989// @var flag Flag to compare with string s1
1990// @return TRUE: both strings match; FALSE: oth.
1991//
1992// @date Wed Jul 8 15:25:39 MET DST 1998
1993//------------------------------------------------------------
1994// @function
1995
1996//!@{
1997int
1998isA( char * s1, const char * flag ) {
1999 return ( (strncmp((char *)s1, flag, SIZE_OF_FLAGS)==0) ? 1 : 0 );
2000}
2001//!@}
2002
2003
2004//!-----------------------------------------------------------
2005// @name read_ct_file
2006//
2007// @desc read CT definition file
2008//
2009// @date Sat Jun 27 05:58:56 MET DST 1998
2010//------------------------------------------------------------
2011// @function
2012
2013//!@{
2014void
2015read_ct_file(void)
2016{
2017 char line[LINE_MAX_LENGTH]; //@< line to get from the ctin
2018 char token[ITEM_MAX_LENGTH]; //@< a single token
2019 int i, j; //@< dummy counters
2020
2021 log( "read_ct_file", "start.\n" );
2022
2023 ifstream ctin ( ct_filename );
2024
2025 if ( ctin.bad() )
2026 error( "read_ct_file",
2027 "Cannot open CT def. file: %s\n", ct_filename );
2028
2029 // loop till the "end" directive is reached
2030
2031 while (!ctin.eof()) {
2032
2033 // get line from stdin
2034
2035 ctin.getline(line, LINE_MAX_LENGTH);
2036
2037 // look for each item at the beginning of the line
2038
2039 for (i=0; i<=define_mirrors; i++)
2040 if (strstr(line, CT_ITEM_NAMES[i]) == line)
2041 break;
2042
2043 // if it is not a valid line, just ignore it
2044
2045 if (i == define_mirrors+1)
2046 continue;
2047
2048 // case block for each directive
2049
2050 switch ( i ) {
2051
2052 case type: // <type of telescope> (0:CT1 ¦ 1:MAGIC)
2053
2054 // get focal distance
2055
2056 sscanf(line, "%s %d", token, &ct_Type);
2057
2058 log( "read_ct_file", "<Type of Telescope>: %s\n",
2059 ((ct_Type==0) ? "CT1" : "MAGIC") );
2060
2061 break;
2062
2063 case focal_distance: // <focal distance> [cm]
2064
2065 // get focal distance
2066
2067 sscanf(line, "%s %f", token, &ct_Focal_mean);
2068
2069 log( "read_ct_file", "<Focal distance>: %f cm\n", ct_Focal_mean );
2070
2071 break;
2072
2073 case focal_std: // s(focal distance) [cm]
2074
2075 // get focal distance
2076
2077 sscanf(line, "%s %f", token, &ct_Focal_std);
2078
2079 log( "read_ct_file", "s(Focal distance): %f cm\n", ct_Focal_std );
2080
2081 break;
2082
2083 case point_spread: // <point spread> [cm]
2084
2085 // get point spread
2086
2087 sscanf(line, "%s %f", token, &ct_PSpread_mean);
2088
2089 log( "read_ct_file", "<Point spread>: %f cm\n", ct_PSpread_mean );
2090
2091 break;
2092
2093 case point_std: // s(point spread) [cm]
2094
2095 // get point spread
2096
2097 sscanf(line, "%s %f", token, &ct_PSpread_std);
2098
2099 log( "read_ct_file", "s(Point spread): %f cm\n", ct_PSpread_std );
2100
2101 break;
2102
2103 case adjustment_dev: // s(adjustment_dev) [cm]
2104
2105 // get point spread
2106
2107 sscanf(line, "%s %f", token, &ct_Adjustment_std);
2108
2109 log( "read_ct_file", "s(Adjustment): %f cm\n", ct_Adjustment_std );
2110
2111 break;
2112
2113 case black_spot: // radius of the black spot in the center [cm]
2114
2115 // get black spot radius
2116
2117 sscanf(line, "%s %f", token, &ct_BlackSpot_rad);
2118
2119 log( "read_ct_file", "Radius of the black spots: %f cm\n",
2120 ct_BlackSpot_rad);
2121
2122 break;
2123
2124 case r_mirror: // radius of the mirrors [cm]
2125
2126 // get radius of mirror
2127
2128 sscanf(line, "%s %f", token, &ct_RMirror);
2129
2130 log( "read_ct_file", "Radii of the mirrors: %f cm\n", ct_RMirror );
2131
2132 break;
2133
2134 case n_mirrors: // number of mirrors
2135
2136 // get the name of the output_file from the line
2137
2138 sscanf(line, "%s %d", token, &ct_NMirrors);
2139
2140 log( "read_ct_file", "Number of mirrors: %d\n", ct_NMirrors );
2141
2142 break;
2143
2144 case camera_width: // camera width [cm]
2145
2146 // get the name of the ct_file from the line
2147
2148 sscanf(line, "%s %f", token, &ct_CameraWidth);
2149
2150 log( "read_ct_file", "Camera width: %f cm\n", ct_CameraWidth );
2151
2152 break;
2153
2154 case n_pixels: // number of pixels
2155
2156 // get the name of the output_file from the line
2157
2158 sscanf(line, "%s %d", token, &ct_NPixels);
2159
2160 log( "read_ct_file", "Number of pixels: %d\n", ct_NPixels );
2161
2162 break;
2163
2164 case n_centralpixels: // number of central pixels
2165
2166 // get the name of the output_file from the line
2167
2168 sscanf(line, "%s %d", token, &ct_NCentralPixels);
2169
2170 log( "read_ct_file", "Number of central pixels: %d\n", ct_NCentralPixels );
2171
2172 break;
2173
2174 case n_gappixels: // number of gap pixels
2175
2176 // get the name of the output_file from the line
2177
2178 sscanf(line, "%s %d", token, &ct_NGapPixels);
2179
2180 log( "read_ct_file", "Number of gap pixels: %d\n", ct_NGapPixels );
2181
2182 break;
2183
2184 case pixel_width: // pixel width [cm]
2185
2186 // get the name of the ct_file from the line
2187
2188 sscanf(line, "%s %f", token, &ct_PixelWidth);
2189
2190 ct_PixelWidth_corner_2_corner = ct_PixelWidth / cos(RAD(30.0));
2191 ct_PixelWidth_corner_2_corner_half =
2192 ct_PixelWidth_corner_2_corner * 0.50;
2193 ct_Apot = ct_PixelWidth / 2;
2194 ct_2Apot = ct_Apot * 2.0;
2195
2196 log( "read_ct_file", "Pixel width: %f cm\n", ct_PixelWidth );
2197
2198 break;
2199
2200 case define_mirrors: // read table with the parameters of the mirrors
2201
2202 log( "read_ct_file", "Table of mirrors data:\n" );
2203
2204 // check whether the number of mirrors was already set
2205
2206 if ( ct_NMirrors == 0 )
2207 error( "read_ct_file", "NMirrors was not set.\n" );
2208
2209 // allocate memory for paths list
2210
2211 log( "read_ct_file", "Allocating memory for ct_data\n" );
2212
2213 ct_data = new float*[ct_NMirrors];
2214
2215 for (i=0; i<ct_NMirrors; i++)
2216 ct_data[i] = new float[CT_NDATA];
2217
2218 // read data
2219
2220 log( "read_ct_file", "Reading mirrors data...\n" );
2221
2222 for (i=0; i<ct_NMirrors; i++)
2223 for (j=0; j<CT_NDATA; j++)
2224 ctin >> ct_data[i][j];
2225
2226 break;
2227
2228 } // switch ( i )
2229
2230 } // end while
2231
2232 // end
2233
2234 log( "read_ct_file", "done.\n" );
2235
2236 return;
2237}
2238//!@}
2239
2240
2241//!-----------------------------------------------------------
2242// @name read_pixels
2243//
2244// @desc read pixels data
2245//
2246// @date Fri Mar 12 16:33:34 MET 1999
2247//------------------------------------------------------------
2248// @function
2249
2250//!@{
2251void
2252read_pixels(struct camera *pcam)
2253{
2254 ifstream qefile;
2255 char line[LINE_MAX_LENGTH];
2256 int n, i, j, icount;
2257 float qe;
2258
2259 //------------------------------------------------------------
2260 // first, pixels' coordinates
2261
2262 pcam->inumpixels = ct_NPixels;
2263 pcam->inumcentralpixels = ct_NCentralPixels;
2264 pcam->inumgappixels = ct_NGapPixels;
2265 pcam->inumbigpixels = ct_NPixels - ct_NCentralPixels - ct_NGapPixels;
2266 pcam->dpixdiameter_cm = ct_PixelWidth;
2267
2268 // initialize pixel numbers
2269
2270 pixary = new float* [2*ct_NCentralPixels];
2271 for ( i=0; i<2*ct_NCentralPixels; ++i )
2272 pixary[i] = new float[2];
2273
2274 pixneig = new int* [ct_NCentralPixels];
2275 for ( i=0; i<ct_NCentralPixels; ++i ) {
2276 pixneig[i] = new int[6];
2277 for ( j=0; j<6; ++j )
2278 pixneig[i][j] = -1;
2279 }
2280
2281 npixneig = new int[ct_NCentralPixels];
2282 for ( i=0; i<ct_NCentralPixels; ++i )
2283 npixneig[i] = 0;
2284
2285 // generate all coordinates
2286
2287 igen_pixel_coordinates(pcam);
2288
2289
2290 // calculate tables of neighbours
2291
2292#ifdef __DEBUG__
2293 for ( n=0 ; n<ct_NPixels ; ++n ) {
2294 cout << "Para el pixel " << n << ": ";
2295 for ( i=n+1 ; (i<ct_NPixels)&&(npixneig[n]<6) ; ++i) {
2296 if ( pixels_are_neig(n,i) == TRUE ) {
2297 pixneig[n][npixneig[n]] = i;
2298 pixneig[i][npixneig[i]] = n;
2299 cout << i << ' ';
2300 ++npixneig[n];
2301 ++npixneig[i];
2302 }
2303 }
2304 cout << endl << flush;
2305 }
2306#else // ! __DEBUG__
2307 for ( n=0 ; n<ct_NCentralPixels ; ++n )
2308 for ( i=n+1 ; (i<ct_NCentralPixels)&&(npixneig[n]<6) ; ++i)
2309 if ( pixels_are_neig(n,i) == TRUE ) {
2310 pixneig[n][npixneig[n]] = i;
2311 pixneig[i][npixneig[i]] = n;
2312 ++npixneig[n];
2313 ++npixneig[i];
2314 }
2315#endif // ! __DEBUG__
2316
2317#ifdef __DEBUG__
2318 for ( n=0 ; n<ct_NPixels ; ++n ) {
2319 cout << n << ':';
2320 for ( j=0; j<npixneig[n]; ++j)
2321 cout << ' ' << pixneig[n][j];
2322 cout << endl << flush;
2323 }
2324#endif // __DEBUG__
2325
2326 //------------------------------------------------------------
2327 // second, pixels' QE
2328
2329 // try to open the file
2330
2331 log("read_pixels", "Opening the file \"%s\" . . .\n", QE_FILE);
2332
2333 qefile.open( QE_FILE );
2334
2335 // if it is wrong or does not exist, exit
2336
2337 if ( qefile.bad() )
2338 error( "read_pixels", "Cannot open \"%s\". Exiting.\n", QE_FILE );
2339
2340 // read file
2341
2342 log("read_pixels", "Reading data . . .\n");
2343
2344 i=-1;
2345 icount = 0;
2346
2347 while ( ! qefile.eof() ) {
2348
2349 // get line from the file
2350
2351 qefile.getline(line, LINE_MAX_LENGTH);
2352
2353 // skip if comment
2354
2355 if ( *line == '#' )
2356 continue;
2357
2358 // if it is the first valid value, it is the number of QE data points
2359
2360 if ( i < 0 ) {
2361
2362 // get the number of datapoints
2363
2364 sscanf(line, "%d", &pointsQE);
2365
2366 // allocate memory for the table of QEs
2367
2368 QE = new float ** [ct_NPixels];
2369
2370 for ( i=0; i<ct_NPixels; ++i ) {
2371 QE[i] = new float * [2];
2372 QE[i][0] = new float[pointsQE];
2373 QE[i][1] = new float[pointsQE];
2374 }
2375
2376 QElambda = new float [pointsQE];
2377
2378 for ( i=0; i<pointsQE; ++i ) {
2379 qefile.getline(line, LINE_MAX_LENGTH);
2380 sscanf(line, "%f", &QElambda[i]);
2381 }
2382
2383 i=0;
2384
2385 continue;
2386 }
2387
2388 // get the values (num-pixel, num-datapoint, QE-value)
2389
2390 if( sscanf(line, "%d %d %f", &i, &j, &qe) != 3 )
2391 break;
2392
2393 if ( ((i-1) < ct_NPixels) && ((i-1) > -1) &&
2394 ((j-1) < pointsQE) && ((j-1) > -1) ) {
2395 QE[i-1][0][j-1] = QElambda[j-1];
2396 QE[i-1][1][j-1] = qe;
2397 }
2398
2399 if ( i > ct_NPixels) break;
2400
2401 icount++;
2402
2403 }
2404
2405 if(icount/pointsQE < ct_NPixels){
2406 error( "read_pixels", "The quantum efficiency file is faulty\n (found only %d pixels instead of %d).\n",
2407 icount/pointsQE, ct_NPixels );
2408 }
2409
2410 // close file
2411
2412 qefile.close();
2413
2414 // test QE
2415
2416 for(icount=0; icount< ct_NPixels; icount++){
2417 for(i=0; i<pointsQE; i++){
2418 if( QE[icount][0][i] < 100. || QE[icount][0][i] > 1000. ||
2419 QE[icount][1][i] < 0. || QE[icount][1][i] > 100.){
2420 error( "read_pixels", "The quantum efficiency file is faulty\n pixel %d, point %d is % f, %f\n",
2421 icount, i, QE[icount][0][i], QE[icount][1][i] );
2422 }
2423 }
2424 }
2425
2426 // end
2427
2428 log("read_pixels", "Done.\n");
2429
2430}
2431//!@}
2432
2433
2434//!-----------------------------------------------------------
2435// @name pixels_are_neig
2436//
2437// @desc check whether two pixels are neighbours
2438//
2439// @var pix1 Number of the first pixel
2440// @var pix2 Number of the second pixel
2441// @return TRUE: both pixels are neighbours; FALSE: oth.
2442//
2443// @date Wed Sep 9 17:58:37 MET DST 1998
2444//------------------------------------------------------------
2445// @function
2446
2447//!@{
2448int
2449pixels_are_neig(int pix1, int pix2)
2450{
2451 if ( sqrt(SQR( pixary[pix1][0] - pixary[pix2][0] ) +
2452 SQR( pixary[pix1][1] - pixary[pix2][1] ) )
2453 > ct_PixelWidth_corner_2_corner )
2454 return ( FALSE );
2455 else
2456 return ( TRUE );
2457}
2458//!@}
2459
2460//!-----------------------------------------------------------
2461// @name igen_pixel_coordinates
2462//
2463// @desc generate the pixel center coordinates
2464//
2465// @var *pcam structure camera containing all the
2466// camera information
2467// @return total number of pixels
2468//
2469// DP
2470//
2471// @date Thu Oct 14 10:41:03 CEST 1999
2472//------------------------------------------------------------
2473// @function
2474
2475//!@{
2476/******** igen_pixel_coordinates() *********************************/
2477
2478int igen_pixel_coordinates(struct camera *pcam) {
2479 /* generate pixel coordinates, return value is number of pixels */
2480
2481 int i, itot_inside_ring, iN, in, ipixno, iring_no, ipix_in_ring, isegment;
2482 float fsegment_fract;
2483 double dtsize;
2484 double dhsize;
2485 double dpsize;
2486 double dxfirst_pix;
2487 double dyfirst_pix;
2488 double ddxseg1, ddxseg2, ddxseg3, ddxseg4, ddxseg5, ddxseg6;
2489 double ddyseg1, ddyseg2, ddyseg3, ddyseg4, ddyseg5, ddyseg6;
2490
2491
2492 double dstartx, dstarty; /* for the gap pixels and outer pixels */
2493 int j, nrow;
2494
2495 dpsize = pcam->dpixdiameter_cm;
2496 dtsize = dpsize * sqrt(3.) / 2.;
2497 dhsize = dpsize / 2.;
2498
2499 /* Loop over central pixels to generate co-ordinates */
2500
2501 for(ipixno=1; ipixno <= pcam->inumcentralpixels; ipixno++){
2502
2503 /* Initialise variables. The central pixel = ipixno 1 in ring iring_no 0 */
2504
2505 pcam->dpixsizefactor[ipixno-1] = 1.;
2506
2507 in = 0;
2508
2509 i = 0;
2510 itot_inside_ring = 0;
2511 iring_no = 0;
2512
2513 /* Calculate the number of pixels out to and including the ring containing pixel number */
2514 /* ipixno e.g. for pixel number 17 in ring number 2 itot_inside_ring = 19 */
2515
2516 while (itot_inside_ring == 0){
2517
2518 iN = 3*(i*(i+1)) + 1;
2519
2520 if (ipixno <= iN){
2521 iring_no = i;
2522 itot_inside_ring = iN;
2523 }
2524
2525 i++;
2526 }
2527
2528
2529 /* Find the number of pixels which make up ring number iring_no e.g. ipix_in_ring = 6 for ring 1 */
2530
2531 ipix_in_ring = 0;
2532 for (i = 0; i < iring_no; ++i){
2533
2534 ipix_in_ring = ipix_in_ring + 6;
2535 }
2536
2537 /* The camera is viewed as 6 radial segments ("pie slices"). Knowing the number of pixels in its */
2538 /* ring calculate which segment the pixel ipixno is in. Then find how far across this segment it is */
2539 /* as a fraction of the number of pixels in this sixth of the ring (ask SMB). */
2540
2541 isegment = 0;
2542 fsegment_fract = 0.;
2543 if (iring_no > 0) {
2544
2545 isegment = (int)((ipixno - itot_inside_ring + ipix_in_ring - 0.5) / iring_no + 1); /* integer division ! numbering starts at 1 */
2546
2547 fsegment_fract = (ipixno - (itot_inside_ring - ipix_in_ring)) - ((isegment-1)*iring_no) - 1 ;
2548
2549 }
2550
2551 /* the first pixel in each ring lies on the positive x axis at a distance dxfirst_pix = iring_no * the */
2552 /* pixel width (flat to flat) dpsize. */
2553
2554 dxfirst_pix = dpsize*iring_no;
2555 dyfirst_pix = 0.;
2556
2557 /* the vector between the first and last pixels in a segment n is (ddxsegn, ddysegn) */
2558
2559 ddxseg1 = - dhsize*iring_no;
2560 ddyseg1 = dtsize*iring_no;
2561 ddxseg2 = -dpsize*iring_no;
2562 ddyseg2 = 0.;
2563 ddxseg3 = ddxseg1;
2564 ddyseg3 = -ddyseg1;
2565 ddxseg4 = -ddxseg1;
2566 ddyseg4 = -ddyseg1;
2567 ddxseg5 = -ddxseg2;
2568 ddyseg5 = 0.;
2569 ddxseg6 = -ddxseg1;
2570 ddyseg6 = ddyseg1;
2571
2572 /* to find the position of pixel ipixno take the position of the first pixel in the ring and move */
2573 /* anti-clockwise around the ring by adding the segment to segment vectors. */
2574
2575 switch (isegment) {
2576
2577 case 0:
2578
2579 pcam->dxc[ipixno-1] = 0.;
2580 pcam->dyc[ipixno-1] = 0.;
2581
2582 case 1:
2583 pcam->dxc[ipixno-1] = dxfirst_pix - dhsize*fsegment_fract;
2584 pcam->dyc[ipixno-1] = dyfirst_pix + dtsize*fsegment_fract;
2585
2586 break;
2587
2588 case 2:
2589
2590 pcam->dxc[ipixno-1] = dxfirst_pix + ddxseg1 - dpsize*fsegment_fract;
2591 pcam->dyc[ipixno-1] = dyfirst_pix + ddyseg1 + 0.;
2592
2593 break;
2594
2595 case 3:
2596
2597 pcam->dxc[ipixno-1] = dxfirst_pix + ddxseg1 + ddxseg2 - dhsize*fsegment_fract;
2598 pcam->dyc[ipixno-1] = dyfirst_pix + ddyseg1 + ddyseg2 - dtsize*fsegment_fract;
2599
2600 break;
2601
2602 case 4:
2603
2604 pcam->dxc[ipixno-1] = dxfirst_pix + ddxseg1 + ddxseg2 + ddxseg3 + dhsize*fsegment_fract;
2605 pcam->dyc[ipixno-1] = dyfirst_pix + ddyseg1 + ddyseg2 + ddyseg3 - dtsize*fsegment_fract;
2606
2607 break;
2608
2609 case 5:
2610
2611 pcam->dxc[ipixno-1] = dxfirst_pix + ddxseg1 + ddxseg2 + ddxseg3 + ddxseg4 + dpsize*fsegment_fract;
2612 pcam->dyc[ipixno-1] = dyfirst_pix + ddyseg1 + ddyseg2 + ddyseg3 + ddyseg4 + 0.;
2613
2614 break;
2615
2616 case 6:
2617
2618 pcam->dxc[ipixno-1] = dxfirst_pix + ddxseg1 + ddxseg2 + ddxseg3 + ddxseg4 + ddxseg5 + dhsize*fsegment_fract;
2619 pcam->dyc[ipixno-1] = dyfirst_pix + ddyseg1 + ddyseg2 + ddyseg3 + ddyseg4 + ddyseg5 + dtsize*fsegment_fract;
2620
2621 break;
2622
2623 default:
2624
2625 fprintf(stderr, "ERROR: problem in coordinate generation for pixel %d\n", ipixno);
2626 return(0);
2627
2628 } /* end switch */
2629
2630 } /* end for */
2631
2632 dstartx = pcam->dxc[pcam->inumcentralpixels - 1] + dhsize;
2633 dstarty = pcam->dyc[pcam->inumcentralpixels - 1] + dtsize;
2634
2635 if(pcam->inumgappixels > 0){ /* generate the positions of the gap pixels */
2636
2637 j = pcam->inumcentralpixels;
2638
2639 for(i=0; i<pcam->inumgappixels; i=i+6){
2640 pcam->dxc[j + i ] = dstartx + 2. * (i/6 + 1) * dpsize;
2641 pcam->dyc[j + i ] = dstarty;
2642 pcam->dpixsizefactor[j + i] = 1.;
2643 pcam->dxc[j + i + 1] = pcam->dxc[j + i ] / 2.;
2644 pcam->dyc[j + i + 1] = sqrt(3.) * pcam->dxc[j + i + 1];
2645 pcam->dpixsizefactor[j + i + 1] = 1.;
2646 pcam->dxc[j + i + 2] = - pcam->dxc[j + i + 1];
2647 pcam->dyc[j + i + 2] = pcam->dyc[j + i + 1];
2648 pcam->dpixsizefactor[j + i+ 2] = 1.;
2649 pcam->dxc[j + i + 3] = - pcam->dxc[j + i];
2650 pcam->dyc[j + i + 3] = dstarty;
2651 pcam->dpixsizefactor[j + i+ 3] = 1.;
2652 pcam->dxc[j + i + 4] = pcam->dxc[j + i + 2];
2653 pcam->dyc[j + i + 4] = - pcam->dyc[j + i + 2];
2654 pcam->dpixsizefactor[j + i+ 4] = 1.;
2655 pcam->dxc[j + i + 5] = pcam->dxc[j + i + 1];
2656 pcam->dyc[j + i + 5] = - pcam->dyc[j + i + 1];
2657 pcam->dpixsizefactor[j + i + 5] = 1.;
2658 } /* end for */
2659 } /* end if */
2660
2661 /* generate positions of the outer pixels */
2662
2663 if( pcam->inumbigpixels > 0 ){
2664
2665 j = pcam->inumcentralpixels + pcam->inumgappixels;
2666
2667 for(i=0; i<pcam->inumbigpixels; i++){
2668 pcam->dpixsizefactor[j + i] = 2.;
2669 }
2670
2671 in = 0;
2672
2673 nrow = (int) ceil(dstartx / 2. / dpsize);
2674
2675 while(in < pcam->inumbigpixels){
2676
2677 pcam->dxc[j + in] = dstartx + dpsize;
2678 pcam->dyc[j + in] = dstarty + 2 * dpsize / sqrt(3.);
2679 pcam->dxc[j + in + nrow] = dstartx / 2. - dpsize / 2.;
2680 pcam->dyc[j + in + nrow] = sqrt(3.)/2. * dstartx + 2.5 * dpsize/sqrt(3.);
2681 pcam->dxc[j + in + 3 * nrow - 1] = - pcam->dxc[j + in];
2682 pcam->dyc[j + in + 3 * nrow - 1] = pcam->dyc[j + in];
2683 pcam->dxc[j + in + 3 * nrow] = - pcam->dxc[j + in];
2684 pcam->dyc[j + in + 3 * nrow] = - pcam->dyc[j + in];
2685 pcam->dxc[j + in + 5 * nrow - 1] = pcam->dxc[j + in + nrow];
2686 pcam->dyc[j + in + 5 * nrow - 1] = - pcam->dyc[j + in + nrow];
2687 pcam->dxc[j + in + 6 * nrow - 1] = pcam->dxc[j + in];
2688 pcam->dyc[j + in + 6 * nrow - 1] = - pcam->dyc[j + in];
2689 for(i=1; i<nrow; i++){
2690 pcam->dxc[j + in + i] = pcam->dxc[j + in] - i * dpsize;
2691 pcam->dyc[j + in + i] = pcam->dyc[j + in] + i * dpsize * sqrt(3.);
2692 pcam->dxc[j + in + i + nrow] = pcam->dxc[j + in + nrow] - i * 2 * dpsize;
2693 pcam->dyc[j + in + i + nrow] = pcam->dyc[j + in + nrow];
2694 pcam->dxc[j + in + 3 * nrow - 1 - i] = - pcam->dxc[j + in + i];
2695 pcam->dyc[j + in + 3 * nrow - 1- i] = pcam->dyc[j + in + i];
2696 pcam->dxc[j + in + i + 3 * nrow] = - pcam->dxc[j + in + i];
2697 pcam->dyc[j + in + i + 3 * nrow] = - pcam->dyc[j + in + i];
2698 pcam->dxc[j + in + 5 * nrow - 1 - i] = pcam->dxc[j + in + i + nrow];
2699 pcam->dyc[j + in + 5 * nrow - 1 - i] = - pcam->dyc[j + in + i + nrow];
2700 pcam->dxc[j + in + 6 * nrow - 1 - i] = pcam->dxc[j + in + i];
2701 pcam->dyc[j + in + 6 * nrow - 1 - i] = - pcam->dyc[j + in + i];
2702 }
2703 in = in + 6 * nrow;
2704 dstartx = dstartx + 2. * dpsize;
2705 nrow = nrow + 1;
2706 } /* end while */
2707
2708 } /* end if */
2709
2710 return(pcam->inumpixels);
2711
2712}
2713//!@}
2714
2715//!-----------------------------------------------------------
2716// @name bpoint_is_in_pix
2717//
2718// @desc check if a point (x,y) in camera coordinates is inside a given pixel
2719//
2720// @var *pcam structure camera containing all the
2721// camera information
2722// @var dx, dy point coordinates in centimeters
2723// @var ipixnum pixel number (starting at 0)
2724// @return TRUE if the point is inside the pixel, FALSE otherwise
2725//
2726// DP
2727//
2728// @date Thu Oct 14 16:59:04 CEST 1999
2729//------------------------------------------------------------
2730// @function
2731
2732//!@{
2733
2734/******** bpoint_is_in_pix() ***************************************/
2735/*
2736int bpoint_is_in_pix(double dx, double dy, int ipixnum, struct camera *pcam){
2737 // return TRUE if point (dx, dy) is in pixel number ipixnum, else return FALSE (use camera coordinate system)
2738 // the pixel is assumed to be a "closed set"
2739
2740 double a, b; // a = length of one of the edges of one pixel, b = half the width of one pixel
2741 double c, xx, yy; // auxiliary variable
2742
2743 b = pcam->dpixdiameter_cm / 2. * pcam->dpixsizefactor[ipixnum];
2744 a = pcam->dpixdiameter_cm / sqrt(3.) * pcam->dpixsizefactor[ipixnum];
2745 c = 1./sqrt(3.);
2746
2747 if((ipixnum < 0)||(ipixnum >= pcam->inumpixels)){
2748 fprintf(stderr, "Error in bpoint_is_in_pix: invalid pixel number %d\n", ipixnum);
2749 fprintf(stderr, "Exiting.\n");
2750 exit(203);
2751 }
2752 xx = dx - pcam->dxc[ipixnum];
2753 yy = dy - pcam->dyc[ipixnum];
2754
2755 if(((-b <= xx) && (xx <= 0.) && ((-c * xx - a) <= yy) && (yy <= ( c * xx + a))) ||
2756 ((0. < xx) && (xx <= b ) && (( c * xx - a) <= yy) && (yy <= (-c * xx + a))) ){
2757 return(TRUE); // point is inside
2758 }
2759 else{
2760 return(FALSE); // point is outside
2761 }
2762}
2763*/
2764
2765#define sqrt13 0.577350269 // = 1./sqrt(3.)
2766#define sqrt3 1.732050807 // = sqrt(3.)
2767
2768int bpoint_is_in_pix(double dx, double dy, struct camera *pcam)
2769{
2770 /* return TRUE if point (dx, dy) is in pixel number ipixnum, else return FALSE (use camera coordinate system) */
2771 /* the pixel is assumed to be a "closed set" */
2772
2773 /*
2774 a = length of one of the edges of one pixel,
2775 b = half the width of one pixel
2776 */
2777
2778 const int num = pcam->inumpixels;
2779 const double diam = pcam->dpixdiameter_cm;
2780
2781 const double diam2 = diam/2;
2782 const double diam3 = diam/sqrt3;
2783
2784 for (int i=0; i<num; i++)
2785 {
2786 const double size = pcam->dpixsizefactor[i];
2787
2788 const double b = diam2 * size;
2789 const double a = diam3 * size;
2790
2791 const double xx = dx - pcam->dxc[i];
2792 const double yy = dy - pcam->dyc[i];
2793
2794 if(((-b <= xx) && (xx <= 0.) && ((-sqrt13 * xx - a) <= yy) && (yy <= ( sqrt13 * xx + a))) ||
2795 ((0. < xx) && (xx <= b ) && (( sqrt13 * xx - a) <= yy) && (yy <= (-sqrt13 * xx + a))) ){
2796
2797 return i; // inside i
2798 }
2799
2800 // return -1; // outside
2801 }
2802 return -1; // outside
2803}
2804
2805//!@}
2806
2807//------------------------------------------------------------
2808// @name dist_r_P
2809//
2810// @desc distance straight line r - point P
2811//
2812// @date Sat Jun 27 05:58:56 MET DST 1998
2813// @function @code
2814//------------------------------------------------------------
2815// dist_r_P
2816//
2817// distance straight line r - point P
2818//------------------------------------------------------------
2819
2820float
2821dist_r_P(float a, float b, float c,
2822 float l, float m, float n,
2823 float x, float y, float z)
2824{
2825 return (
2826 sqrt((SQR((a-x)*m-(b-y)*l) +
2827 SQR((b-y)*n-(c-z)*m) +
2828 SQR((c-z)*l-(a-x)*n))/
2829 (SQR(l)+SQR(m)+SQR(n))
2830 )
2831 );
2832}
2833
2834//------------------------------------------------------------
2835// @name check_reflector_file
2836//
2837// @desc check if a given reflector file has the right signature
2838// @desc return TRUE or FALSE
2839//
2840// @date Mon Feb 14 16:44:21 CET 2000
2841// @function @code
2842//------------------------------------------------------------
2843
2844int check_reflector_file(FILE *infile){
2845
2846 char Signature[20]; // auxiliary variable
2847 char sign[20]; // auxiliary variable
2848
2849 strcpy(Signature, REFL_SIGNATURE);
2850
2851 strcpy(sign, Signature);
2852
2853 fread( (char *)sign, strlen(Signature), 1, infile);
2854
2855 if (strcmp(sign, Signature) != 0) {
2856 cout << "ERROR: Signature of .rfl file is not correct\n";
2857 cout << '"' << sign << '"' << '\n';
2858 cout << "should be: " << Signature << '\n';
2859 return(FALSE);
2860 }
2861
2862 fread( (char *)sign, 1, 1, infile);
2863
2864 return(TRUE);
2865
2866}
2867
2868//------------------------------------------------------------
2869// @name lin_interpol
2870//
2871// @desc interpolate linearly between two points returning the
2872// @desc y-value of the result
2873//
2874// @date Thu Feb 17 11:31:32 CET 2000
2875// @function @code
2876//------------------------------------------------------------
2877
2878float lin_interpol( float x1, float y1, float x2, float y2, float x){
2879
2880 if( (x2 - x1)<=0. ){ // avoid division by zero, return average
2881 cout << "Warning: lin_interpol was asked to interpolate between two points with x1>=x2.\n";
2882 return((y1+y2)/2.);
2883 }
2884 else{ // note: the check whether x1 < x < x2 is omitted for speed reasons
2885 return((float) (y1 + (y2-y1)/(x2-x1)*(x-x1)) );
2886 }
2887}
2888
2889
2890//------------------------------------------------------------
2891// @name produce_phes
2892//
2893// @desc read the photons of an event, pixelize them and simulate QE
2894// @desc return various statistics and the array of Photoelectrons
2895//
2896// @date Mon Feb 14 16:44:21 CET 2000
2897// @function @code
2898//------------------------------------------------------------
2899
2900int produce_phes( FILE *sp, // the input file
2901 struct camera *cam, // the camera layout
2902 float minwl_nm, // the minimum accepted wavelength
2903 float maxwl_nm, // the maximum accepted wavelength
2904 class MTrigger *trigger, // the generated phes
2905 class MFadc *fadc,
2906 int *itotnphe, // total number of produced photoelectrons
2907 float nphe[iMAXNUMPIX], // number of photoelectrons in each pixel
2908 int *incph, // total number of cph read
2909 float *tmin_ns, // minimum arrival time of all phes
2910 float *tmax_ns // maximum arrival time of all phes
2911 ){
2912
2913 static int i, k, ipixnum;
2914 static float cx, cy, wl, qe, t;
2915 static MCCphoton photon;
2916 static float **qept;
2917 static char flag[SIZE_OF_FLAGS + 1];
2918 static float radius;
2919
2920
2921 // reset variables
2922
2923 for ( i=0; i<cam->inumpixels; ++i ){
2924
2925 nphe[i] = 0.0;
2926
2927 }
2928
2929 *incph = 0;
2930
2931 radius = cam->dxc[cam->inumpixels-1]
2932 + 1.5*cam->dpixdiameter_cm*cam->dpixsizefactor[cam->inumpixels-1];
2933
2934 //- - - - - - - - - - - - - - - - - - - - - - - - -
2935 // read photons and "map" them into the pixels
2936 //--------------------------------------------------
2937
2938 // initialize CPhoton
2939
2940 photon.fill(0., 0., 0., 0., 0., 0., 0., 0.);
2941
2942 // read the photons data
2943
2944
2945 // loop over the photons
2946
2947 while (1) {
2948
2949 fread ( flag, SIZE_OF_FLAGS, 1, sp );
2950
2951 if (isA( flag, FLAG_END_OF_EVENT ))
2952 break;
2953
2954 memcpy( (char*)&photon, flag, SIZE_OF_FLAGS );
2955
2956 fread( ((char*)&photon)+SIZE_OF_FLAGS, photon.mysize()-SIZE_OF_FLAGS, 1, sp );
2957
2958 // increase number of photons
2959
2960 (*incph)++;
2961
2962 // Chceck if photon is inside trigger time range
2963
2964 t = photon.get_t() ;
2965
2966 if (t-*tmin_ns>TOTAL_TRIGGER_TIME) {
2967 continue;
2968 }
2969
2970 //
2971 // Pixelization
2972 //
2973
2974 cx = photon.get_x();
2975 cy = photon.get_y();
2976
2977 // get wavelength
2978
2979 wl = photon.get_wl();
2980
2981 // cout << "wl " << wl << " radius " << sqrt(cx*cx + cy*cy) << "\n";
2982
2983 // check if photon has valid wavelength and is inside outermost camera radius
2984
2985 if( (wl > maxwl_nm) || (wl < minwl_nm) || (sqrt(cx*cx + cy*cy) > radius ) ){
2986 continue;
2987
2988 }
2989
2990 ipixnum = bpoint_is_in_pix(cx, cy, cam);
2991
2992 // -1 = the photon is in none of the pixels
2993 // 0 = the phton is in the central pixel, which is not used for trigger
2994 if (ipixnum==-1 || ipixnum==0) {
2995 continue;
2996 }
2997
2998 //+++
2999 // QE simulation
3000 //---
3001
3002 // set pointer to the QE table of the relevant pixel
3003
3004 qept = (float **)QE[ipixnum];
3005
3006 // check if wl is inside table; outside the table, QE is assumed to be zero
3007
3008 if((wl < qept[0][0]) || (wl > qept[0][pointsQE-1])){
3009 continue;
3010
3011 }
3012
3013 // find data point in the QE table (-> k)
3014
3015 k = 1; // start at 1 because the condition was already tested for 0
3016 while (k < pointsQE-1 && qept[0][k] < wl){
3017 k++;
3018 }
3019
3020 // calculate the qe value between 0. and 1.
3021
3022 qe = lin_interpol(qept[0][k-1], qept[1][k-1], qept[0][k], qept[1][k], wl) / 100.0;
3023
3024 // if random > quantum efficiency, reject it
3025
3026 if ( (RandomNumber) > qe ) {
3027 continue;
3028 }
3029
3030 //+++
3031 // The photon has produced a photo electron
3032 //---
3033
3034 // cout << " accepted\n";
3035
3036 // increment the number of photoelectrons in the relevant pixel
3037
3038 nphe[ipixnum] += 1.0;
3039
3040 // store the new photoelectron
3041
3042 fadc->Fill(ipixnum,(t-*tmin_ns) , trigger->FillShow(ipixnum,t-*tmin_ns));
3043
3044 *itotnphe += 1;
3045 }
3046
3047 return(0);
3048
3049}
3050
3051
3052//------------------------------------------------------------
3053// @name produce_nsbrates
3054//
3055// @desc read the starfield file, call produce_phes on it in,
3056// @desc different wavebands, calculate the nsbrates
3057//
3058// @date Mon Feb 14 16:44:21 CET 2000
3059// @function @code
3060//------------------------------------------------------------
3061
3062int produce_nsbrates( char *iname, // the starfield input file name
3063 struct camera *cam, // camera layout
3064 float rate_phepns[iMAXNUMPIX][iNUMWAVEBANDS] // the product of this function:
3065 // the NSB rates in phe/ns for each pixel
3066 ){
3067
3068 int i, j, k, ii; // counters
3069
3070 MTrigger trigger(Trigger_gate_length, Trigger_overlaping_time, Trigger_response_ampl, Trigger_response_fwhm);
3071 MFadc flashadc;
3072
3073 static float wl_nm[iNUMWAVEBANDS + 1] = { WAVEBANDBOUND1,
3074 WAVEBANDBOUND2,
3075 WAVEBANDBOUND3,
3076 WAVEBANDBOUND4,
3077 WAVEBANDBOUND5,
3078 WAVEBANDBOUND6 };
3079
3080 FILE *infile; // the input file
3081 fpos_t fileposition; // marker on the input file
3082 static char cflag[SIZE_OF_FLAGS + 1]; // auxiliary variable
3083 static MCEventHeader evth; // the event header
3084 static float nphe[iMAXNUMPIX]; // the number of photoelectrons in each pixel
3085 int itnphe; // total number of produced photoelectrons
3086 int itotnphe; // total number of produced photoelectrons after averaging
3087 int incph; // total number of cph read
3088 float tmin_ns; // minimum arrival time of all phes
3089 float tmax_ns; // maximum arrival time of all phes
3090 float integtime_ns; // integration time from the starfield generator
3091
3092 // open input file
3093
3094 log(SIGNATURE, "Opening starfield input \"rfl\" file %s\n", iname );
3095
3096 infile = fopen( iname, "r" );
3097
3098 // check if the satrfield input file exists
3099
3100 if ( infile == NULL ) {
3101
3102 log( SIGNATURE, "Cannot open starfield input file: %s\n", iname );
3103
3104 log( SIGNATURE, "There is not NSB from the Stars\n");
3105
3106 return (0);
3107 }
3108
3109 // get signature, and check it
3110
3111 if(check_reflector_file(infile)==FALSE){
3112 exit(1);
3113 }
3114
3115 // initialize flag
3116
3117 strcpy( cflag, " \0" );
3118
3119 // get flag
3120
3121 fread( cflag, SIZE_OF_FLAGS, 1, infile );
3122
3123 if ( ! feof(infile)){
3124
3125 // reading .rfl file
3126
3127 if(!isA( cflag, FLAG_START_OF_RUN )){
3128 error( SIGNATURE, "Expected start of run flag, but found: %s\n", cflag );
3129 }
3130 else { // found start of run
3131
3132 fread( cflag, SIZE_OF_FLAGS, 1, infile );
3133
3134 if( isA( cflag, FLAG_START_OF_EVENT )){ // there is a event
3135
3136 // get MCEventHeader
3137
3138 fread( (char*)&evth, evth.mysize(), 1, infile );
3139
3140 integtime_ns = evth.get_energy();
3141
3142 // memorize where we are in the file
3143
3144 if (fgetpos( infile, &fileposition ) != 0){
3145 error( SIGNATURE, "Cannot position in file ...\n");
3146 }
3147
3148 // loop over the wavebands
3149
3150 for(i=0; i<iNUMWAVEBANDS; i++){
3151
3152 // initialize the rate array
3153
3154 for(j = 0; j<cam->inumpixels; j++){ // loop over pixels
3155 rate_phepns[j][i] = 0.;
3156 }
3157
3158 itotnphe = 0;
3159
3160 // read the photons and produce the photoelectrons
3161 // - in order to average over the QE simulation, call the
3162 // production function iNUMNSBPRODCALLS times
3163
3164 for(ii=0; ii<iNUMNSBPRODCALLS; ii++){
3165
3166 // position the file pointer to the beginning of the photons
3167
3168 fsetpos( infile, &fileposition);
3169
3170 // produce photoelectrons
3171
3172 k = produce_phes( infile,
3173 cam,
3174 wl_nm[i],
3175 wl_nm[i+1],
3176 &trigger, // this is a dummy here
3177 &flashadc, // this is a dummy here
3178 &itnphe,
3179 nphe, // we want this!
3180 &incph,
3181 &tmin_ns,
3182 &tmax_ns );
3183
3184 if( k != 0 ){ // non-zero returnvalue means error
3185 cout << "Exiting.\n";
3186 exit(1);
3187 }
3188
3189 for(j = 0; j<cam->inumpixels; j++){ // loop over pixels
3190 rate_phepns[j][i] += nphe[j]/integtime_ns/(float)iNUMNSBPRODCALLS;
3191 }
3192
3193 itotnphe += itnphe;
3194
3195 } // end for(ii=0 ...
3196
3197 fprintf(stdout, "Starfield, %6f - %6f nm: %d photoelectrons for %6f ns integration time\n",
3198 wl_nm[i], wl_nm[i+1], itotnphe/iNUMNSBPRODCALLS, integtime_ns);
3199
3200 } // end for(i=0 ...
3201
3202 }
3203 else{
3204 cout << "Starfield file contains no event.\nExiting.\n";
3205 exit(1);
3206 } // end if( isA ... event
3207 } // end if ( isA ... run
3208 }
3209 else{
3210 cout << "Starfield file contains no run.\nExiting.\n";
3211 exit(1);
3212 }
3213
3214 fclose( infile );
3215
3216 return(0);
3217
3218}
3219
3220
3221//------------------------------------------------------------
3222// @name produce_nsb_phes
3223//
3224// @desc produce the photoelectrons from the nsbrates
3225//
3226// @date Thu Feb 17 17:10:40 CET 2000
3227// @function @code
3228//------------------------------------------------------------
3229
3230int produce_nsb_phes( float *atmin_ns,
3231 float *atmax_ns,
3232 float theta_rad,
3233 struct camera *cam,
3234 float nsbr_phepns[iMAXNUMPIX][iNUMWAVEBANDS],
3235 float difnsbr_phepns[iMAXNUMPIX],
3236 float extinction[iNUMWAVEBANDS],
3237 float fnpx[iMAXNUMPIX],
3238 MTrigger *trigger,
3239 MFadc *fadc,
3240 int *inphe,
3241 float base_mv[iMAXNUMPIX]){
3242
3243 float simtime_ns; // NSB simulation time
3244 int i, j, k, ii;
3245 float zenfactor; // correction factor calculated from the extinction
3246 int inumnsbphe; // number of photoelectrons caused by NSB
3247
3248 float t;
3249 TRandom random; // Random numbers generator
3250
3251 random.SetSeed ((UInt_t) (RandomNumber*1000));
3252
3253 ii = *inphe; // avoid dereferencing
3254
3255 // check if the arrival times are set; if not generate them
3256
3257 if(*atmin_ns <SIMTIMEOFFSET_NS || *atmin_ns > *atmax_ns){
3258 *atmin_ns = 0.;
3259 *atmax_ns = simtime_ns = TOTAL_TRIGGER_TIME;
3260
3261 }
3262 else{ // extend the event time window by the given offsets
3263
3264 *atmin_ns = *atmin_ns - SIMTIMEOFFSET_NS;
3265 *atmax_ns = *atmax_ns + SIMTIMEOFFSET_NS;
3266
3267 simtime_ns = *atmax_ns - *atmin_ns;
3268
3269 // make sure the simulated time is long enough for the FADC
3270 // simulation and not too long
3271
3272 if(simtime_ns< TOTAL_TRIGGER_TIME){
3273 *atmin_ns = *atmin_ns -(TOTAL_TRIGGER_TIME-simtime_ns)/2;
3274 *atmax_ns = *atmin_ns + TOTAL_TRIGGER_TIME;
3275 simtime_ns = TOTAL_TRIGGER_TIME;
3276 }
3277
3278 if(simtime_ns> TOTAL_TRIGGER_TIME){
3279 *atmax_ns =*atmin_ns + TOTAL_TRIGGER_TIME;
3280 simtime_ns = TOTAL_TRIGGER_TIME;
3281 }
3282
3283 }
3284
3285 // initialize baselines
3286
3287 for(i=0; i<cam->inumpixels; i++){
3288 base_mv[i] = 0.;
3289 }
3290
3291 // calculate baselines and generate phes
3292
3293 for(i=0; i<iNUMWAVEBANDS; i++){ // loop over the wavebands
3294
3295 // calculate the effect of the atmospheric extinction
3296
3297 zenfactor = pow(10., -0.4 * extinction[i]/cos(theta_rad) );
3298
3299 for(j=0; j<cam->inumpixels; j++){ // loop over the pixels
3300
3301 inumnsbphe = (int) ((zenfactor * nsbr_phepns[j][i] + difnsbr_phepns[j]/iNUMWAVEBANDS)
3302 * simtime_ns );
3303
3304 base_mv[j] += inumnsbphe;
3305
3306 // randomize
3307
3308 if (inumnsbphe>0.0){
3309 inumnsbphe = random.Poisson (inumnsbphe );
3310 }
3311
3312 // create the photoelectrons
3313
3314 for(k=0; k < inumnsbphe; k++){
3315
3316 t=(RandomNumber * simtime_ns);
3317
3318 (*fadc).Fill(j,t ,(*trigger).FillNSB(j,t));
3319
3320 ii++; // increment total number of photoelectons
3321
3322 fnpx[j] += 1.; // increment number of photoelectrons in this pixel
3323
3324 }
3325
3326 } // end for(j=0 ...
3327 } // end for(i=0 ...
3328
3329 // finish baseline calculation
3330
3331 for(i=0; i<cam->inumpixels; i++){
3332 base_mv[i] *= RESPONSE_FWHM * RESPONSE_AMPLITUDE / simtime_ns;
3333 }
3334
3335 *inphe = ii; // update the pointer
3336
3337 return(0);
3338}
3339
3340
3341// @endcode
3342
3343
3344//=------------------------------------------------------------
3345//!@subsection Log of this file.
3346
3347//!@{
3348//
3349// $Log: not supported by cvs2svn $
3350// Revision 1.31 2002/01/18 17:41:02 blanch
3351// The option of adding noise to all pixels or to not adding the noise
3352// has been added.
3353// We removed the pixels larger than 577. When there were more than one
3354// trigger in one shower, the pixel number was increasing. Now it is
3355// flagged by the variable MMcTrig::fFirstLvlTrig.
3356//
3357// Revision 1.30 2001/11/27 09:49:54 blanch
3358// Fixing bug which was treating wrongly the extension of star photons.
3359//
3360// Revision 1.29 2001/11/14 17:38:23 blanch
3361// Sveral changes have been done:
3362// - bpoint_in_in_pixel has been dodified to speed up the program
3363// - Some minor changes have been done to remove warnings
3364// - buffer size and split version of the Branches have been removed
3365// - Some modifications were needed to adat the program to the new
3366// MRawEvtData::DeletePixels
3367//
3368// Revision 1.28 2001/10/26 16:31:45 blanch
3369// Removing several warnings.
3370//
3371// Revision 1.27 2001/09/05 10:04:33 blanch
3372// *** empty log message ***
3373//
3374// Revision 1.26 2001/07/19 09:29:53 blanch
3375// Different threshold for each pixel can be used.
3376//
3377// Revision 1.25 2001/05/08 08:07:54 blanch
3378// New numbering for branches from different trigger conditions has been
3379// implemented. Now, they are calles: ClassName;1., ClasNema;2., ...
3380// The MontaCarlo Headers (MMcTrigHeader and MMcFadcHeader) have been move to
3381// the RunHeaders tree. Also the MRawRunHeader is thera with some of its
3382// information already filled.
3383//
3384// Revision 1.24 2001/04/06 16:48:09 magicsol
3385// New camera version able to read the new format of the reflector output:
3386// reflector 0.4
3387//
3388// Revision 1.23 2001/03/28 16:13:41 blanch
3389// While feeling the MMcFadeHeader branch the boolean conditoin was wrong. It has
3390// been solved.
3391//
3392// Revision 1.22 2001/03/20 18:52:43 blanch
3393// *** empty log message ***
3394//
3395// Revision 1.21 2001/03/19 19:53:03 blanch
3396// Some print outs have been removed.
3397//
3398// Revision 1.20 2001/03/19 19:30:06 magicsol
3399// Minor changes have been done to improve the FADC pedestals treatment.
3400//
3401// Revision 1.19 2001/03/05 11:14:41 magicsol
3402// I changed the position of readinf a parameter. It is a minnor change.
3403//
3404// Revision 1.18 2001/03/05 10:36:52 blanch
3405// A branch with information about the FADC simulation (MMcFadcHeader) is writen
3406// in the McHeaders tree of the aoutput root file.
3407// The NSB contribution is only applied if the the number of phe form the shower
3408// are above a given number.
3409//
3410// Revision 1.17 2001/02/23 11:05:57 magicsol
3411// Small changes due to slightly different output format and the introduction of
3412// pedesals for teh FADC.
3413//
3414// Revision 1.16 2001/01/18 18:44:40 magicsol
3415// *** empty log message ***
3416//
3417// Revision 1.15 2001/01/17 09:32:27 harald
3418// The changes are neccessary to have the same name for trees in MC and in
3419// data. So now there should be no differences in MC data and real data from
3420// FADC system.
3421//
3422// Revision 1.14 2001/01/15 12:33:34 magicsol
3423// Some modifications have been done to use the new (Dec'2000) Raw data format.
3424// There are also some minnors modifications to adapt the improvements in the
3425// MTrigger class (overlaping time and trigger cells).
3426//
3427// Revision 1.13 2000/10/25 08:14:23 magicsol
3428// The routine that produce poisson random numbers to decide how many phe
3429// form NSB are emmited in each pixel has been replaced. Now a ROOT routine
3430// is used.
3431//
3432// Revision 1.12 2000/09/22 17:40:18 harald
3433// Added a lot of changes done by oscar.
3434//
3435// Revision 1.11 2000/09/21 11:47:33 harald
3436// Oscar found some smaller errors in the calculation of the pixel shape and
3437// corrected it.
3438//
3439// $Log: not supported by cvs2svn $
3440// Revision 1.31 2002/01/18 17:41:02 blanch
3441// The option of adding noise to all pixels or to not adding the noise
3442// has been added.
3443// We removed the pixels larger than 577. When there were more than one
3444// trigger in one shower, the pixel number was increasing. Now it is
3445// flagged by the variable MMcTrig::fFirstLvlTrig.
3446//
3447// Revision 1.30 2001/11/27 09:49:54 blanch
3448// Fixing bug which was treating wrongly the extension of star photons.
3449//
3450// Revision 1.29 2001/11/14 17:38:23 blanch
3451// Sveral changes have been done:
3452// - bpoint_in_in_pixel has been dodified to speed up the program
3453// - Some minor changes have been done to remove warnings
3454// - buffer size and split version of the Branches have been removed
3455// - Some modifications were needed to adat the program to the new
3456// MRawEvtData::DeletePixels
3457//
3458// Revision 1.28 2001/10/26 16:31:45 blanch
3459// Removing several warnings.
3460//
3461// Revision 1.27 2001/09/05 10:04:33 blanch
3462// *** empty log message ***
3463//
3464// Revision 1.26 2001/07/19 09:29:53 blanch
3465// Different threshold for each pixel can be used.
3466//
3467// Revision 1.25 2001/05/08 08:07:54 blanch
3468// New numbering for branches from different trigger conditions has been
3469// implemented. Now, they are calles: ClassName;1., ClasNema;2., ...
3470// The MontaCarlo Headers (MMcTrigHeader and MMcFadcHeader) have been move to
3471// the RunHeaders tree. Also the MRawRunHeader is thera with some of its
3472// information already filled.
3473//
3474// Revision 1.24 2001/04/06 16:48:09 magicsol
3475// New camera version able to read the new format of the reflector output:
3476// reflector 0.4
3477//
3478// Revision 1.23 2001/03/28 16:13:41 blanch
3479// While feeling the MMcFadeHeader branch the boolean conditoin was wrong. It has
3480// been solved.
3481//
3482// Revision 1.22 2001/03/20 18:52:43 blanch
3483// *** empty log message ***
3484//
3485// Revision 1.21 2001/03/19 19:53:03 blanch
3486// Some print outs have been removed.
3487//
3488// Revision 1.20 2001/03/19 19:30:06 magicsol
3489// Minor changes have been done to improve the FADC pedestals treatment.
3490//
3491// Revision 1.19 2001/03/05 11:14:41 magicsol
3492// I changed the position of readinf a parameter. It is a minnor change.
3493//
3494// Revision 1.18 2001/03/05 10:36:52 blanch
3495// A branch with information about the FADC simulation (MMcFadcHeader) is writen
3496// in the McHeaders tree of the aoutput root file.
3497// The NSB contribution is only applied if the the number of phe form the shower
3498// are above a given number.
3499//
3500// Revision 1.17 2001/02/23 11:05:57 magicsol
3501// Small changes due to slightly different output format and the introduction of
3502// pedesals for teh FADC.
3503//
3504// Revision 1.16 2001/01/18 18:44:40 magicsol
3505// *** empty log message ***
3506//
3507// Revision 1.15 2001/01/17 09:32:27 harald
3508// The changes are neccessary to have the same name for trees in MC and in
3509// data. So now there should be no differences in MC data and real data from
3510// FADC system.
3511//
3512// Revision 1.14 2001/01/15 12:33:34 magicsol
3513// Some modifications have been done to use the new (Dec'2000) Raw data format.
3514// There are also some minnors modifications to adapt the improvements in the
3515// MTrigger class (overlaping time and trigger cells).
3516//
3517// Revision 1.13 2000/10/25 08:14:23 magicsol
3518// The routine that produce poisson random numbers to decide how many phe
3519// form NSB are emmited in each pixel has been replaced. Now a ROOT routine
3520// is used.
3521//
3522// Revision 1.10 2000/07/04 14:10:20 MagicSol
3523// Some changes have been done in the root output file. The RawEvt tree is only
3524// stored in the single trigger mode.
3525// The trigger input parameters are also given by the general input card.
3526// The diffuse NSB and the star NSB have been decoupled. Now the contribution of
3527// each one can be studied seperately.
3528//
3529// Revision 1.9 2000/06/13 13:25:24 blanch
3530// The multiple arrays have been replaced, since they do not work
3531// in alpha machines. Now we are using pointers and the command new
3532// to allocate memory.
3533//
3534// Revision 1.8 2000/05/11 13:57:27 blanch
3535// The option to loop over several trigger configurations has been included.
3536// Some non-sense with triggertime range has been solved.
3537// Montecarlo information and ADC counts are saved in a root file.
3538// There was a problem with the maximum number of phe that the program could analyse. Now there is not limit.
3539//
3540// Revision 1.7 2000/03/24 18:10:46 blanch
3541// A first FADC simulation and a trigger simulation are already implemented.
3542// The calculation of the Hillas Parameters have been removed, since it was decided that it should be in the analysis software.
3543// A loop over trigger threshold and some corretcions in the time range where it looks for a trigger will be implemented as soon as possible.
3544//
3545// Revision 1.6 2000/03/20 18:35:11 blanch
3546// The trigger is already implemented but it does not save the trigger information in any file as it is implemented in timecam. In the next days there will be a version which also creates the files with the trigger information. It is going to be a mixing of the current camera and timecam programs.
3547//
3548// Revision 1.5 2000/02/18 17:40:35 petry
3549// This version includes drastic changes compared to camera.cxx 1.4.
3550// It is not yet finished and not immediately useful because the
3551// trigger simulation is not yet re-implemented. I had to take it
3552// out together with some other stuff in order to tidy the whole
3553// program up. This is not meant as an insult to anyone. I needed
3554// to do this in order to be able to work on it.
3555//
3556// This version has been put in the repository in order to be
3557// able to share the further development with others.
3558//
3559// If you need something working, wait or take an earlier one.
3560// See file README.
3561//
3562// Revision 1.4 2000/01/25 08:36:23 petry
3563// The pixelization in previous versions was buggy.
3564// This is the first version with a correct pixelization.
3565//
3566// Revision 1.3 2000/01/20 18:22:17 petry
3567// Found little bug which makes camera crash if it finds a photon
3568// of invalid wavelength. This bug is now fixed and the range
3569// of valid wavelengths extended to 290 - 800 nm.
3570// This is in preparation for the NSB simulation to come.
3571// Dirk
3572//
3573// Revision 1.2 1999/11/19 08:40:42 harald
3574// Now it is possible to compile the camera programm under osf1.
3575//
3576// Revision 1.1.1.1 1999/11/05 11:59:31 harald
3577// This the starting point for CVS controlled further developments of the
3578// camera program. The program was originally written by Jose Carlos.
3579// But here you can find a "rootified" version to the program. This means
3580// that there is no hbook stuff in it now. Also the output of the
3581// program changed to the MagicRawDataFormat.
3582//
3583// The "rootification" was done by Dirk Petry and Harald Kornmayer.
3584//
3585// Revision 1.3 1999/10/22 15:01:28 petry
3586// version sent to H.K. and N.M. on Fri Oct 22 1999
3587//
3588// Revision 1.2 1999/10/22 09:44:23 petry
3589// first synthesized version which compiles and runs without crashing;
3590//
3591// Revision 1.1.1.1 1999/10/21 16:35:10 petry
3592// first synthesised version
3593//
3594// Revision 1.13 1999/03/15 14:59:05 gonzalez
3595// camera-1_1
3596//
3597// Revision 1.12 1999/03/02 09:56:10 gonzalez
3598// *** empty log message ***
3599//
3600//
3601//!@}
3602
3603//=EOF
Note: See TracBrowser for help on using the repository browser.