Changeset 5072 for trunk/MagicSoft/Simulation/Detector/Camera/camera.cxx
- Timestamp:
- 09/16/04 16:16:34 (20 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/MagicSoft/Simulation/Detector/Camera/camera.cxx
r3044 r5072 21 21 // 22 22 // $RCSfile: camera.cxx,v $ 23 // $Revision: 1.6 8$24 // $Author: blanch$25 // $Date: 2004-0 2-06 17:39:24 $23 // $Revision: 1.69 $ 24 // $Author: moralejo $ 25 // $Date: 2004-09-16 15:16:34 $ 26 26 // 27 27 //////////////////////////////////////////////////////////////////////// … … 84 84 #include "MGeomCamCT1Daniel.h" 85 85 #include "MGeomPix.h" 86 #include "MGeomCorsikaCT.h" 86 87 87 88 /*!@" … … 151 152 static int ct_Number; 152 153 153 //@: Camera geometries154 static int ct_Geometry;155 156 154 //@: list of showers to be skipped 157 155 static int *Skip; … … 200 198 201 199 //@: Properties of the FADC 202 static float FADC_response_ampl = MFADC_RESPONSE_INTEGRAL; 200 static int FADC_shape = 0; 201 static float FADC_response_integ = MFADC_RESPONSE_INTEGRAL; 203 202 static float FADC_response_fwhm = MFADC_RESPONSE_FWHM; 204 static float FADC_resp_ampl_out = MFADC_RESPONSE_INTEGRAL; 203 static int FADC_shape_out = 0; 204 static float FADC_resp_integ_out = MFADC_RESPONSE_INTEGRAL; 205 205 static float FADC_resp_fwhm_out = MFADC_RESPONSE_FWHM; 206 static float FADC_noise = 2.0; 206 static float FADC_noise_inner = 2.0; 207 static float FADC_noise_outer = 2.0; 207 208 static float DIGITAL_noise = 2.0; 208 209 static float FADC_high2low = HIGH2LOWGAIN; … … 210 211 //@: Trigger conditions for a single trigger mode 211 212 static float **qThreshold; 212 static int Trigger_multiplicity[ 100];213 static int Trigger_topology[ 100];213 static int Trigger_multiplicity[MAX_NUMBER_OF_CTS]; 214 static int Trigger_topology[MAX_NUMBER_OF_CTS]; 214 215 215 216 //@: Upper and lower edges of the trigger loop … … 222 223 static int Trigger_loop_utop = 2; 223 224 225 //@: Direction of each shower 226 static float Zenith = 0.0; 227 static float Azimutal = 90.0; 228 229 //@: Miss Pointing Simulation 230 static int missPointing = 0; 231 static float missP_x = 0.0; 232 static float missP_y = 0.0; 233 234 //@: Point Spread Function Added 235 static float Spot_x=0.0; 236 static float Spot_y=0.0; 237 static float Spotsigma=0.0; 238 239 224 240 //!@} 225 241 … … 259 275 260 276 //@: number of datapoints for the QE curve 261 static int pointsQE[ 100];277 static int pointsQE[MAX_NUMBER_OF_CTS]; 262 278 263 279 //@: table of QE 264 280 static float *QElambda; 265 281 266 //@: table of lightguide = WC; 282 //@: table of lightguide = WC; WC_outer for outer pixels. 267 283 static float **WC; 284 static float **WC_outer; 268 285 269 286 //@: number of datapoints for the WC curve … … 313 330 //@' 314 331 315 char inname_CT[100][256]; //@< array of names for each CT input file332 char **inname_CT; //@< array of names for each CT input file 316 333 char starfieldname[256]; //@< starfield input file name 317 334 char qe_filename[256]; //@< qe input file name … … 328 345 329 346 char flag[SIZE_OF_FLAGS + 1]; //@< flags in the .rfl file 330 char flag_new[SIZE_OF_FLAGS + 1]; 331 char GeometryName[100][50];//@< Name of MGeomCam for each CT332 int GeometryCamera[ 100];//@< Identification of MGeomCam for each CT333 int TriggerPixels[ 100];//@< Number of pixels in the trigger region for each CT347 char flag_new[SIZE_OF_FLAGS + 1]; //@< New flag for the run header in the .rfl file 348 char **GeometryName; //@< Name of MGeomCam for each CT 349 int GeometryCamera[MAX_NUMBER_OF_CTS]; //@< Identification of MGeomCam for each CT 350 int TriggerPixels[MAX_NUMBER_OF_CTS]; //@< Number of pixels in the trigger region for each CT 334 351 335 352 int reflector_file_version=0; //@< vrsion of he reflector file 336 353 337 FILE *inputfile[ 100];//@< stream for the input file354 FILE *inputfile[MAX_NUMBER_OF_CTS]; //@< stream for the input file 338 355 339 356 ofstream datafile; //@< stream for the data file 340 357 341 358 MCRunHeader mcrunh; //@< Run Header class (MC) 342 MCEventHeader mcevth[ 100];//@< Event Header class (MC)343 MCEventHeader_2 mcevth_2[ 100]; //@< Event Header class (MC) for reflector > 0.6359 MCEventHeader mcevth[MAX_NUMBER_OF_CTS]; //@< Event Header class (MC) 360 MCEventHeader_2 mcevth_2[MAX_NUMBER_OF_CTS]; //@< Event Header class (MC) for reflector > 0.6 344 361 MCCphoton cphoton; //@< Cherenkov Photon class (MC) 345 362 346 363 int inumphe; //@< number of photoelectrons in an event from showers 347 int inumphe_CT[ 100];//@< number of photoelectrons in an event from showers348 float inumphensb[ 100];//@< number of photoelectrons in an event from nsb364 int inumphe_CT[MAX_NUMBER_OF_CTS]; //@< number of photoelectrons in an event from showers 365 float inumphensb[MAX_NUMBER_OF_CTS]; //@< number of photoelectrons in an event from nsb 349 366 350 367 float arrtmin_ns; //@ arrival time of the first photoelectron 351 368 float arrtmax_ns; //@ arrival time of the last photoelectron 352 369 353 float thetaCT[100], phiCT[100]; //@< parameters of a given shower 370 float thetaCT[MAX_NUMBER_OF_CTS], phiCT[MAX_NUMBER_OF_CTS]; //@< theta and phi of telescopes 371 372 //@: Coordinates of telescopes in Corsika's coordinate system 373 float CTx[MAX_NUMBER_OF_CTS]; 374 float CTy[MAX_NUMBER_OF_CTS]; 375 float CTz[MAX_NUMBER_OF_CTS]; 376 377 float mirror_frac[MAX_NUMBER_OF_CTS]; 378 354 379 float thetashw, phishw; //@< parameters of a given shower 355 380 float coreX, coreY; //@< core position 356 float impactD[ 100];//@< impact parameter381 float impactD[MAX_NUMBER_OF_CTS]; //@< impact parameter 357 382 float l1, m1, n1; //@< auxiliary variables 358 float l2, m2, n2; //@< auxiliary variables 359 float num, den; //@< auxiliary variables 360 float factorqe_NSB[100]; //@< factor on the NSB depending of QE 383 float factorqe_NSB[MAX_NUMBER_OF_CTS]; //@< factor on the NSB depending of QE 361 384 362 385 int nshow=0; //@< partial number of shower in a given run 363 386 int ntshow=0; //@< total number of showers 364 int ncph[ 100];//@< partial number of photons in a given run365 int ntcph[ 100];//@< total number of photons387 int ncph[MAX_NUMBER_OF_CTS]; //@< partial number of photons in a given run 388 int ntcph[MAX_NUMBER_OF_CTS]; //@< total number of photons 366 389 367 390 int ibr, j, k; //@< simple counters … … 375 398 int nphe2NSB; //@< From how many phe will we simulate NSB? 376 399 float meanNSB; //@< diffuse NSB mean value (phe per ns per central pixel) 377 float diffnsb_phepns[100][iMAXNUMPIX]; //@< diffuse NSB values for each pixel 378 //@< derived from meanNSB 379 float nsbrate_phepns[iMAXNUMPIX][iNUMWAVEBANDS]; //@< non-diffuse nsb 380 //@< photoelectron rates 381 float nsb_phepns[100][iMAXNUMPIX]; //@< NSB values for each pixel 382 float nsb_phepns_rotated[100][iMAXNUMPIX]; //@< NSB values for each pixel after rotation 400 float **diffnsb_phepns; 401 //@< diffuse NSB values for each pixel derived from meanNSB 402 403 float **nsbrate_phepns; //@< non-diffuse nsb 404 //@< photoelectron rates 405 float **nsb_phepns; 406 //@< NSB values for each pixel 407 408 float **nsb_phepns_rotated; 409 //@< NSB values for each pixel after rotation 383 410 384 411 Float_t nsb_trigresp[TRIGGER_TIME_SLICES]; //@< array to write the trigger … … 406 433 int flagstoring = 0; 407 434 408 int ntrigger[ 100];//@< number of triggers in the whole file435 int ntrigger[MAX_NUMBER_OF_CTS]; //@< number of triggers in the whole file 409 436 int btrigger = 0; //@< trigger flag 410 437 int ithrescount; //@< counter for loop over threshold trigger … … 435 462 Float_t telestheta = 0.0; 436 463 Float_t telesphi = 0.0; 437 Float_t sofftheta = 0.0;438 Float_t soffphi = 0.0;439 464 UInt_t corsika = 5200 ; 440 465 Float_t maxpimpact = 0.0; … … 453 478 //@' 454 479 455 qThreshold = new float *[100]; 456 for(int i=0;i<100;i++) 480 inname_CT = new char *[MAX_NUMBER_OF_CTS]; 481 GeometryName = new char *[MAX_NUMBER_OF_CTS]; 482 diffnsb_phepns = new float *[MAX_NUMBER_OF_CTS]; 483 nsb_phepns = new float *[MAX_NUMBER_OF_CTS]; 484 nsb_phepns_rotated = new float *[MAX_NUMBER_OF_CTS]; 485 486 for(int i=0;i<MAX_NUMBER_OF_CTS;i++) 487 { 488 inname_CT[i] = new char[256]; 489 GeometryName[i] = new char[50]; 490 diffnsb_phepns[i] = new float[iMAXNUMPIX]; 491 nsb_phepns[i] = new float[iMAXNUMPIX]; 492 nsb_phepns_rotated[i] = new float[iMAXNUMPIX]; 493 CTx[i] = 0.; CTy[i] = 0.; CTz[i] = 0.; 494 } 495 496 nsbrate_phepns = new float *[iMAXNUMPIX]; 497 for(int i=0;i<iMAXNUMPIX;i++) 498 nsbrate_phepns[i] = new float[iNUMWAVEBANDS]; 499 500 qThreshold = new float *[MAX_NUMBER_OF_CTS]; 501 for(int i=0;i<MAX_NUMBER_OF_CTS;i++) 457 502 qThreshold[i] = new float [CAMERA_PIXELS]; 458 503 459 504 for(int i=0;i<iMAXNUMPIX;i++){ 460 for(int ict=0;ict< 100;ict++){505 for(int ict=0;ict<MAX_NUMBER_OF_CTS;ict++){ 461 506 nsb_phepns[ict][i]=0; 462 507 nsb_phepns_rotated[ict][i]=0; … … 465 510 nsbrate_phepns[i][j]=0.0; //@< Starlight rates initialised at 0.0 466 511 } 467 for(int i=0;i< 100;i++)512 for(int i=0;i<MAX_NUMBER_OF_CTS;i++) 468 513 ntcph[i]=0; 469 514 /*!@' … … 527 572 528 573 ct_Number=get_ct_number(); 529 ct_Geometry=get_ct_geometry(); 574 if (ct_Number > MAX_NUMBER_OF_CTS) 575 { 576 error( SIGNATURE, "Number of telescopes is larger than maximum allowed (%i). Stoping camera program ...", MAX_NUMBER_OF_CTS); 577 exit(1); 578 } 530 579 531 580 for(int ict=0;ict<ct_Number;ict++){ 532 581 ntrigger[ict]=0; 533 if(ct_Geometry>=ict*10){ 534 GeometryCamera[ict]=int(ct_Geometry/pow(10.0,ict))%10; 535 } 536 else 537 GeometryCamera[ict]=0; 582 GeometryCamera[ict]=get_ct_geometry(ict); 583 584 // 585 // Get telescope coordinates (if supplied) from input card (units cm). 586 // 587 CTx[ict] = get_telescope_location_cm(ict,0); 588 CTy[ict] = get_telescope_location_cm(ict,1); 589 CTz[ict] = get_telescope_location_cm(ict,2); 590 591 // 592 // Get fraction of operative mirror: 593 // 594 mirror_frac[ict] = get_mirror_fraction(ict); 538 595 } 539 596 … … 615 672 get_secure_threhold(&riseDiskThres,&secureDiskThres); 616 673 617 get_FADC_properties( &FADC_response_ampl, &FADC_response_fwhm, 618 &FADC_resp_ampl_out, &FADC_resp_fwhm_out); 674 get_FADC_properties 675 (&FADC_shape, &FADC_response_integ, &FADC_response_fwhm, 676 &FADC_shape_out, &FADC_resp_integ_out, &FADC_resp_fwhm_out); 677 619 678 FADC_high2low=get_High_to_Low(); 620 679 621 // FIXME --- t irgger properties may depend on the Camrea geometry680 // FIXME --- trigger properties may depend on the Camera geometry 622 681 623 682 get_Trigger_properties( &Trigger_gate_length, &Trigger_overlaping_time, &Trigger_response_ampl, &Trigger_response_fwhm); … … 630 689 (Trigger_loop_utop-Trigger_loop_ltop+1); 631 690 632 // Trigger loop operation is not implemented for Multi tel scopes691 // Trigger loop operation is not implemented for Multi telescopes 633 692 634 693 if ( Trigger_Loop && ct_Number > 1 ){ … … 651 710 652 711 for(int ict=0;ict<ct_Number;ict++) 653 strcpy( inname_CT[ict], get_input_filename(ict) ); 712 { 713 strcpy( inname_CT[ict], get_input_filename(ict) ); 714 if (strlen(inname_CT[ict]) == 0) 715 { 716 printf("\nError: missing input file name for CT id = %d. Exiting.\n\n", ict); 717 exit(1); 718 } 719 } 654 720 655 721 strcpy( starfieldname, get_starfield_filename() ); … … 662 728 // get different parameters of the simulation 663 729 664 addElecNoise = add_elec_noise(&FADC_noise , &DIGITAL_noise, &Trigger_noise);730 addElecNoise = add_elec_noise(&FADC_noise_inner, &FADC_noise_outer, &DIGITAL_noise, &Trigger_noise); 665 731 simulateNSB = get_nsb( &meanNSB, &nphe2NSB ); 732 missPointing = get_misspointing(&missP_x,&missP_y); 733 Spotsigma = get_sigma_xy_cm_spot(&Spot_x,&Spot_y); 666 734 667 735 … … 681 749 "Geometry ", GeometryName[ict]); 682 750 strcpy( qe_filename, get_qe_filename(ict)); 751 752 printf("Telescope coordinates (cm): %.1f %.1f %.1f\n", CTx[ict], CTy[ict], CTz[ict]); 683 753 684 754 // Look to factor for NSB respect to emi_coat PMTs … … 748 818 749 819 log(SIGNATURE, 750 "%s:\n\t%20s: %s\n\t%20s: %s\n\t%20s: %s\n\t%20s: % 3.2f(%s) %3.2f+%3.2f(%s) %s\n",820 "%s:\n\t%20s: %s\n\t%20s: %s\n\t%20s: %s\n\t%20s: %s %3.2f, %s %3.2f (%s), %3.2f (%s) + %3.2f (%s) %s\n", 751 821 "Flags", 752 822 "Data_From_STDIN", ONoff(Data_From_STDIN), 753 823 "Write_All_Events", ONoff(Write_All_Images), 754 824 "Rotate Starfield", ONoff(Starfield_rotate), 755 "Electronic Noise", Trigger_noise,"trigger", 756 FADC_noise,DIGITAL_noise,"fadc",ONoff(addElecNoise) 825 "Electronic Noise", "trigger (rel. noise): ", Trigger_noise, 826 "FADC (ADC counts): ", FADC_noise_inner, "inner pixels", 827 FADC_noise_outer, "outer pixels", 828 DIGITAL_noise, "added digital noise at FADC", ONoff(addElecNoise) 757 829 ); 758 830 … … 779 851 780 852 ntriggerloop= new int ** [(int)((Trigger_loop_uthres-Trigger_loop_lthres) 781 /Trigger_loop_sthres) ];853 /Trigger_loop_sthres)+1]; 782 854 for (ithrescount=0, fthrescount=Trigger_loop_lthres;fthrescount<=Trigger_loop_uthres;fthrescount+=Trigger_loop_sthres, ithrescount++){ 783 855 ntriggerloop[ithrescount]= new int * [Trigger_loop_umult-Trigger_loop_lmult+1]; … … 821 893 822 894 Int_t Lev0, Lev1; 823 Int_t Lev0MT[ 100], Lev1MT[100];895 Int_t Lev0MT[MAX_NUMBER_OF_CTS], Lev1MT[MAX_NUMBER_OF_CTS]; 824 896 825 897 fadcValues = new TArrayC(FADC_SLICES); … … 843 915 844 916 for (int i=0; i<ct_Number;i++){ 845 Trigger_CT[i] = new 917 Trigger_CT[i] = new MTrigger(TriggerPixels[i], 846 918 ((MGeomCam*)(camgeom.UncheckedAt(i))), 847 919 Trigger_gate_length, 848 920 Trigger_overlaping_time, 849 921 Trigger_response_ampl, 850 Trigger_response_fwhm ); //@< A instance of the Class MTrigger922 Trigger_response_fwhm, i); //@< A instance of the Class MTrigger 851 923 Trigger_CT[i]->SetSeed(UInt_t(i+get_seeds(0))); 852 924 } … … 912 984 Fadc_CT[i] = 913 985 new MFadc(((MGeomCam*)(camgeom.UncheckedAt(i)))->GetNumPixels(), 914 FADC_response_ampl,FADC_response_fwhm, 915 FADC_resp_ampl_out,FADC_resp_fwhm_out, 986 FADC_shape, 987 FADC_response_integ,FADC_response_fwhm, 988 FADC_shape_out, 989 FADC_resp_integ_out,FADC_resp_fwhm_out, 916 990 get_trig_delay() 917 991 ) ; //@< A instance of the Class MFadc … … 940 1014 941 1015 // Generate database for the Fadc electronic noise 942 if (addElecNoise){ 943 Fadc_CT[ict]->SetElecNoise(FADC_noise); 944 Fadc_CT[ict]->SetDigitalNoise(DIGITAL_noise); 945 } 1016 1017 if (!addElecNoise) 1018 continue; 1019 1020 MGeomCam *camg = (MGeomCam*)(camgeom.UncheckedAt(ict)); 1021 UInt_t n_inner_pixels; // Number of inner(small) pixels 1022 for (n_inner_pixels = 0; n_inner_pixels < camg->GetNumPixels(); 1023 n_inner_pixels ++) 1024 { 1025 if (camg->GetPixRatio(n_inner_pixels) < 1.) 1026 break; 1027 } 1028 Fadc_CT[ict]->SetElecNoise(FADC_noise_inner, FADC_noise_outer, 1029 n_inner_pixels); 1030 Fadc_CT[ict]->SetDigitalNoise(DIGITAL_noise); 946 1031 } 947 1032 … … 955 1040 MRawRunHeader *RunHeader= new MRawRunHeader(); 956 1041 MMcRunHeader *McRunHeader = new MMcRunHeader(); 957 MMcCorsikaRunHeader *McCorsikaRunHeader = new MMcCorsikaRunHeader(); 1042 MMcCorsikaRunHeader *McCorsikaRunHeader = new MMcCorsikaRunHeader("","",ct_Number); 1043 1044 1045 for (int i = 0; i < ct_Number; i++) 1046 McCorsikaRunHeader->FillCT(CTx[i], CTy[i], CTz[i], -1., -1., -1., -1., i); 1047 958 1048 959 1049 MMcConfigRunHeader **McConfigRunHeader = NULL; … … 973 1063 EvtHeader[i] = new MRawEvtHeader(); 974 1064 } 1065 975 1066 } 976 1067 … … 1015 1106 char help[4]; 1016 1107 1017 HeaderTree.Branch("MRawRunHeader ","MRawRunHeader",1108 HeaderTree.Branch("MRawRunHeader.","MRawRunHeader", 1018 1109 &RunHeader); 1019 1110 1020 HeaderTree.Branch("MMcRunHeader ","MMcRunHeader",1111 HeaderTree.Branch("MMcRunHeader.","MMcRunHeader", 1021 1112 &McRunHeader); 1022 1113 1023 HeaderTree.Branch("MMcCorsikaRunHeader ","MMcCorsikaRunHeader",1024 1114 HeaderTree.Branch("MMcCorsikaRunHeader.","MMcCorsikaRunHeader", 1115 &McCorsikaRunHeader); 1025 1116 1026 1117 if(!Trigger_Loop && Write_McTrig && ct_Number==1){ 1027 1118 1028 HeaderTree.Branch("MMcTrigHeader ","MMcTrigHeader",1119 HeaderTree.Branch("MMcTrigHeader.","MMcTrigHeader", 1029 1120 &HeaderTrig[0]); 1030 1121 } 1122 1031 1123 if (ct_Number==1){ 1032 HeaderTree.Branch("MGeomCam",GeometryName[0],1033 1034 HeaderTree.Branch("MMcConfigRunHeader ","MMcConfigRunHeader",1124 // HeaderTree.Branch("MGeomCam.", "MGeomCam", &camdummy[0]); 1125 HeaderTree.Branch("MGeomCam.", GeometryName[0], &camdummy[0]); 1126 HeaderTree.Branch("MMcConfigRunHeader.","MMcConfigRunHeader", 1035 1127 &McConfigRunHeader[0]); 1036 1128 } 1037 1129 else{ 1038 char branchname[2 0];1130 char branchname[256]; 1039 1131 for (int ict=0; ict<ct_Number;ict++){ 1040 1132 sprintf(help,"%i",ict+1); … … 1042 1134 strcat (branchname, & help[0]); 1043 1135 strcat (branchname, "."); 1044 HeaderTree.Branch(branchname, GeometryName[ict],1136 HeaderTree.Branch(branchname, GeometryName[ict], 1045 1137 &camdummy[ict]); 1046 1138 } … … 1058 1150 if ((Trigger_Loop || ct_Number>1) && Write_McTrig){ 1059 1151 ibr=0; 1060 for(char branchname[2 0];ibr<numberBranches;ibr++){1152 for(char branchname[256];ibr<numberBranches;ibr++){ 1061 1153 1062 1154 sprintf(help,"%i",ibr+1); … … 1071 1163 if(!Trigger_Loop && Write_McFADC && ct_Number==1){ 1072 1164 1073 HeaderTree.Branch("MMcFadcHeader ","MMcFadcHeader",1165 HeaderTree.Branch("MMcFadcHeader.","MMcFadcHeader", 1074 1166 &HeaderFadc[0]); 1075 1167 } 1076 1168 if ((Trigger_Loop || ct_Number>1) && Write_McFADC){ 1077 1169 ibr=0; 1078 for(char branchname[2 0];ibr<numberBranches;ibr++){1170 for(char branchname[256];ibr<numberBranches;ibr++){ 1079 1171 1080 1172 sprintf(help,"%i",ibr+1); … … 1082 1174 strcat (branchname, & help[0]); 1083 1175 strcat (branchname, "."); 1176 1084 1177 HeaderTree.Branch(branchname,"MMcFadcHeader", 1085 1178 &HeaderFadc[ibr]); … … 1094 1187 RunHeader->SetRunType(256); 1095 1188 RunHeader->SetRunNumber(0); 1096 RunHeader->SetNumSamples( 0,FADC_SLICES);1189 RunHeader->SetNumSamples(FADC_SLICES, FADC_SLICES); 1097 1190 RunHeader->SetNumCrates(1); 1098 1191 RunHeader->SetNumPixInCrate(ct_NPixels); … … 1149 1242 1150 1243 // Fill branches for MMcFadcHeader 1151 1152 for(int i=0;i<ct_NPixels;i++){1153 fadc_elecnoise[i]=FADC_noise;1154 fadc_diginoise[i]=DIGITAL_noise;1155 }1156 1157 1244 Fadc_CT[0]->GetPedestals(&fadc_pedestals[0]); 1158 1245 1159 1246 if(!Trigger_Loop && Write_McFADC && ct_Number==1){ 1160 1247 1161 HeaderFadc[0]->SetShape(0.0); 1162 HeaderFadc[0]->SetAmplitud(FADC_response_ampl*2.35/ 1163 sqrt(2*M_PI*FADC_response_fwhm 1164 *FADC_response_fwhm), 1165 FADC_resp_ampl_out*2.35/ 1166 sqrt(2*M_PI*FADC_resp_fwhm_out 1167 *FADC_resp_fwhm_out)); 1248 for(int k = 0; k < ct_NPixels; k++){ 1249 if ( ((MGeomCam*)(camgeom.UncheckedAt(0)))->GetPixRatio(k) < 1.) 1250 fadc_elecnoise[k]=FADC_noise_outer; // outer pixels 1251 else 1252 fadc_elecnoise[k]=FADC_noise_inner; // inner pixels 1253 1254 fadc_diginoise[k]=DIGITAL_noise; 1255 } 1256 1257 HeaderFadc[0]->SetShape(FADC_shape); 1258 HeaderFadc[0]->SetShapeOuter(FADC_shape_out); 1259 HeaderFadc[0]->SetAmplitud(FADC_response_integ, 1260 FADC_resp_integ_out); 1168 1261 HeaderFadc[0]->SetFwhm(FADC_response_fwhm,FADC_resp_fwhm_out); 1169 1262 HeaderFadc[0]->SetLow2High(FADC_high2low); … … 1173 1266 ((MGeomCam*)(camgeom.UncheckedAt(0)))->GetNumPixels()); 1174 1267 } 1268 1175 1269 if(!Trigger_Loop && Write_McFADC && ct_Number>1){ 1176 1270 for(int i=0;i<ct_Number;i++){ 1271 1272 for(int k = 0; k < ct_NPixels; k++){ 1273 if ( ((MGeomCam*)(camgeom.UncheckedAt(i)))->GetPixRatio(k) < 1.) 1274 fadc_elecnoise[k]=FADC_noise_outer; // outer pixels 1275 else 1276 fadc_elecnoise[k]=FADC_noise_inner; // inner pixels 1277 1278 fadc_diginoise[k]=DIGITAL_noise; 1279 } 1280 1177 1281 Fadc_CT[i]->GetPedestals(&fadc_pedestals[0]); 1178 HeaderFadc[i]->SetShape(0.0); 1179 HeaderFadc[i]->SetAmplitud(FADC_response_ampl*2.35/ 1180 sqrt(2*M_PI*FADC_response_fwhm 1181 *FADC_response_fwhm), 1182 FADC_resp_ampl_out*2.35/ 1183 sqrt(2*M_PI*FADC_resp_fwhm_out 1184 *FADC_resp_fwhm_out)); 1282 HeaderFadc[i]->SetShape(FADC_shape); 1283 HeaderFadc[i]->SetShapeOuter(FADC_shape_out); 1284 HeaderFadc[i]->SetAmplitud(FADC_response_integ, 1285 FADC_resp_integ_out); 1185 1286 HeaderFadc[i]->SetFwhm(FADC_response_fwhm,FADC_resp_fwhm_out); 1186 1287 HeaderFadc[i]->SetLow2High(FADC_high2low); … … 1189 1290 ((MGeomCam*)(camgeom.UncheckedAt(i)))->GetNumPixels()); 1190 1291 } 1191 } 1292 } 1293 1192 1294 if(Trigger_Loop && Write_McFADC){ 1295 1296 for(int k = 0; k < ct_NPixels; k++){ 1297 if ( ((MGeomCam*)(camgeom.UncheckedAt(0)))->GetPixRatio(k) < 1.) 1298 fadc_elecnoise[k]=FADC_noise_outer; // outer 1299 else 1300 fadc_elecnoise[k]=FADC_noise_inner; // inner 1301 1302 fadc_diginoise[k]=DIGITAL_noise; 1303 } 1304 1193 1305 int iconcount; 1194 1306 for (iconcount=0,ithrescount=0,fthrescount=Trigger_loop_lthres;fthrescount<=Trigger_loop_uthres;ithrescount++, fthrescount+=Trigger_loop_sthres){ … … 1196 1308 for(itopocount=0;itopocount<=Trigger_loop_utop-Trigger_loop_ltop;itopocount++){ 1197 1309 Fadc_CT[0]->GetPedestals(&fadc_pedestals[0]); 1198 HeaderFadc[iconcount]->SetShape(0.0); 1199 HeaderFadc[iconcount]->SetAmplitud(FADC_response_ampl*2.35/ 1200 sqrt(2*M_PI*FADC_response_fwhm 1201 *FADC_response_fwhm), 1202 FADC_resp_ampl_out*2.35/ 1203 sqrt(2*M_PI*FADC_resp_fwhm_out 1204 *FADC_resp_fwhm_out)); 1310 HeaderFadc[iconcount]->SetShape(FADC_shape); 1311 HeaderFadc[iconcount]->SetShapeOuter(FADC_shape_out); 1312 HeaderFadc[iconcount]->SetAmplitud(FADC_response_integ, 1313 FADC_resp_integ_out); 1205 1314 HeaderFadc[iconcount]->SetFwhm(FADC_response_fwhm, 1206 1315 FADC_resp_fwhm_out); … … 1222 1331 } 1223 1332 1224 1225 1333 // create a Tree for the Event data stream 1226 1334 TTree EvtTree("Events","Normal Triggered Events"); … … 1228 1336 if (Write_McEvt && ct_Number==1){ 1229 1337 1230 EvtTree.Branch("MMcEvt ","MMcEvt",1338 EvtTree.Branch("MMcEvt.","MMcEvt", 1231 1339 &McEvt[0]); 1232 1340 } … … 1234 1342 if (Write_McEvt && ct_Number!=1){ 1235 1343 ibr=0; 1236 for(char branchname[ 10];ibr<numberBranches;ibr++){1344 for(char branchname[256];ibr<numberBranches;ibr++){ 1237 1345 1238 1346 sprintf(help,"%i",ibr+1); … … 1248 1356 1249 1357 if (Write_RawEvt){ 1250 EvtTree.Branch("MRawEvtHeader ","MRawEvtHeader",1358 EvtTree.Branch("MRawEvtHeader.","MRawEvtHeader", 1251 1359 &EvtHeader[0]); 1252 EvtTree.Branch("MRawEvtData ","MRawEvtData",1360 EvtTree.Branch("MRawEvtData.","MRawEvtData", 1253 1361 &EvtData[0]); 1254 1362 } 1255 1363 if (Write_McTrig){ 1256 EvtTree.Branch("MMcTrig ","MMcTrig",1364 EvtTree.Branch("MMcTrig.","MMcTrig", 1257 1365 &McTrig[0]); 1258 1366 } … … 1262 1370 if (Write_McTrig){ 1263 1371 ibr=0; 1264 for(char branchname[ 10];ibr<numberBranches;ibr++){1372 for(char branchname[256];ibr<numberBranches;ibr++){ 1265 1373 1266 1374 sprintf(help,"%i",ibr+1); … … 1276 1384 if ((Trigger_Loop || ct_Number>1) && Write_RawEvt){ 1277 1385 ibr=0; 1278 for(char branchname[ 15];ibr<numberBranches;ibr++){1386 for(char branchname[256];ibr<numberBranches;ibr++){ 1279 1387 1280 1388 sprintf(help,"%i",ibr+1); … … 1286 1394 } 1287 1395 ibr=0; 1288 for(char branchname[ 15];ibr<numberBranches;ibr++){1396 for(char branchname[256];ibr<numberBranches;ibr++){ 1289 1397 1290 1398 sprintf(help,"%i",ibr+1); … … 1315 1423 } 1316 1424 1317 1318 1425 // prepare the NSB simulation 1319 1426 1320 1427 // Instance of the Mlons class 1321 MLons lons( Trigger_response_ampl, Trigger_response_fwhm,1322 FADC_response_ampl,FADC_response_fwhm);1428 MLons lons(0.0, Trigger_response_ampl, Trigger_response_fwhm, 1429 float(FADC_shape),FADC_response_integ,FADC_response_fwhm); 1323 1430 1324 1431 lons.SetSeed(Int_t(get_seeds(1)/get_seeds(0))+1); … … 1327 1434 1328 1435 // Instance of the Mlons class 1329 MLons lons_outer( Trigger_response_ampl, Trigger_response_fwhm,1330 FADC_resp_ampl_out,FADC_resp_fwhm_out);1436 MLons lons_outer(0.0, Trigger_response_ampl, Trigger_response_fwhm, 1437 float(FADC_shape_out),FADC_resp_integ_out,FADC_resp_fwhm_out); 1331 1438 1332 1439 lons_outer.SetSeed(Int_t(get_seeds(1)/get_seeds(0))+2); … … 1340 1447 // 1341 1448 1342 // FIXME --- star NSB different for each camera? 1449 // 1450 // FIXME! --- star NSB different for each camera? 1451 // Then we will have to use mirror_frac[ict] 1452 // 1343 1453 log(SIGNATURE,"Produce NSB rates from Star Field"); 1344 1454 … … 1346 1456 ((MGeomCam*)(camgeom.UncheckedAt(0))), 1347 1457 nsbrate_phepns, 1348 0); 1458 0, 1459 mirror_frac[0]); 1460 1461 1462 // 1463 // Call to "produce_nsbrates" above accounts ONLY for 1464 // non-diffuse NSB (i.e. from stars). NOTE: produce_nsbrates already 1465 // accounts for the possibly different light collection efficiencies 1466 // of inner and outer pixels, through a call (see function) to 1467 // "produce_phes". The output array nsbrate_phepns contains only the 1468 // rates due to individual stars in the FOV, and not diffuse NSB light! 1469 // 1349 1470 1350 1471 if (k != 0){ … … 1358 1479 for(int ict=0;ict<ct_Number;ict++){ 1359 1480 1360 // First we set the factor due to the mirror size respect to the MAGIC mirror. 1481 // First we set the factor due to the mirror size with respect to the normal 1482 // MAGIC mirror geometry. 1361 1483 1362 1484 switch(GeometryCamera[ict]){ … … 1379 1501 } 1380 1502 1381 factorNSB_ct =factorNSB_ct/1503 factorNSB_ct = factorNSB_ct / 1382 1504 ((*((MGeomCam*)(camgeom.UncheckedAt(ict)))).GetCameraDist()*1000* 1383 1505 (*((MGeomCam*)(camgeom.UncheckedAt(ict)))).GetCameraDist()*1000* 1384 PIXEL_SIZE*PIXEL_SIZE); 1506 PIXEL_SIZE*PIXEL_SIZE); // [mm^-2] 1385 1507 1386 1508 for(UInt_t ui=0; 1387 1509 ui<((MGeomCam*)(camgeom.UncheckedAt(ict)))->GetNumPixels(); ui++){ 1388 1510 const Float_t size= 1389 (*((MGeomCam*)(camgeom.UncheckedAt(ict))))[ui].GetD(); 1390 diffnsb_phepns[ict][ui] = (Int_t(meanNSB*factorNSB_ct*100*size*size+0.5))/(100.0)*factorqe_NSB[ict]; 1511 (*((MGeomCam*)(camgeom.UncheckedAt(ict))))[ui].GetD(); 1512 // Returns distance [mm] between two paralel sides of pixel 1513 1514 1515 Float_t diffusensb = meanNSB*mirror_frac[ict]; 1516 1517 // 1518 // If pixel is outer pixel: 1519 // 1520 if ( ((MGeomCam*)(camgeom.UncheckedAt(ict)))->GetPixRatio(ui) < 1. ) 1521 diffusensb *= WC_outer[1][90] / WC[1][90]; 1522 // 1523 // FIXME! Correction above is for (possibly) different light collection efficiencies of 1524 // inner and outer pixels. For the moment we assume the angular dependence of the light 1525 // collection is the same and hence use simply the ratio of efficiencies for light impinging 1526 // perpendicular to the camera plane (index 90 stands for 90 degrees) 1527 // 1528 1529 diffnsb_phepns[ict][ui] = (Int_t(diffusensb*factorNSB_ct*100*size*size+0.5))/(100.0)*factorqe_NSB[ict]; 1391 1530 } 1392 1531 } … … 1396 1535 for(int ict=0;ict<ct_Number;ict++){ 1397 1536 for(j=0;j<iNUMWAVEBANDS;j++){ 1398 // calculate the effect of the atmospheric extinction 1537 // calculate the effect of the atmospheric extinction (for stars!) 1399 1538 1400 1539 zenfactor = pow(10., -0.4 * ext[j] ); … … 1411 1550 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 1412 1551 // 1413 // Now 500 empty event with the conditin in which the camera is run1414 // are simulated. I Nthis way one gets an estimation of the1415 // sigma forthe pedestal of each FADC channel.1416 // This sigma computtaion is done assuming any noise taht effects1552 // Now 500 empty events with the condition in which the camera is run 1553 // are simulated. In this way one gets an estimation of the 1554 // fluctuations of the pedestal of each FADC channel. 1555 // This computation is done assuming any noise that affects 1417 1556 // the FADC but there is no rotation of the Star Field (otherwise it 1418 // should be done for each event) 1557 // should be done for each event). So it is valid if no starfield 1558 // rotation is used. 1559 // 1560 // Changed 20/03/2004, AM: now we no longer calculate the individual 1561 // FADC slice RMS. Due to correlations in the noise of neighboring 1562 // slides, it follows that RMS(sum_n_slices) != sqrt(n)*RMS(single_slice) 1563 // 1564 // In the analysis in Mars, however, the RMS of the fluctuations of the 1565 // signal (resulting from the integration of n slices) is estimated as 1566 // sqrt(n) * MMcFadcHeader.fPedesSigmaHigh, where the latter value, 1567 // stored in the camera output, is calculated in the next lines of code. 1568 // We have then made the following, as is being done also in real data: 1569 // calculate the RMS of the distribution of the sum of 14 slices, then 1570 // the stored value is 1571 // MMcFadcHeader.fPedesSigmaHigh = RMS(sum_14_slices)/sqrt(14), and the 1572 // same for the low gain. It can be seen that the RMS of the sum of n 1573 // slices, with n not too low (n>=6 or so), is more or less: 1574 // RMS(sum_n_slices) ~ sqrt(n) * RMS(sum_14_slices)/sqrt(14) 1575 // 1576 // The reason to sum 14 slices (and not 15) comes from the fact that in 1577 // real data there is a FADC clock noise affecting differently odd and 1578 // even FADC slices, so always an even number of them is added up so that 1579 // this cancels out. So we do the calculation in the same way as in real 1580 // data. 1419 1581 // 1420 1582 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 1583 1584 Int_t empty_events = 500; 1585 Int_t n_slices = 14; 1421 1586 1422 1587 for(int ict=0;ict<ct_Number;ict++){ … … 1427 1592 fadc_sigma_low[ui]=0.0; 1428 1593 } 1429 for(int ie=0; ie<500;ie++){1594 for(int ie=0; ie < empty_events; ie++){ 1430 1595 Fadc_CT[ict]->Reset() ; 1431 1596 if (addElecNoise){ 1432 Fadc_CT[ict]->ElecNoise( FADC_noise) ;1597 Fadc_CT[ict]->ElecNoise() ; 1433 1598 } 1434 1599 if(simulateNSB){ … … 1455 1620 } 1456 1621 Fadc_CT[ict]->Pedestals(); 1622 1457 1623 for(UInt_t ui=0; 1458 1624 ui<((MGeomCam*)(camgeom.UncheckedAt(ict)))->GetNumPixels(); 1459 ui++){ 1460 fadc_sigma[ui]+=(Fadc_CT[ict]->GetPedestalNoise(ui,1))/500.0; 1461 fadc_sigma_low[ui]+=(Fadc_CT[ict]->GetPedestalNoise(ui,0))/500.0; 1625 ui++) 1626 { 1627 // 1628 // We add up n_slices FADC slices (pedestal subtracted), then 1629 // calculate the sigma_n-1 of this sum for the number of generated 1630 // noise events (=empty_events). 1631 // 1632 Float_t sumslices = Fadc_CT[ict]->AddNoiseInSlices(ui,1,n_slices); 1633 fadc_sigma[ui] += sumslices*sumslices; 1634 1635 // Now the low gain: 1636 sumslices = Fadc_CT[ict]->AddNoiseInSlices(ui,0,n_slices); 1637 fadc_sigma_low[ui]+= sumslices*sumslices; 1638 } 1639 } 1640 1641 for(UInt_t ui=0; 1642 ui<((MGeomCam*)(camgeom.UncheckedAt(ict)))->GetNumPixels(); 1643 ui++) 1644 { 1645 Float_t s_high = fadc_sigma[ui] / (Float_t)(empty_events-1) / 1646 (Float_t)(n_slices); 1647 fadc_sigma[ui] = sqrt(s_high); 1648 1649 Float_t s_low = fadc_sigma_low[ui] / (Float_t)(empty_events-1) / 1650 (Float_t)(n_slices); 1651 fadc_sigma_low[ui] = sqrt(s_low); 1462 1652 } 1463 } 1653 1464 1654 HeaderFadc[ict]->SetPedestalSigma(&fadc_sigma_low[0],&fadc_sigma[0], 1465 1655 ((MGeomCam*)(camgeom.UncheckedAt(ict))) … … 1560 1750 } 1561 1751 1562 fread((char*)&mcrunh,(SIZE_OF_MCRUNHEADER)*sizeof(float), 1, inputfile[ict] ); 1752 // fread((char*)&mcrunh,(SIZE_OF_MCRUNHEADER)*sizeof(float), 1, inputfile[ict] ); 1753 // AM, changed reading method, 02/2004: 1754 1755 mcrunh.read(inputfile[ict]); 1756 1563 1757 } 1564 1758 … … 1598 1792 if (reflector_file_version<6){ 1599 1793 for(int ict=0;ict<ct_Number;ict++) 1600 fread( (char*)&mcevth[ict], mcevth[ict].mysize(), 1601 1, inputfile[ict] ); 1794 { 1795 mcevth[ict].read(inputfile[ict]); 1796 } 1797 1602 1798 } 1603 1799 else{ 1604 1800 for(int ict=0;ict<ct_Number;ict++) 1605 fread( (char*)&mcevth_2[ict], mcevth_2[ict].mysize(), 1606 1, inputfile[ict] ); 1801 { 1802 mcevth_2[ict].read(inputfile[ict]); 1803 } 1607 1804 } 1608 1805 1609 // calculate impact parameter (shortest distance betwee the original 1610 // trajectory of the primary (assumed shower-axis) and the 1611 // direction where the telescope points to 1806 // 1807 // AM March 2004 simplified impact parameter calculation, 1808 // and allowed for correct estimate also for telescopes not 1809 // placed at Corsika's origin of coordinates (0.,0.). 1810 // FIXME: telescope coordinates still set by the user in the 1811 // input card, since they are not available in the reflector 1812 // file! 1813 // 1814 // Calculate impact parameter as distance between telescope 1815 // location and shower axis. In the previous implementation, 1816 // the definition was the distance between telescope axis and 1817 // shower axis, but this has less physical meaning in general. 1818 // Light yield depends above all on distance to shower axis! 1819 // Of course for shower axis paralel to telescope the old and 1820 // the new definitions of impact parameter agree. 1612 1821 // 1613 // we use the following equation, given that the shower core position 1614 // is (x1,y1,z1)=(x,y,0),the trajectory is given by (l1,m1,n1), 1615 // and the telescope position and orientation are (x2,y2,z2)=(0,0,0) 1616 // and (l2,m2,n2) 1617 // 1618 // | | 1619 // | x1-x2 y1-y2 z1-z2 | 1620 // | | 1621 // + | l1 m1 n1 | 1622 // - | | 1623 // | l2 m2 n2 | 1624 // | | 1625 // dist = ------------------------------------ ( > 0 ) 1626 // [ |l1 m1|2 |m1 n1|2 |n1 l1|2 ]1/2 1627 // [ | | + | | + | | ] 1628 // [ |l2 m2| |m2 n2| |n2 l2| ] 1629 // 1630 // playing a little bit, we get this reduced for in our case: 1631 // 1632 // 1633 // dist = (- m2 n1 x + m1 n2 x + l2 n1 y - l1 n2 y - l2 m1 z + l1 m2 z) / 1634 // [(l2^2 (m1^2 + n1^2) + (m2 n1 - m1 n2)^2 - 1635 // 2 l1 l2 (m1 m2 + n1 n2) + l1^2 (m2^2 + n2^2) ] ^(1/2) 1636 1822 1823 1637 1824 // read the direction of the incoming shower 1638 1825 // It is done only for one telescope since it is suposed … … 1646 1833 phishw = mcevth_2[0].get_phi(); 1647 1834 } 1835 Zenith=thetashw; Azimutal=phishw; 1648 1836 1649 1837 // calculate vector for shower … … 1653 1841 n1 = cos(thetashw); 1654 1842 1655 if (reflector_file_version<6){ 1656 1657 mcevth[0].get_core(&coreX, &coreY); 1658 1659 for(int ict=0;ict<ct_Number;ict++){ 1660 // read the deviation of the telescope with respect to the shower 1661 mcevth[ict].get_deviations ( &thetaCT[ict], &phiCT[ict] ); 1662 1663 if ( (thetaCT[ict] == 0.) && (phiCT[ict] == 0.) ) { 1664 1665 // CT was looking to the source (both lines are parallel) 1666 // therefore, we calculate the impact parameter as the distance 1667 // between the CT axis and the core position 1668 1669 impactD[ict] = dist_r_P( 0., 0., 0., l1, m1, n1, coreX, coreY, 0. ); 1670 thetaCT[ict] += thetashw; 1671 phiCT[ict] += phishw; 1672 } else { 1673 1674 // the shower comes off-axis 1675 1676 // obtain with this the final direction of the CT 1677 1678 thetaCT[ict] += thetashw; 1679 phiCT[ict] += phishw; 1680 1681 // calculate vector for telescope 1682 1683 l2 = sin(thetaCT[ict])*cos(phiCT[ict]); 1684 m2 = sin(thetaCT[ict])*sin(phiCT[ict]); 1685 n2 = cos(thetaCT[ict]); 1686 1687 num = (m1*n2*coreX - m2*n1*coreX + l2*n1*coreY - l1*n2*coreY); 1688 den = (SQR(l1*m2 - l2*m1) + 1689 SQR(m1*n2 - m2*n1) + 1690 SQR(n1*l2 - n2*l1)); 1691 den = sqrt(den); 1692 impactD[ict] = fabs(num)/den; 1693 } 1694 } 1695 } 1696 else{ 1697 mcevth_2[0].get_core(&coreX, &coreY); 1698 for(int ict=0;ict<ct_Number;ict++){ 1699 thetaCT[ict]=mcevth_2[ict].get_theta_CT(); 1700 phiCT[ict]=mcevth_2[ict].get_phi_CT(); 1701 if ( (thetaCT[ict] == thetashw) && (phiCT[ict] == phishw) ) { 1702 1703 // CT was looking to the source (both lines are parallel) 1704 // therefore, we calculate the impact parameter as the distance 1705 // between the CT axis and the core position 1706 1707 impactD[ict] = dist_r_P( 0., 0., 0., l1, m1, n1, coreX, coreY, 0. ); 1708 1709 } else { 1710 1711 // the shower comes off-axis 1712 1713 // calculate vector for telescope 1714 1715 l2 = sin(thetaCT[ict])*cos(phiCT[ict]); 1716 m2 = sin(thetaCT[ict])*sin(phiCT[ict]); 1717 n2 = cos(thetaCT[ict]); 1718 1719 num = (m1*n2*coreX - m2*n1*coreX + l2*n1*coreY - l1*n2*coreY); 1720 den = (SQR(l1*m2 - l2*m1) + 1721 SQR(m1*n2 - m2*n1) + 1722 SQR(n1*l2 - n2*l1)); 1723 den = sqrt(den); 1724 1725 impactD[ict] = fabs(num)/den; 1726 1727 } 1728 } 1729 } 1843 // 1844 // Note, A.M.: 1845 // Attention! "core vector from mcevth*.get_core 1846 // is the vector from the core to the telescope! 1847 // 1848 Float_t core2ct_x; 1849 Float_t core2ct_y; 1850 1851 if (reflector_file_version<6) 1852 mcevth[0].get_core(&core2ct_x, &core2ct_y); 1853 else 1854 mcevth_2[0].get_core(&core2ct_x, &core2ct_y); 1855 1856 // 1857 // Then true core position in Corsika's system is: 1858 // 1859 1860 coreX = CTx[0] - core2ct_x; 1861 coreY = CTy[0] - core2ct_y; 1862 1863 // 1864 // FIXME: This may not work fine for CTs at z != 0 !! 1865 // 1866 for(int ict=0;ict<ct_Number;ict++) 1867 impactD[ict] = dist_r_P( CTx[ict], CTy[ict], CTz[ict], 1868 l1, m1, n1, coreX, coreY, 0. ); 1869 1730 1870 1731 1871 // energy cut … … 1772 1912 &arrtmin_ns, // will be changed by the function! 1773 1913 &arrtmax_ns, // will be changed by the function! 1774 ict); 1914 ict, 1915 mirror_frac[ict]); 1775 1916 1776 1917 inumphe=(inumphe<inumphe_CT[ict])?inumphe_CT[ict]:inumphe; … … 1908 2049 Trigger_CT[ict]->ElecNoise(Trigger_noise) ; 1909 2050 1910 Fadc_CT[ict]->ElecNoise( FADC_noise) ;2051 Fadc_CT[ict]->ElecNoise() ; 1911 2052 } 1912 2053 } … … 2079 2220 mcevth[0].get_phi(), 2080 2221 mcevth[0].get_core(), 2081 mcevth[0].get_coreX(),2082 mcevth[0].get_coreY(),2222 coreX, 2223 coreY, 2083 2224 impactD[0], 2084 2225 phiCT[0], … … 2116 2257 mcevth_2[0].get_phi(), 2117 2258 mcevth_2[0].get_core(), 2118 mcevth_2[0].get_coreX(),2119 mcevth_2[0].get_coreY(),2259 coreX, 2260 coreY, 2120 2261 impactD[0], 2121 2262 mcevth_2[0].get_phi_CT(), … … 2314 2455 // 2315 2456 2457 2316 2458 for (int ict=0;ict<ct_Number;ict++){ 2317 2459 Float_t ftime, ltime; … … 2327 2469 mcevth[ict].get_phi(), 2328 2470 mcevth[ict].get_core(), 2329 mcevth[ict].get_coreX(),2330 mcevth[ict].get_coreY(),2471 coreX, 2472 coreY, 2331 2473 impactD[ict], 2332 2474 phiCT[ict], … … 2364 2506 mcevth_2[ict].get_phi(), 2365 2507 mcevth_2[ict].get_core(), 2366 mcevth_2[ict].get_coreX(),2367 mcevth_2[ict].get_coreY(),2508 coreX, 2509 coreY, 2368 2510 impactD[ict], 2369 2511 mcevth_2[ict].get_phi_CT(), … … 2470 2612 for(int ict=0;ict<ct_Number;ict++){ 2471 2613 read_ascii(inputfile[ict], McConfigRunHeader[ict]); 2472 2473 if (get_sigma_xy_cm_spot() > 0.) 2614 McConfigRunHeader[ict]->SetMissPointingX(missP_x); 2615 McConfigRunHeader[ict]->SetMissPointingY(missP_y); 2616 if ( Spotsigma > 0.) 2474 2617 { 2475 Float_t spotsigma = McConfigRunHeader[ict]->GetPointSpread(); 2476 Float_t newsigma = sqrt(spotsigma * spotsigma + 2477 get_sigma_xy_cm_spot() * get_sigma_xy_cm_spot()); 2478 McConfigRunHeader[ict]->SetPointSpread(newsigma); 2618 Float_t ref_spotsigma = McConfigRunHeader[ict]->GetPointSpread(); 2619 Float_t newsigma = sqrt(ref_spotsigma * ref_spotsigma + 2620 Spot_x* Spot_x); 2621 McConfigRunHeader[ict]->SetPointSpreadX(newsigma); 2622 newsigma = sqrt(ref_spotsigma * ref_spotsigma + Spot_y* Spot_y); 2623 McConfigRunHeader[ict]->SetPointSpreadY(newsigma); 2479 2624 } 2480 2625 } … … 2534 2679 } 2535 2680 2536 get_source_off(&sofftheta,&soffphi);2537 2681 if(!Trigger_Loop) icontrigger=0; 2538 2682 time (<ime); … … 2564 2708 telestheta, 2565 2709 telesphi, 2566 sofftheta,2567 soffphi,2568 2710 shthetamax, 2569 2711 shthetamin, … … 2605 2747 telestheta, 2606 2748 telesphi, 2607 sofftheta,2608 soffphi,2609 2749 shthetamax, 2610 2750 shthetamin, … … 2623 2763 // Fill some missing values for MRawRunHeader 2624 2764 2625 RunHeader->SetRunNumber( rnum);2765 RunHeader->SetRunNumber((UInt_t)rnum); 2626 2766 RunHeader->SetNumEvents(nstoredevents); 2627 2767 … … 2688 2828 } 2689 2829 2690 // Store Light Guides factors in the output file 2691 TArrayF theta_lg; 2692 TArrayF factor_lg; 2693 theta_lg.Set(pointsWC,WC[0]); 2694 factor_lg.Set(pointsWC,WC[1]); 2695 McConfigRunHeader[ict]->SetLightGuides(theta_lg,factor_lg); 2830 // Store Light Collection factors in the output file 2831 TArrayF theta_lc; 2832 TArrayF factor_lc; 2833 TArrayF factor_lc_outer; 2834 2835 theta_lc.Set(pointsWC,WC[0]); 2836 factor_lc.Set(pointsWC,WC[1]); 2837 factor_lc_outer.Set(pointsWC,WC_outer[1]); 2838 2839 McConfigRunHeader[ict]->SetLightCollection(theta_lc, factor_lc, 2840 factor_lc_outer); 2696 2841 2697 2842 } … … 2980 3125 break; 2981 3126 2982 if ( ( (i-1) < ct_NPixels) && ((i-1)> -1) &&3127 if ( (i < ct_NPixels) && (i > -1) && 2983 3128 ((j-1) < pointsQE[ict]) && ((j-1) > -1) ) { 2984 QE[ict][i -1][0][j-1] = QElambda[j-1];2985 QE[ict][i -1][1][j-1] = qe;3129 QE[ict][i][0][j-1] = QElambda[j-1]; 3130 QE[ict][i][1][j-1] = qe; 2986 3131 } 2987 3132 … … 3036 3181 3037 3182 //------------------------------------------------------------ 3038 // Read Light Guidesdata3183 // Read Light Collection data 3039 3184 3040 3185 // try to open the file … … 3055 3200 // get line from the file 3056 3201 3057 wcfile.getline(line, LINE_MAX_LENGTH); 3058 3202 do 3203 wcfile.getline(line, LINE_MAX_LENGTH); 3204 while (line[0] == '#'); 3205 3059 3206 // get the number of datapoints 3060 3207 … … 3071 3218 sscanf(line, "%f %f", &WC[0][i], &WC[1][i]); 3072 3219 } 3073 3220 3221 // 3222 // Now read info for outer pixels 3223 // 3224 WC_outer = new float * [2]; 3225 WC_outer[0] = new float[pointsWC]; 3226 WC_outer[1] = new float[pointsWC]; 3227 3228 do 3229 wcfile.getline(line, LINE_MAX_LENGTH); 3230 while (line[0] == '#'); 3231 3232 if (wcfile.eof()) 3233 { 3234 log("read_WC", "ERROR. Missing data for outer pixels in file \"%s\"...\n",WC_FILE); 3235 log("read_WC", "EXITING camera\n"); 3236 exit(-1); 3237 } 3238 3239 sscanf(line, "%f %f", &WC_outer[0][0], &WC_outer[1][0]); 3240 for ( i=1; i<pointsWC; ++i ) { 3241 wcfile.getline(line, LINE_MAX_LENGTH); 3242 sscanf(line, "%f %f", &WC_outer[0][i], &WC_outer[1][i]); 3243 } 3244 3074 3245 // close file 3075 3246 … … 3548 3719 // dist_r_P 3549 3720 // 3550 // distance straight line r - point P 3721 // distance straight line r (x+t*l, y+t*m, z+t*n) to point P(a,b,c) 3722 // 3723 // We assume that vector (l, m, n) is normalized l^2+m^2+n^2 = 1 3551 3724 //------------------------------------------------------------ 3552 3725 … … 3559 3732 sqrt((SQR((a-x)*m-(b-y)*l) + 3560 3733 SQR((b-y)*n-(c-z)*m) + 3561 SQR((c-z)*l-(a-x)*n))/ 3562 (SQR(l)+SQR(m)+SQR(n)) 3563 ) 3734 SQR((c-z)*l-(a-x)*n))) 3564 3735 ); 3565 3736 } … … 3636 3807 int size_rotated( 3637 3808 float *rotated, 3638 float nsb[iMAXNUMPIX],3809 float *nsb, 3639 3810 float rho) 3640 3811 { … … 3737 3908 class MFadc *fadc, 3738 3909 int *itotnphe, // total number of produced photoelectrons 3739 float nphe[iMAXNUMPIX], // number of photoelectrons in each pixel3910 float *nphe, // number of photoelectrons in each pixel 3740 3911 int *incph, // total number of cph within camera 3741 3912 float *tmin_ns, // minimum arrival time of all phes 3742 3913 float *tmax_ns, // maximum arrival time of all phes 3743 int ict // Telescope that is being analised to get the right QE. 3914 int ict, // Telescope that is being analised to get the right QE. 3915 float mirror_fraction // Fraction of total mirror really present 3744 3916 ){ 3745 3917 3746 3918 static uint i; 3747 3919 static int k, ipixnum; 3748 static float cx, cy, wl, qe , t;3749 static float c u, cv, cw;3920 static float cx, cy, wl, qe; 3921 static float cw; 3750 3922 static MCCphoton photon; 3751 3923 static float **qept; … … 3753 3925 static float radius_mm; 3754 3926 3927 Float_t t; 3928 3755 3929 // reset variables 3756 3930 … … 3761 3935 } 3762 3936 3937 *itotnphe = 0; 3763 3938 *incph = 0; 3764 3939 … … 3768 3943 random.SetSeed((Int_t)(get_seeds(0)*get_seeds(1))); 3769 3944 3770 float spotsigma = get_sigma_xy_cm_spot(); 3945 float C1, C2, C3, rho; 3946 3771 3947 3772 3948 //- - - - - - - - - - - - - - - - - - - - - - - - - … … 3779 3955 3780 3956 // read the photons data 3781 3782 3957 3783 3958 // loop over the photons 3784 3959 3785 3960 while (1) { 3786 3961 3787 fread ( flag, SIZE_OF_FLAGS, 1, sp ); 3962 photon.read(sp); 3963 photon.get_flag(flag); 3788 3964 3789 3965 if (isA( flag, FLAG_END_OF_EVENT )) 3790 break; 3791 3792 memcpy( (char*)&photon, flag, SIZE_OF_FLAGS ); 3793 3794 fread( ((char*)&photon)+SIZE_OF_FLAGS, photon.mysize()-SIZE_OF_FLAGS, 1, sp ); 3795 3966 { 3967 fseek (sp, SIZE_OF_FLAGS-photon.mysize(), SEEK_CUR); 3968 break; 3969 } 3796 3970 3797 3971 // Check if photon is inside trigger time range 3798 3972 3799 t = photon.get_t() ; 3973 t = photon.get_t() ; 3800 3974 3801 3975 if (t-*tmin_ns>TOTAL_TRIGGER_TIME) { 3802 3976 continue; 3803 3977 } 3804 3978 3979 // 3980 // Account for possibly missing mirrors, or lower reflectivity... 3981 // mirror_fraction is the fraction of the total mirror really 3982 // working. 3983 // 3984 if (mirror_fraction < 1.) 3985 if (RandomNumber > mirror_fraction) 3986 continue; 3987 3805 3988 // 3806 3989 // Pixelization … … 3810 3993 cy = photon.get_y(); 3811 3994 3812 3813 if (spotsigma > 0.) 3995 if (Spotsigma > 0.) 3814 3996 { 3815 cx += random.Gaus(0.,spotsigma); 3816 cy += random.Gaus(0.,spotsigma); 3817 } 3997 cx += random.Gaus(0.,Spot_x); 3998 cy += random.Gaus(0.,Spot_y); 3999 } 4000 if (missPointing > 0.) 4001 { 4002 // We should take intot acount the rotation of the FoV 4003 C1 = 0.48 * sin(Zenith) - 0.87 * cos(Zenith) * cos(Azimutal); 4004 C3 = (0.87 * cos(Zenith) - 0.48 * sin(Zenith) * cos(Azimutal)); 4005 C2 = sqrt( sin(Zenith) * sin(Zenith) * sin(Azimutal) * sin(Azimutal) + C3 * C3 ); 4006 rho = acos( C1/C2 ); 4007 rho=(sin(Azimutal)<0 ? (2 * 3.14159 - rho) : rho); 4008 4009 rho = rho*180/3.14159; 4010 4011 cx += (missP_x*cos(rho)-missP_y*sin(rho))/(10*camgeom->GetConvMm2Deg()); 4012 cy += (missP_x*sin(rho)+missP_y*cos(rho))/(10*camgeom->GetConvMm2Deg()); 4013 } 4014 3818 4015 3819 4016 // get wavelength … … 3849 4046 3850 4047 // set pointer to the QE table of the relevant pixel 3851 4048 3852 4049 qept = (float **)QE[ict][ipixnum]; 3853 4050 … … 3870 4067 qe = lin_interpol(qept[0][k-1], qept[1][k-1], qept[0][k], qept[1][k], wl) / 100.0; 3871 4068 3872 // Apply incient angular correction due to Light Guides 3873 3874 cu=photon.get_u(); 3875 cv=photon.get_v(); 3876 cw=90.0-acos(sqrt(1-cu*cu-cv*cv))*3.14159/180.0; 3877 3878 // find data point in the QE table (-> k) 3879 3880 k = 0; 3881 while (k < pointsWC-1 && WC[0][k] < cw){ 3882 k++; 3883 } 3884 3885 // correct the qe with WC data. 3886 3887 qe = qe*lin_interpol(WC[0][k-1], WC[1][k-1], WC[0][k], WC[1][k], cw); 4069 // 4070 // Apply incient angular correction due to Light Guides, plexiglas, 4071 // 1st dynode collection efficiency, double crossings... etc. 4072 // This information is contained in the file Data/LightCollection.dat 4073 // 4074 cw=photon.get_phi()*180./3.14159265; 4075 4076 // find data point in the WC table (-> k) 4077 4078 if ( camgeom->GetPixRatio(ipixnum) < 1.) // => Pixel is outer pixel 4079 { 4080 k = 0; 4081 while (k < pointsWC-1 && WC_outer[0][k] < cw) 4082 k++; 4083 // correct the qe with WC data. 4084 qe = qe*lin_interpol(WC_outer[0][k-1], WC_outer[1][k-1], 4085 WC_outer[0][k], WC_outer[1][k], cw); 4086 } 4087 4088 else // => Pixel is inner pixel 4089 { 4090 k = 0; 4091 while (k < pointsWC-1 && WC[0][k] < cw) 4092 k++; 4093 // correct the qe with WC data. 4094 qe = qe*lin_interpol(WC[0][k-1], WC[1][k-1], WC[0][k], WC[1][k], cw); 4095 } 4096 3888 4097 3889 4098 // if random > quantum efficiency, reject it … … 3902 4111 3903 4112 nphe[ipixnum] += 1.0; 3904 4113 4114 3905 4115 // store the new photoelectron 3906 4116 … … 3929 4139 int produce_nsbrates( char *iname, // the starfield input file name 3930 4140 MGeomCam *camgeom, // camera layout 3931 float rate_phepns[iMAXNUMPIX][iNUMWAVEBANDS], // the product of this function: 3932 // the NSB rates in phe/ns for each pixel 3933 int ict 3934 ){ 3935 4141 float **rate_phepns, 4142 // the product of this function: 4143 // the NSB rates in phe/ns for each pixel 4144 int ict, 4145 float mirror_fraction) 4146 { 3936 4147 uint i, j; // counters 3937 4148 int k, ii; // counters … … 3959 4170 char flag_new[4]; 3960 4171 4172 3961 4173 // open input file 3962 4174 … … 3965 4177 infile = fopen( iname, "r" ); 3966 4178 3967 // check if the s atrfield input file exists4179 // check if the starfield input file exists 3968 4180 3969 4181 if ( infile == NULL ) { … … 3975 4187 return (0); 3976 4188 } 3977 4189 3978 4190 // get signature, and check it 3979 4191 … … 3982 4194 } 3983 4195 3984 // Instance of MTrigger and MFadc 3985 3986 MTrigger trigger(camgeom->GetNumPixels(),camgeom,Trigger_gate_length, Trigger_overlaping_time, Trigger_response_ampl, Trigger_response_fwhm); 3987 MFadc flashadc(camgeom->GetNumPixels()); 3988 3989 // initialize flag 3990 4196 // Instance of MTrigger and MFadc; needed here only as dummies for 4197 // a call to produce_phes (see below). 4198 // 15/09/2004, A. Moralejo, changed "trigger" and "flashadc" to 4199 // pointers, the former static allocation caused memory problems and 4200 // segmentation fault in some systems. 4201 4202 MTrigger* trigger = new MTrigger(camgeom->GetNumPixels(),camgeom, 4203 Trigger_gate_length, 4204 Trigger_overlaping_time, 4205 Trigger_response_ampl, 4206 Trigger_response_fwhm); 4207 4208 MFadc* flashadc = new MFadc(camgeom->GetNumPixels(), 4209 FADC_shape, 4210 FADC_response_integ,FADC_response_fwhm, 4211 FADC_shape_out, 4212 FADC_resp_integ_out,FADC_resp_fwhm_out, 4213 get_trig_delay()); 4214 4215 // initialize flag 3991 4216 strcpy( cflag, " \0" ); 3992 4217 … … 4038 4263 4039 4264 if (reflector_file_version<6) 4040 fread( (char*)&evth, evth.mysize(), 1, infile ); 4265 // fread( (char*)&evth, evth.mysize(), 1, infile ); 4266 evth.read(infile); 4041 4267 else 4042 fread( (char*)&evth_2, evth_2.mysize(), 1, infile ); 4043 4268 // fread( (char*)&evth_2, evth_2.mysize(), 1, infile ); 4269 evth_2.read(infile); 4270 4044 4271 if (reflector_file_version<6) 4045 4272 integtime_ns = evth.get_energy(); … … 4081 4308 wl_nm[i], 4082 4309 wl_nm[i+1], 4083 &trigger, // this is a dummy here4084 &flashadc, // this is a dummy here4310 trigger, // this is a dummy here 4311 flashadc, // this is a dummy here 4085 4312 &itnphe, 4086 4313 nphe, // we want this! … … 4088 4315 &tmin_ns, 4089 4316 &tmax_ns, 4090 0 4091 ); // photons from starfield4317 0, 4318 mirror_fraction); // photons from starfield 4092 4319 4093 4320 if( k != 0 ){ // non-zero returnvalue means error … … 4124 4351 4125 4352 return(0); 4126 4127 }4128 4129 4130 //------------------------------------------------------------4131 // @name produce_nsb_phes4132 //4133 // @desc produce the photoelectrons from the nsbrates4134 //4135 // @date Thu Feb 17 17:10:40 CET 20004136 // @function @code4137 //------------------------------------------------------------4138 4139 int produce_nsb_phes( float *atmin_ns,4140 float *atmax_ns,4141 float theta_rad,4142 struct camera *cam,4143 float nsbr_phepns[iMAXNUMPIX][iNUMWAVEBANDS],4144 float difnsbr_phepns[iMAXNUMPIX],4145 float extinction[iNUMWAVEBANDS],4146 float fnpx[iMAXNUMPIX],4147 MTrigger *trigger,4148 MFadc *fadc,4149 int *inphe,4150 float base_mv[iMAXNUMPIX]){4151 4152 float simtime_ns; // NSB simulation time4153 int i, j, k, ii;4154 float zenfactor; // correction factor calculated from the extinction4155 int inumnsbphe; // number of photoelectrons caused by NSB4156 4157 float t;4158 TRandom random; // Random numbers generator4159 4160 random.SetSeed(get_seeds(1));4161 4162 ii = *inphe; // avoid dereferencing4163 4164 // check if the arrival times are set; if not generate them4165 4166 if(*atmin_ns <SIMTIMEOFFSET_NS || *atmin_ns > *atmax_ns){4167 *atmin_ns = 0.;4168 *atmax_ns = simtime_ns = TOTAL_TRIGGER_TIME;4169 4170 }4171 else{ // extend the event time window by the given offsets4172 4173 *atmin_ns = *atmin_ns - SIMTIMEOFFSET_NS;4174 *atmax_ns = *atmax_ns + SIMTIMEOFFSET_NS;4175 4176 simtime_ns = *atmax_ns - *atmin_ns;4177 4178 // make sure the simulated time is long enough for the FADC4179 // simulation and not too long4180 4181 if(simtime_ns< TOTAL_TRIGGER_TIME){4182 *atmin_ns = *atmin_ns -(TOTAL_TRIGGER_TIME-simtime_ns)/2;4183 *atmax_ns = *atmin_ns + TOTAL_TRIGGER_TIME;4184 simtime_ns = TOTAL_TRIGGER_TIME;4185 }4186 4187 if(simtime_ns> TOTAL_TRIGGER_TIME){4188 *atmax_ns =*atmin_ns + TOTAL_TRIGGER_TIME;4189 simtime_ns = TOTAL_TRIGGER_TIME;4190 }4191 4192 }4193 4194 // initialize baselines4195 4196 for(i=0; i<cam->inumpixels; i++){4197 base_mv[i] = 0.;4198 }4199 4200 // calculate baselines and generate phes4201 4202 for(i=0; i<iNUMWAVEBANDS; i++){ // loop over the wavebands4203 4204 // calculate the effect of the atmospheric extinction4205 4206 zenfactor = pow(10., -0.4 * extinction[i]/cos(theta_rad) );4207 4208 for(j=0; j<cam->inumpixels; j++){ // loop over the pixels4209 4210 inumnsbphe = (int) ((zenfactor * nsbr_phepns[j][i] + difnsbr_phepns[j]/iNUMWAVEBANDS)4211 * simtime_ns );4212 4213 base_mv[j] += inumnsbphe;4214 4215 // randomize4216 4217 if (inumnsbphe>0.0){4218 inumnsbphe = random.Poisson (inumnsbphe );4219 }4220 4221 // create the photoelectrons4222 4223 for(k=0; k < inumnsbphe; k++){4224 4225 t=(RandomNumber * simtime_ns);4226 4227 (*fadc).Fill(j,t ,(*trigger).FillNSB(j,t));4228 4229 ii++; // increment total number of photoelectons4230 4231 fnpx[j] += 1.; // increment number of photoelectrons in this pixel4232 4233 }4234 4235 } // end for(j=0 ...4236 } // end for(i=0 ...4237 4238 // finish baseline calculation4239 4240 for(i=0; i<cam->inumpixels; i++){4241 base_mv[i] *= RESPONSE_FWHM * RESPONSE_AMPLITUDE / simtime_ns;4242 }4243 4244 *inphe = ii; // update the pointer4245 4246 return(0);4247 4353 } 4248 4354 … … 4257 4363 // 4258 4364 // $Log: not supported by cvs2svn $ 4365 // 4366 // Revision 1.70 2004/09/15 A. Moralejo 4367 // Changed "flashadc" and "trigger" in procedure produce_nsbrates from 4368 // objects to pointers (followed by dynamical allocation). This is only 4369 // to avoid memory problems (-> segmentation fault) in some systems. 4370 // Introduced missing initialization to 0 of *itotnphe in produce_phes. 4371 // Now the number of phes produced by stars shown on the screen make sense. 4372 // 4373 // Revision 1.69 2004/03/30 4374 // Changed calculation of MMcFadcHeader.fPedesSigmaHigh and 4375 // MMcFadcHeader.fPedesSigmaLow to do as in real data (see comments in 4376 // code). Changed meaning of MMcFadcHeader.fAmplFadc and fAmplFadcOuter, 4377 // from amplitude to integral of single photoelectron pulse in FADC 4378 // counts. Added possibility to choose a realistic pulse shaped (as 4379 // measured using pulpo). Changed file Data/lightguides.dat by 4380 // Data/LightCollection.dat, intended to contain the information on 4381 // light collection efficiency regarding Winston cones, plexiglas, double 4382 // PMT crossing and colection efficiency of 1st dynode of PMT. Now the 4383 // information for inner and outer pixels can be different, since in the 4384 // LightCollection.dat file they are set independently. 4385 // 4386 // Revision 1.68 2004/02/06 17:39:24 blanch 4387 // Compiling with root 3.05 and updating MARS files. 4388 // 4259 4389 // Revision 1.67 2004/01/30 09:51:18 blanch 4260 4390 // [Changes mainly done by A. Moralejo] … … 4265 4395 // has been introduced. 4266 4396 // 4267 // The possibilty to unlarge the point spread function has been introduced4397 // The possibilty to enlarge the point spread function has been introduced 4268 4398 // in order to be able to simualte the current data. 4269 4399 //
Note:
See TracChangeset
for help on using the changeset viewer.