NCFS-Pack
A generic (astro)particle physics analysis framework
 
Loading...
Searching...
No Matches
NcAstrolab.cxx
Go to the documentation of this file.
1
31
33
187
188#include "NcAstrolab.h"
189#include "Riostream.h"
190
191ClassImp(NcAstrolab); // Class implementation to enable ROOT I/O
192
194NcAstrolab::NcAstrolab(const char* name,const char* title) : TTask(name,title),NcTimestamp()
195{
201
202 fExperiment="User";
203 fLabId=0;
204 fToffset=0;
205 fRefs=0;
206 fSigs=0;
207 fNen[0]=0;
208 fNen[1]=0;
209 fBias=0;
210 fGal=0;
211 fIndices=0;
212 fUsMeridian=0;
213 fMeridian=0;
214 fProj="none";
215 fCanvas=0;
216 fHist[0]=0;
217 fHist[1]=0;
218 fMarkers=0;
219 fMarkerSize[0]=1.5;
220 fMarkerSize[1]=1;
221 fMarkerSize[2]=1.5;
222 fMarkerSize[3]=0.3;
223 fMarkerStyle[0]=29;
224 fMarkerStyle[1]=8;
225 fMarkerStyle[2]=34;
226 fMarkerStyle[3]=8;
227 fMarkerColor[0]=kRed;
228 fMarkerColor[1]=kBlue;
229 fMarkerColor[2]=kBlack;
230 fMarkerColor[3]=kBlack;
231 fSkyMapPanel=0;
232 fTscmode=0;
233 fTscmin=0;
234 fTscmax=0;
235 fTscfunc=0;
236 fRscmode=0;
237 fDscmin=0;
238 fDscmax=0;
239 fDscfunc=0;
240 fThetascmin=0;
241 fThetascmax=0;
242 fThetascfunc=0;
243 fPhiscmin=0;
244 fPhiscmax=0;
245 fPhiscfunc=0;
246 fRan=0;
247 fMaxDt=-1;
248 fSolUpdate=0;
249
250 // Standard values (Particle Data Group 2018) for some (astro)physical parameters
251 fSpeedC=299792458;
252 fQe=1.602176565e-19;
253 fMe=0.510998928;
254 fMmu=105.6583715;
255 fMtau=1776.82;
256 fAmu=931.494061;
257 fMp=1.007276466812*fAmu;
258 fMn=1.00866491600*fAmu;
259 fMW=80.385;
260 fGammaW=2.085;
261 fMZ=91.1876;
262 fGammaZ=2.4952;
263 fAlphaEM=1./137.035999074;
264 fFermi=1.1663787e-5;
265 fPlanck=6.62606957e-34;
266 fBoltz=1.3806488e-23;
267 fNewton=6.67384e-11;
268 fGn=9.80665;
269 fAu=1.49597870700e11;
270 fPc=3.08567758149e16;
271 // Cosmological parameters from the final Planck 2018 results (arXiv:1807.06209)
272 fHubble=67.4;
273 fOmegaM=0.315;
274 fOmegaR=5.38e-5;
275 fOmegaL=0.685;
276 fOmegaB=0.0492;
277 fOmegaC=0.264;
278
279 // Some derived (astro)physical parameters c.q. conversion constants
280 fHbar=6.58211928e-22;
281 fHbarc=197.3269718;
282 fHbarc2=3.89379338e-4;
283
284 // Function to parametrize the Neutrino-Lepton kinematic opening angle
285 fNuAngle=0;
286
287 // Specifications of the data from a ROOT input Tree
288 fDataDir=0;
289 fDataFrame="undefined";
290 fDataMode="undefined";
291
292 // Identifiers of the signal and background energy profiles
293 fSigEmode="-";
294 fBkgEmode="-";
295
296 // Storage for transient burst investigations
298
299 // Initialize the default values for the burst parameters
300 SetBurstParameter("*",0);
301
302 // Load the UTC parameters
304
305 // Set the default local frame convention
306 // X-axis pointing South (=Greenwich)
307 // Y-axis pointing East
308 // Z-axis pointing towards Zenith
309 SetLocalFrame(90,0,90,90,0,0);
310
311 // First initialization of the various SkyMapPanel GUI parameters.
312 // In case SkyMapPanel() is invoked, the current Lab settings will be imported.
313 fSkyMapPanel=0;
314 fMapTS.LoadUTCparameterFiles();
315 for (Int_t i=0; i<3; i++)
316 {
317 fMapLabLBI[i]=0;
318 }
319 fMapLabU=0;
320 fMapLabE=0;
321 fMapLabLocL=0;
322 fMapLabLocB=0;
323 fMapLabLocU="deg";
324 fMapLabExpName="User";
325 fMapLabId=0;
328 fMapDate="";
329 fMapTime="";
330 fMapTimeType="-";
331 fMapDateTime="";
332 fMapLabTS=kTRUE;
333 for (Int_t i=0; i<6; i++)
334 {
335 fMapLabLframe[i]=0;
336 }
337 fMapCinfo="Lab";
338 fMapTinfo=-1;
339 fMapUinfo="deg";
340 fMapIname="";
341 fMapEa=0;
342 fMapEua="deg";
343 fMapEb=0;
344 fMapEub="deg";
345 fMapEtype=1;
346 fMapEcoord="-";
347 fMapEmode="-";
348 fMapEname="";
349 fMapDcoord="-";
350 fMapProj="-";
351 fMapDmode="-";
352 for (Int_t i=0; i<5; i++)
353 {
354 fMapDoptions[i]=kFALSE;
355 }
356 fMapNmax=-1;
357 fMapNdigs=1;
358 fMapDname="";
359 for (Int_t i=0; i<10; i++)
360 {
361 fMapSolar[i]=kFALSE;
362 }
363 fMapMerMode=0;
364 fMapMerC=0;
365 fMapMerUc="deg";
366 fMapMarkSize=1;
367 fMapMarkStyle=23;
368 fMapMarkColor=kRed;
369 fMapMarkType=0;
370}
371
373{
379
380 if (fRefs)
381 {
382 delete fRefs;
383 fRefs=0;
384 }
385 if (fSigs)
386 {
387 delete fSigs;
388 fSigs=0;
389 }
390 if (fIndices)
391 {
392 delete fIndices;
393 fIndices=0;
394 }
395 for (Int_t i=0; i<2; i++)
396 {
397 if (fHist[i])
398 {
399 delete fHist[i];
400 fHist[i]=0;
401 }
402 }
403 if (fMarkers)
404 {
405 delete fMarkers;
406 fMarkers=0;
407 }
408 if (fCanvas)
409 {
410 if (gROOT->GetListOfCanvases()->FindObject("NcAstrolab")) delete fCanvas;
411 fCanvas=0;
412 }
413 if (fTscfunc)
414 {
415 delete fTscfunc;
416 fTscfunc=0;
417 }
418 if (fDscfunc)
419 {
420 delete fDscfunc;
421 fDscfunc=0;
422 }
423 if (fThetascfunc)
424 {
425 delete fThetascfunc;
426 fThetascfunc=0;
427 }
428 if (fPhiscfunc)
429 {
430 delete fPhiscfunc;
431 fPhiscfunc=0;
432 }
433 if (fRan)
434 {
435 delete fRan;
436 fRan=0;
437 }
438
439 if (fNuAngle)
440 {
441 delete fNuAngle;
442 fNuAngle=0;
443 }
444
446 {
447 delete fBurstParameters;
449 }
450
451 // Remove the subtasks from the internal TTask list without deleting them
452 if (fTasks) fTasks->Clear();
453}
454
456{
462
465 fLabId=t.fLabId;
466 fL=t.fL;
467 Int_t size=0;
468 fRefs=0;
469 if (t.fRefs)
470 {
471 size=t.fRefs->GetSize();
472 fRefs=new TObjArray(size);
473 for (Int_t i=0; i<size; i++)
474 {
475 NcSignal* sx=(NcSignal*)t.fRefs->At(i);
476 if (sx) fRefs->AddAt(sx->Clone(),i);
477 }
478 }
479 fSigs=0;
480 if (t.fSigs)
481 {
482 size=t.fSigs->GetSize();
483 fSigs=new TObjArray(size);
484 for (Int_t i=0; i<size; i++)
485 {
486 NcSignal* sx=(NcSignal*)t.fSigs->At(i);
487 if (sx) fSigs->AddAt(sx->Clone(),i);
488 }
489 }
490 fNen[0]=t.fNen[0];
491 fNen[1]=t.fNen[1];
492 fBias=0;
493 fGal=0;
494 fIndices=0;
495 fMeridian=-999;
496 fProj="none";
497 fCanvas=0;
498 for (Int_t ih=0; ih<2; ih++)
499 {
500 fHist[ih]=0;
501 }
502 fMarkers=0;
503 for (Int_t i=0; i<4; i++)
504 {
505 fMarkerSize[i]=t.fMarkerSize[i];
506 fMarkerStyle[i]=t.fMarkerStyle[i];
507 fMarkerColor[i]=t.fMarkerColor[i];
508 }
509
510 fTscmode=0;
511 fTscmin=0;
512 fTscmax=0;
513 fTscfunc=0;
514 SetTimeScramble(t.fTscmode,t.fTscmin,t.fTscmax,t.fTscfunc);
515
516 fRscmode=0;
517 fDscmin=0;
518 fDscmax=0;
519 fDscfunc=0;
520 fThetascmin=0;
521 fThetascmax=0;
522 fThetascfunc=0;
523 fPhiscmin=0;
524 fPhiscmax=0;
525 fPhiscfunc=0;
526 SetPositionScramble(t.fRscmode,t.fDscmin,t.fDscmax,t.fDscfunc,t.fThetascmin,t.fThetascmax,t.fThetascfunc,t.fPhiscmin,t.fPhiscmax,t.fPhiscfunc);
527
528 fRan=0;
529 NcRandom* ran=t.fRan;
530 if (ran) fRan=new NcRandom(*ran);
531
532 fMaxDt=t.fMaxDt;
533
534 TF1* fx=t.fNuAngle;
535 if (fx) fNuAngle=(TF1*)fx->Clone();
536
537 NcDevice* dx=t.fBurstParameters;
538 if (dx) fBurstParameters=(NcDevice*)dx->Clone();
539}
540
541void NcAstrolab::Data(Int_t mode,TString u,Bool_t utc)
542{
564
565 TString name=GetName();
566 TString title=GetTitle();
567 printf(" *%-s::Data*",ClassName());
568 if (name!="") printf(" Name : %-s",name.Data());
569 if (title!="") printf(" Title : %-s",title.Data());
570 printf("\n");
571
572 Double_t l,b;
573 GetLabPosition(l,b,"deg");
574 printf(" Position longitude : "); PrintAngle(l,"deg",u,3);
575 printf(" latitude : "); PrintAngle(b,"deg",u,3);
576 printf(" for detector ID : %-i \n",fLabId);
577 printf(" Local user reference frame orientation w.r.t X0=South, Y0=East and Z0=Zenith : \n");
578 printf(" (Note : At the Poles (e.g. IceCube) South means the Greenwich meridian) \n");
579 TString saxes[3]={"Local X-axis","Local Y-axis","Local Z-axis"};
580 for (Int_t i=0; i<5; i+=2)
581 {
582 printf(" %-s : zenith=",saxes[i/2].Data()); PrintAngle(fAxes[i],"deg",u,3,kTRUE);
583 printf(" | phi="); PrintAngle(fAxes[i+1],"deg",u,3,kTRUE);
584 printf("\n");
585 }
586 printf(" Lab time offset w.r.t. UT : "); PrintTime(fToffset,12);
587 printf("\n");
588
589 // UT and Local time info
590 Date(mode,fToffset);
591
592 // Add the UTC and TAI related date/time information if requested
593 if (utc && mode!=4) Date(4);
594
595 if (fTscmode)
596 {
597 printf(" ------------------ Time scrambling ----------------- \n");
598 if (fTscmode<0)
599 {
600 printf(" *** Scrambling is applied only for off-source patch (background) data generation in MatchBurstData() *** \n");
601 printf(" *** The actual stored source and measurement data are not modified *** \n");
602 printf("\n");
603 }
604 if (abs(fTscmode)==1)
605 {
606 printf(" *** Each obtained time difference will be scrambled (mode %-i) *** \n",fTscmode);
607 printf(" *** The angular differences are not affected *** \n");
608 printf(" --> Tailored for scrambling entries in a specific time window without affecting \n");
609 printf(" the event selection based on angular separation w.r.t. a source. \n");
610 }
611 if (abs(fTscmode)==2)
612 {
613 if (fTscmode>0)
614 {
615 printf(" *** Each measurement is stored with a scrambled timestamp (mode %-i) *** \n",fTscmode);
616 printf(" *** The data of the sources are not modified *** \n");
617 printf(" *** Off-source (background) data : At each source matching, the measurement is given a new scrambled fake timestamp *** \n");
618 printf(" --> Tailored for blind analyses without access to the unblinded measurement data \n");
619 }
620 else
621 {
622 printf(" *** At each source matching, the measurement is given a new scrambled fake timestamp (mode %-i) *** \n",fTscmode);
623 }
624 printf(" --> Possible patterns in the distribution of sources on the sky will stay intact \n");
625 }
626 if (abs(fTscmode)==3)
627 {
628 printf(" *** At each measurement matching, the source is retrieved from the storage with a scrambled fake timestamp (mode %-i) *** \n",fTscmode);
629 printf(" *** The measurements are not affected --> Detection efficiency is unaltered *** \n");
630 printf(" --> Both time and angular differences will be scrambled \n");
631 printf(" --> Possible patterns in the distribution of sources on the sky will be washed out \n");
632 }
633 TString sx="offsets";
634 if (abs(fTscmode)==1) sx="differences";
635 printf(" Time %-s are randomly drawn from the interval [%-g,%-g] sec. \n",sx.Data(),fTscmin,fTscmax);
636 if (fTscfunc)
637 {
638 printf(" Randomising TF1 function %-s is used. \n",fTscfunc->GetName());
639 }
640 else
641 {
642 printf(" Uniform randomisation is used. \n");
643 }
644 }
645
646 if (fRscmode)
647 {
648 printf(" ------------------ Position scrambling ------------------ \n");
649 if (fRscmode<0)
650 {
651 printf(" *** Scrambling is applied only for off-source patch (background) data generation in MatchBurstData() *** \n");
652 printf(" *** The actual stored source and measurement data are not modified *** \n");
653 }
654 else
655 {
656 printf(" *** The data of the sources and the measurement timestamps are not modified *** \n");
657 }
658 printf("\n");
659
660 if (abs(fRscmode)==1)
661 {
662 printf(" *** Each obtained angular difference will be scrambled (mode %-i) *** \n",fRscmode);
663 printf(" *** The time differences are not affected *** \n");
664 printf(" ---> Tailored for scrambling entries within a specific angular range w.r.t. a source,");
665 printf(" without affecting the event selection based on the time difference w.r.t. a transient source. \n");
666 printf(" Angular differences are randomly drawn from the interval [%-g,%-g] degrees. \n",fDscmin,fDscmax);
667 if (fDscfunc)
668 {
669 printf(" Randomising TF1 function %-s is used. \n",fDscfunc->GetName());
670 }
671 else
672 {
673 printf(" Homogeneous solid angle randomisation is used. \n");
674 }
675 }
676
677 if (fRscmode==2)
678 {
679 printf(" *** Each measurement is stored with a scrambled fake local position (mode %-i) *** \n",fRscmode);
680 printf(" *** Off-source (background) data : At each source matching, the measurement is given a new scrambled fake local position *** \n");
681 printf(" --> Tailored for blind analyses without access to the unblinded measurement data \n");
682 }
683
684 if (abs(fRscmode)==3 || fRscmode==-2)
685 {
686 printf(" *** At each source matching, the measurement is given a new scrambled fake local position (mode %-i) *** \n",fRscmode);
687 }
688
689 if (abs(fRscmode)>1)
690 {
691 printf(" The local coordinates (r,theta,phi) of the measurement are modified to (r+dr,theta+dtheta,phi+dphi) with : \n");
692
693 printf(" dr is randomly drawn from the interval [%-g,%-g] \n",fDscmin,fDscmax);
694 if (fDscfunc)
695 {
696 printf(" Randomising TF1 function %-s is used. \n",fDscfunc->GetName());
697 }
698 else
699 {
700 printf(" Uniform randomisation is used. \n");
701 }
702
703 printf(" dtheta is randomly drawn from the interval [%-g,%-g] degrees. \n",fThetascmin,fThetascmax);
704 if (fThetascfunc)
705 {
706 printf(" Randomising TF1 function %-s is used. \n",fThetascfunc->GetName());
707 }
708 else
709 {
710 printf(" Uniform cos(theta) randomisation is used. \n");
711 }
712
713 printf(" dphi is randomly drawn from the interval [%-g,%-g] degrees. \n",fPhiscmin,fPhiscmax);
714 if (fPhiscfunc)
715 {
716 printf(" Randomising TF1 function %-s is used. \n",fPhiscfunc->GetName());
717 }
718 else
719 {
720 printf(" Uniform phi randomisation is used. \n");
721 }
722 }
723 }
724
725 printf(" ------------------ \n");
726 if (fRan)
727 {
728 Int_t iseed,cnt1,cnt2;
729 GetRandomiser(iseed,cnt1,cnt2);
730 cout << " *** Current settings of the internal NcRandom randomiser : iseed=" << iseed << " cnt1=" << cnt1 << " cnt2=" << cnt2 << endl;
731 }
732 else
733 {
734 cout << " *** The internal NcRandom randomiser is currently not intialised ***" << endl;
735 cout << " Automatic initialisation will be performed with the actual timestamp at the first random number request." << endl;
736 cout << " This will ensure different random sequences for different NcAstrolab instances." << endl;
737 cout << " To obtain reproducible scrambled results, please invoke SetRandomiser() before the first SetSignal() invokation." << endl;
738 }
739 printf(" ------------------ \n");
740}
741
743{
764
765 fLabPos.SetPosition(p);
766
767 // Determine local time offset in fractional hours w.r.t. UT.
768 Double_t vec[3];
769 p.GetVector(vec,"sph","deg");
770 Double_t l=vec[2];
771 fToffset=l/15.;
772}
773
774void NcAstrolab::SetLabPosition(Double_t l,Double_t b,TString u)
775{
808
809 Double_t r=1,theta=0,phi=0;
810
811 l=ConvertAngle(l,u,"deg");
812 b=ConvertAngle(b,u,"deg");
813
814 Double_t offset=90.;
815
816 theta=offset-b;
817 phi=l;
818
819 Double_t p[3]={r,theta,phi};
820 fLabPos.SetPosition(p,"sph","deg");
821
822 // Local time offset in fractional hours w.r.t. UT.
823 fToffset=l/15.;
824}
825
826void NcAstrolab::SetExperiment(TString name,Int_t id)
827{
866
867 fExperiment="User";
868 fLabId=0;
869
870 Double_t l=0; // Longitude
871 Double_t b=0; // Lattitude
872
873 if (name=="User")
874 {
875 SetNameTitle("User","Virtual Lab for general use");
876 SetLabPosition(0,90,"deg"); // North Pole
877 // Right handed local grid frame has X-South (to Greenwich), Y-East and Z-Zenith
878 // which is the same as the Master Reference Frame (MRF)
879 SetLocalFrame(90,0,90,90,0,0);
880 fExperiment=name;
881 fLabId=id;
882 return;
883 }
884
885 if (name=="Greenwich")
886 {
887 // Exact location : 51d 28' 36.6672" (N) and 0d 0' 1.8000" (W)
888 SetNameTitle("Greenwich","The Royal Observatory in the UK");
889 l=-0.000500;
890 b=51.476852;
891 SetLabPosition(l,b,"deg"); // South Pole
892 // Right handed Greenwich local grid frame has X-South, Y-East and Z-Zenith
893 // which is the same as the Master Reference Frame (MRF)
894 SetLocalFrame(90,0,90,90,0,0);
895 fExperiment=name;
896 return;
897 }
898
899 if (name=="Amanda")
900 {
901 SetNameTitle("Amanda","Antarctic Muon And Neutrino Detector Array");
902 SetLabPosition(0,-90,"deg"); // South Pole
903 // Right handed Amanda local grid frame has Y-North (to Greenwich), X-East and Z-Zenith
904 SetLocalFrame(90,90,90,180,0,0);
905 fExperiment=name;
906 return;
907 }
908
909 if (name=="IceCube")
910 {
911 // Exact location : 89d 59' 23.977" (S) and 63d 37' 21.432" (W)
912 SetNameTitle("IceCube","The South Pole Neutrino Observatory");
913 l=-63.453056;
914 b=-89.99;
915 SetLabPosition(l,b,"deg"); // South Pole
916 // Right handed IceCube local grid frame has Y-North (to Greenwich), X-East and Z-Zenith
917 SetLocalFrame(90,90.+l,90,180.+l,0,0);
918 fExperiment=name;
919 return;
920 }
921
922 if (name=="WSRT")
923 {
924 SetNameTitle("WSRT","The Westerbork Synthesis Radio Telescope");
925 SetLabPosition(63612.74,525454.33,"dms");
926 // Right handed local grid frame has X-South, Y-East and Z-Zenith
927 // which is the same as the Master Reference Frame (MRF)
928 SetLocalFrame(90,0,90,90,0,0);
929 fExperiment=name;
930 return;
931 }
932
933 if (name=="Astron")
934 {
935 SetNameTitle("Astron","The Netherlands Institute for Radio Astronomy");
936 SetLabPosition(62346.23,524843.99,"dms");
937 // Right handed local grid frame has X-South, Y-East and Z-Zenith
938 // which is the same as the Master Reference Frame (MRF)
939 SetLocalFrame(90,0,90,90,0,0);
940 fExperiment=name;
941 return;
942 }
943
944 if (name=="ARA")
945 {
946 SetNameTitle("ARA","The Askaryan Radio Array at the South Pole");
947 SetLabPosition(0,-90,"deg"); // South Pole
948 // Right handed ARA local grid frame has Y-North (to Greenwich), X-East and Z-Zenith
949 SetLocalFrame(90,90,90,180,0,0);
950 fExperiment=name;
951 return;
952 }
953
954 if (name=="RNO-G")
955 {
956 SetNameTitle("RNO-G","The Greenland Radio Neutrino Observatory at Summit Station");
957 // Use the location of the Big House as global location
958 l=-38.4604;
959 b=72.57889;
960
961 // The locations of the various stations
962 Int_t ids[35]={11,12,13,14,15,16,17,21,22,23,24,25,26,27,33,34,35,36,37,44,45,46,47,54,55,56,57,64,65,66,67,74,75,76,77};
963 Float_t ls[35]={-38.5023,-38.4962,-38.4901,-38.4841,-38.4780,-38.4719,-38.4657,-38.4660,-38.4599,-38.4538,-38.4477,-38.4416,-38.4355,-38.4293, /*last is 27*/
964 -38.4175,-38.4114,-38.4053,-38.3991,-38.3930,-38.3751,-38.3689,-38.3627,-38.3566,-38.3388,-38.3326,-38.3264,-38.3202,-38.3025, /*last is 64*/
965 -38.2963,-38.2900,-38.2838,-38.2662,-38.2599,-38.2537,-38.2474};
966 Float_t bs[35]={72.58923,72.60009,72.61095,72.62181,72.63267,72.64353,72.65439,72.58741,72.59827,72.60912,72.61998,72.63084,72.64170,72.65256, /*last is 27*/
967 72.60729,72.61815,72.62901,72.63987,72.65073,72.61631,72.62717,72.63803,72.64889,72.61447,72.62533,72.63618,72.64704,72.61262, /*last is 64*/
968 72.62347,72.63433,72.64518,72.61076,72.62161,72.63247,72.64332};
969
970 // Select a specific station, if requested
971 if (id)
972 {
973 for (Int_t i=0; i<35; i++)
974 {
975 if (id==ids[i])
976 {
977 l=ls[i];
978 b=bs[i];
979 fLabId=id;
980 break;
981 }
982 }
983 }
984
985 // Set the selected location
986 SetLabPosition(l,b,"deg"); // Summit Station
987 // Right handed RNO-G local grid frame has Y-North, X-East and Z-Zenith
988 SetLocalFrame(90,90,90,180,0,0);
989 fExperiment=name;
990 return;
991 }
992
993 if (name=="ARCA")
994 {
995 SetNameTitle("ARCA","The KM3NeT/ARCA Neutrino detector near Sicily");
996 SetLabPosition(155842.25,361748.34,"dms");
997 // Right handed ARCA local grid frame has Y-North, X-East and Z-Zenith
998 SetLocalFrame(90,90,90,180,0,0);
999 fExperiment=name;
1000 return;
1001 }
1002
1003 cout << " *" << ClassName() << "::SetExperiment* Unsupported experiment name : " << name.Data() << endl;
1004 printf(" Experiment is set to %-s with detector identifier %-i \n",fExperiment.Data(),fLabId);
1005}
1006
1008{
1018
1019 fToffset=dt;
1020}
1021
1023{
1032
1033 return fLabPos;
1034}
1035
1036void NcAstrolab::GetLabPosition(Double_t& l,Double_t& b,TString u) const
1037{
1053
1054 Double_t pi=acos(-1.);
1055
1056 Double_t offset=90.;
1057 if (u=="rad") offset=pi/2.;
1058
1059 Double_t p[3];
1060 fLabPos.GetPosition(p,"sph",u);
1061 b=offset-p[1];
1062 l=p[2];
1063}
1064
1066{
1072
1073 return fExperiment;
1074}
1075
1077{
1083
1084 return fLabId;
1085}
1086
1088{
1096
1097 return fToffset;
1098}
1099
1100void NcAstrolab::SetRandomiser(Int_t iseed,Int_t cnt1,Int_t cnt2,NcTimestamp* ts)
1101{
1145
1146 if (!ts) ts=(NcTimestamp*)this;
1147
1148 if (fRan) delete fRan;
1149
1150 fRan=new NcRandom(iseed,cnt1,cnt2,ts);
1151}
1152
1153NcRandom* NcAstrolab::GetRandomiser(Int_t& iseed,Int_t& cnt1,Int_t& cnt2) const
1154{
1164
1165 iseed=-1;
1166 cnt1=-1;
1167 cnt2=-1;
1168
1169 if (!fRan) return 0;
1170
1171 iseed=fRan->GetSeed();
1172 cnt1=fRan->GetCnt1();
1173 cnt2=fRan->GetCnt2();
1174
1175 return fRan;
1176}
1177
1178void NcAstrolab::SetMaxDt(Double_t s)
1179{
1191
1192 fMaxDt=s;
1193}
1194
1195Double_t NcAstrolab::GetMaxDt() const
1196{
1206
1207 return fMaxDt;
1208}
1209
1211{
1220
1221 Double_t h=GetLT(fToffset);
1222 return h;
1223}
1224
1226{
1238
1239 Double_t h=GetLMST(fToffset);
1240 return h;
1241}
1242
1244{
1256
1257 Double_t h=GetLAST(fToffset);
1258 return h;
1259}
1260
1261void NcAstrolab::PrintAngle(Double_t a,TString in,TString out,Int_t ndig,Bool_t align) const
1262{
1298
1299 Double_t b=ConvertAngle(a,in,out);
1300
1301 if (out=="deg" || out=="rad")
1302 {
1303 if (align)
1304 {
1305 printf("%*.*f %-s",5+ndig,ndig,b,out.Data());
1306 }
1307 else
1308 {
1309 printf("%-.*f %-s",ndig,b,out.Data());
1310 }
1311 return;
1312 }
1313
1314 Double_t epsilon=1.e-12; // Accuracy in (arc)seconds
1315 Int_t word=0,ddd=0,hh=0,mm=0,ss=0;
1316 Double_t s;
1317
1318 if (out=="dms")
1319 {
1320 word=Int_t(b);
1321 word=abs(word);
1322 ddd=word/10000;
1323 word=word%10000;
1324 mm=word/100;
1325 ss=word%100;
1326 s=fabs(b)-Double_t(ddd*10000+mm*100+ss);
1327 if (s>(1.-epsilon))
1328 {
1329 s=0.;
1330 ss++;
1331 }
1332 while (ss>=60)
1333 {
1334 ss-=60;
1335 mm++;
1336 }
1337 while (mm>=60)
1338 {
1339 mm-=60;
1340 ddd++;
1341 }
1342 while (ddd>=360)
1343 {
1344 ddd-=360;
1345 }
1346 if (b<0) ddd=-ddd;
1347 s+=double(ss);
1348 if (align)
1349 {
1350 if (!ddd && b<0)
1351 {
1352 printf(" -0d %02i' %0*.*f\"",mm,3+ndig,ndig,s);
1353 }
1354 else
1355 {
1356 printf("%4id %02i' %0*.*f\"",ddd,mm,3+ndig,ndig,s);
1357 }
1358 }
1359 else
1360 {
1361 if (!ddd && b<0)
1362 {
1363 printf("-0d %-i' %-.*f\"",mm,ndig,s);
1364 }
1365 else
1366 {
1367 printf("%-id %-i' %-.*f\"",ddd,mm,ndig,s);
1368 }
1369 }
1370 return;
1371 }
1372
1373 if (out=="hms")
1374 {
1375 word=Int_t(b);
1376 word=abs(word);
1377 hh=word/10000;
1378 word=word%10000;
1379 mm=word/100;
1380 ss=word%100;
1381 s=fabs(b)-Double_t(hh*10000+mm*100+ss);
1382 if (s>(1.-epsilon))
1383 {
1384 s=0.;
1385 ss++;
1386 }
1387 while (ss>=60)
1388 {
1389 ss-=60;
1390 mm++;
1391 }
1392 while (mm>=60)
1393 {
1394 mm-=60;
1395 hh++;
1396 }
1397 while (hh>=24)
1398 {
1399 hh-=24;
1400 }
1401 if (b<0) hh=-hh;
1402 s+=double(ss);
1403 if (align)
1404 {
1405 if (!hh && b<0)
1406 {
1407 printf(" -0h %02im %0*.*fs",mm,3+ndig,ndig,s);
1408 }
1409 else
1410 {
1411 printf("%3ih %02im %0*.*fs",hh,mm,3+ndig,ndig,s);
1412 }
1413 }
1414 else
1415 {
1416 if (!hh && b<0)
1417 {
1418 printf("-0h %-im %-.*fs",mm,ndig,s);
1419 }
1420 else
1421 {
1422 printf("%-ih %-im %-.*fs",hh,mm,ndig,s);
1423 }
1424 }
1425 return;
1426 }
1427}
1428
1429NcSignal* NcAstrolab::SetSignal(Nc3Vector* r,TString frame,TString mode,NcTimestamp* ts,Int_t jref,TString name,Int_t type)
1430{
1502
1503 // Cope with the (obsolete) jref=0 specification
1504 if (!jref)
1505 {
1506 type=1;
1507 jref=1;
1508 delete fSigs;
1509 fSigs=0;
1510 }
1511
1512 if (!r) return 0;
1513
1514 if (!r->HasVector()) return 0;
1515
1516 if (frame!="equ" && frame!="gal" && frame!="ecl" && frame!="hor" && frame!="icr" && frame!="loc") return 0;
1517
1518 if (frame=="equ" && mode!="M" && mode!="m" && mode!="T" && mode!="t" && mode!="B" && mode!="b" && mode!="J" && mode!="j") return 0;
1519
1520 NcSignal* sx=0;
1521
1522 if (!ts) ts=(NcTimestamp*)this;
1523
1524 // Make a local copy of the timestamp to make sure that the newly stored
1525 // signal will never contain the Tree with the UTCparameter data.
1526 NcTimestamp ts2;
1527 Int_t mjd=0;
1528 Int_t isec=0;
1529 Int_t ins=0;
1530 Int_t ips=0;
1531 ts->GetMJD(mjd,isec,ins);
1532 ips=ts->GetPs();
1533 ts2.SetMJD(mjd,isec,ins,ips);
1534
1535 Double_t vec[3];
1536 vec[0]=r->GetX(1,"sph","rad");
1537 vec[1]=r->GetX(2,"sph","rad");
1538 vec[2]=r->GetX(3,"sph","rad");
1539 Nc3Vector q;
1540 q.SetVector(vec,"sph","rad");
1541
1542 // Recursive invokation in case of local coordinates
1543 if (frame=="loc")
1544 {
1545 // Convert to horizontal coordinates
1546 q=q.GetUnprimed(&fL);
1547
1548 // Store the signal
1549 sx=SetSignal(&q,"hor",mode,&ts2,jref,name,type);
1550 return sx;
1551 }
1552
1553 // If needed, initialise the randomiser with a "date/time driven" seed
1554 // using the timestamp of the moment of this invokation of the member function.
1555 // This will ensure different random sequences if the user repeats analyses
1556 // with identical measurements and reference signals without explicit initialisation
1557 // of the randomiser by the user at the start of the analysis.
1558 if (!fRan && type && (fTscmode==2 || fRscmode==2)) fRan=new NcRandom(-1);
1559
1560 // Local timestamp copy to allow time scrambling
1561 NcTimestamp tx(ts2);
1562
1563 // Perform time scrambling (measurements only) if requested
1564 if (type && fTscmode==2)
1565 {
1566 Double_t dt=0;
1567
1568 // Allow for specific offset studies
1569 if (fTscmin==fTscmax) dt=fTscmin;
1570
1571 // Go for randomly scrambled values
1572 if (fTscfunc)
1573 {
1574 if (fTscmax>fTscmin)
1575 {
1576 dt=fTscfunc->GetRandom(fTscmin,fTscmax);
1577 }
1578 }
1579 else
1580 {
1581 if (fTscmax>fTscmin) dt=fRan->Uniform(fTscmin,fTscmax);
1582 }
1583 tx.AddSec(dt);
1584 }
1585
1586 // Construct the corresponding ICRS position vector to be stored
1587 if (frame=="equ")
1588 {
1589 // Convert to "mean" values at specified epoch
1590 if (mode=="T" || mode=="t")
1591 {
1592 SetNmatrix(&tx);
1593 q=q.GetUnprimed(&fN);
1594 }
1595
1596 // Convert to "mean" values at J2000
1597 if (mode=="T" || mode=="t" || mode=="M" || mode=="m")
1598 {
1599 SetPmatrix(&tx);
1600 }
1601 else
1602 {
1603 NcTimestamp te;
1604 if (mode=="B" || mode=="b") te.SetEpoch(1950,"B");
1605 if (mode=="J" || mode=="j") te.SetEpoch(2000,"J");
1606 SetPmatrix(&te);
1607 }
1608 q=q.GetUnprimed(&fP);
1609
1610 // Convert to ICRS values
1611 if (!fBias) SetBmatrix();
1612 q=q.GetUnprimed(&fB);
1613 }
1614
1615 if (frame=="gal")
1616 {
1617 // Convert to J2000 equatorial mean coordinates
1618 if (fGal != 2) SetGmatrix("J");
1619 q=q.GetUnprimed(&fG);
1620
1621 // Convert to ICRS values
1622 if (!fBias) SetBmatrix();
1623 q=q.GetUnprimed(&fB);
1624 }
1625
1626 if (frame=="ecl")
1627 {
1628 // Convert to mean equatorial values at specified epoch
1629 SetEmatrix(&tx);
1630 q=q.GetUnprimed(&fE);
1631
1632 // Convert to "mean" values at J2000
1633 SetPmatrix(&tx);
1634 q=q.GetUnprimed(&fP);
1635
1636 // Convert to ICRS values
1637 if (!fBias) SetBmatrix();
1638 q=q.GetUnprimed(&fB);
1639 }
1640
1641 if (frame=="hor")
1642 {
1643 // Convert to "true" equatorial values at the specified timestamp
1644 SetHmatrix(&tx);
1645 q=q.GetUnprimed(&fH);
1646
1647 // Convert to "mean" values at specified timestamp
1648 SetNmatrix(&tx);
1649 q=q.GetUnprimed(&fN);
1650
1651 // Convert to "mean" values at J2000
1652 SetPmatrix(&tx);
1653 q=q.GetUnprimed(&fP);
1654
1655 // Convert to ICRS values
1656 if (!fBias) SetBmatrix();
1657 q=q.GetUnprimed(&fB);
1658 }
1659
1660 // Store the signal in ICRS coordinates
1661 Int_t size=0;
1662 Int_t jmax=0;
1663 Int_t jlast=0;
1664 if (type) // Storage of a measurement
1665 {
1666 NcSignal* sxsig=0;
1667 if (!fSigs)
1668 {
1669 fSigs=new TObjArray();
1670 fSigs->SetOwner();
1671 }
1672 // Expand array size if needed
1673 size=fSigs->GetSize();
1674 jmax=size-1;
1675 jlast=fSigs->GetLast();
1676 if (jref>0)
1677 {
1678 if (jref>size) fSigs->Expand(jref);
1679 }
1680 else
1681 {
1682 if (jlast==jmax) fSigs->Expand(size+1);
1683 }
1684 sxsig=GetSignal(jref,type);
1685 if (!sxsig)
1686 {
1687 sxsig=new NcSignal();
1688 }
1689 else
1690 {
1691 sxsig->Reset(1);
1692 }
1693 if (name=="") // Generate a corresponding measurement name
1694 {
1695 fNen[1]++;
1696 name="Meas";
1697 name+=fNen[1];
1698 name+="#";
1699 }
1700 sxsig->SetName(name);
1701 sxsig->SetTitle("Observed event in ICRS coordinates");
1702 sxsig->SetTimestamp(tx);
1703 sxsig->SetPosition(q);
1704 if (jref<0)
1705 {
1706 fSigs->Add(sxsig);
1707 }
1708 else
1709 {
1710 fSigs->AddAt(sxsig,jref-1);
1711 }
1712 sx=sxsig;
1713 }
1714 else // Storage of a reference signal
1715 {
1716 NcSignal* sxref=0;
1717 if (!fRefs)
1718 {
1719 fRefs=new TObjArray();
1720 fRefs->SetOwner();
1721 }
1722 // Expand array size if needed
1723 size=fRefs->GetSize();
1724 jmax=size-1;
1725 jlast=fRefs->GetLast();
1726 if (jref>0)
1727 {
1728 if (jref>size) fRefs->Expand(jref);
1729 }
1730 else
1731 {
1732 if (jlast==jmax) fRefs->Expand(size+1);
1733 }
1734 sxref=GetSignal(jref,type);
1735 if (!sxref)
1736 {
1737 sxref=new NcSignal();
1738 }
1739 else
1740 {
1741 sxref->Reset(1);
1742 }
1743 if (name=="") // Generate a corresponding reference name
1744 {
1745 fNen[0]++;
1746 name="Ref";
1747 name+=fNen[0];
1748 name+="#";
1749 }
1750 sxref->SetName(name);
1751 sxref->SetTitle("Reference event in ICRS coordinates");
1752 sxref->SetTimestamp(tx);
1753 sxref->SetPosition(q);
1754 if (jref<0)
1755 {
1756 fRefs->Add(sxref);
1757 }
1758 else
1759 {
1760 fRefs->AddAt(sxref,jref-1);
1761 }
1762 sx=sxref;
1763 }
1764
1765 if (fRscmode !=2 || !type) return sx;
1766
1768 // Perform position scrambling (measurements only) if requested //
1770
1771 // Get the measurement in local coordinates
1772 Int_t index=fSigs->IndexOf(sx);
1773 index++; // First storage is at index=1 and not index=0
1774 GetSignal(q,"loc",mode,&tx,index,type);
1775
1776 q.GetVector(vec,"sph","deg");
1777
1778 Double_t dd=0;
1779 Double_t dtheta=0;
1780 Double_t dphi=0;
1781
1782 // Allow specific offset studies
1783 if (fDscmin==fDscmax) dd=fDscmin;
1784 if (fThetascmin==fThetascmax) dtheta=fThetascmin;
1785 if (fPhiscmin==fPhiscmax) dphi=fPhiscmin;
1786
1787 // Go for randomly scrambled values
1788 if (fDscfunc)
1789 {
1790 if (fDscmax>fDscmin)
1791 {
1792 dd=fDscfunc->GetRandom(fDscmin,fDscmax);
1793 }
1794 }
1795 else
1796 {
1797 if (fDscmax>fDscmin) dd=fRan->Uniform(fDscmin,fDscmax);
1798 }
1799
1800 if (fThetascfunc)
1801 {
1803 {
1804 dtheta=fThetascfunc->GetRandom(fThetascmin,fThetascmax);
1805 }
1806 }
1807 else if (fThetascmax>fThetascmin)
1808 {
1809 Double_t pi=acos(-1.);
1810 Float_t cosmin=cos(fThetascmin*pi/180.);
1811 Float_t cosmax=cos(fThetascmax*pi/180.);
1812 if (cosmin>cosmax)
1813 {
1814 Float_t temp=cosmin;
1815 cosmin=cosmax;
1816 cosmax=temp;
1817 }
1818 Double_t cosang=fRan->Uniform(cosmin,cosmax);
1819 dtheta=acos(cosang)*180./pi;
1820 }
1821
1822 if (fPhiscfunc)
1823 {
1824 if (fPhiscmax>fPhiscmin)
1825 {
1826 dphi=fPhiscfunc->GetRandom(fPhiscmin,fPhiscmax);
1827 }
1828 }
1829 else
1830 {
1831 if (fPhiscmax>fPhiscmin) dphi=fRan->Uniform(fPhiscmin,fPhiscmax);
1832 }
1833
1834 vec[0]+=dd;
1835 if (vec[0]<=0) vec[0]=1e-20; // Keep a physical situation
1836 vec[1]+=dtheta;
1837 vec[2]+=dphi;
1838 q.SetVector(vec,"sph","deg");
1839
1841 // Construct the corresponding ICRS position vector to be stored //
1843
1844 // Convert to horizontal coordinates
1845 q=q.GetUnprimed(&fL);
1846
1847 // Convert to "true" equatorial values at the specified timestamp
1848 SetHmatrix(&tx);
1849 q=q.GetUnprimed(&fH);
1850
1851 // Convert to "mean" values at specified timestamp
1852 SetNmatrix(&tx);
1853 q=q.GetUnprimed(&fN);
1854
1855 // Convert to "mean" values at J2000
1856 SetPmatrix(&tx);
1857 q=q.GetUnprimed(&fP);
1858
1859 // Convert to ICRS values
1860 if (!fBias) SetBmatrix();
1861 q=q.GetUnprimed(&fB);
1862
1863 // Store the measurement position
1864 sx->SetPosition(q);
1865
1866 return sx;
1867}
1868
1869Int_t NcAstrolab::SetSolarSystem(TString name,NcTimestamp* ts,Int_t type)
1870{
1896
1897 // Only geocentric positions are allowed
1898 if (name.Contains("*")) return 0;
1899
1900 if (!ts) ts=(NcTimestamp*)this;
1901
1902 Double_t lx=0; // Geocentric ecliptic longitude of the object in degrees
1903 Double_t bx=0; // Geocentric ecliptic latitude of the object in degrees
1904 Double_t rx=0; // Distance (AU for planets, km for the Moon) between the object and the Earth.
1905
1906 Int_t set=0; // Flag to indicate that a location has been set
1907
1908 ts->Almanac(0,0,0,0,name,&lx,&bx,&rx);
1909
1910 if (rx>0) set=1;
1911
1912 // Replace c.q. store the object data as a reference or measured signal according to "type".
1913 // In case the object wasn't stored yet, jref=-1 and the object will be
1914 // added to the list of stored signals of "type".
1915 Int_t jref=GetSignalIndex(name,type);
1916 if (set && jref) SetSignal(rx,lx,"deg",bx,"deg","ecl",ts,jref,"M",name,type);
1917
1918 return set;
1919}
1920
1921NcSignal* NcAstrolab::SetSignal(Double_t d,Double_t a,TString au,Double_t b,TString bu,TString frame,NcTimestamp* ts,Int_t jref,TString mode,TString name,Int_t type)
1922{
2001
2002 // Assure physical value for the norm of the location vector
2003 if (d<=0) d=1;
2004
2005 // Convert angular coordinates to fractional degrees.
2006 a=ConvertAngle(a,au,"deg");
2007 b=ConvertAngle(b,bu,"deg");
2008
2009 Nc3Vector r;
2010 Double_t vec[3]={0,0,0};
2011 vec[0]=d;
2012
2013 // Equatorial coordinates
2014 if (frame=="equ")
2015 {
2016 if (mode!="M" && mode!="m" && mode!="T" && mode!="t" && mode!="B" && mode!="b" && mode!="J" && mode!="j") return 0;
2017 vec[1]=90.-b;
2018 vec[2]=a;
2019 }
2020
2021 // Galactic coordinates
2022 if (frame=="gal")
2023 {
2024 vec[1]=90.-b;
2025 vec[2]=a;
2026 }
2027
2028 // Geocentric ecliptic coordinates
2029 if (frame=="ecl")
2030 {
2031 vec[1]=90.-b;
2032 vec[2]=a;
2033 }
2034
2035 // Horizontal coordinates
2036 if (frame=="hor")
2037 {
2038 vec[1]=b;
2039 vec[2]=180.-a;
2040 }
2041
2042 // ICRS coordinates
2043 if (frame=="icr")
2044 {
2045 vec[1]=90.-b;
2046 vec[2]=a;
2047 }
2048
2049 // Local coordinates
2050 if (frame=="loc" || frame=="pdir")
2051 {
2052 vec[1]=a;
2053 vec[2]=b;
2054 }
2055
2056 if (!ts) ts=(NcTimestamp*)this;
2057
2058 r.SetVector(vec,"sph","deg");
2059
2060 // Revert momentum direction in order to get the source direction
2061 if (frame=="pdir")
2062 {
2063 r*=-1.;
2064 frame="loc";
2065 }
2066
2067 NcSignal* sx=SetSignal(&r,frame,mode,ts,jref,name,type);
2068 return sx;
2069}
2070
2071NcSignal* NcAstrolab::SetSignal(Double_t d,Double_t a,TString au,Double_t b,TString bu,TString frame,TString s,Double_t e,Int_t jref,TString mode,TString name,Int_t type)
2072{
2154
2155 NcTimestamp tx;
2156 tx.SetEpoch(e,s);
2157
2158 NcSignal* sx=SetSignal(d,a,au,b,bu,frame,&tx,jref,mode,name,type);
2159 return sx;
2160}
2161
2162Int_t NcAstrolab::SetSourceAttributes(NcSignal* s,Double_t sigmapos,TString u,Double_t z,Double_t T90)
2163{
2190
2191 if (!s) return 0;
2192
2193 Int_t n=3;
2194
2195 if (sigmapos<0)
2196 {
2197 sigmapos=-999;
2198 n--;
2199 }
2200 if (z<0)
2201 {
2202 z=-999;
2203 n--;
2204 }
2205 if (T90<0)
2206 {
2207 T90=-999;
2208 n--;
2209 }
2210
2211 // Convert the position uncertainty into degrees
2212 Double_t sigma=ConvertAngle(sigmapos,u,"deg");
2213
2214 s->AddNamedSlot("csigma");
2215 s->AddNamedSlot("z");
2216 s->AddNamedSlot("T90");
2217 s->SetSignal(sigma,"csigma");
2218 s->SetSignal(z,"z");
2219 s->SetSignal(T90,"T90");
2220
2221 return n;
2222}
2223
2224Double_t NcAstrolab::GetSourceAttributes(NcSignal* s,Float_t* z,Float_t* T90)
2225{
2244
2245 if (!s) return -999;
2246
2247 Double_t sigma=s->GetSignal("csigma");
2248 if (z) *z=s->GetSignal("z");
2249 if (T90) *T90=s->GetSignal("T90");
2250
2251 return sigma;
2252}
2253
2254Int_t NcAstrolab::GetNRefSignals(Int_t mode) const
2255{
2281
2282 Int_t n=GetNsignals(0,mode);
2283 return n;
2284}
2285
2286Int_t NcAstrolab::GetNsignals(Int_t type,Int_t mode) const
2287{
2311
2312 TObjArray* arr=fRefs;
2313 if (type) arr=fSigs;
2314
2315 if (!arr) return 0;
2316
2317 Int_t n=0;
2318 if (!mode)
2319 {
2320 n=arr->GetEntries();
2321 }
2322 else
2323 {
2324 n=arr->GetSize();
2325 }
2326 return n;
2327}
2328
2329NcSignal* NcAstrolab::GetSignal(Nc3Vector& r,TString frame,TString mode,NcTimestamp* ts,Int_t jref,Int_t type)
2330{
2389
2390 r.SetZero();
2391
2392 if (frame!="equ" && frame!="gal" && frame!="ecl" && frame!="hor" && frame!="icr" && frame!="loc") return 0;
2393
2394 if (frame=="equ" && mode!="M" && mode!="m" && mode!="T" && mode!="t" && mode!="B" && mode!="b" && mode!="J" && mode!="j") return 0;
2395
2396 // For backward compatibility
2397 if (!jref)
2398 {
2399 jref=1;
2400 type=1;
2401 }
2402
2403 NcSignal* sx=GetSignal(jref,type);
2404
2405 if (!sx) return 0;
2406
2407 if (!ts) ts=(NcTimestamp*)this;
2408
2409 // Check on maximum time difference
2410 if (fMaxDt>0)
2411 {
2412 NcTimestamp* tx=sx->GetTimestamp();
2413 if (!tx) return 0;
2414 Double_t dt=tx->GetDifference(ts,"s",1);
2415 if (fabs(dt)>fMaxDt) return 0;
2416 }
2417
2418 // Update coordinates for Solar system objects
2419 TString name=sx->GetName();
2420 SetSolarSystem(name,ts,type);
2421
2422 Double_t vec[3];
2423 sx->GetPosition(vec,"sph","rad");
2424 Nc3Vector q;
2425 q.SetVector(vec,"sph","rad");
2426
2427 if (frame=="icr")
2428 {
2429 r.Load(q);
2430 return sx;
2431 }
2432
2433 // Convert from ICRS to equatorial J2000 coordinates
2434 if (!fBias) SetBmatrix();
2435 q=q.GetPrimed(&fB);
2436
2437 if (frame=="equ" && mode!="J" && mode!="j")
2438 {
2439 // Precess to specified timestamp
2440 NcTimestamp ts1;
2441 ts1.SetEpoch(2000,"J");
2442 if (mode!="B" && mode!="b")
2443 {
2444 Precess(q,&ts1,ts);
2445 }
2446 else
2447 {
2448 NcTimestamp ts2;
2449 ts2.SetEpoch(1950,"B");
2450 Precess(q,&ts1,&ts2);
2451 }
2452
2453 // Nutation correction if requested
2454 if (mode=="T" || mode=="t") Nutate(q,ts);
2455 }
2456
2457 if (frame=="gal")
2458 {
2459 // Convert from equatorial J2000 to galactic
2460 if (fGal != 2) SetGmatrix("J");
2461 q=q.GetPrimed(&fG);
2462 }
2463
2464 if (frame=="ecl")
2465 {
2466 // Precess to specified timestamp
2467 NcTimestamp ts1;
2468 ts1.SetEpoch(2000,"J");
2469 Precess(q,&ts1,ts);
2470
2471 // Convert from equatorial to ecliptic coordinates
2472 SetEmatrix(ts);
2473 q=q.GetPrimed(&fE);
2474 }
2475
2476 if (frame=="hor")
2477 {
2478 // Precess to specified timestamp
2479 NcTimestamp ts1;
2480 ts1.SetEpoch(2000,"J");
2481 Precess(q,&ts1,ts);
2482
2483 // Nutation correction
2484 Nutate(q,ts);
2485
2486 // Convert from equatorial to horizontal coordinates
2487 SetHmatrix(ts);
2488 q=q.GetPrimed(&fH);
2489 }
2490
2491 if (frame=="loc")
2492 {
2493 // Get the signal in horizontal coordinates
2494 GetSignal(q,"hor",mode,ts,jref,type);
2495
2496 // Convert from horizontal to local-frame coordinates
2497 q=q.GetPrimed(&fL);
2498 }
2499
2500 r.Load(q);
2501 return sx;
2502}
2503
2504void NcAstrolab::GeoToHeliocentric(Double_t& R,Double_t& B,Double_t& L,NcTimestamp* ts,TString Bu,TString Lu)
2505{
2539
2540 if (!ts) ts=(NcTimestamp*)this;
2541
2542 // Convert the angles into radians
2543 B=ConvertAngle(B,Bu,"rad");
2544 L=ConvertAngle(L,Lu,"rad");
2545
2546 // The Carthesian Geocentric ecliptic coordinates of the object
2547 Double_t xg=R*cos(B)*cos(L);
2548 Double_t yg=R*cos(B)*sin(L);
2549 Double_t zg=R*sin(B);
2550
2551 // Get the Heliocentric ecliptic coordinates of the Earth
2552 Double_t r0,b0,l0;
2553 ts->Almanac(0,0,0,0,"Earth*",&l0,&b0,&r0);
2554
2555 l0=ConvertAngle(l0,"deg","rad");
2556 b0=ConvertAngle(b0,"deg","rad");
2557
2558 Double_t x0=r0*cos(b0)*cos(l0);
2559 Double_t y0=r0*cos(b0)*sin(l0);
2560 Double_t z0=r0*sin(b0);
2561
2562 // The Heliocentric Carthesian ecliptic coordinates of the object
2563 Double_t xh=xg+x0;
2564 Double_t yh=yg+y0;
2565 Double_t zh=zg+z0;
2566
2567 // Convert to Heliocentric distance, latitude and longitude
2568 Double_t Rh=sqrt(xh*xh+yh*yh+zh*zh);
2569 Double_t Bh=atan2(zh,sqrt(xh*xh+yh*yh));
2570 Double_t Lh=atan2(yh,xh);
2571
2572 Double_t twopi=2.*acos(-1.);
2573 while (Lh<0) { Lh+=twopi; }
2574 while (Lh>twopi) { Lh-=twopi; }
2575
2576 // Return the Heliocentric values in the original units
2577 R=Rh;
2578 B=ConvertAngle(Bh,"rad",Bu);
2579 L=ConvertAngle(Lh,"rad",Lu);
2580}
2581
2582void NcAstrolab::HelioToGeocentric(Double_t& R,Double_t& B,Double_t& L,NcTimestamp* ts,TString Bu,TString Lu)
2583{
2617
2618 if (!ts) ts=(NcTimestamp*)this;
2619
2620 // Convert the angles into radians
2621 B=ConvertAngle(B,Bu,"rad");
2622 L=ConvertAngle(L,Lu,"rad");
2623
2624 // The Carthesian Heliocentric ecliptic coordinates of the object
2625 Double_t xh=R*cos(B)*cos(L);
2626 Double_t yh=R*cos(B)*sin(L);
2627 Double_t zh=R*sin(B);
2628
2629 // Get the Heliocentric ecliptic coordinates of the Earth
2630 Double_t r0,b0,l0;
2631 ts->Almanac(0,0,0,0,"Earth*",&l0,&b0,&r0);
2632
2633 l0=ConvertAngle(l0,"deg","rad");
2634 b0=ConvertAngle(b0,"deg","rad");
2635
2636 Double_t x0=r0*cos(b0)*cos(l0);
2637 Double_t y0=r0*cos(b0)*sin(l0);
2638 Double_t z0=r0*sin(b0);
2639
2640 // The Geocentric Carthesian ecliptic coordinates of the object
2641 Double_t xg=xh-x0;
2642 Double_t yg=yh-y0;
2643 Double_t zg=zh-z0;
2644
2645 // Convert to Geocentric distance, latitude and longitude
2646 Double_t Rg=sqrt(xg*xg+yg*yg+zg*zg);
2647 Double_t Bg=atan2(zg,sqrt(xg*xg+yg*yg));
2648 Double_t Lg=atan2(yg,xg);
2649
2650 Double_t twopi=2.*acos(-1.);
2651 while (Lg<0) { Lg+=twopi; }
2652 while (Lg>twopi) { Lg-=twopi; }
2653
2654 // Return the Geocentric values in the original units
2655 R=Rg;
2656 B=ConvertAngle(Bg,"rad",Bu);
2657 L=ConvertAngle(Lg,"rad",Lu);
2658}
2659
2660NcSignal* NcAstrolab::GetSignal(Double_t& d,Double_t& a,TString au,Double_t& b,TString bu,TString frame,NcTimestamp* ts,Int_t jref,TString mode,Int_t type)
2661{
2732
2733 d=0;
2734 a=0;
2735 b=0;
2736
2737 Nc3Vector r;
2738 NcSignal* sx=GetSignal(r,frame,mode,ts,jref,type);
2739
2740 if (!sx) return 0;
2741
2742 // Retrieve the requested (a,d) values in the correct format
2743 Double_t vec[3];
2744 r.GetVector(vec,"sph","deg");
2745
2746 d=vec[0];
2747 if (d<=0) d=1;
2748 b=vec[1];
2749 a=vec[2];
2750
2751 if (frame=="equ" || frame=="gal" || frame=="ecl" || frame=="icr")
2752 {
2753 b=90.-vec[1];
2754 while (b<-90.)
2755 {
2756 b+=90.;
2757 }
2758 while (b>90.)
2759 {
2760 b-=90.;
2761 }
2762 }
2763
2764 if (frame=="hor")
2765 {
2766 a=180.-vec[2];
2767 }
2768
2769 while (a<-360.)
2770 {
2771 a+=360.;
2772 }
2773 while (a>360.)
2774 {
2775 a-=360.;
2776 }
2777
2778 // Interchange a and b to represent theta and phi, respectively, for local coordinates
2779 if (frame=="loc")
2780 {
2781 Double_t temp=a;
2782 a=b;
2783 b=temp;
2784 }
2785
2786 // Convert coordinates to appropriate format
2787 a=ConvertAngle(a,"deg",au);
2788 b=ConvertAngle(b,"deg",bu);
2789
2790 return sx;
2791}
2792
2793NcSignal* NcAstrolab::GetSignal(Double_t& d,Double_t& a,TString au,Double_t& b,TString bu,TString frame,NcTimestamp* ts,TString name,TString mode,Int_t type)
2794{
2866
2867 // Set c.q. update coordinates for Solar system objects
2868 SetSolarSystem(name,ts,type);
2869
2870 NcSignal* sx=0;
2871 Int_t j=GetSignalIndex(name,type);
2872 if (j>=0) sx=GetSignal(d,a,au,b,bu,frame,ts,j,mode,type);
2873 return sx;
2874}
2875
2876NcSignal* NcAstrolab::GetSignal(Double_t& d,Double_t& a,TString au,Double_t& b,TString bu,TString frame,TString s,Double_t e,Int_t jref,TString mode,Int_t type)
2877{
2952
2953 d=0;
2954 a=0;
2955 b=0;
2956
2957 if (s!="B" && s!="b" && s!="J" && s!="j") return 0;
2958
2959 NcTimestamp tx;
2960 tx.SetEpoch(e,s);
2961
2962 NcSignal* sx=GetSignal(d,a,au,b,bu,frame,&tx,jref,mode,type);
2963 return sx;
2964}
2965
2966NcSignal* NcAstrolab::GetSignal(Double_t& d,Double_t& a,TString au,Double_t& b,TString bu,TString frame,TString s,Double_t e,TString name,TString mode,Int_t type)
2967{
3043
3044 // Set c.q. update coordinates for Solar system objects
3045 NcTimestamp tx;
3046 tx.SetEpoch(e,s);
3047 SetSolarSystem(name,&tx,type);
3048
3049 NcSignal* sx=0;
3050 Int_t j=GetSignalIndex(name,type);
3051 if (j>=0) sx=GetSignal(d,a,au,b,bu,frame,s,e,j,mode,type);
3052 return sx;
3053}
3054
3055NcSignal* NcAstrolab::GetSignal(Int_t jref,Int_t type)
3056{
3077
3078 if (jref<0) return 0;
3079
3080 if (!jref) // For backward compatibility
3081 {
3082 jref=1;
3083 type=1;
3084 }
3085
3086 if (!type && !fRefs) return 0;
3087 if (type && !fSigs) return 0;
3088
3089 NcSignal* sx=0;
3090 if (type)
3091 {
3092 if (jref<=fSigs->GetSize()) sx=(NcSignal*)fSigs->At(jref-1);
3093 }
3094 else
3095 {
3096 if (jref<=fRefs->GetSize()) sx=(NcSignal*)fRefs->At(jref-1);
3097 }
3098 return sx;
3099}
3100
3101NcSignal* NcAstrolab::GetSignal(TString name,Int_t type,NcTimestamp* ts)
3102{
3121
3122 NcSignal* sx=0;
3123 Int_t j=GetSignalIndex(name,type);
3124
3125 if (j==-1) // Set and store info for the requested Solar system object if not already stored
3126 {
3127 SetSolarSystem(name,ts,type);
3128 j=GetSignalIndex(name,type);
3129 }
3130
3131 if (j>=0) sx=GetSignal(j,type);
3132 return sx;
3133}
3134
3135Int_t NcAstrolab::RemoveRefSignal(Int_t j,Int_t compress)
3136{
3158
3159 Int_t nrem=0;
3160
3161 if (!fRefs) return 0;
3162
3163 // Clearing of the complete storage
3164 if (!j)
3165 {
3166 nrem=fRefs->GetEntries();
3167 delete fRefs;
3168 fRefs=0;
3169 return nrem;
3170 }
3171
3172 // Removing a specific reference signal
3173 if (j>0 && j<=fRefs->GetSize())
3174 {
3175 TObject* obj=fRefs->RemoveAt(j-1);
3176 if (obj)
3177 {
3178 delete obj;
3179 nrem++;
3180 }
3181 }
3182
3183 // Compression of the storage array
3184 if (compress) fRefs->Compress();
3185
3186 return nrem;
3187}
3188
3189Int_t NcAstrolab::RemoveRefSignal(TString name,Int_t compress)
3190{
3210
3211 Int_t nrem=0;
3212
3213 Int_t j=GetSignalIndex(name);
3214 if (j>0) nrem=RemoveRefSignal(j,compress);
3215
3216 return nrem;
3217}
3218
3219Int_t NcAstrolab::RemoveSignal(Int_t j,Int_t type,Int_t compress)
3220{
3240
3241 Int_t nrem=0;
3242
3243 TObjArray* arr=fRefs;
3244 if (type) arr=fSigs;
3245
3246 if (!arr) return nrem;
3247
3248 // Clearing of the complete "type" storage
3249 if (!j)
3250 {
3251 nrem=arr->GetEntries();
3252 delete arr;
3253 if (type)
3254 {
3255 fSigs=0;
3256 fNen[1]=0;
3257 }
3258 else
3259 {
3260 fRefs=0;
3261 fNen[0]=0;
3262 }
3263 return nrem;
3264 }
3265
3266 // Removing the specified signal
3267 if (j>0 && j<=arr->GetSize())
3268 {
3269 TObject* obj=arr->RemoveAt(j-1);
3270 if (obj)
3271 {
3272 delete obj;
3273 nrem++;
3274 }
3275 }
3276
3277 // Compression of the storage array
3278 if (compress)
3279 {
3280 arr->Compress();
3281 Int_t n=arr->GetEntries();
3282 arr->Expand(n);
3283 }
3284
3285 return nrem;
3286}
3287
3288Int_t NcAstrolab::RemoveSignal(TString name,Int_t type,Int_t compress)
3289{
3312
3313 Int_t nrem=0;
3314
3315 if (name=="") return nrem;
3316
3317 if (name=="*")
3318 {
3319 nrem=RemoveSignal(0,type,compress);
3320 }
3321 else
3322 {
3323 Int_t j=GetSignalIndex(name,type);
3324 if (j>0) nrem=RemoveSignal(j,type,compress);
3325 }
3326
3327 return nrem;
3328}
3329
3330Int_t NcAstrolab::RemoveSignals(TString name,Int_t type,Int_t compress)
3331{
3354
3355 Int_t nrem=0;
3356
3357 if (name=="") return 0;
3358
3359 if (name=="*")
3360 {
3361 nrem=RemoveSignal(0,type,compress);
3362 }
3363 else
3364 {
3365 TObjArray* arr=fRefs;
3366 if (type) arr=fSigs;
3367
3368 if (!arr) return 0;
3369
3370 NcSignal* sx=0;
3371 TString namex="";
3372 Int_t nremx=0;
3373 for (Int_t j=1; j<=arr->GetSize(); j++)
3374 {
3375 sx=GetSignal(j,type);
3376 if (!sx) continue;
3377
3378 namex=sx->GetName();
3379 if (!namex.Contains(name)) continue;
3380
3381 nremx=RemoveSignal(j,type,0);
3382 if (nremx) nrem++;
3383 }
3384
3385 // Compression of the storage array
3386 if (compress)
3387 {
3388 arr->Compress();
3389 Int_t n=arr->GetEntries();
3390 arr->Expand(n);
3391 }
3392 }
3393
3394 return nrem;
3395}
3396
3397Int_t NcAstrolab::GetSignalIndex(TString name,Int_t type)
3398{
3411
3412 if (name=="") return -1;
3413
3414 Int_t index=-1;
3415
3416 TObjArray* arr=fRefs;
3417 if (type) arr=fSigs;
3418
3419 if (!arr) return -1;
3420
3421 for (Int_t i=0; i<arr->GetSize(); i++)
3422 {
3423 NcSignal* sx=(NcSignal*)arr->At(i);
3424 if (!sx) continue;
3425
3426 if (name==sx->GetName())
3427 {
3428 index=i+1;
3429 break;
3430 }
3431 }
3432
3433 return index;
3434}
3435
3437{
3448
3449 if (!s) return -1;
3450
3451 Int_t index=-1;
3452
3453 TObjArray* arr=fRefs;
3454 if (type) arr=fSigs;
3455
3456 if (!arr) return -1;
3457
3458 for (Int_t i=0; i<arr->GetSize(); i++)
3459 {
3460 NcSignal* sx=(NcSignal*)arr->At(i);
3461 if (!sx) continue;
3462
3463 if (sx==s)
3464 {
3465 index=i+1;
3466 break;
3467 }
3468 }
3469
3470 return index;
3471}
3472
3473void NcAstrolab::PrintSignal(TString frame,TString mode,NcTimestamp* ts,Int_t ndig,Int_t jref,TString emode,Int_t type,Bool_t align)
3474{
3553
3554 NcSignal* sx=GetSignal(jref,type);
3555
3556 if (!sx) return;
3557
3558 if (!ts) ts=sx->GetTimestamp();
3559
3560 Nc3Vector r;
3561 GetSignal(r,frame,mode,ts,jref,type);
3562
3563 // Local Hour Angle of the signal
3564 Double_t lha=GetHourAngle("A",ts,jref,type);
3565 TString slha="LAHA";
3566 if (mode=="M" || mode=="m")
3567 {
3568 lha=GetHourAngle("M",ts,jref,type);
3569 slha="LMHA";
3570 }
3571 else if ((mode=="B" || mode=="b" || mode=="J" || mode=="j") && emode=="M")
3572 {
3573 lha=GetHourAngle("M",ts,jref,type);
3574 slha="LMHA";
3575 }
3576
3577 if (frame=="equ")
3578 {
3579 Double_t a,d;
3580 d=90.-r.GetX(2,"sph","deg");
3581 a=r.GetX(3,"sph","rad");
3582 if (mode=="B" || mode=="b") mode="B1950";
3583 if (mode=="J" || mode=="j") mode="J2000";
3584 cout << "Equatorial (" << mode.Data() <<") | a :";
3585 if (!align) {cout << " ";} PrintAngle(a,"rad","hms",ndig,align);
3586 if (!align) {cout << " ";} PrintAngle(a,"rad","deg",ndig,align);
3587 cout << " | b :";
3588 if (!align) {cout << " ";} PrintAngle(d,"deg","dms",ndig,align);
3589 if (!align) {cout << " ";} PrintAngle(d,"deg","deg",ndig,align);
3590 cout << " | " << slha.Data() << " : ";
3591 PrintAngle(lha,"deg","hms",ndig,align);
3592 cout << " "; PrintAngle(lha,"deg","deg",ndig,align);
3593 }
3594
3595 if (frame=="gal")
3596 {
3597 Double_t l,b;
3598 b=90.-r.GetX(2,"sph","deg");
3599 l=r.GetX(3,"sph","deg");
3600 cout << "Galactic | l :";
3601 if (!align) {cout << " ";} PrintAngle(l,"deg","deg",ndig,align);
3602 if (!align) {cout << " ";} PrintAngle(l,"deg","dms",ndig,align);
3603 cout << " | b :";
3604 if (!align) {cout << " ";} PrintAngle(b,"deg","deg",ndig,align);
3605 if (!align) {cout << " ";} PrintAngle(b,"deg","dms",ndig,align);
3606 cout << " | " << slha.Data() << " : ";
3607 PrintAngle(lha,"deg","hms",ndig,align);
3608 cout << " "; PrintAngle(lha,"deg","deg",ndig,align);
3609 }
3610
3611 if (frame=="icr")
3612 {
3613 Double_t l,b;
3614 b=90.-r.GetX(2,"sph","deg");
3615 l=r.GetX(3,"sph","deg");
3616 cout << "ICRS | l :";
3617 if (!align) {cout << " ";} PrintAngle(l,"deg","deg",ndig,align);
3618 if (!align) {cout << " ";} PrintAngle(l,"deg","dms",ndig,align);
3619 cout << " | b :";
3620 if (!align) {cout << " ";} PrintAngle(b,"deg","deg",ndig,align);
3621 if (!align) {cout << " ";} PrintAngle(b,"deg","dms",ndig,align);
3622 cout << " | " << slha.Data() << " : ";
3623 PrintAngle(lha,"deg","hms",ndig,align);
3624 cout << " "; PrintAngle(lha,"deg","deg",ndig,align);
3625 }
3626
3627 if (frame=="ecl")
3628 {
3629 Double_t l,b;
3630 b=90.-r.GetX(2,"sph","deg");
3631 l=r.GetX(3,"sph","deg");
3632 cout << "Geocentric ecliptic | l :";
3633 if (!align) {cout << " ";} PrintAngle(l,"deg","deg",ndig,align);
3634 if (!align) {cout << " ";} PrintAngle(l,"deg","dms",ndig,align);
3635 cout << " | b :";
3636 if (!align) {cout << " ";} PrintAngle(b,"deg","deg",ndig,align);
3637 if (!align) {cout << " ";} PrintAngle(b,"deg","dms",ndig,align);
3638 cout << " | " << slha.Data() << " : ";
3639 PrintAngle(lha,"deg","hms",ndig,align);
3640 cout << " "; PrintAngle(lha,"deg","deg",ndig,align);
3641 }
3642
3643 if (frame=="hor")
3644 {
3645 Double_t alt=90.-r.GetX(2,"sph","deg");
3646 Double_t azi=180.-r.GetX(3,"sph","deg");
3647 while (azi>360)
3648 {
3649 azi-=360.;
3650 }
3651 while (azi<0)
3652 {
3653 azi+=360.;
3654 }
3655 cout << "Horizontal | azi :";
3656 if (!align) {cout << " ";} PrintAngle(azi,"deg","deg",ndig,align);
3657 if (!align) {cout << " ";} PrintAngle(azi,"deg","dms",ndig,align);
3658 cout << " | alt :";
3659 if (!align) {cout << " ";} PrintAngle(alt,"deg","deg",ndig,align);
3660 if (!align) {cout << " ";} PrintAngle(alt,"deg","dms",ndig,align);
3661 cout << " | " << slha.Data() << " : ";
3662 PrintAngle(lha,"deg","hms",ndig,align);
3663 cout << " "; PrintAngle(lha,"deg","deg",ndig,align);
3664 }
3665
3666 if (frame=="loc")
3667 {
3668 Double_t theta=r.GetX(2,"sph","deg");
3669 Double_t phi=r.GetX(3,"sph","deg");
3670 cout << "Local-frame | phi :";
3671 if (!align) {cout << " ";} PrintAngle(phi,"deg","deg",ndig,align);
3672 if (!align) {cout << " ";} PrintAngle(phi,"deg","dms",ndig,align);
3673 cout << " | theta :";
3674 if (!align) {cout << " ";} PrintAngle(theta,"deg","deg",ndig,align);
3675 if (!align) {cout << " ";} PrintAngle(theta,"deg","dms",ndig,align);
3676 cout << " | " << slha.Data() << " : ";
3677 PrintAngle(lha,"deg","hms",ndig,align);
3678 cout << " "; PrintAngle(lha,"deg","deg",ndig,align);
3679 }
3680
3681 cout << " |";
3682
3683 TString name=sx->GetName();
3684 if (name != "") cout << " " << name.Data();
3685}
3686
3687void NcAstrolab::PrintSignal(TString frame,TString mode,NcTimestamp* ts,Int_t ndig,TString name,TString emode,Int_t type,Bool_t align)
3688{
3764
3765 // Set c.q. update coordinates for Solar system objects
3766 SetSolarSystem(name,ts,type);
3767
3768 Int_t j=GetSignalIndex(name,type);
3769 if (j>=0) PrintSignal(frame,mode,ts,ndig,j,emode,type,align);
3770}
3771
3772void NcAstrolab::ListSignals(TString frame,TString mode,Int_t ndig,TString emode,Int_t nmax,Int_t j,Int_t type,NcTimestamp* ts,TString name)
3773{
3845
3846 Int_t iprint=0;
3847 Int_t width=0; // Width for printing of the index
3848 if (nmax>0) width=log10(nmax);
3849 if (nmax<0)
3850 {
3851 Int_t maxref=0;
3852 if (fRefs) maxref=fRefs->GetSize();
3853 Int_t maxsig=0;
3854 if (fSigs) maxsig=fSigs->GetSize();
3855 Int_t maxj=maxref;
3856 if (maxsig>maxj) maxj=maxsig;
3857 if (maxj>0) width=log10(maxj);
3858 }
3859 width++;
3860
3861 NcSignal* sx=0;
3862 NcTimestamp* tx=0;
3863
3864 Int_t dform=1;
3865 if (mode=="T" || mode=="t") dform=-1;
3866 if ((mode=="B" || mode=="b" || mode=="J" || mode=="j") && emode=="T") dform=-1;
3867
3868 if (j>0) sx=GetSignal(j,1);
3869 if (sx)
3870 {
3871 tx=sx->GetTimestamp();
3872 if (!tx) tx=ts;
3873 if (!tx) tx=(NcTimestamp*)this;
3874 printf(" *%-s::ListSignals* Name : %-s Title : %-s \n",ClassName(),GetName(),GetTitle());
3875 if (fTscmode!=2)
3876 {
3877 cout << " Timestamp of the measurement stored at index=" << j;
3878 }
3879 else
3880 {
3881 cout << " *Scrambled* timestamp of the measurement stored at index=" << j;
3882 }
3883 cout << " (Lab time offset w.r.t. UT : "; PrintTime(fToffset,12); cout << ")" << endl;
3884 tx->Date(dform,fToffset);
3885 tx->Date(4);
3886 cout << " Corresponding location of this measurement" << endl;
3887 cout << " "; PrintSignal(frame,mode,tx,ndig,j,emode,1); cout << endl;
3888 iprint=1;
3889 }
3890
3891 TObjArray* arr=0;
3892 Int_t nstored=0;
3893 Int_t jlist=0;
3894 Int_t test=type;
3895 while (test<2)
3896 {
3897 if (test==0)
3898 {
3899 type=0;
3900 arr=fRefs;
3901 test=999;
3902 }
3903 if (test==1)
3904 {
3905 type=1;
3906 arr=fSigs;
3907 test=999;
3908 }
3909 if (test<0)
3910 {
3911 type=0;
3912 arr=fRefs;
3913 test=1;
3914 }
3915
3916 if (!arr) continue;
3917
3918 nstored=arr->GetEntries();
3919 jlist=0;
3920 TString namex="";
3921 for (Int_t i=1; i<=arr->GetSize(); i++)
3922 {
3923 sx=GetSignal(i,type);
3924 if (!sx) continue;
3925
3926 jlist++;
3927 if (nmax>=0 && jlist>nmax) break;
3928
3929 // Check for the name pattern
3930 namex=sx->GetName();
3931 if (name!="*" && !namex.Contains(name)) continue;
3932
3933 if (!iprint)
3934 {
3935 printf(" *%-s::ListSignals* Name : %-s Title : %-s \n",ClassName(),GetName(),GetTitle());
3936 if (j==0) tx=ts;
3937 if (tx)
3938 {
3939 cout << " User provided timestamp (Lab time offset w.r.t. UT : "; PrintTime(fToffset,12); cout << ")";
3940 cout << endl;
3941 tx->Date(dform,fToffset);
3942 tx->Date(4);
3943 }
3944 else
3945 {
3946 tx=(NcTimestamp*)this;
3947 if (j>=0)
3948 {
3949 cout << " Current timestamp of the laboratory (Lab time offset w.r.t. UT : "; PrintTime(fToffset,12); cout << ")";
3950 cout << endl;
3951 tx->Date(dform,fToffset);
3952 tx->Date(4);
3953 }
3954 }
3955 iprint=1;
3956 }
3957 if (iprint==1)
3958 {
3959 if (nmax<0 || nmax>=nstored)
3960 {
3961 if (!type)
3962 {
3963 if (j>=0)
3964 {
3965 cout << " === All stored reference signals according to the above timestamp ===" << endl;
3966 }
3967 else
3968 {
3969 cout << " === All stored reference signals according to their actual recorded timestamp ===" << endl;
3970 }
3971 }
3972 else
3973 {
3974 if (fTscmode!=2)
3975 {
3976 cout << " === All stored measurements according to their actual observation timestamp ===" << endl;
3977 }
3978 else
3979 {
3980 cout << " === All stored measurements according to their *scrambled* observation timestamp ===" << endl;
3981 cout << " === Time scrambling was performed by adding dt from the interval [dtmin,dtmax] to their actual timestamp" << endl;
3982 cout << " === dtmin : " << fTscmin << " dtmax : " << fTscmax << " sec.";
3983 if (fTscfunc)
3984 {
3985 cout << " Randomising TF1 function " << fTscfunc->GetName() << " was used." << endl;
3986 }
3987 else
3988 {
3989 cout << " Uniform randomisation was used." << endl;
3990 }
3991 }
3992 }
3993 }
3994 else
3995 {
3996 if (!type)
3997 {
3998 if (j>=0)
3999 {
4000 cout << " === The first " << nmax << " stored reference signals according to the above timestamp ===" << endl;
4001 }
4002 else
4003 {
4004 cout << " === The first " << nmax << " stored reference signals according to their actual recorded timestamp ===" << endl;
4005 }
4006 }
4007 else
4008 {
4009 if (fTscmode!=2)
4010 {
4011 cout << " === The first " << nmax << " stored measurements according to their actual observation timestamp ===" << endl;
4012 }
4013 else
4014 {
4015 cout << " === The first " << nmax << " stored measurements according to their *scrambled* observation timestamp ===" << endl;
4016 cout << " === Time scrambling was performed by adding dt from the interval [dtmin,dtmax] to their actual timestamp" << endl;
4017 cout << " === dtmin : " << fTscmin << " dtmax : " << fTscmax << " sec.";
4018 if (fTscfunc)
4019 {
4020 cout << " Randomising TF1 function " << fTscfunc->GetName() << " was used." << endl;
4021 }
4022 else
4023 {
4024 cout << " Uniform randomisation was used." << endl;
4025 }
4026 }
4027 }
4028 }
4029 iprint=2;
4030 }
4031 if (type==1 || (!type && j<0)) tx=0;
4032 printf(" Index : %*d ",width,i); PrintSignal(frame,mode,tx,ndig,i,emode,type,kTRUE); printf("\n");
4033 }
4034 iprint=1;
4035 }
4036}
4037
4039{
4064
4065 // Convert back to J2000 values
4066 Nc3Vector r0;
4067 SetPmatrix(ts1);
4068 r0=r.GetUnprimed(&fP);
4069
4070 // Precess to the specified timestamp
4071 if (!ts2) ts2=(NcTimestamp*)this;
4072 SetPmatrix(ts2);
4073 r=r0.GetPrimed(&fP);
4074}
4075
4077{
4097
4098 // Nutation correction for the specified timestamp
4099 if (!ts) ts=(NcTimestamp*)this;
4100 SetNmatrix(ts);
4101 r=r.GetPrimed(&fN);
4102}
4103
4105{
4114
4115 Double_t pi=acos(-1.);
4116
4117 // Parameters in mas
4118 Double_t a=-14.6;
4119 Double_t x=-16.6170;
4120 Double_t e=-6.8192;
4121
4122 // Convert to radians
4123 a*=pi/(180.*3600.*1000.);
4124 x*=pi/(180.*3600.*1000.);
4125 e*=pi/(180.*3600.*1000.);
4126
4127 Double_t mat[9];
4128 mat[0]=1.-0.5*(a*a+x*x);
4129 mat[1]=a;
4130 mat[2]=-x;
4131 mat[3]=-a-e*x;
4132 mat[4]=1.-0.5*(a*a+e*e);
4133 mat[5]=-e;
4134 mat[6]=x-e*a;
4135 mat[7]=e+x*a;
4136 mat[8]=1.-0.5*(e*e+x*x);
4137
4138 fB.SetMatrix(mat);
4139 fBias=1;
4140}
4141
4143{
4153
4154 Double_t mat[9]={0,0,0,0,0,0,0,0,0};
4155 if (!ts)
4156 {
4157 fP.SetMatrix(mat);
4158 return;
4159 }
4160
4161 Double_t pi=acos(-1.);
4162
4163 Double_t t=(ts->GetJD()-2451545.0)/36525.; // Julian centuries since J2000.0
4164
4165 // Parameters for the precession matrix in arcseconds
4166 Double_t eps0=84381.406; // Mean ecliptic obliquity at J2000.0
4167 Double_t psi=5038.481507*t-1.0790069*pow(t,2)-0.00114045*pow(t,3)+0.000132851*pow(t,4)
4168 -0.0000000951*pow(t,4);
4169 Double_t om=eps0-0.025754*t+0.0512623*pow(t,2)-0.00772503*pow(t,3)-0.000000467*pow(t,4)
4170 +0.0000003337*pow(t,5);
4171 Double_t chi=10.556403*t-2.3814292*pow(t,2)-0.00121197*pow(t,3)+0.000170663*pow(t,4)
4172 -0.0000000560*pow(t,5);
4173
4174 // Convert to radians
4175 eps0*=pi/(180.*3600.);
4176 psi*=pi/(180.*3600.);
4177 om*=pi/(180.*3600.);
4178 chi*=pi/(180.*3600.);
4179
4180 Double_t s1=sin(eps0);
4181 Double_t s2=sin(-psi);
4182 Double_t s3=sin(-om);
4183 Double_t s4=sin(chi);
4184 Double_t c1=cos(eps0);
4185 Double_t c2=cos(-psi);
4186 Double_t c3=cos(-om);
4187 Double_t c4=cos(chi);
4188
4189 mat[0]=c4*c2-s2*s4*c3;
4190 mat[1]=c4*s2*c1+s4*c3*c2*c1-s1*s4*s3;
4191 mat[2]=c4*s2*s1+s4*c3*c2*s1+c1*s4*s3;
4192 mat[3]=-s4*c2-s2*c4*c3;
4193 mat[4]=-s4*s2*c1+c4*c3*c2*c1-s1*c4*s3;
4194 mat[5]=-s4*s2*s1+c4*c3*c2*s1+c1*c4*s3;
4195 mat[6]=s2*s3;
4196 mat[7]=-s3*c2*c1-s1*c3;
4197 mat[8]=-s3*c2*s1+c3*c1;
4198
4199 fP.SetMatrix(mat);
4200}
4201
4203{
4212
4213 Double_t mat[9]={0,0,0,0,0,0,0,0,0};
4214 if (!ts)
4215 {
4216 fN.SetMatrix(mat);
4217 return;
4218 }
4219
4220 Double_t pi=acos(-1.);
4221
4222 Double_t dpsi,deps,eps;
4223 ts->Almanac(&dpsi,&deps,&eps);
4224
4225 // Convert to radians
4226 dpsi*=pi/(180.*3600.);
4227 deps*=pi/(180.*3600.);
4228 eps*=pi/(180.*3600.);
4229
4230 Double_t s1=sin(eps);
4231 Double_t s2=sin(-dpsi);
4232 Double_t s3=sin(-(eps+deps));
4233 Double_t c1=cos(eps);
4234 Double_t c2=cos(-dpsi);
4235 Double_t c3=cos(-(eps+deps));
4236
4237 mat[0]=c2;
4238 mat[1]=s2*c1;
4239 mat[2]=s2*s1;
4240 mat[3]=-s2*c3;
4241 mat[4]=c3*c2*c1-s1*s3;
4242 mat[5]=c3*c2*s1+c1*s3;
4243 mat[6]=s2*s3;
4244 mat[7]=-s3*c2*c1-s1*c3;
4245 mat[8]=-s3*c2*s1+c3*c1;
4246
4247 fN.SetMatrix(mat);
4248}
4249
4250void NcAstrolab::SetGmatrix(TString mode)
4251{
4264
4265 Nc3Vector x; // The Galactic x-axis in the equatorial frame
4266 Nc3Vector y; // The Galactic y-axis in the equatorial frame
4267 Nc3Vector z; // The Galactic z-axis in the equatorial frame
4268
4269 Double_t a,d;
4270 Double_t vec[3]={1,0,0};
4271
4272 fGal=1; // Set flag to indicate B1950 matrix values
4273
4274 // B1950 equatorial coordinates of the North Galactic Pole (NGP)
4275 a=124900.;
4276 d=272400.;
4277 a=ConvertAngle(a,"hms","deg");
4278 d=ConvertAngle(d,"dms","deg");
4279 vec[1]=90.-d;
4280 vec[2]=a;
4281 z.SetVector(vec,"sph","deg");
4282
4283 // B1950 equatorial coordinates of the Galactic l=b=0 point
4284 a=174224.;
4285 d=-285500.;
4286 a=ConvertAngle(a,"hms","deg");
4287 d=ConvertAngle(d,"dms","deg");
4288 vec[1]=90.-d;
4289 vec[2]=a;
4290 x.SetVector(vec,"sph","deg");
4291
4292 // Precess to the corresponding J2000 values if requested
4293 if (mode=="J")
4294 {
4295 fGal=2; // Set flag to indicate J2000 matrix values
4296 NcTimestamp t1;
4297 t1.SetEpoch(1950,"B");
4298 NcTimestamp t2;
4299 t2.SetEpoch(2000,"J");
4300 Precess(z,&t1,&t2);
4301 Precess(x,&t1,&t2);
4302 }
4303
4304 // The Galactic y-axis is determined for the right handed frame
4305 y=z.Cross(x);
4306
4307 fG.SetAngles(x.GetX(2,"sph","deg"),x.GetX(3,"sph","deg"),
4308 y.GetX(2,"sph","deg"),y.GetX(3,"sph","deg"),
4309 z.GetX(2,"sph","deg"),z.GetX(3,"sph","deg"));
4310}
4311
4313{
4322
4323 Double_t dpsi,deps,eps;
4324 ts->Almanac(&dpsi,&deps,&eps);
4325
4326 // Convert to degrees
4327 eps/=3600.;
4328
4329 // Positions of the ecliptic axes w.r.t. the equatorial ones
4330 // at the moment of the specified timestamp
4331 Double_t theta1=90; // Ecliptic x-axis
4332 Double_t phi1=0;
4333 Double_t theta2=90.-eps; //Ecliptic y-axis
4334 Double_t phi2=90;
4335 Double_t theta3=eps; // Ecliptic z-axis
4336 Double_t phi3=270;
4337
4338 fE.SetAngles(theta1,phi1,theta2,phi2,theta3,phi3);
4339}
4340
4342{
4354
4355 Nc3Vector x; // The (South pointing) horizontal x-axis in the equatorial frame
4356 Nc3Vector y; // The (East pointing) horizontal y-axis in the equatorial frame
4357 Nc3Vector z; // The (Zenith pointing) horizontal z-axis in the equatorial frame
4358
4359 Double_t l,b;
4360 GetLabPosition(l,b,"deg");
4361
4362 Double_t a;
4363 Double_t vec[3]={1,0,0};
4364
4365 // Equatorial coordinates of the horizontal z-axis
4366 // at the moment of the specified timestamp
4367 a=ts->GetLAST(fToffset);
4368 a*=15.; // Convert fractional hours to degrees
4369 vec[1]=90.-b;
4370 vec[2]=a;
4371 z.SetVector(vec,"sph","deg");
4372
4373 // Equatorial coordinates of the horizontal x-axis
4374 // at the moment of the specified timestamp
4375 vec[1]=180.-b;
4376 vec[2]=a;
4377 x.SetVector(vec,"sph","deg");
4378
4379 // The horizontal y-axis is determined for the right handed frame
4380 y=z.Cross(x);
4381
4382 fH.SetAngles(x.GetX(2,"sph","deg"),x.GetX(3,"sph","deg"),
4383 y.GetX(2,"sph","deg"),y.GetX(3,"sph","deg"),
4384 z.GetX(2,"sph","deg"),z.GetX(3,"sph","deg"));
4385}
4386
4387void NcAstrolab::SetLocalFrame(Double_t t1,Double_t p1,Double_t t2,Double_t p2,Double_t t3,Double_t p3)
4388{
4417
4418 // Set the matrix for the conversion of our reference frame coordinates
4419 // into the local-frame ones.
4420
4421 fL.SetAngles(t1,p1,t2,p2,t3,p3);
4422
4423 // Store the local user frame axes orientations w.r.t. the standard local Horizon (zen,azi) frame
4424 fAxes[0]=t1;
4425 fAxes[1]=p1;
4426 fAxes[2]=t2;
4427 fAxes[3]=p2;
4428 fAxes[4]=t3;
4429 fAxes[5]=p3;
4430}
4431
4433{
4443
4444 arr[0]=fAxes[0];
4445 arr[1]=fAxes[1];
4446 arr[2]=fAxes[2];
4447 arr[3]=fAxes[3];
4448 arr[4]=fAxes[4];
4449 arr[5]=fAxes[5];
4450}
4451
4452Double_t NcAstrolab::ConvertAngle(Double_t a,TString in,TString out) const
4453{
4474
4475 if (in==out) return a;
4476
4477 // Convert input to its absolute value in (fractional) degrees.
4478 Double_t pi=acos(-1.);
4479 Double_t epsilon=1.e-12; // Accuracy in (arc)seconds
4480 Int_t word=0,ddd=0,hh=0,mm=0,ss=0;
4481 Double_t s=0;
4482
4483 Double_t b=fabs(a);
4484
4485 if (in=="rad") b*=180./pi;
4486
4487 if (in=="hrs") b*=15.;
4488
4489 if (in=="dms")
4490 {
4491 word=Int_t(b);
4492 ddd=word/10000;
4493 word=word%10000;
4494 mm=word/100;
4495 ss=word%100;
4496 s=b-Double_t(ddd*10000+mm*100+ss);
4497 b=Double_t(ddd)+Double_t(mm)/60.+(Double_t(ss)+s)/3600.;
4498 }
4499
4500 if (in=="hms")
4501 {
4502 word=Int_t(b);
4503 hh=word/10000;
4504 word=word%10000;
4505 mm=word/100;
4506 ss=word%100;
4507 s=b-Double_t(hh*10000+mm*100+ss);
4508 b=15.*(Double_t(hh)+Double_t(mm)/60.+(Double_t(ss)+s)/3600.);
4509 }
4510
4511 while (b>360)
4512 {
4513 b-=360.;
4514 }
4515
4516 if (out=="rad") b*=pi/180.;
4517
4518 if (out=="hrs") b/=15.;
4519
4520 if (out=="dms")
4521 {
4522 ddd=Int_t(b);
4523 b=b-Double_t(ddd);
4524 b*=60.;
4525 mm=Int_t(b);
4526 b=b-Double_t(mm);
4527 b*=60.;
4528 ss=Int_t(b);
4529 s=b-Double_t(ss);
4530 if (s>(1.-epsilon))
4531 {
4532 s=0.;
4533 ss++;
4534 }
4535 while (ss>=60)
4536 {
4537 ss-=60;
4538 mm++;
4539 }
4540 while (mm>=60)
4541 {
4542 mm-=60;
4543 ddd++;
4544 }
4545 while (ddd>=360)
4546 {
4547 ddd-=360;
4548 }
4549 b=Double_t(10000*ddd+100*mm+ss)+s;
4550 }
4551
4552 if (out=="hms")
4553 {
4554 b/=15.;
4555 hh=Int_t(b);
4556 b=b-Double_t(hh);
4557 b*=60.;
4558 mm=Int_t(b);
4559 b=b-Double_t(mm);
4560 b*=60.;
4561 ss=Int_t(b);
4562 s=b-Double_t(ss);
4563 if (s>(1.-epsilon))
4564 {
4565 s=0.;
4566 ss++;
4567 }
4568 while (ss>=60)
4569 {
4570 ss-=60;
4571 mm++;
4572 }
4573 while (mm>=60)
4574 {
4575 mm-=60;
4576 hh++;
4577 }
4578 while (hh>=24)
4579 {
4580 hh-=24;
4581 }
4582 b=Double_t(10000*hh+100*mm+ss)+s;
4583 }
4584
4585 if (a<0) b=-b;
4586
4587 return b;
4588}
4589
4590Double_t NcAstrolab::GetSolidAngle(Double_t thetamin,Double_t thetamax,TString tu,Double_t phimin,Double_t phimax,TString pu) const
4591{
4606
4607 Double_t omega=0;
4608
4609 Double_t th1=ConvertAngle(thetamin,tu,"rad");
4610 Double_t th2=ConvertAngle(thetamax,tu,"rad");
4611 Double_t ph1=ConvertAngle(phimin,pu,"rad");
4612 Double_t ph2=ConvertAngle(phimax,pu,"rad");
4613
4614 omega=(ph2-ph1)*(cos(th1)-cos(th2));
4615 if (omega<0) omega=-omega;
4616
4617 return omega;
4618}
4619
4620Double_t NcAstrolab::GetHourAngle(TString mode,NcTimestamp* ts,Int_t jref,Int_t type)
4621{
4655
4656 if (!ts) ts=(NcTimestamp*)this;
4657
4658 // Get corrected right ascension and declination for the specified timestamp.
4659 Double_t d,a,b;
4660 if (mode=="M" || mode=="m") GetSignal(d,a,"deg",b,"deg","equ",ts,jref,"M",type);
4661 if (mode=="A" || mode=="a") GetSignal(d,a,"deg",b,"deg","equ",ts,jref,"T",type);
4662
4663 a/=15.; // Convert a to fractional hours
4664 Double_t ha=0;
4665 if (mode=="M" || mode=="m") ha=ts->GetLMST(fToffset)-a;
4666 if (mode=="A" || mode=="a") ha=ts->GetLAST(fToffset)-a;
4667 ha*=15.; // Convert to (fractional) degrees
4668
4669 // Project to the interval [-180,180]
4670 while (ha<-180)
4671 {
4672 ha+=360.;
4673 }
4674 while (ha>180)
4675 {
4676 ha-=360.;
4677 }
4678
4679 return ha;
4680}
4681
4682void NcAstrolab::SetLT(Int_t y,Int_t m,Int_t d,Int_t hh,Int_t mm,Int_t ss,Int_t ns,Int_t ps)
4683{
4705
4706 SetLT(fToffset,y,m,d,hh,mm,ss,ns,ps);
4707}
4708
4709void NcAstrolab::SetLT(Int_t y,Int_t m,Int_t d,Int_t hh,Int_t mm,Double_t s)
4710{
4731
4732 SetLT(fToffset,y,m,d,hh,mm,s);
4733}
4734
4735void NcAstrolab::SetLT(Int_t y,Int_t m,Int_t d,TString time)
4736{
4755
4756 SetLT(fToffset,y,m,d,time);
4757}
4758
4759void NcAstrolab::SetLT(TString date,TString time,Int_t mode)
4760{
4781
4782 SetLT(fToffset,date,time,mode);
4783}
4784
4785void NcAstrolab::SetLT(Int_t y,Int_t d,Int_t s,Int_t ns,Int_t ps)
4786{
4811
4812 SetLT(fToffset,y,d,s,ns,ps);
4813}
4814
4815Double_t NcAstrolab::GetDifference(Int_t j,TString au,Double_t& dt,TString tu,Int_t mode,Int_t* ia,Int_t* it)
4816{
4862
4863 Double_t da=999;
4864 dt=1.e30;
4865
4866 if (ia) *ia=0;
4867 if (it) *it=0;
4868
4869 if (j<0) return da;
4870
4871 NcDevice matches;
4872 Int_t nhits=0;
4873 NcSignal* sx=0;
4874 if (j) // Space and time difference w.r.t. a specific reference signal
4875 {
4876 MatchSignals(matches,da,au,dt,tu,mode,j,j,0,1,1,1);
4877 nhits=matches.GetNhits();
4878 if (nhits)
4879 {
4880 da=matches.GetSignal(1);
4881 dt=matches.GetSignal(2);
4882 if (ia) *ia=j;
4883 if (it) *it=j;
4884 }
4885 }
4886 else // Minimal space and time difference encountered over all reference signals
4887 {
4888 MatchSignals(matches,da,au,dt,tu,mode,1,0,0,1,1,1);
4889 nhits=matches.GetNhits();
4890 if (nhits)
4891 {
4892 da=matches.GetSignal(1);
4893 dt=matches.GetSignal(2);
4894 if (ia)
4895 {
4896 Int_t ipsi=matches.GetSignal("ipsi");
4897 sx=matches.GetHit(ipsi);
4898 if (sx) *ia=sx->GetSignal("index1");
4899 }
4900 if (it)
4901 {
4902 Int_t idt=matches.GetSignal("idt");
4903 sx=matches.GetHit(idt);
4904 if (sx) *it=sx->GetSignal("index1");
4905 }
4906 }
4907 }
4908 return da;
4909}
4910
4911Double_t NcAstrolab::GetSeparation(TString name1,TString name2,TString au,Double_t* dt,TString tu,Int_t mode,Double_t* diftheta,Double_t* difphi)
4912{
4959
4960 // Obtain the storage indices for the requested signals
4961 Int_t i=GetSignalIndex(name1,1); // Search for "name1" among the measurement signals
4962 Int_t j=GetSignalIndex(name2,1); // Search for "name2" among the measurement signals
4963
4964 if (i>0) // Set to negative value to indicate measurement entry
4965 {
4966 i=-i;
4967 }
4968 else // Search for "name1" among the reference signals
4969 {
4970 // In case a Solar system body was specified, store c.q. update it as a reference object.
4971 SetSolarSystem(name1,0,0);
4972 i=GetSignalIndex(name1,0);
4973 if (i<0) i=0;
4974 }
4975
4976 if (j>0) // Set to negative value to indicate measurement entry
4977 {
4978 j=-j;
4979 }
4980 else // Search for "name2" among the reference signals
4981 {
4982 // In case a Solar system body was specified, store c.q. update it as a reference object.
4983 SetSolarSystem(name2,0,0);
4984 j=GetSignalIndex(name2,0);
4985 if (j<0) j=0;
4986 }
4987
4988 // Retrieve the requested data via the internal GetSeparation() memberfunction
4989 Double_t dtx;
4990 Double_t da=GetSeparation(i,j,au,dtx,tu,mode,0,diftheta,difphi);
4991
4992Double_t dthetax,dphix;
4993da=GetSeparation(i,j,au,dtx,tu,mode,0,&dthetax,&dphix);
4994printf(" i=%-i j=%-i da=%-g dt=%-g %-s dtheta=%-g dphi=%-g %-s \n",i,j,da,dtx,tu.Data(),dthetax,dphix,au.Data());
4995
4996 if (dt) *dt=dtx;
4997 return da;
4998}
4999
5000Double_t NcAstrolab::GetSeparation(Int_t i,Int_t j,TString au,Double_t& dt,TString tu,Int_t mode,Int_t bkgpatch,Double_t* diftheta,Double_t* difphi)
5001{
5049
5050 Double_t dang=-999;
5051 dt=1.e30;
5052 if (diftheta) *diftheta=-999;
5053 if (difphi) *difphi=-999;
5054
5055 if (!i || !j) return dang;
5056 if ((i>0 || j>0) && !fRefs) return dang;
5057 if ((i<0 || j<0) && !fSigs) return dang;
5058
5059 // If needed, initialise the randomiser with a "date/time driven" seed
5060 // using the timestamp of the moment of this invokation of the member function.
5061 // This will ensure different random sequences if the user repeats analyses
5062 // with identical measurements and reference signals without explicit initialisation
5063 // of the randomiser by the user at the start of the analysis.
5064 if (!fRan && (fRscmode>0 || fTscmode>0)) fRan=new NcRandom(-1);
5065
5066 Int_t itype=0;
5067 if (i<0)
5068 {
5069 itype=1;
5070 i=abs(i);
5071 }
5072
5073 Int_t jtype=0;
5074 if (j<0)
5075 {
5076 jtype=1;
5077 j=abs(j);
5078 }
5079
5080 Nc3Vector ri; // Position of the i-th signal
5081 Nc3Vector rj; // Position of the j-th signal
5082 NcSignal* si=0; // Link to the stored i-th signal
5083 NcSignal* sj=0; // Link to the stored j-th signal
5084 NcTimestamp* ti=0; // Link to the timestamp of the i-th signal
5085 NcTimestamp* tj=0; // Link to the timestamp of the j-th signal
5086
5087 si=GetSignal(i,itype);
5088 sj=GetSignal(j,jtype);
5089 if (!si || !sj) return dang;
5090
5091 ti=si->GetTimestamp();
5092 tj=sj->GetTimestamp();
5093 if (!ti || !tj) return dang;
5094
5095 Int_t reftype=0;
5096 Int_t evttype=0;
5097 Int_t idxref=0;
5098 Int_t idxevt=0;
5099 NcSignal* sxref=0; // Link to the stored reference signal
5100 NcTimestamp* txref=0; // Link to the timestamp of the reference signal
5101 NcTimestamp* txevt=0; // Link to the timestamp of the measurement signal
5102 Nc3Vector rxref; // Position of the reference signal
5103 Nc3Vector rxevt; // Position of the measurement signal
5104
5105 if (itype==jtype) // Self correlations
5106 {
5107 reftype=itype;
5108 idxref=i;
5109 sxref=si;
5110 txref=ti;
5111 evttype=jtype;
5112 idxevt=j;
5113 txevt=tj;
5114 }
5115 else // Correlations between sources and measurements
5116 {
5117 if (itype)
5118 {
5119 evttype=itype;
5120 idxevt=i;
5121 txevt=ti;
5122 reftype=jtype;
5123 idxref=j;
5124 sxref=sj;
5125 txref=tj;
5126 }
5127 else
5128 {
5129 reftype=itype;
5130 idxref=i;
5131 sxref=si;
5132 txref=ti;
5133 evttype=jtype;
5134 idxevt=j;
5135 txevt=tj;
5136 }
5137 }
5138
5139 // Update the location and timestamp in case of a Solar system reference object
5140 TString name=sxref->GetName();
5141 if (SetSolarSystem(name,txevt,reftype)) txref=sxref->GetTimestamp();
5142
5143 // Local variables to act on requested scrambling
5144 Int_t Tscmode=fTscmode;
5145 Int_t Rscmode=fRscmode;
5146
5147 // Create scrambled background patch data even when also the on-source data are scrambled
5148 if (bkgpatch)
5149 {
5150 Tscmode=-abs(fTscmode);
5151 Rscmode=-abs(fRscmode);
5152 }
5153
5154 // Apply time scrambling of the date/time of the observation if requested
5155 NcTimestamp txtmp(*txevt);
5156 Double_t trndm=0;
5157 if (Tscmode==1 || Tscmode==3 || (Tscmode<0 && bkgpatch))
5158 {
5159 if (!fTscfunc)
5160 {
5161 trndm=fRan->Uniform(fTscmin,fTscmax);
5162 }
5163 else
5164 {
5165 trndm=fTscfunc->GetRandom(fTscmin,fTscmax);
5166 }
5167 // Creating a fake scrambled timestamp
5168 if (Tscmode==3 || (abs(Tscmode)>1 && bkgpatch)) txtmp.AddSec(trndm);
5169 }
5170
5171 // Obtain the (scrambled) time difference
5172 if (Tscmode==1 || (Tscmode==-1 && bkgpatch)) // Only provide a random time difference
5173 {
5174 if (tu=="d")
5175 {
5176 trndm/=double(24*3600);
5177 }
5178 if (tu=="ns")
5179 {
5180 trndm*=1.e9;
5181 trndm*=1.e9;
5182 }
5183 if (tu=="ps")
5184 {
5185 trndm*=1.e12;
5186 trndm*=1.e12;
5187 }
5188 dt=trndm;
5189 }
5190 else // Determine the time difference w.r.t. the fake timestamp of the measurement
5191 {
5192 dt=txref->GetDifference(&txtmp,tu,mode);
5193 }
5194
5195 // Update the location of Solar system objects if needed
5196 name=sxref->GetName();
5197 SetSolarSystem(name,&txtmp,reftype);
5198
5199 // Get the original measurement position and (time modified) reference position in local coordinates
5200 GetSignal(rxevt,"loc","T",txevt,idxevt,evttype);
5201 GetSignal(rxref,"loc","T",&txtmp,idxref,reftype);
5202
5203 // Apply position scrambling of the measurement if requested
5204 Double_t pi=acos(-1.);
5205 Float_t cosmin=0;
5206 Float_t cosmax=0;
5207 Double_t cosang=0;
5208 Double_t vec[3];
5209 Double_t dd=0;
5210 Double_t dtheta=0;
5211 Double_t dphi=0;
5212
5213 if (Rscmode==1 || (Rscmode==-1 && bkgpatch)) // Only provide a random angular separation
5214 {
5215 if (!fDscfunc)
5216 {
5217 cosmin=cos(fDscmin*pi/180.);
5218 cosmax=cos(fDscmax*pi/180.);
5219 if (cosmin>cosmax)
5220 {
5221 Float_t temp=cosmin;
5222 cosmin=cosmax;
5223 cosmax=temp;
5224 }
5225 cosang=fRan->Uniform(cosmin,cosmax);
5226 dang=acos(cosang);
5227 if (au=="deg") dang*=180./pi;
5228 }
5229 else
5230 {
5231 dang=fDscfunc->GetRandom(fDscmin,fDscmax);
5232 if (au=="rad") dang*=pi/180.;
5233 }
5234 }
5235 else // Create a fake local position for the measurement
5236 {
5237 if (Rscmode==3 || (abs(Rscmode)>1 && bkgpatch))
5238 {
5239 rxevt.GetVector(vec,"sph","deg");
5240
5241 // Allow specific offset studies
5242 if (fDscmin==fDscmax) dd=fDscmin;
5243 if (fThetascmin==fThetascmax) dtheta=fThetascmin;
5244 if (fPhiscmin==fPhiscmax) dphi=fPhiscmin;
5245
5246 // Go for randomly scrambled values
5247 if (fDscfunc)
5248 {
5249 if (fDscmax>fDscmin)
5250 {
5251 dd=fDscfunc->GetRandom(fDscmin,fDscmax);
5252 }
5253 }
5254 else
5255 {
5256 if (fDscmax>fDscmin) dd=fRan->Uniform(fDscmin,fDscmax);
5257 }
5258
5259 if (fThetascfunc)
5260 {
5262 {
5263 dtheta=fThetascfunc->GetRandom(fThetascmin,fThetascmax);
5264 }
5265 }
5266 else if (fThetascmax>fThetascmin)
5267 {
5268 cosmin=cos(fThetascmin*pi/180.);
5269 cosmax=cos(fThetascmax*pi/180.);
5270 if (cosmin>cosmax)
5271 {
5272 Float_t temp=cosmin;
5273 cosmin=cosmax;
5274 cosmax=temp;
5275 }
5276 cosang=fRan->Uniform(cosmin,cosmax);
5277 dtheta=acos(cosang)*180./pi;
5278 }
5279
5280 if (fPhiscfunc)
5281 {
5282 if (fPhiscmax>fPhiscmin)
5283 {
5284 dphi=fPhiscfunc->GetRandom(fPhiscmin,fPhiscmax);
5285 }
5286 }
5287 else
5288 {
5289 if (fPhiscmax>fPhiscmin) dphi=fRan->Uniform(fPhiscmin,fPhiscmax);
5290 }
5291
5292 vec[0]+=dd;
5293 if (vec[0]<=0) vec[0]=1e-20; // Keep a physical situation
5294 vec[1]+=dtheta;
5295 vec[2]+=dphi;
5296 rxevt.SetVector(vec,"sph","deg");
5297 }
5298
5299 dang=rxref.GetOpeningAngle(rxevt,au);
5300 }
5301
5302 // Determine the difference in local theta and phi
5303 Double_t refvec[3];
5304 rxevt.GetVector(vec,"sph",au);
5305 rxref.GetVector(refvec,"sph",au);
5306 dtheta=vec[1]-refvec[1];
5307 dphi=vec[2]-refvec[2];
5308 if (diftheta) *diftheta=dtheta;
5309 if (difphi) *difphi=dphi;
5310
5311 return dang;
5312}
5313
5314Double_t NcAstrolab::GetDifference(TString name,TString au,Double_t& dt,TString tu,Int_t mode)
5315{
5350
5351 Double_t dang=999;
5352 dt=1.e30;
5353
5354 Int_t j=GetSignalIndex(name);
5355
5356 if (j==-1) // Set and store info for the requested Solar system object if not already stored
5357 {
5358 SetSolarSystem(name,0);
5359 j=GetSignalIndex(name);
5360 }
5361
5362 if (j>0) dang=GetDifference(j,au,dt,tu,mode);
5363 return dang;
5364}
5365
5366TArrayI* NcAstrolab::MatchRefSignal(Double_t da,TString au,Double_t dt,TString tu,Int_t mode)
5367{
5396
5397 if (!fSigs || !fRefs) return 0;
5398
5399 NcDevice matches;
5400 MatchSignals(matches,da,au,dt,tu,mode,1,0,0,1,1,1); // Perform the obsolete MatchRefSignal() action
5401
5402 Int_t nhits=matches.GetNhits();
5403 if (!nhits) return 0;
5404
5405 if (fIndices) delete fIndices;
5406 fIndices=new TArrayI(nhits);
5407
5408 Int_t index=0;
5409 NcSignal* sx=0;
5410 Int_t jfill=0;
5411 for (Int_t i=1; i<=nhits; i++)
5412 {
5413 sx=matches.GetHit(i);
5414
5415 if(!sx) continue;
5416
5417 index=sx->GetSignal("index1");
5418 fIndices->AddAt(index,jfill);
5419 jfill++;
5420 }
5421
5422 fIndices->Set(jfill);
5423
5424 if (!jfill) return 0; // No match found
5425
5426 return fIndices;
5427}
5428
5429void NcAstrolab::MatchSignals(NcDevice& matches,Double_t da,TString au,Double_t dt,TString tu,Int_t mode,Int_t i1,Int_t i2,Int_t itype,Int_t j1,Int_t j2,Int_t jtype)
5430{
5542
5543 // Initialize the Device/Hit structure to contain the correlation info
5544 matches.Reset(1);
5545 matches.SetHitCopy(1);
5546
5547 TString name="Matches";
5548 TString title="Space and time matchings of NcAstrolab stored signals";
5549 matches.SetNameTitle(name.Data(),title.Data());
5550 TString tux=tu;
5551 if (tu=="d") tux="days";
5552 if (tu=="s") tux="sec";
5553 TString namedamin="psimin in ";
5554 namedamin+=au;
5555 TString namedtmin="dtmin in ";
5556 namedtmin+=tux;
5557 matches.AddNamedSlot(namedamin);
5558 matches.AddNamedSlot(namedtmin);
5559 matches.AddNamedSlot("ipsi");
5560 matches.AddNamedSlot("idt");
5561
5562 NcSignal data;
5563 TString nameda="psi in ";
5564 nameda+=au;
5565 TString namedt="t2-t1 in ";
5566 namedt+=tux;
5567 data.AddNamedSlot("type1");
5568 data.AddNamedSlot("index1");
5569 data.AddNamedSlot("type2");
5570 data.AddNamedSlot("index2");
5571 data.AddNamedSlot(nameda);
5572 data.AddNamedSlot(namedt);
5573
5574 if ((!itype || !jtype) && !fRefs)
5575 {
5576 printf(" *%-s::MatchSignals* Error: itype=%-i jtype=%-i but no reference signals are present. \n",ClassName(),itype,jtype);
5577 return;
5578 }
5579
5580 if ((itype || jtype) && !fSigs)
5581 {
5582 printf(" *%-s::MatchSignals* Error: itype=%-i jtype=%-i but no measurements are present. \n",ClassName(),itype,jtype);
5583 return;
5584 }
5585
5586 Int_t nrefs=0;
5587 if (fRefs) nrefs=fRefs->GetSize();
5588 Int_t nsigs=0;
5589 if (fSigs) nsigs=fSigs->GetSize();
5590
5591
5592 // Make input data consistent with conventions
5593 if (itype) itype=1;
5594 if (jtype) jtype=1;
5595 if (!itype)
5596 {
5597 if (i2<1 || i2>nrefs) i2=nrefs;
5598 }
5599 else
5600 {
5601 if (i2<1 || i2>nsigs) i2=nsigs;
5602 }
5603 if (!jtype)
5604 {
5605 if (j2<1 || j2>nrefs) j2=nrefs;
5606 }
5607 else
5608 {
5609 if (j2<1 || j2>nsigs) j2=nsigs;
5610 }
5611
5612 if (i1<1 || j1<1 || i1>i2 || j1>j2)
5613 {
5614 printf(" *%-s::MatchSignals* Inconsistent parameters: i1=%-i i2=%-i itype=%-i j1=%-i j2=%-i jtype=%-i. \n",ClassName(),i1,i2,itype,j1,j2,jtype);
5615 return;
5616 }
5617
5618 Double_t dang,dtime;
5619 Int_t ix=0;
5620 Int_t jx=0;
5621 NcSignal* sx=0;
5622 Int_t id=0;
5623 Double_t dangmin=0;
5624 Double_t dtmin=0;
5625 Int_t idamin=0;
5626 Int_t idtmin=0;
5627 Bool_t first=kTRUE;
5628 for (Int_t i=i1; i<=i2; i++)
5629 {
5630 ix=i;
5631 if (itype) ix=-i;
5632
5633 for (Int_t j=j1; j<=j2; j++)
5634 {
5635 // Skip matching a signal with itself
5636 if (itype==jtype && i==j) continue;
5637
5638 jx=j;
5639 if (jtype) jx=-j;
5640
5641 dang=GetSeparation(ix,jx,au,dtime,tu,mode,0);
5642
5643 if ((fabs(dang)<=da || da<0) && (fabs(dtime)<=dt || dt<0))
5644 {
5645 data.Reset();
5646 name="Object1=";
5647 sx=GetSignal(i,itype);
5648 if (!sx) continue;
5649 name+=sx->GetName();
5650 title="Object2=";
5651 sx=GetSignal(j,jtype);
5652 if (!sx) continue;
5653 title+=sx->GetName();
5654 id++;
5655 data.SetNameTitle(name.Data(),title.Data());
5656 data.SetUniqueID(id);
5657 data.SetSignal(itype,"type1");
5658 data.SetSignal(i,"index1");
5659 data.SetSignal(jtype,"type2");
5660 data.SetSignal(j,"index2");
5661 data.SetSignal(dtime,namedt);
5662 data.SetSignal(dang,nameda);
5663 matches.AddHit(data);
5664
5665 // Record the data for the minimal encountered opening angle
5666 if (first || fabs(dang)<dangmin)
5667 {
5668 dangmin=fabs(dang);
5669 idamin=id;
5670 }
5671
5672 // Record the data for the minimal encountered time difference
5673 if (first || fabs(dtime)<fabs(dtmin))
5674 {
5675 dtmin=dtime;
5676 idtmin=id;
5677 }
5678
5679 first=kFALSE;
5680 }
5681 }
5682 }
5683
5684 // Store the data for the minimal encountered opening angle and time difference
5685 matches.SetSignal(dangmin,namedamin);
5686 matches.SetSignal(dtmin,namedtmin);
5687 matches.SetSignal(idamin,"ipsi");
5688 matches.SetSignal(idtmin,"idt");
5689}
5690
5691void NcAstrolab::MatchSignals(NcDevice& matches,TString name,Double_t da,TString au,Double_t dt,TString tu,Int_t mode,Int_t itype,Int_t j1,Int_t j2,Int_t jtype)
5692{
5802
5803 Int_t i=GetSignalIndex(name,itype);
5804
5805 if (i==-1) // Add the info for the requested Solar system object if not already stored
5806 {
5807 SetSolarSystem(name,0,itype);
5808 i=GetSignalIndex(name,itype);
5809 if (i>0) fSolUpdate=1;
5810 }
5811
5812 if (i<1)
5813 {
5814 printf(" *%-s::MatchSignals* Object %-s not found for itype=%-i. \n",ClassName(),name.Data(),itype);
5815 }
5816 else
5817 {
5818 MatchSignals(matches,da,au,dt,tu,mode,i,i,itype,j1,j2,jtype);
5819 }
5820
5821 fSolUpdate=0;
5822}
5823
5824void NcAstrolab::SetTimeScramble(Int_t mode,Double_t tmin,Double_t tmax,TF1* frndm)
5825{
5895
5896 fTscmode=mode;
5897 fTscmin=tmin;
5898 fTscmax=tmax;
5899 if (fTscfunc)
5900 {
5901 delete fTscfunc;
5902 fTscfunc=0;
5903 }
5904 if (frndm)
5905 {
5906 fTscfunc=new TF1(*frndm);
5907 if (tmax>tmin) fTscfunc->SetRange(tmin,tmax);
5908 }
5909}
5910
5911Int_t NcAstrolab::GetTimeScramble(Double_t* tmin,Double_t* tmax,TF1* frndm)
5912{
5942
5943 if (tmin) *tmin=fTscmin;
5944 if (tmax) *tmax=fTscmax;
5945 if (frndm) *frndm=*fTscfunc;
5946
5947 return fTscmode;
5948}
5949
5950void NcAstrolab::SetPositionScramble(Int_t mode,Double_t dmin,Double_t dmax,TF1* df,Double_t thmin,Double_t thmax,TF1* thf,Double_t phimin,Double_t phimax,TF1* phif)
5951{
6029
6030 // Keep parameters within physical bounds for angular difference scrambling (mode=1)
6031 if (abs(mode)==1 && dmin<0) dmin=0;
6032 if (abs(mode)==1 && dmax>180) dmax=180;
6033
6034 // Check for specific requested offsets
6035 if (dmax<dmin) dmax=dmin;
6036 if (thmax<thmin) thmax=thmin;
6037 if (phimax<phimin) phimax=phimin;
6038
6039 fRscmode=mode;
6040 fDscmin=dmin;
6041 fDscmax=dmax;
6042 if (fDscfunc)
6043 {
6044 delete fDscfunc;
6045 fDscfunc=0;
6046 }
6047 if (df)
6048 {
6049 fDscfunc=new TF1(*df);
6050 if (dmax>dmin) fDscfunc->SetRange(dmin,dmax);
6051 }
6052 fThetascmin=thmin;
6053 fThetascmax=thmax;
6054 if (fThetascfunc)
6055 {
6056 delete fThetascfunc;
6057 fThetascfunc=0;
6058 }
6059 if (thf)
6060 {
6061 fThetascfunc=new TF1(*thf);
6062 if (thmax>thmin) fThetascfunc->SetRange(thmin,thmax);
6063 }
6064 fPhiscmin=phimin;
6065 fPhiscmax=phimax;
6066 if (fPhiscfunc)
6067 {
6068 delete fPhiscfunc;
6069 fPhiscfunc=0;
6070 }
6071 if (phif)
6072 {
6073 fPhiscfunc=new TF1(*phif);
6074 if (phimax>phimin) fPhiscfunc->SetRange(phimin,phimax);
6075 }
6076}
6077
6078Int_t NcAstrolab::GetPositionScramble(Double_t* dmin,Double_t* dmax,TF1* df,Double_t* thmin,Double_t* thmax,TF1* thf,Double_t* phimin,Double_t* phimax,TF1* phif)
6079{
6115
6116 if (dmin) *dmin=fDscmin;
6117 if (dmax) *dmax=fDscmax;
6118 if (df) *df=*fDscfunc;
6119 if (thmin) *thmin=fThetascmin;
6120 if (thmax) *thmax=fThetascmax;
6121 if (thf) *thf=*fThetascfunc;
6122 if (phimin) *phimin=fPhiscmin;
6123 if (phimax) *phimax=fPhiscmax;
6124 if (phif) *phif=*fPhiscfunc;
6125
6126 return fRscmode;
6127}
6128
6129void NcAstrolab::DisplaySignal(TString frame,TString mode,NcTimestamp* ts,Int_t j,TString proj,Int_t clr,TString name)
6130{
6229
6230 // Comply with the new (jref,type) convention for measurements and reference signals.
6231 Int_t jref=abs(j);
6232 Int_t type=0;
6233 if (j<=0) type=1;
6234 if (!j) jref=1;
6235
6236 NcSignal* sx=0;
6237
6238 if (!ts)
6239 {
6240 sx=GetSignal(jref,type);
6241 if (!sx) return;
6242 ts=sx->GetTimestamp();
6243 }
6244
6245 Nc3Vector r;
6246 sx=GetSignal(r,frame,mode,ts,jref,type);
6247
6248 if (!sx) return;
6249
6250 // Save name and timestamp to enable timestamp restoration for Solar system objects
6251 // after a Day View or Year View display
6252 TString namesave=sx->GetName();
6253 NcTimestamp tsave=(*ts);
6254
6255 // The generic input angles (in rad) for the projections
6256 Double_t theta=0;
6257 Double_t phi=0;
6258
6259 Double_t pi=acos(-1.);
6260
6261 if (frame=="equ" || frame=="gal" || frame=="icr" || frame=="ecl" || frame=="loc")
6262 {
6263 theta=(pi/2.)-r.GetX(2,"sph","rad");
6264 phi=r.GetX(3,"sph","rad");
6265 }
6266
6267 if (frame=="hor")
6268 {
6269 theta=(pi/2.)-r.GetX(2,"sph","rad");
6270 phi=pi-r.GetX(3,"sph","rad");
6271 }
6272
6273 // Automatic choice of central meridian if not selected by the user
6274 if (!fUsMeridian || abs(fUsMeridian)>1)
6275 {
6276 if (frame=="equ")
6277 {
6278 fMeridian=pi;
6279 fUsMeridian=-2;
6280 }
6281 if (frame=="gal" || frame=="icr" || frame=="ecl")
6282 {
6283 fMeridian=0;
6284 fUsMeridian=-2;
6285 }
6286 if (frame=="hor" || frame=="loc")
6287 {
6288 fMeridian=0;
6289 fUsMeridian=2;
6290 }
6291 }
6292
6293 // Obtain the projected (x,y) position
6294 Double_t x=0;
6295 Double_t y=0;
6296 Project(phi,theta,proj,x,y);
6297
6298 // X-axis inversion of the display
6299 if (fUsMeridian<0) x*=-1.;
6300
6301 Int_t hist=0;
6302 if (proj=="hamh" || proj=="aith" || proj=="merh" || proj=="cylh" || proj=="angh") hist=1;
6303 if (proj=="UTh" || proj=="LTh" || proj=="GSTh" || proj=="LSTh") hist=1;
6304 if (proj=="UYh" || proj=="LYh" || proj=="GSYh" || proj=="LSYh") hist=1;
6305
6306 // Update the display for this signal position
6307
6308 // Create a new canvas if needed
6309 if (!fCanvas || !(gROOT->GetListOfCanvases()->FindObject("NcAstrolab"))) fCanvas=new TCanvas("NcAstrolab","Skymap");
6310
6311 // Construct the various strings for this map
6312 TString titleup; // The upper title string
6313 TString titlelow; // The lower title string
6314 TString sleft; // The most left coordinate indicator
6315 TString sright; // The most right coordinate indicator
6316 TString sup; // The most upper coordinate indicator
6317 TString slow; // The most lower coordinate indicator
6318 sup="90#circ";
6319 slow="-90#circ";
6320 if (name!="")
6321 {
6322 titleup=name;
6323 titleup+=" ";
6324 }
6325 if (frame=="equ")
6326 {
6327 titleup+="Geocentric Equatorial (";
6328 titleup+=mode;
6329 if (mode=="J") titleup+="2000";
6330 if (mode=="B") titleup+="1950";
6331 titleup+=") ";
6332 }
6333 if (frame=="gal") titleup+="Heliocentric Galactic";
6334 if (frame=="ecl") titleup+=" Geocentric Ecliptic";
6335 if (frame=="hor") titleup+=" Standard Horizon";
6336 if (frame=="icr") titleup+="Static Barycentric ICRS";
6337 if (frame=="loc")
6338 {
6339 titleup+=" User defined Local";
6340 sup=" 0#circ";
6341 slow="180#circ";
6342 }
6343 titleup+=" Coordinates";
6344 titlelow="Projection : ";
6345 if (proj=="ham" || proj=="hamh") titlelow+="Hammer";
6346 if (proj=="cyl" || proj=="cylh") titlelow+="Cylindrical";
6347 if (proj=="ait" || proj=="aith") titlelow+="Aitoff";
6348 if (proj=="mer" || proj=="merh") titlelow+="Mercator";
6349 if (proj=="ang" || proj=="angh")
6350 {
6351 titlelow+="sin(b) vs. l";
6352 sup=" 1";
6353 slow=" -1";
6354 }
6355 titlelow+=" Central Meridian : ";
6356 Int_t ang,h,m,s,d;
6357 Int_t angmax,hmin,hmax,dmin,dmax;
6358 TString corr;
6359 TString scenter="";
6360 if (frame=="equ")
6361 {
6362 ang=int(ConvertAngle(fMeridian,"rad","hms"));
6363 angmax=ang+120000;
6364 h=ang/10000;
6365 ang=ang%10000;
6366 m=ang/100;
6367 s=ang%100;
6368 titlelow+=h;
6369 titlelow+="h ";
6370 titlelow+=m;
6371 titlelow+="m ";
6372 titlelow+=s;
6373 titlelow+="s";
6374 hmax=angmax/10000;
6375 corr="";
6376 while (hmax>24)
6377 {
6378 hmax-=24;
6379 corr="+";
6380 }
6381 hmin=hmax-24;
6382 while (hmin<-12)
6383 {
6384 hmin+=24;
6385 corr="+";
6386 }
6387 sright+=corr;
6388 if (fUsMeridian<0)
6389 {
6390 sright+=hmin;
6391 }
6392 else
6393 {
6394 sright+=hmax;
6395 }
6396 sright+="h";
6397 if (fUsMeridian<0)
6398 {
6399 sleft+=hmax;
6400 }
6401 else
6402 {
6403 sleft+=hmin;
6404 }
6405 sleft+="h";
6406 scenter+=h;
6407 scenter+="h";
6408 }
6409 else
6410 {
6411 ang=int(ConvertAngle(fMeridian,"rad","dms"));
6412 angmax=ang+1800000;
6413 d=ang/10000;
6414 ang=ang%10000;
6415 m=ang/100;
6416 s=ang%100;
6417 titlelow+=d;
6418 titlelow+="d ";
6419 titlelow+=m;
6420 titlelow+="' ";
6421 titlelow+=s;
6422 titlelow+="\"";
6423 dmax=angmax/10000;
6424 corr="";
6425 while (dmax>360)
6426 {
6427 dmax-=360;
6428 corr="+";
6429 }
6430 dmin=dmax-360;
6431 while (dmin<-180)
6432 {
6433 dmin+=360;
6434 corr="+";
6435 }
6436 sright+=corr;
6437 if (fUsMeridian<0)
6438 {
6439 sright+=dmin;
6440 }
6441 else
6442 {
6443 sright+=dmax;
6444 }
6445 sright+="#circ";
6446 if (fUsMeridian<0)
6447 {
6448 sleft+=dmax;
6449 }
6450 else
6451 {
6452 sleft+=dmin;
6453 }
6454 sleft+="#circ";
6455 scenter+=d;
6456 scenter+="#circ";
6457 }
6458
6459 if (!hist) // 2-D Marker display (i.e. not a histogram)
6460 {
6461 TMarker* marker=0;
6462 // Remove existing markers, grid and outline from display if needed
6463 if (clr==1 || proj!=fProj)
6464 {
6465 if (fMarkers)
6466 {
6467 delete fMarkers;
6468 fMarkers=0;
6469 }
6470 fCanvas->Clear();
6471 fProj=proj;
6472 }
6473
6474 // Create a new display if needed
6475 if (!fMarkers)
6476 {
6477 fMarkers=new TObjArray();
6478 fMarkers->SetOwner();
6479
6480 // Set canvas range, header and axes
6481 Float_t xup=2; // Maximal x coordinate of the projection
6482 Float_t yup=1; // maximal y coordinate of the projection
6483 Float_t xlow=-xup;
6484 Float_t ylow=-yup;
6485 Float_t xmargin=0.5; // X margin for canvas size
6486 Float_t ymargin=0.3; // Y margin for canvas size
6487 fCanvas->Range(xlow-xmargin,ylow-ymargin,xup+xmargin,yup+ymargin);
6488
6489 // The ellipse outline with the skymap c.q. projection grid
6490 if (proj=="ham" || proj=="ait")
6491 {
6492 // Draw ellips outline
6493 TEllipse* outline=new TEllipse(0,0,xup,yup);
6494 fMarkers->Add(outline);
6495 outline->Draw();
6496 }
6497
6499 // Draw the skymap c.q. projection grid //
6501
6502 // Drawing of the projected meridians every 30 degrees
6503 const Int_t nphi=13;
6504 Double_t gphiarr[nphi]={0,30,60,90,120,150,180,210,240,270,300,330,360};
6505 Double_t gphi=0;
6506 Double_t gtheta=0;
6507 Int_t ndots=100;
6508 Float_t gstep=180./float(ndots);
6509 Double_t xgrid=0;
6510 Double_t ygrid=0;
6511 for (Int_t iph=0; iph<nphi; iph++)
6512 {
6513 gphi=gphiarr[iph]*pi/180.;
6514 if (frame=="hor") gphi=pi-gphi;
6515 gtheta=pi/2.;
6516 for (Int_t ith=1; ith<ndots; ith++)
6517 {
6518 gtheta=gtheta-(gstep*pi/180.);
6519 Project(gphi,gtheta,proj,xgrid,ygrid);
6520 marker=new TMarker(xgrid,ygrid,fMarkerStyle[3]);
6521 marker->SetMarkerSize(fMarkerSize[3]);
6522 marker->SetMarkerColor(fMarkerColor[3]);
6523 fMarkers->Add(marker);
6524 marker->Draw();
6525 }
6526 }
6527
6528 // Drawing of the projected latitude circles every 15 degrees
6529 const Int_t nth=10;
6530 Double_t gtharr[nth]={15,30,45,60,75,105,120,135,150,165};
6531 gphi=0;
6532 gtheta=0;
6533 gstep=360./float(ndots);
6534 TString gs;
6535 Int_t igs=0;
6536 TLatex* lgs=0;
6537 Double_t xtext=0;
6538 Double_t ytext=0;
6539 for (Int_t ith=0; ith<nth; ith++)
6540 {
6541 gtheta=pi/2.-(gtharr[ith]*pi/180.);
6542 igs=int(90.-gtharr[ith]);
6543 if (frame=="loc") igs=int(gtharr[ith]);
6544 gs="";
6545 gs+=igs;
6546 gs+="#circ";
6547 xtext=0;
6548 for (Int_t iphi=1; iphi<ndots; iphi++)
6549 {
6550 gphi=gphi+gstep;
6551 Project(gphi,gtheta,proj,xgrid,ygrid);
6552 marker=new TMarker(xgrid,ygrid,fMarkerStyle[3]);
6553 marker->SetMarkerSize(fMarkerSize[3]);
6554 marker->SetMarkerColor(fMarkerColor[3]);
6555 if (xgrid<xtext)
6556 {
6557 xtext=xgrid;
6558 ytext=ygrid;
6559 }
6560 fMarkers->Add(marker);
6561 marker->Draw();
6562 }
6563 lgs=new TLatex;
6564 fMarkers->Add(lgs);
6565 if (ytext>0)
6566 {
6567 if (proj=="ham" || proj=="ait")
6568 {
6569 lgs->DrawLatex(xtext-0.25,ytext,gs.Data());
6570 }
6571 else
6572 {
6573 lgs->DrawLatex(xtext-0.4,ytext-0.02,gs.Data());
6574 }
6575 }
6576 else
6577 {
6578 if (proj=="ham" || proj=="ait")
6579 {
6580 lgs->DrawLatex(xtext-0.3,ytext-0.1,gs.Data());
6581 }
6582 else
6583 {
6584 lgs->DrawLatex(xtext-0.4,ytext-0.02,gs.Data());
6585 }
6586 }
6587 }
6588
6589 // The horizontal and vertical axes
6590 TLine* line=new TLine(xlow,0,xup,0);
6591 fMarkers->Add(line);
6592 line->Draw();
6593 line=new TLine(0,yup,0,ylow);
6594 fMarkers->Add(line);
6595 line->Draw();
6596
6597 // The header and footer text
6598 TLatex* header=new TLatex;
6599 fMarkers->Add(header);
6600 header->SetTextAlign(21); // Text will be horizontally centered
6601 header->DrawLatex(0,yup+0.2,titleup.Data());
6602 TLatex* footer=new TLatex;
6603 fMarkers->Add(footer);
6604 footer->SetTextAlign(21); // Text will be horizontally centered
6605 footer->DrawLatex(0,ylow-0.25,titlelow.Data());
6606
6607 // The left side angular value indicator
6608 TLatex* left=new TLatex;
6609 fMarkers->Add(left);
6610 if (proj=="ham" || proj=="ait")
6611 {
6612 left->DrawLatex(xlow-0.4,0,sleft.Data());
6613 }
6614 else
6615 {
6616 left->DrawLatex(xlow-0.15,yup+0.05,sleft.Data());
6617 }
6618 // The right side angular value indicator
6619 TLatex* right=new TLatex;
6620 fMarkers->Add(right);
6621 if (proj=="ham" || proj=="ait")
6622 {
6623 right->DrawLatex(xup+0.1,0,sright.Data());
6624 }
6625 else
6626 {
6627 right->DrawLatex(xup-0.1,yup+0.05,sright.Data());
6628 }
6629 // The upper angular value indicator
6630 TLatex* up=new TLatex;
6631 fMarkers->Add(up);
6632 if (proj=="ham" || proj=="ait")
6633 {
6634 up->DrawLatex(-0.1,yup+0.05,sup.Data());
6635 }
6636 else
6637 {
6638 up->DrawLatex(-0.1,yup+0.05,scenter.Data());
6639 if (proj!="ang")
6640 {
6641 up=new TLatex;
6642 fMarkers->Add(up);
6643 up->DrawLatex(xlow-0.4,yup-0.04,sup.Data());
6644 }
6645 }
6646 // The lower angular value indicator
6647 TLatex* low=new TLatex;
6648 fMarkers->Add(low);
6649 if (proj=="ham" || proj=="ait")
6650 {
6651 low->DrawLatex(-0.15,ylow-0.15,slow.Data());
6652 }
6653 else
6654 {
6655 if (proj!="ang") low->DrawLatex(xlow-0.4,ylow,slow.Data());
6656 }
6657
6659 // Indicate the Galactic Center //
6661
6662 // Add the Galactic Center temporarily as a reference signal for coordinate retrieval
6663 sx=SetSignal(1,0,"deg",0,"deg","gal",0,-1,"J","GC",0);
6664 Int_t idx=fRefs->IndexOf(sx);
6665 idx++;
6666 Nc3Vector rgc;
6667 sx=GetSignal(rgc,frame,mode,ts,idx,0);
6668 if (sx)
6669 {
6670 Double_t thetagc=0;
6671 Double_t phigc=0;
6672 if (frame=="equ" || frame=="gal" || frame=="icr" || frame=="ecl" || frame=="loc")
6673 {
6674 thetagc=(pi/2.)-rgc.GetX(2,"sph","rad");
6675 phigc=rgc.GetX(3,"sph","rad");
6676 }
6677 if (frame=="hor")
6678 {
6679 thetagc=(pi/2.)-rgc.GetX(2,"sph","rad");
6680 phigc=pi-rgc.GetX(3,"sph","rad");
6681 }
6682 // Obtain the projected (x,y) position
6683 Double_t xgc=0;
6684 Double_t ygc=0;
6685 Project(phigc,thetagc,proj,xgc,ygc);
6686 if (fUsMeridian<0) xgc*=-1.;
6687 marker=new TMarker(xgc,ygc,fMarkerStyle[2]);
6688 marker->SetMarkerSize(fMarkerSize[2]);
6689 marker->SetMarkerColor(fMarkerColor[2]);
6690 fMarkers->Add(marker);
6691 marker->Draw();
6692 // Remove the temporary Galactic Center object again
6693 RemoveSignal(idx,0,0);
6694 }
6695 }
6696
6697 // Indicate the measurement(s) or reference signal(s) on the display
6698 marker=new TMarker(x,y,fMarkerStyle[type]);
6699 marker->SetMarkerSize(fMarkerSize[type]);
6700 marker->SetMarkerColor(fMarkerColor[type]);
6701 fMarkers->Add(marker);
6702 marker->Draw();
6703 }
6704 else if (hist==1) // 2-D display via histogram
6705 {
6706 Float_t xfac=90;
6707 Float_t yfac=90;
6708 if (frame=="equ") xfac=6;
6709 if (proj=="angh") yfac=1;
6710 // Reset the histogram if needed
6711 if (clr==1 || proj!=fProj || !fHist[type])
6712 {
6713 if (clr==1 || proj!=fProj)
6714 {
6715 fCanvas->Clear();
6716 fCanvas->SetGrid();
6717 for (Int_t i=0; i<2; i++)
6718 {
6719 if (fHist[i])
6720 {
6721 fHist[i]->Delete();
6722 fHist[i]=0;
6723 }
6724 }
6725 }
6726 if (!fHist[type]) fHist[type]=new TH2F();
6727 fHist[type]->Reset();
6728 fHist[type]->SetMarkerStyle(fMarkerStyle[type]);
6729 fHist[type]->SetMarkerSize(fMarkerSize[type]);
6730 fHist[type]->SetMarkerColor(fMarkerColor[type]);
6731 TString title=titleup;
6732 title+=" ";
6733 title+=titlelow;
6734 fHist[type]->SetNameTitle("SkyMap",title.Data());
6735 fHist[type]->GetXaxis()->SetTitle("Degrees from central Meridian");
6736 if (proj=="angh")
6737 {
6738 fHist[type]->SetBins(1000,-181,181,100,-1.1,1.1);
6739 fHist[type]->GetYaxis()->SetTitle("sin(b)");
6740 }
6741 else
6742 {
6743 fHist[type]->SetBins(1000,-181,181,500,-91,91);
6744 fHist[type]->GetYaxis()->SetTitle("Projected Latitude in degrees");
6745 }
6746 if (frame=="equ")
6747 {
6748 fHist[type]->GetXaxis()->SetTitle("Hours from central Meridian");
6749 if (proj=="angh")
6750 {
6751 fHist[type]->SetBins(200,-12.1,12.1,100,-1.1,1.1);
6752 if (frame=="equ") fHist[type]->GetYaxis()->SetTitle("sin(#delta)");
6753 }
6754 else
6755 {
6756 fHist[type]->SetBins(200,-12.1,12.1,500,-91,91);
6757 if (frame=="equ") fHist[type]->GetYaxis()->SetTitle("Projected Declination in degrees");
6758 }
6759 }
6760 if (frame=="hor")
6761 {
6762 if (proj=="angh")
6763 {
6764 fHist[type]->GetYaxis()->SetTitle("sin(alt)=cos(zenith)");
6765 }
6766 else
6767 {
6768 fHist[type]->GetYaxis()->SetTitle("Projected Altitude in degrees");
6769 }
6770 }
6771 if (frame=="loc")
6772 {
6773 if (proj=="angh")
6774 {
6775 fHist[type]->GetYaxis()->SetTitle("cos(#theta)=sin(b)");
6776 }
6777 else
6778 {
6779 fHist[type]->GetYaxis()->SetTitle("Projected degrees from the equator");
6780 }
6781 }
6782 fProj=proj;
6783 }
6784
6785 if (proj=="merh")
6786 {
6787 fHist[type]->Fill(x*xfac,theta*180./pi);
6788 }
6789 else if (proj=="hamh" || proj=="aith" || proj=="cylh" || proj=="angh")
6790 {
6791 fHist[type]->Fill(x*xfac,y*yfac);
6792 }
6793 else if (proj=="UTh" || proj=="LTh" || proj=="GSTh" || proj=="LSTh") // The 24 hour day view
6794 {
6795 // Set histogram binning and axes attributes
6796 fHist[type]->SetBins(100,0,24,181,-90.5,90.5);
6797 if (!ts) ts=(NcTimestamp*)this;
6798 NcTimestamp tx=(*ts);
6799 Double_t toffset=GetLabTimeOffset();
6800 TString title="Day view";
6801 if (name!="")
6802 {
6803 title+=" of ";
6804 title+=name;
6805 }
6806 title+=" at ";
6807 title+=GetName();
6808 title+=" on ";
6809 TString date;
6810 ts->GetDayTimeString("UT",0,0,&date);
6811 title+=date;
6812 TString tmode="UT";
6813 if (proj=="LTh") tmode="LMT";
6814 if (proj=="GSTh")
6815 {
6816 tmode="GMST";
6817 if (mode=="T") tmode="GAST";
6818 }
6819 if (proj=="LSTh")
6820 {
6821 tmode="LMST";
6822 if (mode=="T") tmode="LAST";
6823 }
6824 if (proj=="UTh") title+=";Universal Time";
6825 if (proj=="LTh") title+=";Local Time";
6826 if (proj=="GSTh") title+=";Greenwich Sidereal Time";
6827 if (proj=="LSTh") title+=";Local Sidereal Time";
6828 if (proj!="UTh")
6829 {
6830 title+=" (";
6831 title+=tmode;
6832 title+=")";
6833 }
6834 title+=" in hours;";
6835 TString ytitle="Declination ";
6836 if (frame=="equ" && mode=="J") ytitle+="(J2000)";
6837 if (frame=="equ" && mode=="B") ytitle+="(B1950)";
6838 if (frame=="equ" && mode=="M") ytitle+="(Mean)";
6839 if (frame=="equ" && mode=="T") ytitle+="(True)";
6840 if (frame=="gal") ytitle="Galactic latitude";
6841 if (frame=="ecl") ytitle="Geocentric Ecliptic latitude";
6842 if (frame=="hor") ytitle="Horizon altitude";
6843 if (frame=="icr") ytitle="ICRS latitude";
6844 if (frame=="loc") ytitle="Angle w.r.t. local frame equator";
6845 ytitle+=" in degrees";
6846 title+=ytitle;
6847 fHist[type]->SetTitle(title);
6848 fHist[type]->SetStats(kFALSE);
6849
6850 // Fill the day view histogram
6851 Double_t hour=0;
6852 Double_t d,a,b;
6853 for (Int_t i=0; i<24; i++)
6854 {
6855 if (tmode=="UT") hour=tx.GetUT();
6856 if (tmode=="LMT") hour=tx.GetLT(toffset);
6857 if (tmode=="GMST") hour=tx.GetGMST();
6858 if (tmode=="GAST") hour=tx.GetGAST();
6859 if (tmode=="LMST") hour=tx.GetLMST(toffset);
6860 if (tmode=="LAST") hour=tx.GetLAST(toffset);
6861
6862 // Get coordinates at this time step
6863 GetSignal(d,a,"deg",b,"deg",frame,&tx,jref,mode,type);
6864
6865 if (frame=="hor") b=90.-b;
6866 if (frame=="loc") b=90.-a;
6867
6868 fHist[type]->Fill(hour,b);
6869
6870 tx.Add(1); // Add 1 hour for each time step
6871 }
6872
6873 // Restore the original timestamp for Solar system objects
6874 SetSolarSystem(namesave,&tsave,type);
6875 }
6876 else if (proj=="UYh" || proj=="LYh" || proj=="GSYh" || proj=="LSYh") // The day of the year view
6877 {
6878 // Set histogram binning and axes attributes
6879 fHist[type]->SetBins(1500,0,370,181,-90.5,90.5);
6880 if (!ts) ts=(NcTimestamp*)this;
6881 NcTimestamp tx=(*ts);
6882 Double_t toffset=GetLabTimeOffset();
6883 TString year="";
6884 year+=int(ts->GetEpoch("J"));
6885 TString tmode="UT";
6886 if (proj=="LYh") tmode="LMT";
6887 if (proj=="GSYh")
6888 {
6889 tmode="GMST";
6890 if (mode=="T") tmode="GAST";
6891 }
6892 if (proj=="LSYh")
6893 {
6894 tmode="LMST";
6895 if (mode=="T") tmode="LAST";
6896 }
6897 TString time;
6898 if (proj=="UYh" || proj=="GSYh") ts->GetDayTimeString(tmode,0,0,0,&time);
6899 if (proj=="LYh" || proj=="LSYh") ts->GetDayTimeString(tmode,0,toffset,0,&time);
6900
6901 TString title="Year view";
6902 if (name!="")
6903 {
6904 title+=" of ";
6905 title+=name;
6906 }
6907 title+=" at ";
6908 title+=GetName();
6909 title+=" in ";
6910 title+=year;
6911 title+=" at ";
6912 title+=time;
6913 title+=";Day of the year;";
6914 TString ytitle="Declination ";
6915 if (frame=="equ" && mode=="J") ytitle+="(J2000)";
6916 if (frame=="equ" && mode=="B") ytitle+="(B1950)";
6917 if (frame=="equ" && mode=="M") ytitle+="(Mean)";
6918 if (frame=="equ" && mode=="T") ytitle+="(True)";
6919 if (frame=="gal") ytitle="Galactic latitude";
6920 if (frame=="ecl") ytitle="Geocentric Ecliptic latitude";
6921 if (frame=="hor") ytitle="Horizon altitude";
6922 if (frame=="icr") ytitle="ICRS latitude";
6923 if (frame=="loc") ytitle="Angle w.r.t. local frame equator";
6924 ytitle+=" in degrees";
6925 title+=ytitle;
6926 fHist[type]->SetTitle(title);
6927 fHist[type]->SetStats(kFALSE);
6928
6929 // Fill the year view histogram
6930 // Start at 01-jan 00:00:00h for the corresponding year at the selected location
6931 // and then set the time according to the specified timestamp
6932 Double_t hour=0;
6933 if (proj=="UYh" || proj=="GSYh") // Location is Greenwich
6934 {
6935 tx.SetUT(year.Atoi(),1,1,"00:00:00");
6936 hour=ts->GetUT();
6937 }
6938 if (proj=="LYh" || proj=="LSYh") // The lab location
6939 {
6940 tx.SetLT(toffset,year.Atoi(),1,1,"00:00:00");
6941 hour=ts->GetLT(toffset);
6942 }
6943 tx.Add(hour); // Set the selected time
6944
6945 Double_t d,a,b;
6946 Int_t day=0;
6947 for (Int_t i=0; i<367; i++)
6948 {
6949
6950 // Get coordinates at this time step
6951 GetSignal(d,a,"deg",b,"deg",frame,&tx,jref,mode,type);
6952
6953 if (frame=="hor") b=90.-b;
6954 if (frame=="loc") b=90.-a;
6955
6956 if (proj=="UYh" || proj=="GSYh") day=tx.GetDayOfYear();
6957 if (proj=="LYh" || proj=="LSYh") day=tx.GetDayOfYear(kFALSE,toffset);
6958
6959 fHist[type]->Fill(day,b);
6960
6961 tx.Add(24); // Add 1 day (= 24 hours) for each time step
6962 }
6963
6964 // Restore the original timestamp for Solar system objects
6965 SetSolarSystem(namesave,&tsave,type);
6966 }
6967
6968 // Draw the selected histogram
6969 if ((!type && fHist[1]) || (type && fHist[0]))
6970 {
6971 fHist[type]->Draw("same");
6972 }
6973 else
6974 {
6975 fHist[type]->Draw();
6976
6977 // Draw a horizontal thick line to mark the horizon c.q. equator for the day and year views
6978 if (proj=="UTh" || proj=="LTh" || proj=="GSTh" || proj=="LSTh" ||
6979 proj=="UYh" || proj=="LYh" || proj=="GSYh" || proj=="LSYh")
6980 {
6981 if (!fMarkers)
6982 {
6983 fMarkers=new TObjArray();
6984 fMarkers->SetOwner();
6985 }
6986 TLine* line=0;
6987 if (proj=="UTh" || proj=="LTh" || proj=="GSTh" || proj=="LSTh") line=new TLine(0,0,24,0);
6988 if (proj=="UYh" || proj=="LYh" || proj=="GSYh" || proj=="LSYh") line=new TLine(0,0,370,0);
6989 if (line)
6990 {
6991 line->SetLineWidth(3);
6992 fMarkers->Add(line);
6993 line->Draw();
6994 }
6995 }
6996 }
6997 }
6998}
6999
7000void NcAstrolab::DisplaySignal(TString frame,TString mode,NcTimestamp* ts,TString name,TString proj,Int_t clr,Int_t type)
7001{
7091
7092 // Create a signal for a solar system object if needed
7093 Double_t d,a,b;
7094 GetSignal(d,a,"deg",b,"deg",frame,ts,name,mode,type);
7095
7096 Int_t j=GetSignalIndex(name,type);
7097 if (j>0)
7098 {
7099 if (type) j=-j;
7100 DisplaySignal(frame,mode,ts,j,proj,clr,name);
7101 }
7102
7103 // Update the canvas so that the Skymap GUI immediately shows the result
7104 if (fCanvas) fCanvas->Update();
7105}
7106
7107void NcAstrolab::DisplaySignals(TString frame,TString mode,NcTimestamp* ts,TString proj,Int_t clr,Int_t nmax,Int_t j,Int_t type,TString name)
7108{
7203
7204 NcSignal* sx=0;
7205 TString namex="";
7206 NcTimestamp* tx=0;
7207 Int_t jdisp=0;
7208
7209 // Display stored reference signals
7210 if (fRefs && type<=0)
7211 {
7212 // Use timestamp of j-th measurement if requested
7213 if (j>0)
7214 {
7215 sx=GetSignal(j,1);
7216 if (sx) tx=sx->GetTimestamp();
7217 }
7218
7219 // Use the provided timestamp
7220 if (!j || !tx) tx=ts;
7221
7222 // Use the current lab timestamp if no timestamp selected
7223 if (!tx) tx=(NcTimestamp*)this;
7224
7225 jdisp=0;
7226 for (Int_t i=1; i<=fRefs->GetSize(); i++)
7227 {
7228 sx=GetSignal(i,0);
7229 if (!sx) continue;
7230
7231 jdisp++;
7232 if (nmax>=0 && jdisp>nmax) break;
7233
7234 // Check for the name pattern
7235 namex=sx->GetName();
7236 if (name!="*" && !namex.Contains(name)) continue;
7237
7238 // Use the actual timestamp of the reference signal
7239 if (j<0)
7240 {
7241 tx=sx->GetTimestamp();
7242 if (!tx) tx=ts;
7243 if (!tx) tx=(NcTimestamp*)this;
7244 }
7245
7246 if (name=="*")
7247 {
7248 DisplaySignal(frame,mode,tx,i,proj,clr);
7249 }
7250 else
7251 {
7252 DisplaySignal(frame,mode,tx,i,proj,clr,name);
7253 }
7254 clr=0; // No display clear for subsequent signals
7255 }
7256 }
7257
7258 // Display all stored measurements
7259 if (fSigs && type)
7260 {
7261 jdisp=0;
7262 for (Int_t j=1; j<=fSigs->GetSize(); j++)
7263 {
7264 sx=GetSignal(j,1);
7265 if (!sx) continue;
7266
7267 jdisp++;
7268 if (nmax>=0 && jdisp>nmax) break;
7269
7270 // Check for the name pattern
7271 namex=sx->GetName();
7272 if (name!="*" && !namex.Contains(name)) continue;
7273
7274 tx=sx->GetTimestamp();
7275 if (!tx) tx=ts;
7276 if (!tx) tx=(NcTimestamp*)this;
7277 if (name=="*")
7278 {
7279 DisplaySignal(frame,mode,tx,-j,proj,clr);
7280 }
7281 else
7282 {
7283 DisplaySignal(frame,mode,tx,-j,proj,clr,name);
7284 }
7285 clr=0; // No display clear for subsequent signals
7286 }
7287 }
7288
7289 // Update the canvas so that the Skymap GUI immediately shows the result
7290 if (fCanvas) fCanvas->Update();
7291}
7292
7293void NcAstrolab::SetMarkerSize(Float_t size,Int_t type)
7294{
7306
7307 if (type<0 || type >3) return;
7308
7309 fMarkerSize[type]=size;
7310}
7311
7312void NcAstrolab::SetMarkerStyle(Int_t style,Int_t type)
7313{
7325
7326 if (type<0 || type >3) return;
7327
7328 fMarkerStyle[type]=style;
7329}
7330
7331void NcAstrolab::SetMarkerColor(Int_t color,Int_t type)
7332{
7344
7345 if (type<0 || type >3) return;
7346
7347 fMarkerColor[type]=color;
7348}
7349
7350void NcAstrolab::SetCentralMeridian(Int_t mode,Double_t phi,TString u)
7351{
7375
7376 fMeridian=ConvertAngle(phi,u,"rad");
7377 fUsMeridian=0;
7378 if (mode>0) fUsMeridian=1;
7379 if (mode<0) fUsMeridian=-1;
7380 Double_t pi=acos(-1.);
7381 Double_t twopi=2.*pi;
7382 // Set range to 0 <= meridian < 2pi
7383 while (fMeridian>=twopi)
7384 {
7385 fMeridian-=twopi;
7386 }
7387 while (fMeridian<0)
7388 {
7389 fMeridian+=twopi;
7390 }
7391 // Prevent accuracy problems
7392 if (fMeridian>0) fMeridian+=1.e-6;
7393}
7394
7395void NcAstrolab::Project(Double_t l,Double_t b,TString proj,Double_t& x,Double_t& y)
7396{
7427
7428 Double_t pi=acos(-1.);
7429
7430 // Subtract central meridian from longitude
7431 l-=fMeridian;
7432
7433 // Take l between -180 and 180 degrees
7434 while (l>pi)
7435 {
7436 l-=2.*pi;
7437 }
7438 while (l<-pi)
7439 {
7440 l+=2.*pi;
7441 }
7442
7443 x=0;
7444 y=0;
7445
7446 // Convert (l,b) to (x,y) with -2 < x <= 2
7447 if (proj=="cyl" || proj=="cylh") ProjectCylindrical(l,b,x,y);
7448 if (proj=="ham" || proj=="hamh") ProjectHammer(l,b,x,y);
7449 if (proj=="ait" || proj=="aith") ProjectAitoff(l,b,x,y);
7450 if (proj=="mer" || proj=="merh") ProjectMercator(l,b,x,y);
7451 if (proj=="ang" || proj=="angh")
7452 {
7453 x=2.*l/pi;
7454 y=sin(b);
7455 }
7456}
7457
7458void NcAstrolab::ProjectCylindrical(Double_t l,Double_t b,Double_t& x, Double_t& y)
7459{
7468
7469 Double_t pi=acos(-1.);
7470 x=2.*l/pi;
7471 y=2.*b/pi;
7472}
7473
7474void NcAstrolab::ProjectHammer(Double_t l,Double_t b,Double_t& x,Double_t& y)
7475{
7485
7486 Double_t k=1./sqrt(1.+cos(b)*cos(l/2.));
7487 x=2.*k*cos(b)*sin(l/2.);
7488 y=k*sin(b);
7489}
7490
7491void NcAstrolab::ProjectAitoff(Double_t l,Double_t b,Double_t& x,Double_t& y)
7492{
7501
7502 Double_t pi=acos(-1.);
7503 x=0;
7504 y=0;
7505 Double_t k=acos(cos(b)*cos(l/2.));
7506 if(sin(k)!=0)
7507 {
7508 x=4.*k*cos(b)*sin(l/2.)/(pi*sin(k));
7509 y=2.*k*sin(b)/(pi*sin(k));
7510 }
7511}
7512
7513void NcAstrolab::ProjectMercator(Double_t l,Double_t b,Double_t& x,Double_t& y)
7514{
7529
7530 Double_t pi=acos(-1.);
7531 Double_t bcut=85.051*pi/180.; // Latitude cut off value in radians
7532
7533 x=2.*l/pi;
7534 y=0;
7535 if (b > bcut) b=bcut;
7536 if (b < -bcut) b=-bcut;
7537 y=0.5*log((1.+sin(b))/(1.-sin(b)))/pi;
7538}
7539
7540void NcAstrolab::SetPhysicalParameter(TString name,Double_t value)
7541{
7579
7580 // Variable to correct conversion factors when a parameter is modified
7581 Double_t frac=1;
7582
7583 if (name=="SpeedC")
7584 {
7585 frac=value/fSpeedC;
7586 fSpeedC=value;
7587 fMe*=frac*frac;
7588 fMmu*=frac*frac;
7589 fMtau*=frac*frac;
7590 fAmu*=frac*frac;
7591 fMp*=frac*frac;
7592 fMn*=frac*frac;
7593 fMW*=frac*frac;
7594 fMZ*=frac*frac;
7595 fHbarc*=frac;
7596 fHbarc2*=pow(frac,2.);
7597 }
7598 if (name=="Qe")
7599 {
7600 frac=value/fQe;
7601 fQe=value;
7602 fMe/=frac;
7603 fMmu/=frac;
7604 fMtau/=frac;
7605 fAmu/=frac;
7606 fMp/=frac;
7607 fMn/=frac;
7608 fMW/=frac;
7609 fMZ/=frac;
7610 fHbar/=frac;
7611 fHbarc/=frac;
7612 fHbarc2/=pow(frac,2.);
7613 }
7614 if (name=="Me") fMe=value;
7615 if (name=="Mmu") fMmu=value;
7616 if (name=="Mtau") fMtau=value;
7617 if (name=="Amu")
7618 {
7619 frac=value/fAmu;
7620 fAmu=value;
7621 fMp*=frac;
7622 fMn*=frac;
7623 }
7624 if (name=="Mp") fMp=value;
7625 if (name=="Mn") fMn=value;
7626 if (name=="MW") fMW=value;
7627 if (name=="GammaW") fGammaW=value;
7628 if (name=="MZ") fMZ=value;
7629 if (name=="GammaZ") fGammaZ=value;
7630 if (name=="AlphaEM") fAlphaEM=value;
7631 if (name=="Fermi") fFermi=value;
7632 if (name=="Planck")
7633 {
7634 frac=value/fPlanck;
7635 fPlanck=value;
7636 fHbar*=frac;
7637 fHbarc*=frac;
7638 fFermi/=pow(frac,3.);
7639 }
7640 if (name=="Boltz") fBoltz=value;
7641 if (name=="Newton")
7642 {
7643 frac=value/fNewton;
7644 fNewton=value;
7645 fGn*=frac;
7646 }
7647 if (name=="Gn") fGn=value;
7648 if (name=="Au") fAu=value;
7649 if (name=="Pc") fPc=value;
7650 if (name=="Hubble") fHubble=value;
7651 if (name=="OmegaM") fOmegaM=value;
7652 if (name=="OmegaR") fOmegaR=value;
7653 if (name=="OmegaL") fOmegaL=value;
7654 if (name=="OmegaB") fOmegaB=value;
7655 if (name=="OmegaC") fOmegaC=value;
7656}
7657
7658Double_t NcAstrolab::GetPhysicalParameter(TString name) const
7659{
7681
7682 Double_t val=0;
7683
7684 // Standard parameters
7685 if (name=="SpeedC") return fSpeedC;
7686 if (name=="Qe") return fQe;
7687 if (name=="Me") return fMe;
7688 if (name=="Mmu") return fMmu;
7689 if (name=="Mtau") return fMtau;
7690 if (name=="Amu") return fAmu;
7691 if (name=="Mp") return fMp;
7692 if (name=="Mn") return fMn;
7693 if (name=="MW") return fMW;
7694 if (name=="GammaW") return fGammaW;
7695 if (name=="GammaZ") return fGammaZ;
7696 if (name=="AlphaEM") return fAlphaEM;
7697 if (name=="Fermi") return fFermi;
7698 if (name=="Planck") return fPlanck;
7699 if (name=="Boltz") return fBoltz;
7700 if (name=="Newton") return fNewton;
7701 if (name=="Gn") return fGn;
7702 if (name=="Au") return fAu;
7703 if (name=="Pc") return fPc;
7704 if (name=="Hubble") return fHubble;
7705 if (name=="OmegaM") return fOmegaM;
7706 if (name=="OmegaR") return fOmegaR;
7707 if (name=="OmegaL") return fOmegaL;
7708 if (name=="OmegaB") return fOmegaB;
7709 if (name=="OmegaC") return fOmegaC;
7710
7711 // Derived parameters
7712 if (name=="Hbar") return fHbar;
7713 if (name=="Hbarc") return fHbarc;
7714 if (name=="Hbarc2") return fHbarc2;
7715 if (name=="Mnucl")
7716 {
7717 val=(fMp+fMn)/2.;
7718 return val;
7719 }
7720 if (name=="Sin2w")
7721 {
7722 val=1.-pow(fMW/fMZ,2.);
7723 return val;
7724 }
7725 if (name=="Jy") return 1e-23;
7726 if (name=="Erg")
7727 {
7728 val=1e-7/(fQe*1e9);
7729 return val;
7730 }
7731
7732 // Unknown parameter
7733 return 0;
7734}
7735
7736Double_t NcAstrolab::GetPhysicalDistance(Double_t z,TString u,Int_t t) const
7737{
7771
7772 if (z<=0 || fHubble<=0) return 0;
7773
7774 Double_t c=fSpeedC/1000.; // Lightspeed in km/s
7775
7776 TF1 f("f","1./sqrt([0]*pow((1.+x),4)+[1]*pow((1.+x),3)+[2])");
7777
7778 f.SetParameter(0,fOmegaR);
7779 f.SetParameter(1,fOmegaM);
7780 f.SetParameter(2,fOmegaL);
7781 f.SetRange(0,z);
7782
7783 Double_t dist=f.Integral(0,z);
7784 dist*=c/fHubble; // The distance in Mpc
7785
7786 Double_t distm=dist*1e6*fPc; // corresponding distance in meter
7787
7788 Double_t val=0;
7789
7790 if (u=="Gpc") val=dist*1e-3;
7791 if (u=="Mpc") val=dist;
7792 if (u=="pc") val=dist*1e6;
7793 if (u=="ly") val=dist*3.26156e6;
7794 if (u=="m") val=distm;
7795 if (u=="km") val=distm*1e-3;
7796 if (u=="cm") val=distm*1e2;
7797
7798 if (!t) val=val/(z+1.);
7799
7800 return val;
7801}
7802
7803Double_t NcAstrolab::GetProperDistance(Double_t z,TString u,Int_t t) const
7804{
7838
7839 Double_t val=GetPhysicalDistance(z,u,t);
7840
7841 return val;
7842}
7843
7844Double_t NcAstrolab::GetComovingDistance(Double_t z,TString u) const
7845{
7876
7877 Double_t val=GetPhysicalDistance(z,u,1);
7878
7879 return val;
7880}
7881
7882Double_t NcAstrolab::GetLuminosityDistance(Double_t z,TString u) const
7883{
7917
7918 Double_t val=GetPhysicalDistance(z,u,1);
7919 val=val*(z+1.);
7920
7921 return val;
7922}
7923
7924Double_t NcAstrolab::GetLightTravelDistance(Double_t z,TString u) const
7925{
7959
7960 if (z<=0 || fHubble<=0) return 0;
7961
7962 Double_t c=fSpeedC/1000.; // Lightspeed in km/s
7963
7964 TF1 f("f","1./((1.+x)*sqrt([0]*pow((1.+x),4)+[1]*pow((1.+x),3)+[2]))");
7965
7966 f.SetParameter(0,fOmegaR);
7967 f.SetParameter(1,fOmegaM);
7968 f.SetParameter(2,fOmegaL);
7969 f.SetRange(0,z);
7970
7971 Double_t dist=f.Integral(0,z);
7972 dist*=c/fHubble; // The distance in Mpc
7973
7974 Double_t distm=dist*1e6*fPc; // corresponding distance in meter
7975
7976 Double_t val=0;
7977
7978 if (u=="Gpc") val=dist*1e-3;
7979 if (u=="Mpc") val=dist;
7980 if (u=="pc") val=dist*1e6;
7981 if (u=="ly") val=dist*3.26156e6;
7982 if (u=="m") val=distm;
7983 if (u=="km") val=distm*1e-3;
7984 if (u=="cm") val=distm*1e2;
7985
7986 return val;
7987}
7988
7989Double_t NcAstrolab::GetLightTravelTime(Double_t z) const
7990{
8008
8009 Double_t val=GetLightTravelDistance(z,"ly");
8010
8011 return val;
8012}
8013
8014Double_t NcAstrolab::GetHubbleParameter(Double_t z,TString u) const
8015{
8036
8037 if (z<0 || fHubble<=0) return 0;
8038
8039 TF1 f("f","sqrt([0]*pow((1.+x),4)+[1]*pow((1.+x),3)+[2])");
8040
8041 f.SetParameter(0,fOmegaR);
8042 f.SetParameter(1,fOmegaM);
8043 f.SetParameter(2,fOmegaL);
8044 f.SetRange(0,z);
8045
8046 Double_t H=f.Eval(z);
8047 H*=fHubble; // The current Hubble parameter (H0) in km/s per Mpc
8048
8049 Double_t Hm=H/(1e6*fPc); // corresponding H in km/s per meter
8050
8051 Double_t val=0;
8052
8053 if (u=="Gpc") val=H/1e-3;
8054 if (u=="Mpc") val=H;
8055 if (u=="pc") val=H/1e6;
8056 if (u=="ly") val=H/3.26156e6;
8057 if (u=="m") val=Hm;
8058 if (u=="km") val=Hm/1e-3;
8059 if (u=="cm") val=Hm/1e2;
8060
8061 return val;
8062}
8063
8064Double_t NcAstrolab::GetNuclearMass(Int_t Z,Int_t N,Int_t mode) const
8065{
8093
8094 if (Z<0 || N<0) return 0;
8095
8096 Double_t rz=Z;
8097 Double_t rn=N;
8098 Double_t ra=Z+N;
8099
8100 // Coefficients from a recent fit mentioned in Tipler's modern physics (4th ed.) textbook.
8101 // The values in the comment field are the ones of the slides mentioned above.
8102 Double_t a=15.67; //15.835;
8103 Double_t b=17.23; //18.33;
8104 Double_t s=23.2; //23.20;
8105 Double_t d=0.75; //0.714;
8106 Double_t delta=12; //11.2;
8107
8108 Double_t term1=a*ra; // Constant bulk binding energy like cohesion in a liquid
8109 Double_t term2=b*pow(ra,2./3.); // Surface energy of a sphere like surface tension of liquids
8110 Double_t term3=s*pow((rn-rz),2.)/ra; // Symmetry term
8111 Double_t term4=d*pow(rz,2.)/pow(ra,1./3.); // Coulomb term
8112 Double_t term5=0; // Phenomenological correction for light nuclei (pairing energy term)
8113
8114 Int_t oz=Z%2; // Flag (1) for odd Z nuclei
8115 Int_t on=N%2; // Flag (1) for odd N nuclei
8116
8117 if (oz && on) term5=delta/sqrt(ra);
8118 if (!oz && !on) term5=-delta/sqrt(ra);
8119
8120 // Binding energy in MeV
8121 Double_t bnz=term1-term2-term3-term4-term5;
8122
8123 // In case a single nucleon was specified
8124 if ((Z+N)<2)
8125 {
8126 bnz=0;
8127 ra=1;
8128 }
8129
8130 // Nuclear mass in MeV/c^2
8131 Double_t mass=rz*fMp+rn*fMn-bnz;
8132
8133 // Explicit literature values for very light elements
8134 if (Z==1 && N==1) // Deuteron
8135 {
8136 mass=2.013553212712*fAmu;
8137 bnz=rz*fMp+rn*fMn-mass;
8138 }
8139
8140 if (Z==1 && N==2) // Triton
8141 {
8142 mass=3.0155007134*fAmu;
8143 bnz=rz*fMp+rn*fMn-mass;
8144 }
8145
8146 if (Z==2 && N==1) // Helion
8147 {
8148 mass=3.0149322468*fAmu;
8149 bnz=rz*fMp+rn*fMn-mass;
8150 }
8151
8152 if (Z==2 && N==2) // Alpha
8153 {
8154 mass=4.001506179125*fAmu;
8155 bnz=rz*fMp+rn*fMn-mass;
8156 }
8157
8158 Double_t value=0;
8159
8160 switch(mode)
8161 {
8162 case 1 : // Nuclear mass in GeV/c^2
8163 value=mass/1000.;
8164 break;
8165
8166 case -1 : // Nuclear mass in amu
8167 value=mass/fAmu;
8168 break;
8169
8170 case 2 : // Total binding energy in MeV
8171 value=bnz;
8172 break;
8173
8174 case -2 : // Total binding energy in amu
8175 value=bnz/fAmu;
8176 break;
8177
8178 case 3 : // Binding energy per nucleon in MeV
8179 value=bnz/ra;
8180 break;
8181
8182 case -3 : // Binding energy per nucleon in amu
8183 value=bnz/(fAmu*ra);
8184 break;
8185 }
8186
8187 return value;
8188}
8189
8190Double_t NcAstrolab::GetRadiationLength(Double_t Z,Double_t A,Double_t rho) const
8191{
8220
8221 Double_t X0=-1;
8222
8223 if (Z<=0 || A<1 || A<Z) return -1;
8224
8225 X0=716.4*A/(Z*(Z+1.)*(log(287./sqrt(Z))));
8226
8227 Double_t mN=0.001*fGn*fQe/fAmu; // The nucleon mass in gram
8228 if (rho==0) X0=X0/mN;
8229 if (rho>0) X0=X0/rho;
8230
8231 return X0;
8232}
8233
8234Double_t NcAstrolab::GetMeanFreePath(Double_t sigma,Double_t rho,Int_t mode) const
8235{
8270
8271 Double_t lambda=-1;
8272
8273 if (sigma<=0 || rho<=0 || mode<0 || mode>4) return -1;
8274
8275 Double_t mN=0.001*fGn*fQe/fAmu; // The nucleon mass in gram
8276 Double_t n=fabs(rho)/mN; // The number of nucleons per cm^3
8277 if (mode<2) n=rho; // The number of scattering centers per cm^3
8278 sigma=sigma*1e-24; // Convert to cm^2
8279
8280 lambda=1./(sigma*n);
8281
8282 if (mode==1 || mode==4) lambda=lambda*n;
8283 if (mode==3) lambda=lambda*rho;
8284
8285 return lambda;
8286}
8287
8288Double_t NcAstrolab::GetInteractionProbability(Double_t x,Double_t lambda) const
8289{
8320
8321 Double_t prob=-1;
8322
8323 if (x<0 || lambda<=0) return -1;
8324
8325 prob=1.-exp(-x/lambda);
8326
8327 return prob;
8328}
8329
8330Double_t NcAstrolab::GetInteractionProbability(Double_t x,Double_t sigma,Double_t rho,Int_t mode) const
8331{
8363
8364 Double_t prob=-1;
8365
8366 Double_t lambda=GetMeanFreePath(sigma,rho,mode);
8367
8368 if (lambda>0) prob=GetInteractionProbability(x,lambda);
8369
8370 return prob;
8371}
8372
8373Double_t NcAstrolab::GetSurvivalProbability(Double_t x,Double_t lambda) const
8374{
8405
8406 Double_t prob=-1;
8407
8408 if (x<0 || lambda<=0) return -1;
8409
8410 prob=exp(-x/lambda);
8411
8412 return prob;
8413}
8414
8415Double_t NcAstrolab::GetSurvivalProbability(Double_t x,Double_t sigma,Double_t rho,Int_t mode) const
8416{
8448
8449 Double_t prob=-1;
8450
8451 Double_t lambda=GetMeanFreePath(sigma,rho,mode);
8452
8453 if (lambda>0) prob=GetSurvivalProbability(x,lambda);
8454
8455 return prob;
8456}
8457
8458Double_t NcAstrolab::GetShieldingThickness(Double_t prob,Double_t lambda) const
8459{
8487
8488 Double_t x=-1;
8489
8490 if (prob<=0 || prob>1 || lambda<=0) return -1;
8491
8492 x=-lambda*log(prob);
8493
8494 return x;
8495}
8496
8497Double_t NcAstrolab::GetShieldingThickness(Double_t prob,Double_t sigma,Double_t rho,Int_t mode) const
8498{
8527
8528 Double_t x=-1;
8529
8530 if (prob<=0 || prob>1) return -1;
8531
8532 Double_t lambda=GetMeanFreePath(sigma,rho,mode);
8533
8534 if (lambda>0) x=GetShieldingThickness(prob,lambda);
8535
8536 return x;
8537}
8538
8539Double_t NcAstrolab::GetTargetThickness(Double_t prob,Double_t lambda) const
8540{
8568
8569 if (prob<=0 || prob>1 || lambda<=0) return -1;
8570
8571 Double_t p=1.-prob;
8572 Double_t x=GetShieldingThickness(p,lambda);
8573
8574 return x;
8575}
8576
8577Double_t NcAstrolab::GetTargetThickness(Double_t prob,Double_t sigma,Double_t rho,Int_t mode) const
8578{
8607
8608 Double_t x=-1;
8609
8610 if (prob<=0 || prob>1) return -1;
8611
8612 Double_t lambda=GetMeanFreePath(sigma,rho,mode);
8613
8614 Double_t p=1.-prob;
8615 if (lambda>0) x=GetShieldingThickness(p,lambda);
8616
8617 return x;
8618}
8619
8620Double_t NcAstrolab::GetNeutrinoXsection(Int_t mode,Int_t type,Double_t egev,Double_t xscale,Double_t* eprimgev,Double_t* alpha) const
8621{
8668
8669 if (eprimgev) *eprimgev=0;
8670 if (alpha) *alpha=0;
8671 if (!mode || mode>3 || mode<-4 || !type || abs(type)>3) return 0;
8672
8673 const Double_t fnumuccn=6.77e-15; // Nu_mu+Nucleon CC sigma/E in barn/GeV
8674 const Double_t fanumuccn=3.34e-15; // Anti-Nu_mu+Nucleon CC sigma/E in barn/GeV
8675
8676 const Double_t sinw2=GetPhysicalParameter("Sin2w"); // sin^2 of the Weinberg angle
8677
8678 const Double_t fnuetote=0.25+sinw2+4.*pow(sinw2,2.)/3.; // Nu_e+e total sigma/sigma0
8679 const Double_t fanuetote=(1./12.)+(sinw2/3.)+4.*pow(sinw2,2.)/3.; // Anti-Nu_e+e total sigma/sigma0
8680 Double_t fnumucce=1.; // Nu_mu+e CC sigma/sigma0
8681 const Double_t fnumunce=0.25-sinw2+4.*pow(sinw2,2.)/3.; // Nu_mu+e NC sigma/sigma0
8682 const Double_t fanumunce=(1./12.)-(sinw2/3.)+4.*pow(sinw2,2.)/3.; // Anti-Nu_mu+e NC sigma/sigma0
8683 const Double_t f4=1./3.; // Anti-Nu_e+e-->Anti-Nu_mu+mu CC sigma/sigma0
8684
8685 // Parameters for the (anti)neutrino+Nucleon cross section parametrisations of Conolly et al.
8686 const Double_t c0nu=-1.826;
8687 const Double_t c1nu=-17.31;
8688 const Double_t c2nunc=-6.448;
8689 const Double_t c2nucc=-6.406;
8690 const Double_t c3nu=1.431;
8691 const Double_t c4nunc=-18.61;
8692 const Double_t c4nucc=-17.91;
8693 const Double_t c0anu=-1.033;
8694 const Double_t c1anu=-15.95;
8695 const Double_t c2anunc=-7.296;
8696 const Double_t c2anucc=-7.247;
8697 const Double_t c3anu=1.569;
8698 const Double_t c4anunc=-18.30;
8699 const Double_t c4anucc=-17.72;
8700
8701 Double_t rncnu=0.2261/0.7221; // sigma_nc/sigma_cc for Neutrino+Nucleon DIS at 100 GeV
8702 Double_t rncanu=0.1307/0.3747; // sigma_nc/sigma_cc for Anti-neutrino+Nucleon DIS at 100 GeV
8703
8704 // Average inelasticity (y) values from Gandhi et al.
8705 Double_t ynucc[12]={0.483,0.477,0.472,0.426,0.332,0.237,0.250,0.237,0.225,0.216,0.208,0.205};
8706 Double_t ynunc[12]={0.474,0.470,0.467,0.428,0.341,0.279,0.254,0.239,0.227,0.217,0.210,0.207};
8707 Double_t yanucc[12]={0.333,0.340,0.354,0.345,0.301,0.266,0.249,0.237,0.225,0.216,0.208,0.205};
8708 Double_t yanunc[12]={0.350,0.354,0.368,0.358,0.313,0.273,0.253,0.239,0.227,0.217,0.210,0.207};
8709
8710 Double_t loge=log10(egev);
8711 Double_t y=0;
8712 Int_t index=int(loge+0.5);
8713 if (index<1) index=1;
8714 if (index>12) index=12;
8715 if (eprimgev)
8716 {
8717 if (type>0) // Neutrinos
8718 {
8719 if (abs(mode)==1) y=ynucc[index-1];
8720 if (abs(mode)==2) y=ynunc[index-1];
8721 if (mode==3) y=(ynucc[index-1]+rncnu*ynunc[index-1])/(1.+rncnu);
8722 if (mode==-3) y=(ynucc[index-1]+fnumunce*ynunc[index-1])/(1.+fnumunce);
8723 }
8724 else // Anti-neutrinos
8725 {
8726 if (abs(mode)==1) y=yanucc[index-1];
8727 if (abs(mode)==2) y=yanunc[index-1];
8728 if (mode==3) y=(yanucc[index-1]+rncanu*yanunc[index-1])/(1.+rncanu);
8729 if (mode==-3) y=(yanucc[index-1]+fnumunce*yanunc[index-1])/(1.+fnumunce);
8730 }
8731 *eprimgev=egev*(1.-y);
8732 }
8733
8734 if (alpha)
8735 {
8736 Double_t mtarg=fMe;
8737 if (mode>0) mtarg=GetPhysicalParameter("Mnucl");
8738 *alpha=sqrt(2.e-3*mtarg/egev)*y*180./((1.-y)*acos(-1.));
8739 }
8740
8741 Double_t xsec=0;
8742 Double_t fact=0;
8743 Double_t c0=0,c1=0,c2=0,c3=0,c4=0;
8744
8745 if (mode>0) // DIS on Nucleon target
8746 {
8747 if (mode==3) // Total xsec
8748 {
8749 // Recursive invokation for NC+CC cross section
8750 xsec=GetNeutrinoXsection(1,type,egev,xscale);
8751 xsec+=GetNeutrinoXsection(2,type,egev,xscale);
8752 return xsec;
8753 }
8754 if (egev<1e4) // Energy below 10 TeV
8755 {
8756 if (mode==1) // CC xsec
8757 {
8758 fact=fnumuccn;
8759 if (type<0) fact=fanumuccn;
8760 }
8761 if (mode==2) // NC xsec
8762 {
8763 fact=fnumuccn*rncnu;
8764 if (type<0) fact=fanumuccn*rncanu;
8765 }
8766 xsec=fact*egev;
8767 }
8768 else // Energy of 10 TeV and above
8769 {
8770 if (mode==1) // CC xsec
8771 {
8772 if (type>0)
8773 {
8774 c0=c0nu;
8775 c1=c1nu;
8776 c2=c2nucc;
8777 c3=c3nu;
8778 c4=c4nucc;
8779 }
8780 else
8781 {
8782 c0=c0anu;
8783 c1=c1anu;
8784 c2=c2anucc;
8785 c3=c3anu;
8786 c4=c4anucc;
8787 }
8788 }
8789 if (mode==2) // NC xsec
8790 {
8791 if (type>0)
8792 {
8793 c0=c0nu;
8794 c1=c1nu;
8795 c2=c2nunc;
8796 c3=c3nu;
8797 c4=c4nunc;
8798 }
8799 else
8800 {
8801 c0=c0anu;
8802 c1=c1anu;
8803 c2=c2anunc;
8804 c3=c3anu;
8805 c4=c4anunc;
8806 }
8807 }
8808 Double_t lne=log(loge-c0);
8809 Double_t logsigma=c1+c2*lne+c3*pow(lne,2.)+c4/lne; // Log10(sigma) in cm^2
8810 logsigma+=24.;
8811 xsec=pow(10.,logsigma);
8812 }
8813 }
8814 else // Scattering on electron target
8815 {
8816 // Check whether we are in the Glashow resonance regime
8817 Double_t elow=pow((fMW-2.*fGammaW),2.)/(2.e-3*fMe);
8818 Double_t eup=pow((fMW+2.*fGammaW),2.)/(2.e-3*fMe);
8819 if (mode==-3 && type==-1 && egev>elow && egev<eup) // Total xsec at Glashow resonance
8820 {
8821 xsec=5.02e-7/xscale;
8822 if (eprimgev) *eprimgev=0;
8823 if (alpha) *alpha=0;
8824 return xsec;
8825 }
8826
8827 // Check if we are above the kinematical threshold energy for CC scattering
8828 Double_t mlepton=fMe;
8829 if (abs(type)==2) mlepton=fMmu;
8830 if (abs(type)==3) mlepton=fMtau;
8831 Double_t eth=1.e-3*(pow(mlepton,2.)-pow(fMe,2.))/(2.*fMe);
8832
8833 if (egev<eth) // Below CC kinematical threshold
8834 {
8835 fnumucce=0;
8836 if (mode==-1) // CC xsec was requested
8837 {
8838 if (eprimgev) *eprimgev=egev;
8839 if (alpha) *alpha=0;
8840 return 0;
8841 }
8842 }
8843
8844 // The Nu_mu+e CC cross section in barn well above threshold
8845 Double_t sigma0=pow(fFermi,2.)*fHbarc2*2.e-3*fMe*egev/acos(-1.);
8846
8847 if (mode==-1) // CC xsec
8848 {
8849 if (type>1) fact=fnumucce;
8850 }
8851 if (mode==-2) // NC xsec
8852 {
8853 if (type>1) fact=fnumunce;
8854 if (type<-1) fact=fanumunce;
8855 }
8856 if (mode==-3) // Total xsec
8857 {
8858 if (type==1) fact=fnuetote;
8859 if (type==-1) fact=fanuetote;
8860 if (type>1) fact=fnumucce+fnumunce;
8861 if (type<-1) fact=fanumunce;
8862 }
8863 if (mode==-4 && type==-1) fact=f4;
8864 xsec=fact*sigma0;
8865 }
8866
8867 xsec/=xscale;
8868
8869 return xsec;
8870}
8871
8872Double_t NcAstrolab::GetNeutrinoAngle(Double_t E,TString u,Int_t mode,TF1* f)
8873{
8909
8910 Double_t value=-1;
8911
8912 if (E<=0 || mode<0 || mode>2) return value;
8913
8914 // Convert to TeV
8915 E*=0.001;
8916
8917 // The parametrisation (in degrees) for a 1 TeV neutrino
8918 Double_t mean=1.38711583;
8919 Double_t median=0.86842105;
8920 Double_t mpv=0.560150;
8921 Double_t sigma=0.226679;
8922
8923 // Scaling the parameters to the provided neutrino energy
8924 Double_t p=log10(E);
8925 Double_t scale=1./(pow(1.5,p)*sqrt(E));
8926
8927 mean*=scale;
8928 median*=scale;
8929 mpv*=scale;
8930 sigma*=scale;
8931
8932 // Create a normalized Landau distribution template
8933 if (!fNuAngle)
8934 {
8935 fNuAngle=new TF1("NuAngle","TMath::Landau(x,[0],[1],1)",0,90);
8936 fNuAngle->SetTitle("Landau pdf;Neutrino-lepton opening angle in degrees;PDF");
8937 }
8938
8939 // Set the parameters for the Landau parametrization
8940 fNuAngle->SetParameter(0,mpv);
8941 fNuAngle->SetParameter(1,sigma);
8942
8943 // Obtain an opening angle value according to the pdf
8944 Double_t ang=fNuAngle->GetRandom();
8945
8946 if (u=="rad")
8947 {
8948 Double_t fact=acos(-1.)/180.; // Coversion factor degrees->radians
8949 mean*=fact;
8950 median*=fact;
8951 ang*=fact;
8952 }
8953
8954 // Provide the used pdf if requested
8955 if (f) fNuAngle->Copy(*f);
8956
8957 value=mean;
8958 if (mode==1) value=median;
8959 if (mode==2) value=ang;
8960
8961 return value;
8962}
8963
8964void NcAstrolab::RandomPosition(Nc3Vector& v,Double_t thetamin,Double_t thetamax,Double_t phimin,Double_t phimax)
8965{
8981
8982 // If needed, initialise the randomiser with a "date/time driven" seed
8983 // using the timestamp of the moment of this invokation of the member function.
8984 // This will ensure different random sequences if the user repeats analyses
8985 // with identical measurements and reference signals without explicit initialisation
8986 // of the randomiser by the user at the start of the analysis.
8987 if (!fRan) fRan=new NcRandom(-1);
8988
8989 // Generate random angles in the specified range
8990 Double_t pi=acos(-1.);
8991 Double_t cosmax=cos(thetamin*pi/180.);
8992 Double_t cosmin=cos(thetamax*pi/180.);
8993 Double_t cost=fRan->Uniform(cosmin,cosmax);
8994 Double_t theta=acos(cost)*180./pi;
8995 Double_t phi=fRan->Uniform(phimin,phimax);
8996
8997 Double_t norm=1;
8998 if (v.HasVector()) norm=v.GetNorm();
8999
9000 Double_t err[3]={0,0,0};
9001 Int_t ier=0;
9002 if (v.HasErrors())
9003 {
9004 ier=1;
9005 v.GetErrors(err,"car");
9006 }
9007
9008 v.SetVector(norm,theta,phi,"sph","deg");
9009 if (ier) v.SetErrors(err,"car");
9010}
9011
9013{
9032
9033 if (!v.HasVector()) return;
9034
9035 // If needed, initialise the randomiser with a "date/time driven" seed
9036 // using the timestamp of the moment of this invokation of the member function.
9037 // This will ensure different random sequences if the user repeats analyses
9038 // with identical measurements and reference signals without explicit initialisation
9039 // of the randomiser by the user at the start of the analysis.
9040 if (!fRan) fRan=new NcRandom(-1);
9041
9042 Double_t norm=v.GetX(1,"sph","deg");
9043 Double_t theta=v.GetX(2,"sph","deg");
9044 Double_t phi=v.GetX(3,"sph","deg");
9045 Double_t err[3]={0,0,0};
9046 Int_t ier=0;
9047 if (v.HasErrors())
9048 {
9049 ier=1;
9050 v.GetErrors(err,"car");
9051 }
9052 if (norm<=0)
9053 {
9054 norm=1;
9055 err[0]=0;
9056 }
9057 v.SetVector(norm,theta,phi,"sph","deg");
9058
9059 // The smeared position will be generated as if the actual vector "v" coincided with the positive Z-axis.
9060 // The actual smeared position will be obtained via a "backward rotation" to the real frame orientation.
9061
9062 // Determine the rotation matrix for the frame in which "v" coincides with the positive Z-axis.
9063 TRotMatrix m;
9064 m.SetAngles(90.+theta,phi,90,phi+90.,theta,phi);
9065
9066 // Generate smeared position w.r.t. the fictative Z-axis
9067 Double_t pi=acos(-1.);
9068 Double_t cosmax=1;
9069 Double_t cosmin=cos(fabs(sigma)*pi/180.);
9070 Double_t phimin=0;
9071 Double_t phimax=360;
9072 Double_t cost=0;
9073 if (sigma<0)
9074 {
9075 cost=fRan->Uniform(cosmin,cosmax);
9076 theta=acos(cost)*180./pi;
9077 }
9078 else
9079 {
9080 theta=fRan->Gauss(0.,sigma);
9081 }
9082 phi=fRan->Uniform(phimin,phimax);
9083
9084 // Enter the "fake" smeared position into vector "v".
9085 v.SetVector(norm,theta,phi,"sph","deg");
9086
9087 // Invoke the inverse rotation to obtain the actual smeared position.
9088 v=v.GetUnprimed(&m);
9089 if (ier) v.SetErrors(err,"car");
9090}
9091
9093{
9110
9111 if (!v.HasVector()) return;
9112
9113 // If needed, initialise the randomiser with a "date/time driven" seed
9114 // using the timestamp of the moment of this invokation of the member function.
9115 // This will ensure different random sequences if the user repeats analyses
9116 // under identical conditions without explicit initialisation of the randomiser
9117 // by the user at the start of the analysis.
9118 if (!fRan) fRan=new NcRandom(-1);
9119
9120 Double_t norm=v.GetX(1,"sph","deg");
9121 Double_t theta=v.GetX(2,"sph","deg");
9122 Double_t phi=v.GetX(3,"sph","deg");
9123 Double_t err[3]={0,0,0};
9124 Int_t ier=0;
9125 if (v.HasErrors())
9126 {
9127 ier=1;
9128 v.GetErrors(err,"car");
9129 }
9130 if (norm<=0)
9131 {
9132 norm=1;
9133 err[0]=0;
9134 }
9135 v.SetVector(norm,theta,phi,"sph","deg");
9136
9137 // The shifted position will be generated as if the actual vector "v" coincided with the positive Z-axis.
9138 // The actual shifted position will be obtained via a "backward rotation" to the real frame orientation.
9139
9140 // Determine the rotation matrix for the frame in which "v" coincides with the positive Z-axis.
9141 TRotMatrix m;
9142 m.SetAngles(90.+theta,phi,90,phi+90.,theta,phi);
9143
9144 // Generate the shifted position w.r.t. the fictative Z-axis
9145 Double_t phimin=0;
9146 Double_t phimax=360;
9147 theta=angle;
9148 phi=fRan->Uniform(phimin,phimax);
9149
9150 // Enter the "fake" shifted position into vector "v".
9151 v.SetVector(norm,theta,phi,"sph","deg");
9152
9153 // Invoke the inverse rotation to obtain the actual shifted position.
9154 v=v.GetUnprimed(&m);
9155 if (ier) v.SetErrors(err,"car");
9156}
9157
9158TH1F NcAstrolab::GetDxHistogram(TH1* hx,Int_t nc,Double_t dxbin,Double_t dxmin,Double_t dxmax,Int_t mode,Double_t fact)
9159{
9257
9258 TH1F hdx;
9259
9260 if (mode<0 || mode>3) return hdx;
9261
9262 if (!hx) return hdx;
9263
9264 if (nc<1) return hdx;
9265
9266 Int_t nenhx=hx->GetEntries();
9267 if (nenhx<=nc) return hdx;
9268
9269 Int_t idxbin=TMath::Nint(dxbin);
9270 if (idxbin<-2) return hdx;
9271
9272 // Create the output histogram if all parameters have been specified or determined automatically.
9273 // If not, this will be done at a recursive invokation (see below) once (some of) the
9274 // parameters have been determined automatically from the input histogram.
9275 if (dxmin>=0 && dxmax>=dxmin && dxbin>0)
9276 {
9277 Int_t nbins=1;
9278 Double_t range=dxmax-dxmin;
9279 if (range>dxbin) nbins=TMath::Nint(range/dxbin);
9280 hdx.SetBins(nbins,dxmin,dxmax);
9281
9282 // Add histogram and axes titles
9283 TString s;
9284 Double_t binwidth=hdx.GetXaxis()->GetBinWidth(1);
9285 s.Form("Dx interval distribution between %-i consecutive entries (nc=%-i, mode=%-i);Dx interval;Counts per bin of size %-.3g",nc+1,nc,mode,binwidth);
9286 hdx.SetNameTitle("DxHistogram",s);
9287 }
9288
9289 // If needed, initialise the randomiser with a "date/time driven" seed
9290 // using the timestamp of the moment of this invokation of the member function.
9291 // This will ensure different random sequences if the user repeats analyses
9292 // under identical conditions without explicit initialisation of the randomiser
9293 // by the user at the start of the analysis.
9294 if (!fRan) fRan=new NcRandom(-1);
9295
9296 // Determine the minimum and maximum encountered dx or fill the output histogram
9297 Double_t x1,x2,deltax;
9298 Int_t nx1,nx2;
9299 Double_t deltaxmin=0;
9300 Double_t deltaxmax=0;
9301 Bool_t found=kFALSE;
9302 Int_t ndxcount=0;
9303 Int_t jstart;
9304
9305 Int_t nbhx=hx->GetNbinsX();
9306 Double_t value=0;
9307 Double_t xlow=0;
9308 Double_t xup=0;
9309 Double_t bsize=0;
9310 for (Int_t i=1; i<=nbhx; i++)
9311 {
9312 deltax=-1;
9313 ndxcount=0;
9314 xlow=hx->GetBinLowEdge(i);
9315 bsize=hx->GetBinWidth(i);
9316 xup=xlow+bsize;
9317 x1=hx->GetBinCenter(i);
9318 if (mode==1 || mode==3) x1=fRan->Uniform(xlow,xup);
9319 value=hx->GetBinContent(i);
9320 nx1=0;
9321 if (value) nx1=1;
9322 if (mode<2) nx1=TMath::Nint(value);
9323
9324 while (nx1>0)
9325 {
9326 // Check for multiple counts (left) in this bin
9327 jstart=i+1;
9328 if (nx1>1) jstart=i;
9329
9330 for (Int_t j=jstart; j<=nbhx; j++)
9331 {
9332 xlow=hx->GetBinLowEdge(j);
9333 bsize=hx->GetBinWidth(j);
9334 xup=xlow+bsize;
9335 x2=hx->GetBinCenter(j);
9336 if (mode==1 || mode==3) x2=fRan->Uniform(xlow,xup);
9337 value=hx->GetBinContent(j);
9338 nx2=0;
9339 if (value) nx2=1;
9340 if (mode<2) nx2=TMath::Nint(value);
9341
9342 if (j==i) nx2=nx1-1; // Counting within the same bin
9343
9344 // Empty bin
9345 if (nx2<1) continue;
9346
9347 ndxcount+=nx2;
9348
9349 if (ndxcount>=nc)
9350 {
9351 deltax=fabs(x2-x1);
9352 if (dxmin>=0 && dxmax>=dxmin && dxbin>0) // Output histogram has been initialised
9353 {
9354 hdx.Fill(deltax);
9355 }
9356 else // Auto-determination of the output histogram range
9357 {
9358 if (!found || deltax<deltaxmin) deltaxmin=deltax;
9359 if (!found || deltax>deltaxmax) deltaxmax=deltax;
9360 }
9361 ndxcount=0;
9362 found=kTRUE;
9363 break;
9364 }
9365 }
9366 nx1--;
9367 }
9368 }
9369
9370 // Check if a suitable configuration of entries was encountered
9371 if (!found) return hdx;
9372
9373 // Check if a recursive call is needed to actually create and fill the output histogram
9374 Int_t nen=hdx.GetEntries();
9375 if (!nen)
9376 {
9377 // Set the bin size (if needed) for the output histogram
9378 if (!idxbin && dxbin<=0) dxbin=hx->GetBinWidth(1);
9379 if (idxbin==-1)
9380 {
9381 dxbin=(hx->GetBinWidth(1))*fact;
9382 if (deltaxmin>0 && deltaxmin>dxbin) dxbin=deltaxmin;
9383 if (dxbin<=0) dxbin=hx->GetBinWidth(1);
9384 }
9385 if (idxbin==-2)
9386 {
9387 dxbin=hx->GetBinWidth(1);
9388 dxbin=dxbin*float(nc);
9389 }
9390
9391 // Set the auto-determined range of the output histogram
9392 if (dxmin<0)
9393 {
9394 dxmin=deltaxmin;
9395 // Compensate for randomized x-values within the input histogram bins
9396 if (mode==1 || mode==3)
9397 {
9398 bsize=hx->GetBinWidth(1);
9399 dxmin=dxmin-2.*bsize;
9400 if (dxmin<0) dxmin=0;
9401 }
9402 }
9403 if (dxmax<0)
9404 {
9405 dxmax=deltaxmax+dxbin;
9406 // Compensate for randomized x-values within the input histogram bins
9407 if (mode==1 || mode==3)
9408 {
9409 bsize=hx->GetBinWidth(1);
9410 dxmax=dxmax+2.*bsize;
9411 }
9412 }
9413
9414 // Invoke the recursive call to create and fill the output histogram
9415 hdx=GetDxHistogram(hx,nc,dxbin,dxmin,dxmax,mode,fact);
9416 }
9417
9418 return hdx;
9419}
9420
9421TH1F NcAstrolab::GetDifHistogram(TH1* hin,Int_t mode,TString s,TF1* f) const
9422{
9457
9458 TH1F hout;
9459
9460 if (!hin) return hout;
9461
9462 Int_t nbins=hin->GetNbinsX();
9463 if (!nbins) return hout;
9464
9465 // Set the X-axis parameters identical to the input histogram
9466 const TArrayD* xarr=hin->GetXaxis()->GetXbins();
9467 Int_t xsize=xarr->GetSize();
9468 if (!xsize)
9469 {
9470 Double_t xmin=hin->GetXaxis()->GetXmin();
9471 Double_t xmax=hin->GetXaxis()->GetXmax();
9472 hout.SetBins(nbins,xmin,xmax);
9473 }
9474 else
9475 {
9476 const Double_t* xbins=xarr->GetArray();
9477 hout.SetBins(nbins,xbins);
9478 }
9479
9480 // Set histogram title
9481 hout.SetNameTitle("DifHistogram",hin->GetTitle());
9482
9483 // Set axes titles
9484 TString sxin=hin->GetXaxis()->GetTitle();
9485 TString syin=hin->GetYaxis()->GetTitle();
9486
9487 TString sxout=sxin;
9488
9489 TString syout=s;
9490 if (syout=="")
9491 {
9492 if (f)
9493 {
9494 syout=f->GetExpFormula("p");
9495 syout+="*";
9496 }
9497 syout+="d(";
9498 syout+=syin;
9499 syout+=")/d(";
9500
9501 // Remove Log indication from the "hin" X-axis title
9502 // to get a proper dy/dx label for the "hout" Y-axis
9503 if (mode)
9504 {
9505 sxin.ReplaceAll("^{10}log","");
9506 sxin.ReplaceAll("^{10}Log","");
9507 sxin.ReplaceAll("log10","");
9508 sxin.ReplaceAll("Log10","");
9509 sxin.ReplaceAll("log","");
9510 sxin.ReplaceAll("Log","");
9511 sxin.ReplaceAll("ln","");
9512 sxin.ReplaceAll("Ln","");
9513 }
9514
9515 syout+=sxin;
9516 syout+=")";
9517 syout.ReplaceAll("((","(");
9518 syout.ReplaceAll("))",")");
9519 }
9520
9521 hout.GetXaxis()->SetTitle(sxout.Data());
9522 hout.GetYaxis()->SetTitle(syout.Data());
9523
9524 // Determine the new Y-values and fill the output histogram
9525 Double_t x=0;
9526 Double_t y=0;
9527 Double_t err=0;
9528 Double_t width=0;
9529 Double_t binlow=0;
9530 Double_t binup=0;
9531 Double_t scale=0;
9532 for (Int_t i=1; i<=nbins; i++)
9533 {
9534 x=hin->GetBinCenter(i);
9535 y=hin->GetBinContent(i);
9536 err=fabs(hin->GetBinError(i));
9537 width=hin->GetBinWidth(i);
9538 binlow=hin->GetBinLowEdge(i);
9539 binup=binlow+width;
9540
9541 // Check if the binwidth is physical
9542 if (width<=0) continue;
9543
9544 // Correct for log-scale annotation on X-axis
9545 if (mode==1)
9546 {
9547 x=pow(10.,x);
9548 width=pow(10.,binup)-pow(10.,binlow);
9549 }
9550 if (mode==2)
9551 {
9552 x=exp(x);
9553 width=exp(binup)-exp(binlow);
9554 }
9555
9556 y=y/width;
9557 err=err/width;
9558
9559 // Rescale via the function "f" if provided
9560 if (f)
9561 {
9562 scale=f->Eval(x);
9563 y=y*scale;
9564 err=err*scale;
9565 }
9566
9567 hout.SetBinContent(i,y);
9568 hout.SetBinError(i,err);
9569 }
9570
9571 return hout;
9572}
9573
9574TH1F NcAstrolab::GetCountsHistogram(TF1& spec,Int_t nbins,Double_t xmin,Double_t xmax,Int_t mode,TString s) const
9575{
9601
9602 // Setting up the output histogram
9603 TH1F hout;
9604 hout.SetName("CountsHistogram");
9605
9606 // Set histogram title and axes labels
9607 if (s=="")
9608 {
9609 s="CountsHistogram;";
9610 if (mode==1)
9611 {
9612 s+="^{10}Log(";
9613 }
9614 else if (mode==2)
9615 {
9616 s+="Ln(";
9617 }
9618 s+=spec.GetXaxis()->GetTitle();
9619 if (mode) s+=")";
9620 s+=";Counts";
9621 }
9622 hout.SetTitle(s);
9623
9624 // Setting histogram binning
9625 Double_t step=(xmax-xmin)/double(nbins);
9626 Double_t* xbins=new Double_t[nbins+1];
9627 Double_t x=xmin;
9628 for (Int_t ibin=0; ibin<=nbins; ibin++)
9629 {
9630 xbins[ibin]=x;
9631 x=x+step;
9632 }
9633
9634 hout.SetBins(nbins,xbins);
9635
9636 // Filling the output histogram
9637 Double_t xlow=0;
9638 Double_t xup=0;
9639 Double_t N=0;
9640 x=xmin;
9641 for (Int_t ibin=1; ibin<=nbins; ibin++)
9642 {
9643 if (!mode)
9644 {
9645 xlow=xbins[ibin-1];
9646 xup=xbins[ibin];
9647 }
9648 else if (mode==1)
9649 {
9650 xlow=pow(10,xbins[ibin-1]);
9651 xup=pow(10,xbins[ibin]);
9652 }
9653 else if (mode==2)
9654 {
9655 xlow=exp(xbins[ibin-1]);
9656 xup=exp(xbins[ibin]);
9657 }
9658
9659 N=spec.Integral(xlow,xup);
9660 hout.Fill(x,N);
9661 x=x+step;
9662 }
9663
9664 delete [] xbins;
9665
9666 return hout;
9667}
9668
9669TH1F NcAstrolab::GetCountsHistogram(TH1& hin,Int_t mode,TString s,TF1* fscale) const
9670{
9699
9700 // Setting up the output histogram
9701 TH1F hout;
9702 hout.SetName("CountsHistogram");
9703 Int_t nbins=hin.GetNbinsX();
9704
9705 if (nbins<1) return hout;
9706
9707 TAxis* ax=hin.GetXaxis();
9708 Double_t xmin=ax->GetXmin();
9709 Double_t xmax=ax->GetXmax();
9710 hout.SetBins(nbins,xmin,xmax);
9711
9712 // Set histogram title and axes labels
9713 if (s=="")
9714 {
9715 s=hin.GetTitle();
9716 s+=";";
9717 TString tx=ax->GetTitle();
9718 if (tx!="")
9719 {
9720 s+=tx;
9721 }
9722 else
9723 {
9724 if (mode==0) s+="x";
9725 if (mode==1) s+="^{10}Log(x)";
9726 if (mode==2) s+="Ln(x)";
9727 }
9728 s+=";Counts";
9729 }
9730 hout.SetTitle(s);
9731
9732 // Filling the output histogram
9733 Double_t x=0;
9734 Double_t xlow=0;
9735 Double_t xup=0;
9736 Double_t dx=0;
9737 Double_t xval=0;
9738 Double_t N=0;
9739 Double_t fval=0;
9740 for (Int_t ibin=1; ibin<=nbins; ibin++)
9741 {
9742 x=hin.GetBinCenter(ibin);
9743 xlow=hin.GetBinLowEdge(ibin);
9744 xup=xlow+hin.GetBinWidth(ibin);
9745 N=hin.GetBinContent(ibin);
9746 if (!mode)
9747 {
9748 xval=x;
9749 dx=xup-xlow;
9750 N=N*dx;
9751 }
9752 else if (mode==1)
9753 {
9754 xval=pow(10,x);
9755 dx=pow(10,xup)-pow(10,xlow);
9756 N=N*dx;
9757 }
9758 else if (mode==2)
9759 {
9760 xval=exp(x);
9761 dx=exp(xup)-exp(xlow);
9762 N=N*dx;
9763 }
9764
9765 // Compensate for the Y-axis scaling if needed
9766 if (fscale)
9767 {
9768 fval=fscale->Eval(xval);
9769 if (fval) N=N/fval;
9770 }
9771
9772 hout.Fill(x,N);
9773 }
9774
9775 return hout;
9776}
9777
9778TH1F NcAstrolab::GetLogHistogram(TH1* hin,Int_t mode,TString s) const
9779{
9799
9800 TH1F hout;
9801
9802 if (!hin || mode<1 || mode>2) return hout;
9803
9804 Int_t nbins=hin->GetNbinsX();
9805 if (!nbins) return hout;
9806
9807 // Set the X-axis parameters identical to the input histogram
9808 const TArrayD* xarr=hin->GetXaxis()->GetXbins();
9809 Int_t xsize=xarr->GetSize();
9810 if (!xsize)
9811 {
9812 Double_t xmin=hin->GetXaxis()->GetXmin();
9813 Double_t xmax=hin->GetXaxis()->GetXmax();
9814 hout.SetBins(nbins,xmin,xmax);
9815 }
9816 else
9817 {
9818 const Double_t* xbins=xarr->GetArray();
9819 hout.SetBins(nbins,xbins);
9820 }
9821
9822 // Set histogram and axes titles
9823 hout.SetNameTitle("LogHistogram",hin->GetTitle());
9824
9825 if (s=="")
9826 {
9827 s="^{10}Log(";
9828 if (mode==2) s="Ln(";
9829 s+=hin->GetYaxis()->GetTitle();
9830 s+=")";
9831 }
9832
9833 hout.GetXaxis()->SetTitle(hin->GetXaxis()->GetTitle());
9834 hout.GetYaxis()->SetTitle(s.Data());
9835
9836 // Determine the new Y-values and fill the output histogram
9837 Double_t y=0;
9838 Double_t err=0;
9839 Double_t yplus=0;
9840 for (Int_t i=1; i<=nbins; i++)
9841 {
9842 y=hin->GetBinContent(i);
9843 err=fabs(hin->GetBinError(i));
9844 yplus=y+err;
9845
9846 // Check if Log10(y) or Ln(y) is defined
9847 if (y<=0) continue;
9848
9849 if (mode==1)
9850 {
9851 y=log10(y);
9852 yplus=log10(yplus);
9853 }
9854 else
9855 {
9856 y=log(y);
9857 yplus=log(yplus);
9858 }
9859
9860 hout.SetBinContent(i,y);
9861 err=fabs(yplus-y);
9862 hout.SetBinError(i,err);
9863 }
9864
9865 return hout;
9866}
9867
9868Double_t NcAstrolab::GetBackgroundRateProb(Double_t* vars,Double_t* pars)
9869{
9901
9902 Double_t b=vars[0];
9903 Int_t Noff=int(pars[0]);
9904 Double_t Toff=pars[1];
9905 Double_t bmax=pars[2];
9906 Double_t prec=pars[3];
9907
9908 if (b<=0 || Noff<0 || Toff<=0) return 0;
9909
9910 Double_t rNoff=Noff;
9911 if (bmax<0) bmax=100.*rNoff/Toff;
9912
9913 NcMath math;
9914
9915 Double_t lnU=0;
9916 Double_t lnD=0;
9917 Double_t lnprob=0;
9918 Double_t prob=0;
9919
9920 // The ln of the numerator of Eq.(15) of the publication mentioned above
9921 lnU=log(Toff)+rNoff*log(b*Toff)-b*Toff;
9922
9923 // The ln of the denominator of eq.(15) of the publication mentioned above
9924 lnD=math.LnGamma(Noff+1,bmax*Toff,1);
9925
9926 lnprob=lnU-lnD;
9927
9928 if (lnprob < -fabs(prec)) return 0;
9929
9930 if (lnprob > fabs(prec)) lnprob=fabs(prec);
9931 prob=exp(lnprob);
9932
9933 return prob;
9934}
9935
9936Double_t NcAstrolab::GetSignalRateProb(Double_t* vars,Double_t* pars)
9937{
9980
9981 Double_t s=vars[0];
9982 Int_t Non=TMath::Nint(pars[0]);
9983 Double_t Ton=pars[1];
9984 Int_t Noff=TMath::Nint(pars[2]);
9985 Double_t Toff=pars[3];
9986 Double_t smax=pars[4];
9987 Double_t bmax=pars[5];
9988 Double_t prec=pars[6];
9989
9990 if (s<0 || Non<0 || Ton<=0 || Noff<0 || Toff<=0) return 0;
9991
9992 Double_t rNon=Non;
9993 if (smax<0) smax=100.*rNon/Ton;
9994
9995 Double_t rNoff=Noff;
9996 if (bmax<0) bmax=100.*rNoff/Toff;
9997
9998 NcMath math;
9999
10000 //Store factorials in an array to decrease the processing time
10001 Int_t ndim=Non+Noff+1;
10002 TArrayD lnfacN(ndim);
10003
10004 lnfacN[0]=0;
10005 Double_t x=0;
10006 for (Int_t i=1; i<ndim; i++)
10007 {
10008 x+=log(double(i));
10009 lnfacN[i]=x;
10010 }
10011
10012 Double_t lnU=0;
10013 Double_t lnD=0;
10014 Double_t sumU=0;
10015 Double_t sumD=0;
10016 Double_t prob=0;
10017 Double_t gammaP1=0;
10018 Double_t gammaP2=0;
10019 Double_t ri=0;
10020
10021 for(Int_t i=0; i<=Non; i++)
10022 {
10023 ri=i;
10024
10025 // The incomplete gamma functions P(a,x)
10026 gammaP1=math.Gamma(Non+Noff+1-i,bmax*(Ton+Toff),0);
10027 gammaP2=math.Gamma(i+1,smax*Ton,0);
10028
10029 // The ln of the numerator of Eq.(21) of the publication mentioned above normalized by Non!/(Non+Noff)!
10030 lnU=-s*Ton+ri*log(s)+ri*log(Ton+Toff)-lnfacN[i]-lnfacN[Non-i]+lnfacN[Non+Noff-i]-lnfacN[Non+Noff]+lnfacN[Non];
10031
10032 if ((lnU > -fabs(prec)) && (lnU < fabs(prec))) sumU+=exp(lnU)*gammaP1;
10033
10034 //The ln of the denominator of Eq.(21) of the publication mentioned above normalized by Non!/(Non+Noff)!
10035 lnD=ri*log(Ton+Toff)-(ri+1.)*log(Ton)-lnfacN[i]-lnfacN[Non-i]+lnfacN[Non+Noff-i]+lnfacN[i]-lnfacN[Non+Noff]+lnfacN[Non];
10036
10037 if ((lnD > -fabs(prec)) && (lnD < fabs(prec))) sumD+=exp(lnD)*gammaP1*gammaP2;
10038 }
10039
10040 if (sumD) prob=sumU/sumD;
10041
10042 return prob;
10043}
10044
10045TF1 NcAstrolab::GetBackgroundRatePDF(Double_t Noff,Double_t Toff,Double_t bmax,Double_t prec)
10046{
10076
10077 if (bmax<0) bmax=100.*Noff/Toff;
10078
10079 Int_t npar=4;
10080 TF1 pdf("BkgRatePDF",this,&NcAstrolab::GetBackgroundRateProb,0,bmax,npar,"NcAstrolab","GetBackgroundRateProb");
10081
10082 pdf.SetParName(0,"Noff");
10083 pdf.SetParName(1,"Toff");
10084 pdf.SetParName(2,"bmax");
10085 pdf.SetParName(3,"prec");
10086
10087 pdf.SetParameter("Noff",Noff);
10088 pdf.SetParameter("Toff",Toff);
10089 pdf.SetParameter("bmax",bmax);
10090 pdf.SetParameter("prec",prec);
10091
10092 pdf.SetTitle("Bayesian posterior background rate PDF;Background rate B in Hz;p(B|Noff,Toff,I)");
10093 pdf.SetRange(0,bmax);
10094
10095 return pdf;
10096}
10097
10098TF1 NcAstrolab::GetSignalRatePDF(Double_t Non,Double_t Ton,Double_t Noff,Double_t Toff,Double_t Ra,Double_t Re,Double_t smax,Double_t bmax,Double_t prec)
10099{
10137
10138 if (smax<0) smax=100.*Non/Ton;
10139
10140 // Correct the off source observation for different coverage and detection efficiency
10141 // with respect to the actual on source measurement
10142 Noff=Noff*Ra*Re;
10143
10144 if (bmax<0) bmax=100.*Noff/Toff;
10145
10146 Int_t npar=7;
10147 TF1 pdf("SignalRatePDF",this,&NcAstrolab::GetSignalRateProb,0,smax,npar,"NcAstrolab","GetSignalRateProb");
10148
10149 pdf.SetParName(0,"Non");
10150 pdf.SetParName(1,"Ton");
10151 pdf.SetParName(2,"Noff");
10152 pdf.SetParName(3,"Toff");
10153 pdf.SetParName(4,"smax");
10154 pdf.SetParName(5,"bmax");
10155 pdf.SetParName(6,"prec");
10156
10157 pdf.SetParameter("Non",Non);
10158 pdf.SetParameter("Ton",Ton);
10159 pdf.SetParameter("Noff",Noff);
10160 pdf.SetParameter("Toff",Toff);
10161 pdf.SetParameter("smax",smax);
10162 pdf.SetParameter("bmax",bmax);
10163 pdf.SetParameter("prec",prec);
10164
10165 pdf.SetTitle("Bayesian posterior signal rate PDF;Signal rate S in Hz;p(S|Non,Ton,Noff,Toff,I)");
10166 pdf.SetRange(0,smax);
10167
10168 return pdf;
10169}
10170
10171Double_t NcAstrolab::GetUpperLimit(TF1 pdf,Double_t p)
10172{
10189
10190 if (p<=0 || p>100) return 0;
10191
10192 Double_t ua[2];
10193 Double_t xa[2];
10194 Int_t nu=0;
10195 Double_t ul=0;
10196
10197 xa[0]=p/100.;
10198 nu=pdf.GetQuantiles(1,ua,xa);
10199
10200 if (nu) ul=ua[0];
10201
10202 return ul;
10203}
10204
10205Double_t NcAstrolab::GetUpperLimit(TH1* his,Double_t p)
10206{
10216
10217 if (p<=0 || p>100 || !his) return 0;
10218
10219 Double_t ua[2];
10220 Double_t xa[2];
10221 Int_t nu=0;
10222 Double_t ul=0;
10223
10224 // Ensure correct results als for histograms filled via SetBinContent().
10225 his->ComputeIntegral();
10226
10227 xa[0]=p/100.;
10228 nu=his->GetQuantiles(1,ua,xa);
10229
10230 if (nu) ul=ua[0];
10231
10232 return ul;
10233}
10234
10235Double_t NcAstrolab::GetCredibleInterval(TF1 pdf,Double_t p,Double_t& xlow,Double_t& xup,Int_t n)
10236{
10268
10269 xlow=0;
10270 xup=0;
10271
10272 if (p<=0 || p>100 || n<2) return 0;
10273
10274 // Set the precision
10275 Double_t prec=1./double(n);
10276
10277 // Obtain the n quantiles of the PDF
10278 Double_t* q=new Double_t[n];
10279 Double_t* sumq=new Double_t[n];
10280 Double_t sum=0;
10281 for (Int_t i=0; i<n; i++)
10282 {
10283 sumq[i]=sum;
10284 sum+=prec;
10285 }
10286 Int_t ncalc=pdf.GetQuantiles(n,q,sumq);
10287
10288 // More than 1 quantile is needed
10289 if (ncalc<2)
10290 {
10291 delete [] q;
10292 delete [] sumq;
10293 return 0;
10294 }
10295
10296 // Determine the index in the quantiles array q[] corresponding to
10297 // the X coordinate of the mode of the PDF
10298 Double_t xmode=pdf.GetMaximumX();
10299 Int_t imode=0;
10300 Double_t diff,diffmin;
10301 diffmin=fabs(q[ncalc-1]-q[0]);
10302 for (Int_t i=0; i<ncalc; i++)
10303 {
10304 diff=fabs(xmode-q[i]);
10305 if (diff<diffmin)
10306 {
10307 diffmin=diff;
10308 imode=i;
10309 }
10310 }
10311
10312 // Get the total integral over the quantiles range of the PDF
10313 Double_t xmin=q[0];
10314 Double_t xmax=q[ncalc-1];
10315 Double_t totint=pdf.Integral(xmin,xmax);
10316
10317 // The PDF should have a total integral >0
10318 if (totint<=0)
10319 {
10320 delete [] q;
10321 delete [] sumq;
10322 return 0;
10323 }
10324
10325 // Determine the requested credible interval around the mode
10326 Int_t ilow=imode;
10327 Int_t iup=imode;
10328 xlow=q[ilow];
10329 xup=q[iup];
10330 Double_t ylow=pdf.Eval(q[ilow]);
10331 Double_t yup=pdf.Eval(q[iup]);
10332 Double_t frac=p/100.;
10333 if (frac>1) frac=1;
10334 Double_t credint=-1;
10335 while (credint<frac*totint)
10336 {
10337 if (yup>ylow && iup<(ncalc-1)) // Shift the upper bound up
10338 {
10339 iup++;
10340 xup=q[iup];
10341 yup=pdf.Eval(xup);
10342 }
10343 else if (ylow>yup && ilow>0) // Shift the lower bound down
10344 {
10345 ilow--;
10346 xlow=q[ilow];
10347 ylow=pdf.Eval(xlow);
10348 }
10349 else if (iup<(ncalc-1)) // Shift the upper bound up in case yup=ylow
10350 {
10351 iup++;
10352 xup=q[iup];
10353 yup=pdf.Eval(xup);
10354 }
10355 else if (ilow>0) // Shift the lower bound down in case yup=ylow
10356 {
10357 ilow--;
10358 xlow=q[ilow];
10359 ylow=pdf.Eval(xlow);
10360 }
10361 else // No shift in any bound -> stop
10362 {
10363 break;
10364 }
10365 credint=pdf.Integral(xlow,xup);
10366 }
10367
10368 // Normalisation for non-normalised PDF
10369 Double_t intfrac=credint/totint;
10370
10371 delete [] q;
10372 delete [] sumq;
10373
10374 return intfrac;
10375}
10376
10377Double_t NcAstrolab::GetCredibleInterval(TF1 pdf,Double_t p,Float_t& xlow,Float_t& xup,Int_t n)
10378{
10410
10411 Double_t xxl=0;
10412 Double_t xxu=0;
10413 Double_t val=0;
10414
10415 val=GetCredibleInterval(pdf,p,xxl,xxu,n);
10416
10417 xlow=xxl;
10418 xup=xxu;
10419 return val;
10420}
10421
10422Double_t NcAstrolab::GetCredibleInterval(TH1* his,Double_t p,Double_t& xlow,Double_t& xup)
10423{
10445
10446 xlow=0;
10447 xup=0;
10448
10449 if (p<=0 || p>100 || !his) return 0;
10450
10451 Int_t nbins=his->GetNbinsX();
10452
10453 // More than 2 bins are always needed
10454 if (nbins<2) return 0;
10455
10456 // Ensure correct results also for histograms filled via SetBinContent()
10457 his->ComputeIntegral();
10458
10459 // Obtain the quantiles at the end of each bin of the histogram and at the start of the 1st bin
10460 Int_t n=nbins+1;
10461 Double_t* q=new Double_t[n];
10462 Int_t ncalc=his->GetQuantiles(n,q);
10463
10464 // More than 1 quantile is needed
10465 if (ncalc<2)
10466 {
10467 delete [] q;
10468 return 0;
10469 }
10470
10471 // Determine the index in the quantiles array q[] corresponding to
10472 // the X coordinate of the mode of the histogram
10473 Int_t imode=his->GetMaximumBin();
10474
10475 // Get the total integral of the histogram over the quantiles range
10476 Double_t totint=his->Integral(1,ncalc,"width");
10477
10478 // The histogram should have a total integral >0
10479 if (totint<=0)
10480 {
10481 delete [] q;
10482 return 0;
10483 }
10484
10485 // Determine the requested credible interval around the mode
10486 Int_t ilow=imode;
10487 Int_t iup=imode;
10488 xlow=q[ilow];
10489 xup=q[iup];
10490 Double_t ylow=his->GetBinContent(ilow);
10491 Double_t yup=his->GetBinContent(iup);
10492 Double_t frac=p/100.;
10493 if (frac>1) frac=1;
10494 Double_t credint=-1;
10495 while (credint<frac*totint)
10496 {
10497 if (yup>ylow && iup<(ncalc-1)) // Shift the upper bound up
10498 {
10499 iup++;
10500 xup=q[iup];
10501 yup=his->GetBinContent(iup);
10502 }
10503 else if (ylow>yup && ilow>0) // Shift the lower bound down
10504 {
10505 ilow--;
10506 xlow=q[ilow];
10507 ylow=his->GetBinContent(ilow);
10508 }
10509 else if (iup<(ncalc-1)) // Shift the upper bound up in case yup=ylow
10510 {
10511 iup++;
10512 xup=q[iup];
10513 yup=his->GetBinContent(iup);
10514 }
10515 else if (ilow>0) // Shift the lower bound down in case yup=ylow
10516 {
10517 ilow--;
10518 xlow=q[ilow];
10519 ylow=his->GetBinContent(ilow);
10520 }
10521 else // No shift in any bound -> stop
10522 {
10523 break;
10524 }
10525 credint=his->Integral(ilow,iup,"width");
10526 }
10527
10528 // Normalisation for non-normalised PDF
10529 Double_t intfrac=credint/totint;
10530
10531 delete [] q;
10532
10533 return intfrac;
10534}
10535
10536Double_t NcAstrolab::GetCredibleInterval(TH1* his,Double_t p,Float_t& xlow,Float_t& xup)
10537{
10559
10560 Double_t xxl=0;
10561 Double_t xxu=0;
10562 Double_t val=0;
10563
10564 val=GetCredibleInterval(his,p,xxl,xxu);
10565
10566 xlow=xxl;
10567 xup=xxu;
10568 return val;
10569}
10570
10571Double_t NcAstrolab::KolmogorovTest(TString mode,TH1* h1,TH1* h2,TF1* pdf,Double_t nr,TH1F* ksh,Int_t ncut,Double_t* nrx,Int_t mark)
10572{
10665
10666 Double_t value=-1;
10667
10668 if (!mode.Contains("M") && !mode.Contains("K") && !mode.Contains("P")) return -1;
10669 if (mode.Contains("M") && (mode.Contains("K") || mode.Contains("P"))) return -1;
10670 if (mode.Contains("K") && (mode.Contains("M") || mode.Contains("P"))) return -1;
10671 if (mode.Contains("P") && (mode.Contains("M") || mode.Contains("K"))) return -1;
10672
10673 if (!h1) return -1;
10674 if (!h2 && !pdf) return -1;
10675 if (h2 && pdf) return -1;
10676
10677 ULong64_t nrep=ULong64_t(nr);
10678 ULong64_t jrep;
10679 if (!nrep)
10680 {
10681 if (ncut)
10682 {
10683 nrep=ULong64_t(1.e19);
10684 }
10685 else
10686 {
10687 return -1;
10688 }
10689 }
10690
10691 TAxis* xaxis=h1->GetXaxis();
10692 Double_t xmin1=xaxis->GetXmin();
10693 Double_t xmax1=xaxis->GetXmax();
10694 Double_t range1=xmax1-xmin1;
10695 Int_t nbins1=h1->GetNbinsX();
10696 Double_t nen1=h1->GetSumOfWeights();
10697 Double_t underflow1=h1->GetBinContent(0);
10698 Double_t overflow1=h1->GetBinContent(nbins1+1);
10699 if (mode.Contains("U")) nen1=nen1+underflow1;
10700 if (mode.Contains("O")) nen1=nen1+overflow1;
10701
10702 if (nbins1<=0 || nen1<=0 || range1<=0)
10703 {
10704 cout << " *" << ClassName() << "::KolmogorovTest* Histogram h1 is empty or has inconsistent data." << endl;
10705 cout << " h1 : nentries=" << nen1 << " nbins=" << nbins1 << " xmin=" << xmin1 << " xmax=" << xmax1 << endl;
10706 return -1;
10707 }
10708
10709 if (h2)
10710 {
10711 xaxis=h2->GetXaxis();
10712 Double_t xmin2=xaxis->GetXmin();
10713 Double_t xmax2=xaxis->GetXmax();
10714 Double_t range2=xmax2-xmin2;
10715 Int_t nbins2=h2->GetNbinsX();
10716 Double_t nen2=h2->GetSumOfWeights();
10717
10718 if (nen2<=0 || range2<=0)
10719 {
10720 cout << " *" << ClassName() << "::KolmogorovTest* Histogram h2 is empty or has inconsistent data." << endl;
10721 cout << " h2 : nentries=" << nen2 << " nbins=" << nbins2 << " xmin=" << xmin2 << " xmax=" << xmax2 << endl;
10722 return -1;
10723 }
10724
10725 Double_t prec=1e-6;
10726 if (nbins2!=nbins1 || fabs(xmin2-xmin1)>prec || fabs(xmax2-xmax1)>prec)
10727 {
10728 cout << " *" << ClassName() << "::KolmogorovTest* Histograms h1 and h2 do not have the same binning." << endl;
10729 cout << " h1 : nbins=" << nbins1 << " xmin=" << xmin1 << " xmax=" << xmax1 << endl;
10730 cout << " h2 : nbins=" << nbins2 << " xmin=" << xmin2 << " xmax=" << xmax2 << endl;
10731 return -1;
10732 }
10733 }
10734
10735 // Create the "h2" histogram from the "pdf" function to perform the KS test
10736 if (pdf)
10737 {
10738 pdf->SetRange(xmin1,xmax1);
10739 pdf->SetNpx(nbins1);
10740 h2=(TH1*)pdf->GetHistogram()->Clone();
10741 h2->SetName("hpdf");
10742 // Set all bin errors (incl. underflow and overflow bins) to zero
10743 for (Int_t i=0; i<=nbins1+1; i++)
10744 {
10745 h2->SetBinError(i,0);
10746 }
10747 }
10748
10749 // Convert "mode" into the corresponding character string for TH1::KolmogorovTest
10750 TString s="";
10751 if (mode.Contains("U")) s+="U";
10752 if (mode.Contains("O")) s+="O";
10753 if (mode.Contains("N") && !pdf) s+="N";
10754
10755 // Obtain the maximum KS distance (d0) for the input histogram "h1"
10756 TString s2=s;
10757 s2+="M";
10758 Double_t d0=h2->KolmogorovTest(h1,s2.Data());
10759
10760 // Complete "mode" conversion
10761 if (mode.Contains("M")) s+="M";
10762 if (mode.Contains("I")) s+="D";
10763
10764 // Perform the requested KS test
10765 if (mode.Contains("I"))
10766 {
10767 if (pdf)
10768 {
10769 cout << " *" << ClassName() << "::KolmogorovTest* Single sample KS-test results for execution mode "<< mode.Data() << endl;
10770 if (mode.Contains("N")) cout << " === For a single sample KS-test the mode=N is suppressed ===" << endl;
10771 }
10772 else
10773 {
10774 cout << " *" << ClassName() << "::KolmogorovTest* Two sample KS-test results for execution mode "<< mode.Data() << endl;
10775 }
10776 }
10777 value=h1->KolmogorovTest(h2,s.Data());
10778
10779 // Perform the pseudo experiments, if requested
10780 if (ksh) ksh->SetBins(101,0,1.01);
10781 Double_t xval=0;
10782 Double_t dist=0;
10783 Double_t sumrep=0;
10784 Int_t sumd=0;
10785 TH1* htemp=0;
10786 if (mode.Contains("P"))
10787 {
10788 htemp=(TH1*)h1->Clone();
10789 for (jrep=0; jrep<nrep; jrep++) // Loop of pseudo experiments
10790 {
10791 htemp->Reset();
10792 for (Int_t ien=0; ien<nen1; ien++) // Take the random entries from the reference distribution
10793 {
10794 xval=h2->GetRandom();
10795 htemp->Fill(xval);
10796 }
10797 dist=htemp->KolmogorovTest(h2,s2.Data());
10798 if (ksh) ksh->Fill(dist);
10799 sumrep+=1;
10800 if (dist>=d0) sumd++;
10801
10802 // Stop the pseudo experiments if the required precision is reached
10803 if (ncut && sumd>=ncut) break;
10804
10805 } // end loop over pseudo experiments
10806 value=double(sumd)/sumrep;
10807 if (nrx) *nrx=sumrep;
10808 if (mode.Contains("I"))
10809 {
10810 cout << " P-value = " << value << " after " << sumrep << " pseudo experiments." << endl;
10811 }
10812 }
10813
10814 if (mode.Contains("I")) cout << " Returned value = " << value << endl;
10815
10816 // Complete the attributes for the "ksh" histogram
10817 if (ksh)
10818 {
10819 TString xlabel="Dmax";
10820 TString ylabel="Counts after ";
10821 ylabel+=sumrep;
10822 ylabel+=" pseudo experiments";
10823
10824 ksh->SetTitle("KS-test Dmax distribution from pseudo experiments");
10825 ksh->SetXTitle(xlabel.Data());
10826 ksh->SetYTitle(ylabel.Data());
10827
10828 // Mark the actually observed D0 value by a vertical line in the "ksh" histogram
10829 // Also the corresponding P-value is mentioned in the legend
10830 if (mark)
10831 {
10832 Float_t x=d0;
10833 Float_t ymin=0;
10834 Float_t ymax=ksh->GetMaximum();
10835
10836 TLine* vline=new TLine(x,ymin,x,ymax);
10837 vline->SetLineStyle(2); // Dashed line
10838 vline->SetLineWidth(2);
10839 vline->SetLineColor(4); // Blue color
10840
10841 TString title="P-value : %-10.3g";
10842 TString sh=title.Format(title.Data(),value);
10843
10844 TLegend* leg=new TLegend(0.6,0.8,0.8,0.9);
10845 leg->SetFillColor(0);
10846 leg->SetHeader(sh.Data());
10847 leg->AddEntry(vline,"Observed Dmax","L");
10848
10849 TList* hlist=ksh->GetListOfFunctions();
10850 hlist->Add(vline);
10851 hlist->Add(leg);
10852 }
10853 }
10854
10855 // Delete temporary histograms, if any
10856 if (pdf && h2)
10857 {
10858 delete h2;
10859 h2=0;
10860 }
10861
10862 if (htemp) delete htemp;
10863
10864 return value;
10865}
10866
10867TH1F NcAstrolab::GetCumulHistogram(TH1* h,TString name,TString mode) const
10868{
10895
10896 TH1F hcd;
10897 TString title="Cumulative Distribution of histogram ";
10898 hcd.SetNameTitle(name.Data(),title.Data());
10899
10900 if (!h) return hcd;
10901
10902 TAxis* xaxis=h->GetXaxis();
10903 TAxis* yaxis=h->GetYaxis();
10904 Double_t xmin=xaxis->GetXmin();
10905 Double_t xmax=xaxis->GetXmax();
10906 Double_t range=xmax-xmin;
10907 Int_t nbins=h->GetNbinsX();
10908 Double_t nen=h->GetSumOfWeights();
10909 TString nameh=h->GetName();
10910 TString xtitle=xaxis->GetTitle();
10911 TString ytitle=yaxis->GetTitle();
10912 title+=nameh;
10913 hcd.SetNameTitle(name.Data(),title.Data());
10914 hcd.SetXTitle(xtitle.Data());
10915 hcd.SetYTitle(ytitle.Data());
10916
10917 if (nbins<=0 || nen<=0 || range<=0) return hcd;
10918
10919 if(!(mode.Contains("F") || mode.Contains("B")) || (mode.Contains("F") && mode.Contains("B"))) return hcd;
10920
10921 hcd.SetBins(nbins,xmin,xmax);
10922 title="";
10923 if (mode.Contains("N")) title="Normalized ";
10924 if (mode.Contains("F")) title+="Forward ";
10925 if (mode.Contains("B")) title+="Backward ";
10926 title+="Cumulative Distribution of histogram ";
10927 title+=nameh;
10928 hcd.SetNameTitle(name.Data(),title.Data());
10929 hcd.SetXTitle(xtitle.Data());
10930 hcd.SetYTitle(ytitle.Data());
10931
10932 Double_t norm=1;
10933 if (mode.Contains("N")) norm=nen;
10934 Double_t y=0;
10935 Double_t sum=0;
10936
10937 if (mode.Contains("F")) // Forward cumulation
10938 {
10939 for (Int_t ibin=1; ibin<=nbins; ibin++)
10940 {
10941 y=h->GetBinContent(ibin);
10942 sum+=y/norm;
10943 hcd.SetBinContent(ibin,sum);
10944 }
10945 }
10946 else // Backward cumulation
10947 {
10948 for (Int_t ibin=nbins; ibin>=1; ibin--)
10949 {
10950 y=h->GetBinContent(ibin);
10951 sum+=y/norm;
10952 hcd.SetBinContent(ibin,sum);
10953 }
10954 }
10955 return hcd;
10956}
10957
10958TH1F NcAstrolab::GetCumulHistogram(TF1* f,TString name,Int_t nbins,Double_t xmin,Double_t xmax,TString mode) const
10959{
10987
10988 TH1F hcd;
10989 TString title="Cumulative Distribution Histogram of function ";
10990 hcd.SetNameTitle(name.Data(),title.Data());
10991
10992 if (!f) return hcd;
10993
10994 // The original range of the function "f"
10995 Double_t xminold=f->GetXmin();
10996 Double_t xmaxold=f->GetXmax();
10997
10998 f->SetRange(xmin,xmax);
10999 f->SetNpx(nbins);
11000 TH1* hf=(TH1*)f->GetHistogram();
11001
11002 hcd=GetCumulHistogram(hf,name,mode);
11003
11004 if (hcd.GetEntries()>0) // Histogram has been filled
11005 {
11006 title="";
11007 if (mode.Contains("N")) title="Normalized ";
11008 if (mode.Contains("F")) title+="Forward ";
11009 if (mode.Contains("B")) title+="Backward ";
11010 title+="Cumulative Distribution Histogram of function ";
11011 }
11012
11013 TString namef=f->GetName();
11014 title+=namef;
11015
11016 hcd.SetTitle(title.Data());
11017
11018 // Restore the original range for the function "f"
11019 f->SetRange(xminold,xmaxold);
11020
11021 return hcd;
11022}
11023
11024void NcAstrolab::InitDataNames(Int_t dir,TString frame,TString mode)
11025{
11052
11053 if (!dir || (frame!="equ" && frame!="gal" && frame!="ecl" && frame!="hor" && frame!="icr" && frame!="loc") ||
11054 (mode!="M" && mode!="T" && mode!="B" && mode!="J"))
11055 {
11056 cout << endl;
11057 cout << " *" << ClassName() << "::InitDataNames* Invalid input encountered." << endl;
11058 cout << " dir=" << dir << " frame=" << frame << " mode=" << mode << endl;
11059 return;
11060 }
11061
11062 fDataDir=dir;
11063 fDataFrame=frame;
11064 fDataMode=mode;
11065
11066 // Reset the correspondence table
11067 fDataNames.Reset();
11068
11069 TString sdir="arrival";
11070 if (dir<0) sdir="moving";
11071
11072 if (frame=="equ")
11073 {
11074 if (mode=="M") frame="mean";
11075 if (mode=="T") frame="true";
11076 if (mode=="B") frame="B1950";
11077 if (mode=="J") frame="J2000";
11078 frame+=" equatorial";
11079 }
11080 if (frame=="gal") frame="galactic";
11081 if (frame=="ecl") frame="ecliptic";
11082 if (frame=="hor") frame="horizontal";
11083 if (frame=="icr") frame="ICRS";
11084 if (frame=="loc") frame="local";
11085
11086 cout << endl;
11087 cout << " *" << ClassName() << "::InitDataNames* Prepared for input of " << sdir << " directions in " << frame << " coordinates." << endl;
11088 cout << endl;
11089}
11090
11091void NcAstrolab::SetDataNames(TString obsname,TString varname,TString units,TString func)
11092{
11179
11180 Bool_t error=kFALSE;
11181
11182 if (obsname!="Name" && obsname!="Run" && obsname!="Event" && obsname!="Eventb" && obsname!="VetoLevel"
11183 && obsname!="DetId" && obsname!="Date" && obsname!="Tobs" && obsname!="Tstart" && obsname!="Tend"
11184 && obsname!="d" && obsname!="a" && obsname!="b" && obsname!="z"
11185 && obsname!="E" && obsname!="L" && obsname!="S" && obsname!="F" && obsname!="I" && obsname!="J"
11186 && obsname!="T90" && obsname!="T100"
11187 && obsname!="dsigma" && obsname!="csigma" && obsname!="zsigma"
11188 && obsname!="Esigma" && obsname!="Lsigma" && obsname!="Ssigma" && obsname!="Fsigma" && obsname!="Isigma"
11189 && obsname!="T90sigma" && obsname!="T100sigma") error=kTRUE;
11190 if (obsname=="Date" && (units!="ddmmyyyy" && units!="yyyymmdd" && units!="mmddyyyy" && units!="yyyyddmm")) error=kTRUE;
11191 if ((obsname=="Tobs" || obsname=="Tstart" || obsname=="Tend")
11192 && (units!="JD" && units!="MJD" && units!="TJD" && units!="hms" && units!="hrs")) error=kTRUE;
11193 if ((obsname=="a" || obsname=="b" || obsname=="csigma")
11194 && (units!="rad" && units!="deg" && units!="dms" && units!="hms" && units!="hrs")) error=kTRUE;
11195 if (func!="none" && func!="Log" && func!="Ln") error=kTRUE;
11196
11197 if (error)
11198 {
11199 cout << " *" << ClassName() << "::SetDataNames* Invalid input encountered." << endl;
11200 cout << " obsname=" << obsname << " units=" << units << " func=" << func << endl;
11201 return;
11202 }
11203
11204 Int_t n=fDataNames.GetMaxRow();
11205 TObjString* obs=new TObjString(obsname);
11206 TObjString* var=new TObjString(varname);
11207 TObjString* u=new TObjString(units);
11208 TObjString* f=new TObjString(func);
11209 TObjString* val=new TObjString(""); // Value will be filled in LoadInputData()
11210
11211 fDataNames.EnterObject(n+1,1,obs);
11212 fDataNames.EnterObject(n+1,2,var);
11213 fDataNames.EnterObject(n+1,3,u);
11214 fDataNames.EnterObject(n+1,4,f);
11215 fDataNames.EnterObject(n+1,5,val);
11216}
11217
11219{
11226
11227 TString sdir="undefined";
11228 if (fDataDir>0) sdir="arrival";
11229 if (fDataDir<0) sdir="moving";
11230
11231 TString frame="undefined";
11232 if (fDataFrame=="equ")
11233 {
11234 if (fDataMode=="M") frame="mean";
11235 if (fDataMode=="T") frame="true";
11236 if (fDataMode=="B") frame="B1950";
11237 if (fDataMode=="J") frame="J2000";
11238 frame+=" equatorial";
11239 }
11240 if (fDataFrame=="gal") frame="galactic";
11241 if (fDataFrame=="ecl") frame="ecliptic";
11242 if (fDataFrame=="hor") frame="horizontal";
11243 if (fDataFrame=="icr") frame="ICRS";
11244 if (fDataFrame=="loc") frame="local";
11245
11246 cout << endl;
11247 cout << " *" << ClassName() << "::ListDataNames* Settings for input of " << sdir << " directions in " << frame << " coordinates." << endl;
11248
11249 Int_t n=fDataNames.GetMaxRow();
11250
11251 if (n<1)
11252 {
11253 cout << " *** No settings were specified ***" << endl;
11254 }
11255 else
11256 {
11257 cout << " *** The following " << n << " settings were specified ***" << endl;
11258 }
11259
11260 TObjString* obs=0;
11261 TObjString* var=0;
11262 TObjString* u=0;
11263 TObjString* f=0;
11264 for (Int_t i=1; i<=n; i++)
11265 {
11266 obs=(TObjString*)fDataNames.GetObject(i,1);
11267 var=(TObjString*)fDataNames.GetObject(i,2);
11268 u=(TObjString*)fDataNames.GetObject(i,3);
11269 f=(TObjString*)fDataNames.GetObject(i,4);
11270 cout << " obsname=" << obs->GetString() << " varname=" << var->GetString() << " units=" << u->GetString() << " func=" << f->GetString() << endl;
11271 }
11272 cout << endl;
11273}
11274
11275void NcAstrolab::SetBurstParameter(TString name,Double_t value)
11276{
11410
11411 if (!fBurstParameters)
11412 {
11414 fBurstParameters->SetNameTitle("BurstParameters","Parameter settings for transient burst investigations");
11415 }
11416
11417 if (name!="*")
11418 {
11419 fBurstParameters->AddNamedSlot(name);
11420 if (name=="ESigmax" || name=="Emax") value+=1e-10; // To include the max. energy boundary in the histogram
11421 fBurstParameters->SetSignal(value,name);
11422 }
11423 else
11424 {
11425 Double_t pi=acos(-1.);
11426 name="Nmaxsrc";
11427 fBurstParameters->AddNamedSlot(name);
11428 fBurstParameters->SetSignal(-1,name);
11429 name="Nmaxevt";
11430 fBurstParameters->AddNamedSlot(name);
11431 fBurstParameters->SetSignal(-1,name);
11432 name="RAmin";
11433 fBurstParameters->AddNamedSlot(name);
11434 fBurstParameters->SetSignal(0,name);
11435 name="RAmax";
11436 fBurstParameters->AddNamedSlot(name);
11437 fBurstParameters->SetSignal(360,name);
11438 name="Declmin";
11439 fBurstParameters->AddNamedSlot(name);
11440 fBurstParameters->SetSignal(-90,name);
11441 name="Declmax";
11442 fBurstParameters->AddNamedSlot(name);
11443 fBurstParameters->SetSignal(90,name);
11444 name="T90min";
11445 fBurstParameters->AddNamedSlot(name);
11446 fBurstParameters->SetSignal(1e-5,name);
11447 name="T90max";
11448 fBurstParameters->AddNamedSlot(name);
11449 fBurstParameters->SetSignal(1e5,name);
11450 name="Zmin";
11451 fBurstParameters->AddNamedSlot(name);
11452 fBurstParameters->SetSignal(-1e-6,name);
11453 name="Zmax";
11454 fBurstParameters->AddNamedSlot(name);
11455 fBurstParameters->SetSignal(20,name);
11456 name="Sigmamin";
11457 fBurstParameters->AddNamedSlot(name);
11458 fBurstParameters->SetSignal(0,name);
11459 name="Sigmamax";
11460 fBurstParameters->AddNamedSlot(name);
11461 fBurstParameters->SetSignal(2,name);
11462 name="Grbnu";
11463 fBurstParameters->AddNamedSlot(name);
11464 fBurstParameters->SetSignal(0,name);
11465 name="Dweight";
11466 fBurstParameters->AddNamedSlot(name);
11467 fBurstParameters->SetSignal(1,name);
11468 name="DweightSum"; // Reset the sum of the individual distance weights
11469 fBurstParameters->AddNamedSlot(name);
11470 fBurstParameters->SetSignal(0,name);
11471 name="Avgrbz";
11472 fBurstParameters->AddNamedSlot(name);
11473 fBurstParameters->SetSignal(-1,name);
11474 name="Avgrbt90";
11475 fBurstParameters->AddNamedSlot(name);
11476 fBurstParameters->SetSignal(-1,name);
11477 name="Inburst";
11478 fBurstParameters->AddNamedSlot(name);
11479 fBurstParameters->SetSignal(0,name);
11480 name="Dtnu";
11481 fBurstParameters->AddNamedSlot(name);
11482 fBurstParameters->SetSignal(0,name);
11483 name="Dtnus";
11484 fBurstParameters->AddNamedSlot(name);
11485 fBurstParameters->SetSignal(-0.5,name);
11486 name="ESigmin";
11487 fBurstParameters->AddNamedSlot(name);
11488 fBurstParameters->SetSignal(1e3,name);
11489 name="ESigmax";
11490 fBurstParameters->AddNamedSlot(name);
11491 fBurstParameters->SetSignal(1e10,name);
11492 name="Ezcor";
11493 fBurstParameters->AddNamedSlot(name);
11494 fBurstParameters->SetSignal(1,name);
11495 name="Emin";
11496 fBurstParameters->AddNamedSlot(name);
11497 fBurstParameters->SetSignal(200,name);
11498 name="Emax";
11499 fBurstParameters->AddNamedSlot(name);
11500 fBurstParameters->SetSignal(1e7,name);
11501 name="Alphasig";
11502 fBurstParameters->AddNamedSlot(name);
11503 fBurstParameters->SetSignal(2,name);
11504 name="Alphabkg";
11505 fBurstParameters->AddNamedSlot(name);
11506 fBurstParameters->SetSignal(3.5,name);
11507 name="Kinangle";
11508 fBurstParameters->AddNamedSlot(name);
11509 fBurstParameters->SetSignal(3,name);
11510 name="Angresmin";
11511 fBurstParameters->AddNamedSlot(name);
11512 fBurstParameters->SetSignal(0,name);
11513 name="Angresmax";
11514 fBurstParameters->AddNamedSlot(name);
11515 fBurstParameters->SetSignal(2,name);
11516 name="Angresfix";
11517 fBurstParameters->AddNamedSlot(name);
11518 fBurstParameters->SetSignal(1,name);
11519 name="Recoangle";
11520 fBurstParameters->AddNamedSlot(name);
11521 fBurstParameters->SetSignal(3,name);
11522 name="Sumsigmas";
11523 fBurstParameters->AddNamedSlot(name);
11524 fBurstParameters->SetSignal(2,name);
11525 name="Timres";
11526 fBurstParameters->AddNamedSlot(name);
11527 fBurstParameters->SetSignal(1e-5,name);
11528 name="Sensarea";
11529 fBurstParameters->AddNamedSlot(name);
11530 fBurstParameters->SetSignal(1e6,name);
11531 name="Bkgrate";
11532 fBurstParameters->AddNamedSlot(name);
11533 fBurstParameters->SetSignal(-0.003/(2.*pi),name);
11534 name="Nbkg";
11535 fBurstParameters->AddNamedSlot(name);
11536 fBurstParameters->SetSignal(1,name);
11537 name="Tunits";
11538 fBurstParameters->AddNamedSlot(name);
11539 fBurstParameters->SetSignal(2,name);
11540 name="Tmin";
11541 fBurstParameters->AddNamedSlot(name);
11542 fBurstParameters->SetSignal(-3600,name);
11543 name="Tmax";
11544 fBurstParameters->AddNamedSlot(name);
11545 fBurstParameters->SetSignal(3600,name);
11546 name="Dawin";
11547 fBurstParameters->AddNamedSlot(name);
11548 fBurstParameters->SetSignal(5,name);
11549 name="Datype";
11550 fBurstParameters->AddNamedSlot(name);
11551 fBurstParameters->SetSignal(0,name);
11552 name="Tbint90";
11553 fBurstParameters->AddNamedSlot(name);
11554 fBurstParameters->SetSignal(1,name);
11555 name="Tbin";
11556 fBurstParameters->AddNamedSlot(name);
11557 fBurstParameters->SetSignal(1,name);
11558 name="VarTbin";
11559 fBurstParameters->AddNamedSlot(name);
11560 fBurstParameters->SetSignal(10,name);
11561 name="Abin";
11562 fBurstParameters->AddNamedSlot(name);
11563 fBurstParameters->SetSignal(1,name);
11564
11565 // Remove all histograms related to burst investigations
11566 fBurstHistos.Clear();
11567 fBurstHistos.SetOwner();
11568 }
11569
11571 // Store some derived parameters //
11573
11574 // The correction factor to get from Tunits to seconds
11575 Int_t fTunits=TMath::Nint(fBurstParameters->GetSignal("Tunits"));
11576 Double_t Tfact=1;
11577 if (fTunits==0) Tfact=86400;
11578 if (fTunits==1) Tfact=3600;
11579 if (fTunits==3) Tfact=1e-9;
11580 if (fTunits==4) Tfact=1e-12;
11581 name="Tfact";
11582 fBurstParameters->AddNamedSlot(name);
11583 fBurstParameters->SetSignal(Tfact,name);
11584
11585 // Combined burst position and event reconstruction angular uncertainty interval (sigma in degrees)
11586 Int_t fSumsigmas=TMath::Nint(fBurstParameters->GetSignal("Sumsigmas"));
11587 Int_t fRecoangle=TMath::Nint(fBurstParameters->GetSignal("Recoangle"));
11588 Float_t fSigmamin=fabs(fBurstParameters->GetSignal("Sigmamin"));
11589 Float_t fAngresmin=fBurstParameters->GetSignal("Angresmin");
11590 Float_t fAngresfix=fBurstParameters->GetSignal("Angresfix");
11591 if (!fRecoangle) fAngresmin=fAngresfix;
11592 Float_t Minsigmatot=-1;
11593 if (fSumsigmas==-1) Minsigmatot=fAngresmin;
11594 if (fSumsigmas==0) Minsigmatot=fSigmamin;
11595 if (fSumsigmas==1) Minsigmatot=fSigmamin+fAngresmin;
11596 if (fSumsigmas==2) Minsigmatot= sqrt(fSigmamin*fSigmamin+fAngresmin*fAngresmin);
11597 name="Minsigmatot";
11598 fBurstParameters->AddNamedSlot(name);
11599 fBurstParameters->SetSignal(Minsigmatot,name);
11600 Float_t fSigmamax=fBurstParameters->GetSignal("Sigmamax");
11601 Float_t fAngresmax=fBurstParameters->GetSignal("Angresmax");
11602 if (!fRecoangle) fAngresmax=fAngresfix;
11603 Float_t Maxsigmatot=-1;
11604 if (fSumsigmas==-1) Maxsigmatot=fAngresmax;
11605 if (fSumsigmas==0) Maxsigmatot=fSigmamax;
11606 if (fSumsigmas==1) Maxsigmatot=fSigmamax+fAngresmax;
11607 if (fSumsigmas==2) Maxsigmatot= sqrt(fSigmamax*fSigmamax+fAngresmax*fAngresmax);
11608 name="Maxsigmatot";
11609 fBurstParameters->AddNamedSlot(name);
11610 fBurstParameters->SetSignal(Maxsigmatot,name);
11611
11612 // The total search time window in units of "Tunits"
11613 Float_t fTmin=fBurstParameters->GetSignal("Tmin");
11614 Float_t fTmax=fBurstParameters->GetSignal("Tmax");
11615 Float_t Dtwin=fTmax-fTmin;
11616 name="Dtwin";
11617 fBurstParameters->AddNamedSlot(name);
11618 fBurstParameters->SetSignal(Dtwin,name);
11619
11620 Float_t fTbin=fBurstParameters->GetSignal("Tbin");
11621 if (!fTbin) // Center the time window around the burst trigger for variable time bins
11622 {
11623 fTmin=-Dtwin/2.;
11624 fTmax=Dtwin/2.;
11625 name="Tmin";
11626 fBurstParameters->AddNamedSlot(name);
11627 fBurstParameters->SetSignal(fTmin,name);
11628 name="Tmax";
11629 fBurstParameters->AddNamedSlot(name);
11630 fBurstParameters->SetSignal(fTmax,name);
11631 }
11632
11633 // The solid angle corresponding to the selected declination band
11634 Float_t fRAmin=fBurstParameters->GetSignal("RAmin");
11635 Float_t fRAmax=fBurstParameters->GetSignal("RAmax");
11636 Float_t fDeclmin=fBurstParameters->GetSignal("Declmin");
11637 Float_t fDeclmax=fBurstParameters->GetSignal("Declmax");
11638 Float_t phimin=fRAmin;
11639 Float_t phimax=fRAmax;
11640 Float_t thmin=90.-fDeclmax;
11641 Float_t thmax=90.-fDeclmin;
11642 Float_t OmegaDecl=GetSolidAngle(thmin,thmax,"deg",phimin,phimax,"deg");
11643 name="OmegaDecl";
11644 fBurstParameters->AddNamedSlot(name);
11645 fBurstParameters->SetSignal(OmegaDecl,name);
11646
11647 // Background event rate from the selected declination band
11648 Float_t fBkgrate=fBurstParameters->GetSignal("Bkgrate");
11649 Float_t RbkgDecl=fBkgrate;
11650 if (fBkgrate<0)
11651 {
11652 RbkgDecl=fabs(fBkgrate)*OmegaDecl;
11653 }
11654 name="RbkgDecl";
11655 fBurstParameters->AddNamedSlot(name);
11656 fBurstParameters->SetSignal(RbkgDecl,name);
11657
11658 // Mean number of background events per hour from the selected declination band
11659 Float_t NbkgHour=RbkgDecl*3600.;
11660 name="NbkgHour";
11661 fBurstParameters->AddNamedSlot(name);
11662 fBurstParameters->SetSignal(NbkgHour,name);
11663
11664 // Mean number of background events in the search time window from the selected declination band
11665 Float_t fDtwin=fBurstParameters->GetSignal("Dtwin");
11666 Float_t NbkgWin=RbkgDecl*fDtwin*Tfact;
11667 name="NbkgWin";
11668 fBurstParameters->AddNamedSlot(name);
11669 fBurstParameters->SetSignal(NbkgWin,name);
11670}
11671
11673{
11683
11684 return fBurstParameters;
11685}
11686
11688{
11698
11699 // User provided settings
11700 Int_t fNmaxsrc=TMath::Nint(fBurstParameters->GetSignal("Nmaxsrc"));
11701 Int_t fNmaxevt=TMath::Nint(fBurstParameters->GetSignal("Nmaxevt"));
11702 Float_t fRAmin=fBurstParameters->GetSignal("RAmin");
11703 Float_t fRAmax=fBurstParameters->GetSignal("RAmax");
11704 Float_t fDeclmin=fBurstParameters->GetSignal("Declmin");
11705 Float_t fDeclmax=fBurstParameters->GetSignal("Declmax");
11706 Float_t fT90min=fBurstParameters->GetSignal("T90min");
11707 Float_t fT90max=fBurstParameters->GetSignal("T90max");
11708 Float_t fZmin=fBurstParameters->GetSignal("Zmin");
11709 Float_t fZmax=fBurstParameters->GetSignal("Zmax");
11710 Float_t fSigmamin=fBurstParameters->GetSignal("Sigmamin");
11711 Float_t fSigmamax=fBurstParameters->GetSignal("Sigmamax");
11712 Float_t fGrbnu=fBurstParameters->GetSignal("Grbnu");
11713 Int_t fDweight=TMath::Nint(fBurstParameters->GetSignal("Dweight"));
11714 Float_t fAvgrbz=fBurstParameters->GetSignal("Avgrbz");
11715 Float_t fAvgrbt90=fBurstParameters->GetSignal("Avgrbt90");
11716 Float_t fAvgrbsigma=fBurstParameters->GetSignal("Avgrbsigma");
11717 Int_t fInburst=TMath::Nint(fBurstParameters->GetSignal("Inburst"));
11718 Float_t fDtnu=fBurstParameters->GetSignal("Dtnu");
11719 Float_t fDtnus=fBurstParameters->GetSignal("Dtnus");
11720 Float_t fESigmin=fBurstParameters->GetSignal("ESigmin");
11721 Float_t fESigmax=fBurstParameters->GetSignal("ESigmax");
11722 Int_t fEzcor=TMath::Nint(fBurstParameters->GetSignal("Ezcor"));
11723 Float_t fEmin=fBurstParameters->GetSignal("Emin");
11724 Float_t fEmax=fBurstParameters->GetSignal("Emax");
11725 Int_t fKinangle=TMath::Nint(fBurstParameters->GetSignal("Kinangle"));
11726 Float_t fAngresmin=fBurstParameters->GetSignal("Angresmin");
11727 Float_t fAngresmax=fBurstParameters->GetSignal("Angresmax");
11728 Float_t fAngresfix=fBurstParameters->GetSignal("Angresfix");
11729 Int_t fRecoangle=TMath::Nint(fBurstParameters->GetSignal("Recoangle"));
11730 Int_t fSumsigmas=TMath::Nint(fBurstParameters->GetSignal("Sumsigmas"));
11731 Float_t fTimres=fBurstParameters->GetSignal("Timres");
11732 Float_t fSensarea=fBurstParameters->GetSignal("Sensarea");
11733 Float_t fBkgrate=fBurstParameters->GetSignal("Bkgrate");
11734 Int_t fNbkg=TMath::Nint(fBurstParameters->GetSignal("Nbkg"));
11735 Float_t fTmin=fBurstParameters->GetSignal("Tmin");
11736 Float_t fTmax=fBurstParameters->GetSignal("Tmax");
11737 Int_t fTunits=TMath::Nint(fBurstParameters->GetSignal("Tunits"));
11738 Float_t fDawin=fBurstParameters->GetSignal("Dawin");
11739 Int_t fDatype=TMath::Nint(fBurstParameters->GetSignal("Datype"));
11740 Int_t fTbint90=TMath::Nint(fBurstParameters->GetSignal("Tbint90"));
11741 Float_t fTbin=fBurstParameters->GetSignal("Tbin");
11742 Float_t fVarTbin=fBurstParameters->GetSignal("VarTbin");
11743 Float_t fAbin=fBurstParameters->GetSignal("Abin");
11744
11745 // Derived parameters
11746 Float_t fMaxsigmatot=fBurstParameters->GetSignal("Maxsigmatot");
11747 Float_t fMinsigmatot=fBurstParameters->GetSignal("Minsigmatot");
11748 Float_t fOmegaDecl=fBurstParameters->GetSignal("OmegaDecl");
11749 Float_t fRbkgDecl=fBurstParameters->GetSignal("RbkgDecl");
11750 Float_t fNbkgHour=fBurstParameters->GetSignal("NbkgHour");
11751 Float_t fNbkgWin=fBurstParameters->GetSignal("NbkgWin");
11752
11753 // Internal statistics
11754 Int_t fNgrbs=TMath::Nint(fBurstParameters->GetSignal("Ngrbs"));
11755 Int_t fNevts=TMath::Nint(fBurstParameters->GetSignal("Nevts"));
11756
11757 TString tu="days";
11758 if (fTunits==1) tu="hours";
11759 if (fTunits==2) tu="sec";
11760 if (fTunits==3) tu="ns";
11761 if (fTunits==4) tu="ps";
11762
11763 cout << " ========================= User provided source c.q. burst settings ===============================" << endl;
11764 if (fNmaxsrc<0)
11765 {
11766 printf(" No limitation has been put on the number of sources to be accepted for analysis. \n");
11767 }
11768 else
11769 {
11770 printf(" Maximal number of sources to be accepted for analysis : %-i \n",fNmaxsrc);
11771 }
11772 if (fNmaxevt<0)
11773 {
11774 printf(" No limitation has been put on the number of observed events to be accepted for analysis. \n");
11775 }
11776 else
11777 {
11778 printf(" Maximal number of observed events to be accepted for analysis : %-i \n",fNmaxevt);
11779 }
11780 printf(" Right ascension interval (J2000 in degrees) for source c.q. event position acceptance : [%-g,%-g] \n",fRAmin,fRAmax);
11781 printf(" Declination interval (J2000 in degrees) for source c.q. event position acceptance : [%-g,%-g] \n",fDeclmin,fDeclmax);
11782 printf(" Redshift interval for source acceptance : [%-g,%-g] \n",fabs(fZmin),fZmax);
11783 if (fZmin<0) printf(" Random redshift values taken from z-distribution in case of unknown redshift \n");
11784 if (fAvgrbz>=0) printf(" User defined average source redshift : %-g \n",fAvgrbz);
11785 printf(" Event energy interval (in GeV) for event acceptance : [%-g,%-g] \n",fEmin,fEmax);
11786 printf(" Position uncertainty interval (sigma in degrees) for source acceptance : [%-g,%-g] \n",fabs(fSigmamin),fSigmamax);
11787 if (fSigmamin<0) printf(" Random sigma values taken from sigma-distribution when missing in loaded data \n");
11788 printf(" Event angular resolution interval (sigma in degrees) for event acceptance : [%-g,%-g] \n",fAngresmin,fAngresmax);
11789 if (fDatype>0) printf(" Sigma (combination) selection (-1=event sigma only 0=source sigma only 1=linear summation 2=quadratic summation) : %-i \n",fSumsigmas);
11790 if (fDawin>=0)
11791 {
11792 if (fDatype<0) printf(" Unrestricted angular search area. \n");
11793 if (!fDatype) printf(" Fixed angular search circle around the source position : %-g degrees \n",fDawin);
11794 if (fDatype==1) printf(" Fixed angular search circle (in combined max. source/event sigma) around the source position : %-g \n",fDawin);
11795 if (fDatype==2) printf(" Variable angular search circle (in combined actual source/event sigma) around the source position : %-g \n",fDawin);
11796 }
11797 else
11798 {
11799 if (fDatype<0) printf(" Unrestricted angular search area. \n");
11800 if (!fDatype) printf(" Fixed angular local zenith band above/below the source position : %-g degrees \n",fabs(fDawin));
11801 if (fDatype==1) printf(" Fixed angular local zenith band (in combined max. source/event sigma) above/below the source position : %-g \n",fabs(fDawin));
11802 if (fDatype==2) printf(" Variable angular local zenith band (in combined actual source/event sigma) above/below the source position : %-g \n",fabs(fDawin));
11803 }
11804 printf(" Number of requested background patches per source : %-i \n",fNbkg);
11805 if (fT90max>0)
11806 {
11807 printf(" Duration interval (t90 in sec) for burst acceptance : [%-g,%-g] \n",fabs(fT90min),fT90max);
11808 if (fT90min<0) printf(" Random values taken from T90-distribution in case T90 and T100 were missing \n");
11809 if (fAvgrbt90>0) printf(" User defined average burst T90 duration : %-g sec. \n",fAvgrbt90);
11810 if (fTmax>fTmin) printf(" Total search time window (in %-s) with the burst trigger at t=0 : [%-g,%-g] \n",tu.Data(),fTmin,fTmax);
11811 }
11812 if (fTmax<=fTmin) printf(" Search will be performed with no restrictions on the time window \n");
11813 if (fTbin<0) printf(" Automatic time histogram binning with as mean number of bkg counts/bin : %-g \n",fabs(fTbin));
11814 if (!fTbin) printf(" Variable time histogram binning with as size (in %-s) for the first time : %-g \n",tu.Data(),fVarTbin);
11815 if (fTbin>0)
11816 {
11817 if (fTbint90)
11818 {
11819 printf(" Time histogram bin size in average T90 units : %-g",fTbin);
11820 if (fAvgrbt90>0 || fNgrbs>0) printf(" (=%-g sec)",fTbin*fabs(fAvgrbt90));
11821 printf("\n");
11822 }
11823 else
11824 {
11825 printf( " Time histogram bin size : %-g %-s \n",fTbin,tu.Data());
11826 }
11827 }
11828 if (fAbin<0)
11829 {
11830 printf(" Automatic angular histogram binning with as mean number of bkg counts per bin : %-g \n",fabs(fAbin));
11831 }
11832 else
11833 {
11834 printf(" Angular histogram bin size : %-g degrees \n",fAbin);
11835 }
11836
11837 // Parameters for burst signal and background generation
11838 if (fGrbnu)
11839 {
11840 if (!fInburst)
11841 {
11842 printf(" Neutrino production is assumed to be NOT coupled to the observed burst duration \n");
11843 printf(" Mean decoupled time difference between burst gammas/GW and neutrinos : %-g sec. \n",fDtnu);
11844 }
11845 else
11846 {
11847 printf(" Neutrino production is assumed to be coupled to the observed burst duration \n");
11848 printf(" Mean coupled time difference (in units of T90 w.r.t. trigger) between burst gammas/GW and neutrinos : %-g",fDtnu);
11849 }
11850
11851 if (fDtnus>=0)
11852 {
11853 printf(" Sigma of mean time difference between burst gammas/GW flash and neutrinos : %-g sec. \n",fDtnus);
11854 }
11855 else
11856 {
11857 printf(" Sigma of mean time difference (in units of T90) between burst gammas/GW flash and neutrinos : %-g \n",fabs(fDtnus));
11858 }
11859
11860 TString str;
11861 if (fSigEmode=="SigE")
11862 {
11863 str="Signal energy PDF at the source : dN/dE=";
11864 }
11865 else
11866 {
11867 str="Signal energy profile at Earth : dN/dE=";
11868 }
11869 str+=fSigEprofile.GetExpFormula("p");
11870 str.ReplaceAll("x","E");
11871 if (fSigEmode=="SigS") str+=" cm^-2";
11872 if (fSigEmode=="SigF") str+=" cm^-2 s^-1";
11873 if (fSigEmode=="SigI") str+=" cm^-2 s^-1 sr^-1";
11874 printf(" %-s within [%-g,%-g] GeV \n",str.Data(),fESigmin,fESigmax);
11875
11876 if (fSigEmode=="SigE")
11877 {
11878 if (fEzcor)
11879 {
11880 printf(" The signal neutrino energy at Earth will be corrected for redshift \n");
11881 }
11882 else
11883 {
11884 printf(" No redshift correction will be applied on the generated signal neutrino energy \n");
11885 }
11886 }
11887 else if (fSigEmode=="SigS" || fSigEmode=="SigF" || fSigEmode=="SigI")
11888 {
11889 if (fDweight)
11890 {
11891 printf(" The signal contribution of each individual source will be determined based on a distance weight \n");
11892 }
11893 else
11894 {
11895 printf(" No distance weight will be applied for the signal contribution of individual sources \n");
11896 }
11897 }
11898
11899 if (fGrbnu<0)
11900 {
11901 if (fSigEmode=="SigE")
11902 {
11903 printf(" Number of generated neutrinos per burst : %-g without statistical fluctuations \n",fabs(fGrbnu));
11904 }
11905 else
11906 {
11907 printf(" Signal neutrinos are generated without Poisson fluctuation of the expected average counts \n");
11908 }
11909 }
11910 else
11911 {
11912 if (fSigEmode=="SigE")
11913 {
11914 printf(" Average number of generated neutrinos per burst : %-g \n",fGrbnu);
11915 printf(" The actual number of neutrinos may vary due to statistical (Poisson) fluctuations \n");
11916 }
11917 else
11918 {
11919 printf(" Signal neutrinos are generated with Poisson fluctuation of the expected average counts \n");
11920 }
11921 }
11922
11923 if (fBkgEmode=="BkgE")
11924 {
11925 str="Background energy PDF at Earth : dN/dE=";
11926 }
11927 else
11928 {
11929 str="Background energy profile at Earth : dN/dE=";
11930 }
11931 str+=fBkgEprofile.GetExpFormula("p");
11932 str.ReplaceAll("x","E");
11933 if (fBkgEmode=="BkgS") str+=" cm^-2";
11934 if (fBkgEmode=="BkgF") str+=" cm^-2 s^-1";
11935 if (fBkgEmode=="BkgI") str+=" cm^-2 s^-1 sr^-1";
11936 printf(" %-s within [%-g,%-g] GeV \n",str.Data(),fEmin,fEmax);
11937
11938 printf(" Fixed event reco angular resolution (sigma in degrees), also used when no distribution (value) is available : %-g \n",fAngresfix);
11939 printf(" Event reconstruction angular uncertainty selection (0=use fixed value 1=mean 2=median 3=draw from distribution) : %-i \n",fRecoangle);
11940 printf(" Neutrino-lepton kinematic opening angle selection for CC interactions (0=none 1=mean 2=median 3=draw from pdf) : %-i \n",fKinangle);
11941 }
11942
11943 printf("\n");
11944 printf(" Time resolution of the neutrino detector : %-g sec. \n",fTimres);
11945 printf(" Area covered c.q. overlooked by the neutrino detector : %-g m^2 \n",fSensarea);
11946 if (fBkgEmode=="BkgE" && fBkgrate)
11947 {
11948 printf(" User defined mean rate of background events for the specified declination interval (<0 : rate per steradian) : %-g Hz \n",fBkgrate);
11949 }
11950
11951 printf("\n");
11952 printf(" ============================== Derived parameters ==================================== \n");
11953 printf(" Combined source position and event reco angular uncertainty interval (sigma in degrees) : [%-g,%-g] \n",fMinsigmatot,fMaxsigmatot);
11954 printf(" Solid angle coverage corresponding to the selected RA and DEC range : %-g steradian \n",fOmegaDecl);
11955 if (fBkgEmode=="BkgE" && fBkgrate)
11956 {
11957 printf(" Background event rate (from user setting) for the selected RA and DEC range : %-g Hz \n",fRbkgDecl);
11958 printf(" Mean number of background events (from user setting) per hour from the selected RA and DEC range : %-g \n",fNbkgHour);
11959 printf(" Mean number of background events (from user setting) in the time window from the selected RA and DEC range : %-g \n",fNbkgWin);
11960 }
11961 if (fNgrbs>0)
11962 {
11963 printf(" Number of bursts accepted for analysis : %-i \n",fNgrbs);
11964 printf(" Median source redshift from the data sample : %-g \n",fabs(fAvgrbz));
11965 if (fAvgrbt90) printf(" Median burst T90 duration from the data sample : %-g sec. \n",fabs(fAvgrbt90));
11966 printf(" Median souce position uncertainty (sigma in degrees) from the data sample : %-g \n",fAvgrbsigma);
11967 }
11968 if (fNevts>0) printf(" Number of observed events accepted for analysis : %-i \n",fNevts);
11969 printf(" ====================================================================================== \n");
11970 printf("\n");
11971}
11972
11973void NcAstrolab::LoadInputData(Bool_t src,TString file,TString tree,Int_t date1,Int_t date2,Int_t nmax,TString type)
11974{
12031
12032 // Set the default type identifier
12033 if (type=="-" && src) type="GRB";
12034 if (type=="-" && !src) type="EVT";
12035
12036 Int_t nvars=fDataNames.GetMaxRow();
12037
12038 if (nvars<1)
12039 {
12040 cout << " *" << ClassName() << "::LoadInputData* No variables were specified for " << type << " data."<< endl;
12041 return;
12042 }
12043
12044 // Set the data mode : observed events or source data
12045 Int_t iobs=1;
12046 if (src) iobs=0;
12047
12048 // Retreive the needed parameters
12049 Int_t fNmaxsrc=TMath::Nint(fBurstParameters->GetSignal("Nmaxsrc"));
12050 Int_t fNmaxevt=TMath::Nint(fBurstParameters->GetSignal("Nmaxevt"));
12051 Float_t fRAmin=fBurstParameters->GetSignal("RAmin");
12052 Float_t fRAmax=fBurstParameters->GetSignal("RAmax");
12053 Float_t fDeclmin=fBurstParameters->GetSignal("Declmin");
12054 Float_t fDeclmax=fBurstParameters->GetSignal("Declmax");
12055 Float_t fT90min=fBurstParameters->GetSignal("T90min");
12056 Float_t fT90max=fBurstParameters->GetSignal("T90max");
12057 Float_t fZmin=fBurstParameters->GetSignal("Zmin");
12058 Float_t fZmax=fBurstParameters->GetSignal("Zmax");
12059 Float_t fSigmamin=fBurstParameters->GetSignal("Sigmamin");
12060 Float_t fSigmamax=fBurstParameters->GetSignal("Sigmamax");
12061 Float_t fEmin=fBurstParameters->GetSignal("Emin");
12062 Float_t fEmax=fBurstParameters->GetSignal("Emax");
12063 Float_t fAngresmin=fBurstParameters->GetSignal("Angresmin");
12064 Float_t fAngresmax=fBurstParameters->GetSignal("Angresmax");
12065 Int_t fDweight=TMath::Nint(fBurstParameters->GetSignal("Dweight"));
12066
12067 // Internal statistics
12068 Int_t fNgrbs=GetNsignals(0);
12069 Int_t fNevts=GetNsignals(1);
12070
12071 // Get access to a redshift distribution to draw randomly source redshifts if needed
12072 TH1* zdist=0;
12073 if (src && fZmin<0) zdist=GetBurstZdist("LoadInputData()",type);
12074
12075 // Get access to a T90 distribution to draw randomly source c.q. burst T90 values if needed
12076 TH1* t90dist=0;
12077 if (src && fT90min<0) t90dist=GetBurstT90dist("LoadInputData()",type);
12078
12079 // Get access to a 1-sigma position uncertainty distribution to draw randomly source position uncertaintes
12080 TH1* sigmaposdist=0;
12081 if (src && fSigmamin<0) sigmaposdist=GetBurstSigmaPosdist("LoadInputData()",type);
12082
12083 // The TTree containing the source (c.q. burst) or observed event data
12084 TChain data(tree.Data());
12085 data.Add(file.Data());
12086
12087 // The pre-defined (physical) observables
12088 TString obsname;
12089 TString varname;
12090 TString units;
12091 TString func;
12092
12093 // The (physical) observable value in string format
12094 TObjString* pval=0;
12095 TString val;
12096
12097 // The retrieved numerical (physical) observable value from the ROOT Tree
12098 Double_t value=0;
12099
12100 // The conversion factor depending on the units specification
12101 Double_t fact=0;
12102
12103 // Some of the pre-defined observable values that are used for selections
12104 // or that need special treatment
12105 TString Name,Date,Tobs,Tstart,Tend;
12106 Double_t d,a,b;
12107 Float_t z,csigma,T90,T100,E;
12108
12109 UInt_t yyyy,mm,dd; // The date format
12110 Int_t h,m; // The integer hour and minute time format
12111 Double_t s; // The (fractional) seconds time format
12112 Int_t dmode=0;
12113 Int_t idate=0;
12114 Int_t jdate=0;
12115 TString grbname;
12116 NcTimestamp tobs;
12117 NcTimestamp tstart;
12118 NcTimestamp tend;
12119 NcSignal* sx=0;
12120 Int_t nnew=0;
12121 TLeaf* lx=0;
12122 TLeafC* lxc=0;
12123 Int_t jlast=0;
12124
12125 // Create or increase the corresponding storage array to hold the new data
12126 Int_t nent=data.GetEntries();
12127 Int_t size=0;
12128 if (src) // Input represents reference objects
12129 {
12130 if (!fRefs)
12131 {
12132 fRefs=new TObjArray(nent);
12133 fRefs->SetOwner();
12134 }
12135 else
12136 {
12137 size=fRefs->GetSize();
12138 fRefs->Expand(size+nent);
12139 }
12140 }
12141 else // Input represents measured signals
12142 {
12143 if (!fSigs)
12144 {
12145 fSigs=new TObjArray(nent);
12146 fSigs->SetOwner();
12147 }
12148 else
12149 {
12150 size=fSigs->GetSize();
12151 fSigs->Expand(size+nent);
12152 }
12153 }
12154
12155 // Loop over the data entries in the input Tree
12156 for (Int_t ient=0; ient<nent; ient++)
12157 {
12158 if (nmax>=0 && nnew>=nmax) break;
12159 if (src && fNmaxsrc>=0 && (fNgrbs+nnew)>=fNmaxsrc) break;
12160 if (!src && fNmaxevt>=0 && (fNevts+nnew)>=fNmaxevt) break;
12161
12162 data.GetEntry(ient);
12163
12164 // Initialisation of the values that are used for selections
12165 // or that need special treatment
12166 Name="none";
12167 Date="none";
12168 Tobs="none";
12169 Tstart="none";
12170 Tend="none";
12171 d=-999;
12172 a=-999;
12173 b=-999;
12174 z=-999;
12175 csigma=-999;
12176 T90=-999;
12177 T100=-999;
12178 E=-999;
12179
12180 // Loop over the selected input variables and retrieve the corresponding input value
12181 for (Int_t ivar=1; ivar<=nvars; ivar++)
12182 {
12183 obsname=((TObjString*)fDataNames.GetObject(ivar,1))->GetString();
12184 varname=((TObjString*)fDataNames.GetObject(ivar,2))->GetString();
12185 units=((TObjString*)fDataNames.GetObject(ivar,3))->GetString();
12186 func=((TObjString*)fDataNames.GetObject(ivar,4))->GetString();
12187
12188 pval=(TObjString*)fDataNames.GetObject(ivar,5);
12189
12190 if (!pval) continue;
12191
12192 lx=data.GetLeaf(varname);
12193
12194 // Record -999 for missing data
12195 if (!lx)
12196 {
12197 pval->SetString("-999");
12198 continue;
12199 }
12200
12201 if (obsname=="Name") // Character string data from the input Tree
12202 {
12203 value=0;
12204 lxc=(TLeafC*)lx;
12205 Name=lxc->GetValueString();
12206 }
12207 else // Numerical data from the input Tree
12208 {
12209 value=lx->GetValue();
12210 }
12211
12212 if (func=="Log") value=pow(10,value);
12213 if (func=="Ln") value=exp(value);
12214
12215 // Convert all angular values to degrees
12216 if (obsname=="a" || obsname=="b" || obsname=="csigma") value=ConvertAngle(value,units,"deg");
12217
12218 // Convert numerical values to the standard units
12219 if (units.IsFloat())
12220 {
12221 fact=units.Atof();
12222 value*=fact;
12223 }
12224
12225 // Store the obtained value in string format
12226 val="";
12227 val+=value;
12228 pval->SetString(val);
12229
12230 // Special values needed for later selections
12231 if (obsname=="Date")
12232 {
12233 Date="";
12234 Date+=int(value);
12235 if (units=="ddmmyyyy") dmode=0;
12236 if (units=="yyyymmdd") dmode=1;
12237 if (units=="mmddyyyy") dmode=2;
12238 if (units=="yyyyddmm") dmode=3;
12239 }
12240 if (obsname=="Tobs")
12241 {
12242 Tobs="set"; // Indicate that Tobs is encountered
12243 if (units=="JD") tobs.SetJD(value);
12244 if (units=="MJD") tobs.SetMJD(value);
12245 if (units=="TJD") tobs.SetTJD(value);
12246 if (units=="hms")
12247 {
12248 Tobs="";
12249 Tobs+=value;
12250 }
12251 if (units=="hrs") // Convert "hrs" to "hms" time format
12252 {
12253 Tobs="";
12254 Convert(value,h,m,s);
12255 value=s+double(100*m+10000*h);
12256 Tobs+=value;
12257 }
12258 }
12259 if (obsname=="Tstart")
12260 {
12261 Tstart="set"; // Indicate that Tstart is encountered
12262 if (units=="JD") tstart.SetJD(value);
12263 if (units=="MJD") tstart.SetMJD(value);
12264 if (units=="TJD") tstart.SetTJD(value);
12265 if (units=="hms")
12266 {
12267 Tstart="";
12268 Tstart+=value;
12269 }
12270 if (units=="hrs") // Convert "hrs" to "hms" time format
12271 {
12272 Tstart="";
12273 Convert(value,h,m,s);
12274 value=s+double(100*m+10000*h);
12275 Tstart+=value;
12276 }
12277 }
12278 if (obsname=="Tend")
12279 {
12280 Tend="set"; // Indicate that Tend is encountered
12281 if (units=="JD") tend.SetJD(value);
12282 if (units=="MJD") tend.SetMJD(value);
12283 if (units=="TJD") tend.SetTJD(value);
12284 if (units=="hms")
12285 {
12286 Tend="";
12287 Tend+=value;
12288 }
12289 if (units=="hrs") // Convert "hrs" to "hms" time format
12290 {
12291 Tend="";
12292 Convert(value,h,m,s);
12293 value=s+double(100*m+10000*h);
12294 Tend+=value;
12295 }
12296 }
12297
12298 if (obsname=="d") d=value;
12299 if (obsname=="a") a=value;
12300 if (obsname=="b") b=value;
12301 if (obsname=="z") z=value;
12302 if (obsname=="csigma") csigma=value;
12303 if (obsname=="T90") T90=value;
12304 if (obsname=="T100") T100=value;
12305 if (obsname=="E") E=value;
12306 } // End of the loop over the selected input variables
12307
12308 // For angular coordinates the distance may be irrelevant
12309 if (d<=0) d=1;
12310
12311 // Check for the presence of valid location data
12312 if (a<-900 || b<-900) continue;
12313
12314 // Check on (RA,DEC) acceptance in case of J2000 equatorial coordinates
12315 if (fDataFrame=="equ" && fDataMode=="J" && (a<fRAmin || a>fRAmax || b<fDeclmin || b>fDeclmax)) continue;
12316
12317 // Construct the various timestamps from the (date,time) specification if needed
12318 if (Tobs!="none" && Tobs!="set" && Date!="none") tobs.SetUT(Date,Tobs,dmode);
12319 if (Tstart!="none" && Tstart!="set" && Date!="none") tstart.SetUT(Date,Tstart,dmode);
12320 if (Tend!="none" && Tend!="set" && Date!="none") tend.SetUT(Date,Tend,dmode);
12321
12322 // Check for the presence of a valid observation c.q. trigger timestamp
12323 if (Tobs=="none" || (Tobs!="set" && Date=="none")) continue;
12324
12325 // Obtain the date in yyyymmdd format
12326 tobs.GetDate(kTRUE,0,&yyyy,&mm,&dd);
12327 idate=dd+100*mm+10000*yyyy;
12328
12329 if (Name!="none") // Set the name of the object or observation
12330 {
12331 grbname=Name;
12332 }
12333 else // Compose the name of the source c.q. burst with the common yymmdd suffix
12334 {
12335 jdate=idate%1000000;
12336 grbname=type;
12337 if (jdate<100000) grbname+="0"; // Add leading zero for the year if needed
12338 grbname+=jdate;
12339 }
12340
12341 if (date1 && idate<date1) continue;
12342 if (date2 && idate>date2) continue;
12343
12344 if (src) // Source c.q. burst specific selections
12345 {
12346 if (T90<=0) T90=T100;
12347 if (fT90min<0 && T90<0 && t90dist) T90=t90dist->GetRandom();
12348
12349 if (T90<fabs(fT90min) || T90>fT90max) continue;
12350
12351 if (fZmin<0 && z<0 && zdist) z=zdist->GetRandom();
12352
12353 if (z<fabs(fZmin) || z>fZmax) continue;
12354
12355 if (fSigmamin<0 && csigma<0 && sigmaposdist) csigma=sigmaposdist->GetRandom();
12356
12357 if (csigma<fabs(fSigmamin) || csigma>fSigmamax) continue;
12358 }
12359 else // Observed event specific selections
12360 {
12361 if (E<fEmin || E>fEmax) continue;
12362 if (csigma<fAngresmin || csigma>fAngresmax) continue;
12363 }
12364
12365 // Store the location c.q. arrival direction data
12366 sx=SetSignal(d,a,"deg",b,"deg",fDataFrame,&tobs,-1,fDataMode,grbname,iobs);
12367
12368 // Obtain the RA and DEC coordinates for acceptance selection if input was not in J2000
12369 if (fDataFrame!="equ" || fDataMode!="J")
12370 {
12371 jlast=GetSignalIndex(sx,iobs);
12372 GetSignal(d,a,"deg",b,"deg","equ",&tobs,jlast,"J",iobs);
12373
12374 // Remove the signal again when it falls outside the acceptance
12375 if (a<fRAmin || a>fRAmax || b<fDeclmin || b>fDeclmax)
12376 {
12377 RemoveSignal(jlast,iobs,0);
12378 sx=0;
12379 continue;
12380 }
12381 }
12382
12383 if (!sx) continue;
12384
12385 nnew++;
12386
12387 // Storing the requested data in NcSignal slots
12388 for (Int_t ivar=1; ivar<=nvars; ivar++)
12389 {
12390 obsname=((TObjString*)fDataNames.GetObject(ivar,1))->GetString();
12391 val=((TObjString*)fDataNames.GetObject(ivar,5))->GetString();
12392
12393 // The observable Name is not stored in the NcSignal slots
12394 if (obsname=="Name") continue;
12395
12396 value=val.Atof();
12397
12398 // The values of the observables a and b depend on the reference frame
12399 // They should be retrieved via the GetSignal() facility
12400 if (obsname=="a" || obsname=="b") continue;
12401
12402 // The Date and timestamps in specific format
12403 if (obsname=="Date") value=idate;
12404 if (obsname=="Tobs") value=tobs.GetMJD();
12405 if (obsname=="Tstart") value=tstart.GetMJD();
12406 if (obsname=="TEnd") value=tend.GetMJD();
12407
12408 // Values that may have got random values
12409 if (obsname=="z")
12410 {
12411 value=z;
12412 // Determine the distance weight for this burst and update the distance weight sum
12413 if (fDweight)
12414 {
12415 d=GetPhysicalDistance(z,"Gpc");
12416 if (d>0)
12417 {
12418 sx->AddNamedSlot("Dweight");
12419 sx->SetSignal(1./pow(d,2),"Dweight");
12420 fBurstParameters->AddSignal(1./pow(d,2),"DweightSum");
12421 }
12422 }
12423 }
12424 if (obsname=="csigma") value=csigma;
12425 if (obsname=="T90") value=T90;
12426
12427 sx->AddNamedSlot(obsname);
12428 sx->SetSignal(value,obsname);
12429 }
12430
12431 if (!src) continue;
12432 } // End of loop over the entries of the input Tree
12433
12434 // Compress the storage array size to the number of actually stored elements
12435 RemoveSignal(-1,iobs,1);
12436
12437 Int_t nstored=GetNsignals(iobs);
12438
12439 cout << endl;
12440 if (src)
12441 {
12442 // Update internal statistics
12443 fBurstParameters->AddNamedSlot("Ngrbs");
12444 fBurstParameters->SetSignal(nstored,"Ngrbs");
12445 cout << " *" << ClassName() << "::LoadInputData* " << nnew << " new source(s) of type " << type
12446 << " stored from Tree:" << tree << " of file(s):" << file << endl;
12447 cout << " Total number of stored sources c.q. bursts : " << nstored << endl;
12448 }
12449 else
12450 {
12451 // Update internal statistics
12452 fBurstParameters->AddNamedSlot("Nevts");
12453 fBurstParameters->SetSignal(nstored,"Nevts");
12454 cout << " *" << ClassName() << "::LoadInputData* " << nnew
12455 << " new observed event(s) were stored from Tree:" << tree << " of file(s):" << file << endl;
12456 cout << " Total number of stored events : " << nstored << endl;
12457 }
12458}
12459
12460void NcAstrolab::LoadAeffData(TString file,TString hist)
12461{
12483
12484 // Expand the input file pathname
12485 file=gSystem->ExpandPathName(file.Data());
12486
12487 TFile f(file.Data());
12488 TH2* h=(TH2*)f.Get(hist.Data());
12489
12490 if (!h)
12491 {
12492 printf("*%-s::LoadAeffData* No 2D histogram with Aeff data found with name : %-s \n",ClassName(),hist.Data());
12493 return;
12494 }
12495
12496 TH2* hAeffProfile=(TH2*)h->Clone("hAeffProfile");
12497 hAeffProfile->SetDirectory(0); // Disonnect this histogram from the TFile f
12498
12499 fBurstHistos.Add(hAeffProfile);
12500
12501 printf("\n *%-s::LoadAeffData* 2D histogram hAeffProfile(log(E),cos(theta)) with effective area data stored. \n",ClassName());
12502 printf(" The data were obtained from the file : %-s \n",file.Data());
12503
12504 // Create a signal and/or background NuCount and Zenith profile by using the corresponding energy profile(s), if any.
12506}
12507
12509{
12527
12528 Double_t fESigmin=fBurstParameters->GetSignal("ESigmin");
12529 Double_t fESigmax=fBurstParameters->GetSignal("ESigmax");
12530 Double_t fEmin=fBurstParameters->GetSignal("Emin");
12531 Double_t fEmax=fBurstParameters->GetSignal("Emax");
12532
12533 TH2* hAeffProfile=(TH2*)fBurstHistos.FindObject("hAeffProfile");
12534 TH1* hSigEprofile=(TH1*)fBurstHistos.FindObject("hSigEprofile");
12535 TH1* hBkgEprofile=(TH1*)fBurstHistos.FindObject("hBkgEprofile");
12536
12537 if (!hAeffProfile) return;
12538
12539 TAxis* xaxis=hAeffProfile->GetXaxis();
12540 TAxis* yaxis=hAeffProfile->GetYaxis();
12541
12542 if (!xaxis || !yaxis) return;
12543
12544 Int_t nebins=xaxis->GetNbins();
12545 Double_t emin=xaxis->GetXmin();
12546 Double_t emax=xaxis->GetXmax();
12547
12548 Int_t nabins=yaxis->GetNbins();
12549 Double_t amin=yaxis->GetXmin();
12550 Double_t amax=yaxis->GetXmax();
12551
12552 TH2* hSigNuCountProfile=(TH2*)fBurstHistos.FindObject("hSigNuCountProfile");
12553 TH2* hBkgNuCountProfile=(TH2*)fBurstHistos.FindObject("hBkgNuCountProfile");
12554 TH1* hSigZenithProfile=(TH1F*)fBurstHistos.FindObject("hSigZenithProfile");
12555 TH1* hBkgZenithProfile=(TH1F*)fBurstHistos.FindObject("hBkgZenithProfile");
12556
12557 Double_t aeff=0;
12558 Double_t integral=0;
12559 Double_t count=0;
12560 Double_t xlow=0;
12561 Double_t xup=0;
12562 TString title="";
12563
12564 // Create the distributions for signal data
12565 if (hSigEprofile && (mode=="Aeff" || mode=="SigS" || mode=="SigF" || mode=="SigI"))
12566 {
12567 title="Contraction of hSigEprofile and hAeffProfile;Log(E) in GeV;Cosine of the Zenith angle (#theta);Counts";
12568 if (mode.Contains("F")) title+=" s^{-1}";
12569 if (mode.Contains("I")) title+=" s^{-1} sr^{ -1}";
12570 if (!hSigNuCountProfile)
12571 {
12572 hSigNuCountProfile=(TH2*)hAeffProfile->Clone("hSigNuCountProfile");
12573 hSigNuCountProfile->Reset();
12574 hSigNuCountProfile->SetTitle(title);
12575 fBurstHistos.Add(hSigNuCountProfile);
12576 }
12577 else if (mode.Contains("Sig")) // Only renew in case of a new Signal energy profile
12578 {
12579 hSigNuCountProfile->Reset();
12580 hSigNuCountProfile->SetBins(nebins,emin,emax,nabins,amin,amax);
12581 hSigNuCountProfile->SetTitle(title);
12582 }
12583
12584 for (Int_t abin=1; abin<=nabins; abin++) // Loop over the cos(theta) bins
12585 {
12586 for (Int_t ebin=1; ebin<=nebins; ebin++) // Loop over the energy bins of hAeffProfile for this theta bin
12587 {
12588 xlow=xaxis->GetBinLowEdge(ebin);
12589 xup=xaxis->GetBinUpEdge(ebin);
12590 xlow=pow(10,xlow);
12591 xup=pow(10,xup);
12592 if (xup<fESigmin || xlow>fESigmax) continue;
12593 if (xlow<fESigmin && xup>fESigmin) xlow=fESigmin;
12594 if (xup>fESigmax && xlow<fESigmax) xup=fESigmax;
12595 aeff=hAeffProfile->GetBinContent(ebin,abin);
12596 integral=fSigEprofile.Integral(xlow,xup);
12597 count=aeff*integral;
12598 hSigNuCountProfile->SetBinContent(ebin,abin,count);
12599 }
12600 }
12601
12602 // Create also the Zenith profile
12603 title="Projection of hSigNuCountProfile;Cosine of the Zenith angle (#theta);Counts";
12604 if (mode.Contains("F")) title+=" s^{-1}";
12605 if (mode.Contains("I")) title+=" s^{-1} sr^{ -1}";
12606
12607 if (!hSigZenithProfile)
12608 {
12609 hSigZenithProfile=hSigNuCountProfile->ProjectionY("hSigZenithProfile");
12610 fBurstHistos.Add(hSigZenithProfile);
12611 }
12612 else if (mode.Contains("Sig")) // Only renew in case of a new Signal energy profile
12613 {
12614 delete hSigZenithProfile;
12615 hSigZenithProfile=hSigNuCountProfile->ProjectionY("hSigZenithProfile");
12616 }
12617 hSigZenithProfile->SetTitle(title);
12618 }
12619
12620 // Create the distributions for background data
12621 if (hBkgEprofile && (mode=="Aeff" || mode=="BkgS" || mode=="BkgF" || mode=="BkgI"))
12622 {
12623 title="Contraction of hBkgEprofile and hAeffProfile;Log(E) in GeV;Cosine of the Zenith angle (#theta);Counts";
12624 if (mode.Contains("F")) title+=" s^{-1}";
12625 if (mode.Contains("I")) title+=" s^{-1} sr^{ -1}";
12626
12627 if (!hBkgNuCountProfile)
12628 {
12629 hBkgNuCountProfile=(TH2*)hAeffProfile->Clone("hBkgNuCountProfile");
12630 hBkgNuCountProfile->Reset();
12631 hBkgNuCountProfile->SetTitle(title);
12632 fBurstHistos.Add(hBkgNuCountProfile);
12633 }
12634 else if (mode.Contains("Bkg")) // Only renew in case of a new Background energy profile
12635 {
12636 hBkgNuCountProfile->Reset();
12637 hBkgNuCountProfile->SetBins(nebins,emin,emax,nabins,amin,amax);
12638 hBkgNuCountProfile->SetTitle(title);
12639 }
12640
12641 for (Int_t abin=1; abin<=nabins; abin++) // Loop over the cos(theta) bins
12642 {
12643 for (Int_t ebin=1; ebin<=nebins; ebin++) // Loop over the energy bins of hAeffProfile for this theta bin
12644 {
12645 xlow=xaxis->GetBinLowEdge(ebin);
12646 xup=xaxis->GetBinUpEdge(ebin);
12647 xlow=pow(10,xlow);
12648 xup=pow(10,xup);
12649 if (xup<fEmin || xlow>fEmax) continue;
12650 if (xlow<fEmin && xup>fEmin) xlow=fEmin;
12651 if (xup>fEmax && xlow<fEmax) xup=fEmax;
12652 aeff=hAeffProfile->GetBinContent(ebin,abin);
12653 integral=fBkgEprofile.Integral(xlow,xup);
12654 count=aeff*integral;
12655 hBkgNuCountProfile->SetBinContent(ebin,abin,count);
12656 }
12657 }
12658
12659 // Create also the Zenith profile
12660 title="Projection of hBkgNuCountProfile;Cosine of the Zenith angle (#theta);Counts";
12661 if (mode.Contains("F")) title+=" s^{-1}";
12662 if (mode.Contains("I")) title+=" s^{-1} sr^{ -1}";
12663
12664 if (!hBkgZenithProfile)
12665 {
12666 hBkgZenithProfile=hBkgNuCountProfile->ProjectionY("hBkgZenithProfile");
12667 fBurstHistos.Add(hBkgZenithProfile);
12668 }
12669 else if (mode.Contains("Bkg")) // Only renew in case of a new Signal energy profile
12670 {
12671 delete hBkgZenithProfile;
12672 hBkgZenithProfile=hBkgNuCountProfile->ProjectionY("hBkgZenithProfile");
12673 }
12674 hBkgZenithProfile->SetTitle(title);
12675 }
12676}
12677
12678void NcAstrolab::GenBurstGCNdata(Int_t n,TString name,Bool_t scale)
12679{
12700
12701 // Retreive the needed parameters
12702 Int_t fNmaxsrc=TMath::Nint(fBurstParameters->GetSignal("Nmaxsrc"));
12703 Float_t fRAmin=fBurstParameters->GetSignal("RAmin");
12704 Float_t fRAmax=fBurstParameters->GetSignal("RAmax");
12705 Float_t fDeclmin=fBurstParameters->GetSignal("Declmin");
12706 Float_t fDeclmax=fBurstParameters->GetSignal("Declmax");
12707 Float_t fT90min=fBurstParameters->GetSignal("T90min");
12708 Float_t fT90max=fBurstParameters->GetSignal("T90max");
12709 Float_t fZmin=fBurstParameters->GetSignal("Zmin");
12710 Float_t fZmax=fBurstParameters->GetSignal("Zmax");
12711 Float_t fSigmamin=fBurstParameters->GetSignal("Sigmamin");
12712 Float_t fSigmamax=fBurstParameters->GetSignal("Sigmamax");
12713 Float_t fOmegaDecl=fBurstParameters->GetSignal("OmegaDecl");
12714 Int_t fDweight=TMath::Nint(fBurstParameters->GetSignal("Dweight"));
12715
12716 if (scale)
12717 {
12718 Double_t pi=acos(-1.);
12719 n=TMath::Nint(double(n)*fOmegaDecl/(4.*pi));
12720 }
12721
12722 // Internal statistics
12723 Int_t fNgrbs=GetNsignals(0);
12724
12725 // Get access to a redshift distribution to draw randomly redshifts
12726 TH1* zdist=GetBurstZdist("GenBurstGCNdata()",name);
12727
12728 // Get access to a T90 distribution to draw randomly T90 values
12729 TH1* t90dist=GetBurstT90dist("GenBurstGCNdata()",name);
12730
12731 // Get access to a 1-sigma position uncertainty distribution to draw randomly position uncertaintes
12732 TH1* sigmaposdist=GetBurstSigmaPosdist("GenBurstGCNdata()",name);
12733
12734 if (!zdist || !t90dist || !sigmaposdist)
12735 {
12736 cout << endl;
12737 cout << " *" << ClassName() << "::GenBurstGCNdata* A distribution for random values is missing." << endl;
12738 cout << endl;
12739 return;
12740 }
12741
12742 Float_t thlow=90.-fDeclmax; // Lower theta angle in overall Earth spherical coordinates (North Pole is theta=0)
12743 Float_t thup=90.-fDeclmin; // Upper theta angle in overall Earth spherical coordinates (North Pole is theta=0)
12744 Float_t phimin=fRAmin; // Minimal phi angle in overall Earth spherical coordinates
12745 Float_t phimax=fRAmax; // Maximal phi angle in overall Earth spherical coordinates
12746 if (thlow<0) thlow=0;
12747 if (thup>180) thup=180;
12748
12749 NcSignal* sx=0;
12750 NcPosition rgrb;
12751 Float_t t90grb=0;
12752 Float_t zgrb=0;
12753 Float_t sigmagrb=0;
12754 TString grbname;
12755 Double_t thetagrb,phigrb,ragrb,decgrb;
12756 Double_t d=0;
12757 Int_t ngen=0;
12758
12759 for (Int_t igrb=1; igrb<=n; igrb++)
12760 {
12761 if (fNmaxsrc>=0 && (fNgrbs+ngen)>=fNmaxsrc) break;
12762
12763 zgrb=-1;
12764 if (fabs(fZmin)==fZmax) zgrb=fZmax;
12765 while (zgrb<fabs(fZmin) || zgrb>fZmax)
12766 {
12767 zgrb=zdist->GetRandom();
12768 }
12769
12770 t90grb=-1;
12771 if (fabs(fT90min)==fT90max) t90grb=fT90max;
12772 while (t90grb<fabs(fT90min) || t90grb>fT90max)
12773 {
12774 t90grb=t90dist->GetRandom();
12775 t90grb=pow(float(10),t90grb);
12776 }
12777
12778 sigmagrb=-1;
12779 if (fabs(fSigmamin)==fSigmamax) sigmagrb=fSigmamax;
12780 while (sigmagrb<fabs(fSigmamin) || sigmagrb>fSigmamax)
12781 {
12782 sigmagrb=sigmaposdist->GetRandom();
12783 }
12784
12785 rgrb.SetPosition(1,0,0,"sph","deg");
12786 RandomPosition(rgrb,thlow,thup,phimin,phimax);
12787 thetagrb=rgrb.GetX(2,"sph","deg");
12788 phigrb=rgrb.GetX(3,"sph","deg");
12789
12790 grbname="Random-";
12791 grbname+=name;
12792 grbname+=igrb;
12793 grbname+="#";
12794 ragrb=phigrb;
12795 decgrb=90.-thetagrb;
12796 sx=SetSignal(1,ragrb,"deg",decgrb,"deg","equ",0,-1,"J",grbname);
12797
12798 if (!sx) continue;
12799
12800 ngen++;
12801
12802 sx->AddNamedSlot("T90");
12803 sx->SetSignal(t90grb,"T90");
12804 sx->AddNamedSlot("csigma");
12805 sx->SetSignal(sigmagrb,"csigma");
12806 sx->AddNamedSlot("z");
12807 sx->SetSignal(zgrb,"z");
12808 // Determine the distance weight for this burst and update the distance weight sum
12809 if (fDweight)
12810 {
12811 d=GetPhysicalDistance(zgrb,"Gpc");
12812 if (d>0)
12813 {
12814 sx->AddNamedSlot("Dweight");
12815 sx->SetSignal(1./pow(d,2),"Dweight");
12816 fBurstParameters->AddSignal(1./pow(d,2),"DweightSum");
12817 }
12818 }
12819 }
12820
12821 // Update internal statistics
12822 fNgrbs=GetNsignals(0);
12823 fBurstParameters->AddNamedSlot("Ngrbs");
12824 fBurstParameters->SetSignal(fNgrbs,"Ngrbs");
12825
12826 printf("\n *%-s::GenBurstGCNdata* %-i new generated bursts with name %-s were stored. \n",ClassName(),ngen,name.Data());
12827 printf(" Total number of stored bursts : %-i \n",fNgrbs);
12828}
12829
12830void NcAstrolab::MakeBurstZdist(TString file,TString tree,TString name,Int_t nb,Float_t zmin,Float_t zmax)
12831{
12863
12864 // The Tree containing the archival data
12865 TChain data(tree.Data());
12866 data.Add(file.Data());
12867
12868 Int_t nen=data.GetEntries();
12869 TLeaf* lx=data.FindLeaf(name.Data());
12870
12871 if (!nen || !lx)
12872 {
12873 cout << " *" << ClassName() << "::MakeBurstZdist* Missing information for tree variable:" << name << endl;
12874 cout << " of Tree:" << tree << " with " << nen << " entries in file:" << file << endl;
12875 return;
12876 }
12877
12878 // Create new distributions in case a redshift distribution is not yet present
12879 TH1* zdist=(TH1*)fBurstHistos.FindObject("hz");
12880 if (!zdist)
12881 {
12882 // Creation of the archival burst redshift histogram
12883 TH1F* hz=new TH1F("hz","Archival data of observed burst redshifts",nb,zmin,zmax);
12884 fBurstHistos.Add(hz);
12885 hz->GetXaxis()->SetTitle("Burst redshift");
12886 hz->GetYaxis()->SetTitle("Counts");
12887
12888 // Creation of the corresponding physical distance histo
12889 Float_t dmin=GetPhysicalDistance(zmin);
12890 Float_t dmax=GetPhysicalDistance(zmax);
12891 TH1F* hd=new TH1F("hd","Burst distances derived from the archival redshift data",nb,dmin,dmax);
12892 fBurstHistos.Add(hd);
12893 hd->GetXaxis()->SetTitle("Burst physical distance in Mpc");
12894 hd->GetYaxis()->SetTitle("Counts");
12895 }
12896
12897 // Get pointers to the relevant histograms
12898 TH1* hz=(TH1*)fBurstHistos.FindObject("hz");
12899 TH1* hd=(TH1*)fBurstHistos.FindObject("hd");
12900
12901 Int_t nz=0;
12902 Double_t z=0;
12903 Double_t d=0;
12904 for (Int_t ien=0; ien<nen; ien++)
12905 {
12906 data.GetEntry(ien);
12907
12908 lx=data.GetLeaf(name.Data());
12909 if (!lx) continue;
12910
12911 z=lx->GetValue();
12912 if (z<zmin || z>zmax) continue;
12913
12914 hz->Fill(z);
12915 nz++;
12916
12918 hd->Fill(d);
12919 }
12920
12921 cout << " *" << ClassName() << "::MakeBurstZdist* " << nz << " archival z-values have been obtained from tree variable:" << name
12922 << " of Tree:" << tree << " in file(s):" << file << endl;
12923}
12924
12925TH1* NcAstrolab::GetBurstZdist(TString name,TString type)
12926{
12935
12936 TH1* zdist=(TH1*)fBurstHistos.FindObject("hz");
12937 if (!zdist)
12938 {
12939 if (type.Contains("GRB"))
12940 {
12941 cout << endl;
12942 cout << " *" << ClassName() << "::GetBurstZdist* Called from " << name << endl;
12943 cout << " *** Archival observed redshift distribution not found. ***" << endl;
12944 cout << " A Landau fit from Swift GRB redshift data will be used to provide missing c.q. random z values." << endl;
12945
12946 zdist=(TH1*)fBurstHistos.FindObject("hZpdf");
12947 if (!zdist)
12948 {
12949 TF1 fz("fz","59.54*TMath::Landau(x,1.092,0.5203)");
12950 fz.SetRange(0,10);
12951 fz.SetNpx(10000);
12952 TH1* hfz=fz.GetHistogram();
12953 zdist=(TH1*)hfz->Clone();
12954 zdist->SetNameTitle("hZpdf","Landau fit for Swift GRB z data");
12955 zdist->GetXaxis()->SetTitle("GRB redshift");
12956 zdist->GetYaxis()->SetTitle("Counts");
12957 fBurstHistos.Add(zdist);
12958 }
12959 }
12960 else // Source class for which no fit is available
12961 {
12962 cout << endl;
12963 cout << " *" << ClassName() << "::GetBurstZdist* Called from " << name << endl;
12964 cout << " *** No redshift fit is available for source class " << type << " ***" << endl;
12965 }
12966 }
12967
12968 return zdist;
12969}
12970
12971void NcAstrolab::MakeBurstT90dist(TString file,TString tree,TString name,Int_t nb,Float_t xmin,Float_t xmax)
12972{
13002
13003 // The Tree containing the burst data
13004 TChain data(tree.Data());
13005 data.Add(file.Data());
13006
13007 Int_t nen=data.GetEntries();
13008 TLeaf* lx=data.FindLeaf(name.Data());
13009
13010 if (!nen || !lx)
13011 {
13012 cout << " *" << ClassName() << "::MakeBurstT90dist* Missing information for tree variable:" << name << endl;
13013 cout << " of Tree:" << tree << " with " << nen << " entries in file:" << file << endl;
13014 return;
13015 }
13016
13017 // Create a new distribution in case a T90 distribution is not yet present
13018 TH1* t90dist=(TH1*)fBurstHistos.FindObject("ht90");
13019 if (!t90dist)
13020 {
13021 // Creation of observed burst t90 duration histo
13022 TH1F* ht90=new TH1F("ht90","Archival data of observed burst durations",nb,xmin,xmax);
13023 fBurstHistos.Add(ht90);
13024 ht90->GetXaxis()->SetTitle("Burst duration ^{10}log(T90) in sec.");
13025 ht90->GetYaxis()->SetTitle("Counts");
13026 }
13027
13028 // Get pointer to the relevant histogram
13029 TH1* ht90=(TH1*)fBurstHistos.FindObject("ht90");
13030
13031 Int_t nt90=0;
13032 Double_t t90=0;
13033 for (Int_t ien=0; ien<nen; ien++)
13034 {
13035 data.GetEntry(ien);
13036
13037 lx=data.GetLeaf(name.Data());
13038 if (!lx) continue;
13039
13040 t90=lx->GetValue();
13041 if (t90>0)
13042 {
13043 ht90->Fill(log10(t90));
13044 nt90++;
13045 }
13046 }
13047
13048 cout << " *" << ClassName() << "::MakeBurstT90dist* " << nt90 << " archival T90 values have been obtained from variable:" << name
13049 << " of Tree:" << tree << " in file(s):" << file << endl;
13050}
13051
13052TH1* NcAstrolab::GetBurstT90dist(TString name,TString type)
13053{
13062
13063 TH1* t90dist=(TH1*)fBurstHistos.FindObject("ht90");
13064 if (!t90dist)
13065 {
13066 if (type.Contains("GRB"))
13067 {
13068 cout << endl;
13069 cout << " *" << ClassName() << "::GetBurstT90dist* Called from " << name << endl;
13070 cout << " *** Observational T90 distribution not found. ***" << endl;
13071 cout << " A double Gaussian fit from Fermi GRB T90 data will be used to provide missing c.q. random T90 values." << endl;
13072
13073 t90dist=(TH1*)fBurstHistos.FindObject("hT90pdf");
13074 if (!t90dist)
13075 {
13076 TF1 ft("ft","44.39*TMath::Gaus(x,-0.131,0.481)+193.8*TMath::Gaus(x,1.447,0.4752)");
13077 ft.SetRange(-5,5);
13078 ft.SetNpx(10000);
13079 TH1* hft=ft.GetHistogram();
13080 t90dist=(TH1*)hft->Clone();
13081 t90dist->SetNameTitle("hT90pdf","Double Gauss fit for Fermi t90 data");
13082 t90dist->GetXaxis()->SetTitle("GRB duration ^{10}log(T90) in sec.");
13083 t90dist->GetYaxis()->SetTitle("Counts");
13084 fBurstHistos.Add(t90dist);
13085 }
13086 }
13087 else // Source class for which no fit is available
13088 {
13089 cout << endl;
13090 cout << " *" << ClassName() << "::GetBurstT90dist* Called from " << name << endl;
13091 cout << " *** No T90 fit is available for source class " << type << " ***" << endl;
13092 }
13093 }
13094
13095 return t90dist;
13096}
13097
13098void NcAstrolab::MakeBurstSigmaPosdist(TString file,TString tree,TString name,TString u,Int_t nb,Float_t xmin,Float_t xmax)
13099{
13138
13139 // The Tree containing the burst data
13140 TChain data(tree.Data());
13141 data.Add(file.Data());
13142
13143 Int_t nen=data.GetEntries();
13144 TLeaf* lx=data.FindLeaf(name.Data());
13145
13146 if (!nen || !lx)
13147 {
13148 cout << " *" << ClassName() << "::MakeBurstSigmaPosdist* Missing information for tree variable:" << name << endl;
13149 cout << " of Tree:" << tree << " with " << nen << " entries in file:" << file << endl;
13150 return;
13151 }
13152
13153 // Create a new distribution in case a burst position uncertainty distribution is not yet present
13154 TH1* sigmaposdist=(TH1*)fBurstHistos.FindObject("hsigmapos");
13155 if (!sigmaposdist)
13156 {
13157 // Creation of observed 1-sigma burst position uncertainty histo
13158 TH1F* hsigmapos=new TH1F("hsigmapos","Archival data of observed 1-sigma burst position uncertainties",nb,xmin,xmax);
13159 fBurstHistos.Add(hsigmapos);
13160 hsigmapos->GetXaxis()->SetTitle("Burst position uncertainty (sigma in degrees)");
13161 hsigmapos->GetYaxis()->SetTitle("Counts");
13162 }
13163
13164 // Get pointer to the relevant histogram
13165 TH1* hsigmapos=(TH1*)fBurstHistos.FindObject("hsigmapos");
13166
13167 Int_t nsigmapos=0;
13168 Double_t sigmapos=0;
13169 for (Int_t ien=0; ien<nen; ien++)
13170 {
13171 data.GetEntry(ien);
13172
13173 lx=data.GetLeaf(name.Data());
13174 if (!lx) continue;
13175
13176 sigmapos=lx->GetValue();
13177
13178 // Convert declination to degrees if needed
13179 sigmapos=ConvertAngle(sigmapos,u,"deg");
13180
13181 if (sigmapos<xmin || sigmapos>xmax) continue;
13182
13183 hsigmapos->Fill(sigmapos);
13184 nsigmapos++;
13185 }
13186
13187 cout << " *" << ClassName() << "::MakeBurstSigmaPosdist* " << nsigmapos << " archival sigmapos values have been obtained from variable:" << name
13188 << " of Tree:" << tree << " in file(s):" << file << endl;
13189}
13190
13191TH1* NcAstrolab::GetBurstSigmaPosdist(TString name,TString type)
13192{
13201
13202 TH1* sigmaposdist=(TH1*)fBurstHistos.FindObject("hsigmapos");
13203 if (!sigmaposdist)
13204 {
13205 if (type.Contains("GRB"))
13206 {
13207 cout << endl;
13208 cout << " *" << ClassName() << "::GetBurstSigmaPosdist* Called from " << name << endl;
13209 cout << " *** Archival observed GRB position uncertainty distribution not found. ***" << endl;
13210 cout << " A Landau fit from observed GRB data will be used to provide missing c.q. random 1-sigma uncertainty values." << endl;
13211
13212 sigmaposdist=(TH1*)fBurstHistos.FindObject("hSigmaSourcePDF");
13213 if (!sigmaposdist)
13214 {
13215 TF1 fsigmapos("fsigmapos","245.2*TMath::Landau(x,-2.209,0.6721,1)");
13216 fsigmapos.SetRange(0,90);
13217 fsigmapos.SetNpx(10000);
13218 TH1* hfsigmapos=fsigmapos.GetHistogram();
13219 sigmaposdist=(TH1*)hfsigmapos->Clone();
13220 sigmaposdist->SetNameTitle("hSigmaSourcePDF","Landau fit for burst 1-sigma position uncertainty data");
13221 sigmaposdist->GetXaxis()->SetTitle("Burst position uncertainty (sigma in degrees)");
13222 sigmaposdist->GetYaxis()->SetTitle("Counts");
13223 fBurstHistos.Add(sigmaposdist);
13224 }
13225 }
13226 else // Source class for which no fit is available
13227 {
13228 cout << endl;
13229 cout << " *" << ClassName() << "::GetBurstSigmaPosdist* Called from " << name << endl;
13230 cout << " *** No position uncertainty fit is available for source class " << type << " ***" << endl;
13231 }
13232 }
13233
13234 return sigmaposdist;
13235}
13236
13237void NcAstrolab::MakeBurstEnergydist(TString mode,TF1& spec,Int_t nsrc,Int_t nbins)
13238{
13312
13313 if (mode!="SigE" && mode!="SigS" && mode!="SigF" && mode!="SigI" && mode!="BkgE" && mode!="BkgS" && mode!="BkgF" && mode!="BkgI")
13314 {
13315 printf("\n *%-s::MakeBurstEnergydist* Inconsistent mode : %-s \n",ClassName(),mode.Data());
13316 return;
13317 }
13318
13319 // Set the corresponding energy boudaries
13320 Float_t fESigmin=fBurstParameters->GetSignal("ESigmin");
13321 Float_t fESigmax=fBurstParameters->GetSignal("ESigmax");
13322 Float_t fEmin=fBurstParameters->GetSignal("Emin");
13323 Float_t fEmax=fBurstParameters->GetSignal("Emax");
13324
13325 Float_t Emin=0;
13326 Float_t Emax=0;
13327 if (mode.Contains("Sig"))
13328 {
13329 Emin=fESigmin;
13330 Emax=fESigmax;
13331 }
13332 else
13333 {
13334 Emin=fEmin;
13335 Emax=fEmax;
13336 }
13337
13338 if (Emin<=0) Emin=1e-10;
13339
13340 // For background spectra and mode="SigE" the value of nsrc is irrelevant
13341 if (mode.Contains("Bkg") || mode=="SigE") nsrc=1;
13342
13343 if (Emax<=Emin || nbins<1 || nsrc<1)
13344 {
13345 printf("\n *%-s::MakeBurstEnergydist* Inconsistent data : mode=%-s nsrc=%-i Emin=%-g Emax=%-g nbins=%-i \n",ClassName(),mode.Data(),nsrc,Emin,Emax,nbins);
13346 return;
13347 }
13348
13349 // Convert the energy boundaries to the log10 scale of the X-axis
13350 Double_t xmin=log10(Emin);
13351 Double_t xmax=log10(Emax);
13352
13353 // Normalize the Fluence, Flux or Intensity to a single source (if needed)
13354 TString sf="";
13355 Float_t norm=1;
13356 if (nsrc>1 && (mode=="SigS" || mode=="BkgS"))
13357 {
13358 norm=1./float(nsrc);
13359 sf.Form("%-g*%-s",norm,(spec.GetExpFormula("p")).Data());
13360 }
13361 else
13362 {
13363 sf=spec.GetExpFormula("p");
13364 }
13365
13366 // The spectral function normalized (if needed) to a single source
13367 TF1 spec2("spec2",sf);
13368
13369 // Store the normalized spectral function
13370 if (mode.Contains("Sig")) fSigEprofile=spec2;
13371 if (mode.Contains("Bkg")) fBkgEprofile=spec2;
13372
13373 if (mode=="SigE" || mode=="BkgE")
13374 {
13375 sf="PDF for dN/dE=";
13376 sf+=spec2.GetExpFormula("p");
13377 norm=spec2.Integral(xmin,xmax);
13378 }
13379 else
13380 {
13381 sf="Counts cm^{-2}";
13382 if (mode.Contains("F")) sf+=" s^{-1}";
13383 if (mode.Contains("I")) sf+=" s^{-1} sr^{ -1}";
13384 sf+=" for dN/dE=";
13385 sf+=spec2.GetExpFormula("p");
13386 }
13387 sf.ReplaceAll("x","E");
13388 TString sh="";
13389 if (mode.Contains("Bkg")) sh="Isotropic background energy distribution at Earth";
13390 if (mode.Contains("Sig"))
13391 {
13392 if (mode=="SigE")
13393 {
13394 sh="Induced signal energy distribution at the source";
13395 }
13396 else
13397 {
13398 sh="Average per source induced signal energy distribution at Earth";
13399 }
13400 }
13401 sh+=";^{10}log(E) in GeV;";
13402 sh+=sf;
13403 TH1F his=GetCountsHistogram(spec2,nbins,xmin,xmax,1,sh);
13404
13405 // Remove the corresponding old distribution (if any) from the storage
13406 TH1* dist=0;
13407 if (mode.Contains("Bkg")) dist=(TH1*)fBurstHistos.FindObject("hBkgEprofile");
13408 if (mode.Contains("Sig")) dist=(TH1*)fBurstHistos.FindObject("hSigEprofile");
13409 if (dist)
13410 {
13411 fBurstHistos.Remove(dist);
13412 fBurstHistos.Compress();
13413 delete dist;
13414 dist=0;
13415 }
13416
13417 // Store the newly created distribution
13418 // and set a flag to indicate a parametrized distribution
13419 if (mode.Contains("Bkg"))
13420 {
13421 fBkgEmode=mode;
13422 TH1F* hBkgEprofile=(TH1F*)his.Clone("hBkgEprofile");
13423 if (mode=="BkgE") hBkgEprofile->Scale(1./norm);
13424 fBurstHistos.Add(hBkgEprofile);
13425 fBurstParameters->AddNamedSlot("PDFbkgE");
13426 fBurstParameters->SetSignal(1,"PDFbkgE");
13427 }
13428 if (mode.Contains("Sig"))
13429 {
13430 fSigEmode=mode;
13431 TH1F* hSigEprofile=(TH1F*)his.Clone("hSigEprofile");
13432 if (mode=="SigE") hSigEprofile->Scale(1./norm);
13433 fBurstHistos.Add(hSigEprofile);
13434 fBurstParameters->AddNamedSlot("PDFsigE");
13435 fBurstParameters->SetSignal(1,"PDFsigE");
13436 }
13437
13438 printf("\n *%-s::MakeBurstEnergydist* Created a %-s profile %-s on [Emin,Emax]=[%-g,%-g] GeV \n",ClassName(),mode.Data(),sf.Data(),Emin,Emax);
13439
13440 // Create the corresponding NuCount and Zenith profile by using the Effective Area data (if any)
13442}
13443
13444void NcAstrolab::MakeBurstEnergydist(TString mode,Double_t alpha,Int_t nbins)
13445{
13479
13480 if (mode!="SigE" && mode!="BkgE")
13481 {
13482 printf(" *%-s::MakeBurstEnergydist* Unsupported mode : %-s for only spectral index specification \n",ClassName(),mode.Data());
13483 return;
13484 }
13485
13486 TF1 spec("spec","pow(x,[0])");
13487 spec.SetParameter(0,-alpha);
13488 MakeBurstEnergydist(mode,spec,0,nbins);
13489}
13490
13491void NcAstrolab::MakeBurstEnergydist(Int_t mode,TString file,TString tree,TString name1,TString name2,TString u,Int_t nb)
13492{
13549
13550 Float_t fDeclmin=fBurstParameters->GetSignal("Declmin");
13551 Float_t fDeclmax=fBurstParameters->GetSignal("Declmax");
13552
13553 Float_t fESigmin=fBurstParameters->GetSignal("ESigmin");
13554 Float_t fESigmax=fBurstParameters->GetSignal("ESigmax");
13555 Float_t fEmin=fBurstParameters->GetSignal("Emin");
13556 Float_t fEmax=fBurstParameters->GetSignal("Emax");
13557
13558 Float_t Emin=0;
13559 Float_t Emax=0;
13560 if (abs(mode)==2)
13561 {
13562 Emin=fESigmin;
13563 Emax=fESigmax;
13564 }
13565 else
13566 {
13567 Emin=fEmin;
13568 Emax=fEmax;
13569 }
13570
13571 if (Emin<=0) Emin=1e-10;
13572
13573 if ((abs(mode)!=1 && abs(mode)!=2) || Emax<=Emin)
13574 {
13575 printf(" *%-s::MakeBurstEnergydist* Inconsistent data: mode=%-i Emin=%-g Emax=%-g \n",ClassName(),mode,Emin,Emax);
13576 return;
13577 }
13578
13579 // Convert the energy boundaries to the log10 scale of the X-axis
13580 Double_t xmin=log10(Emin);
13581 Double_t xmax=log10(Emax);
13582
13583 // The Tree containing the burst data
13584 TChain data(tree.Data());
13585 data.Add(file.Data());
13586
13587 Int_t nen=data.GetEntries();
13588
13589 if (!nen || !data.FindLeaf(name1.Data()) || !data.FindLeaf(name2.Data()))
13590 {
13591 cout << " *" << ClassName() << "::MakeBurstEnergydist* Missing information for tree variable:" << name1
13592 << " and/or tree variable:" << name2 << endl;
13593 cout << " of Tree:" << tree << " with " << nen << " entries in file:" << file << endl;
13594 return;
13595 }
13596
13597 // A corresponding parametrized distribution will always be removed
13598 Int_t flag=0;
13599 if (abs(mode)==1) flag=TMath::Nint(fBurstParameters->GetSignal("PDFbkgE"));
13600 if (abs(mode)==2) flag=TMath::Nint(fBurstParameters->GetSignal("PDFsigE"));
13601
13602 if (flag) mode=abs(mode);
13603
13604 // Remove the corresponding old distribution (if requested) from the storage
13605 TH1* Edist=0;
13606 if (abs(mode)==1) Edist=(TH1*)fBurstHistos.FindObject("hBkgEprofile");
13607 if (abs(mode)==2) Edist=(TH1*)fBurstHistos.FindObject("hSigEprofile");
13608
13609 if (mode>0 && Edist)
13610 {
13611 fBurstHistos.Remove(Edist);
13612 fBurstHistos.Compress();
13613 delete Edist;
13614 Edist=0;
13615 }
13616
13617 // Create a new distribution if needed
13618 if (!Edist)
13619 {
13620 mode=abs(mode);
13621 if (mode==1)
13622 {
13623 // Creation of the observed background energy histo
13624 fBkgEmode="BkgE";
13625 TH1F* hBkgEprofile=new TH1F("hBkgEprofile","Archival data of observed background energies",nb,xmin,xmax);
13626 fBurstHistos.Add(hBkgEprofile);
13627 hBkgEprofile->GetXaxis()->SetTitle("^{10}log(Energy) in GeV");
13628 hBkgEprofile->GetYaxis()->SetTitle("Counts");
13629 fBurstParameters->AddNamedSlot("PDFbkgE");
13630 fBurstParameters->SetSignal(0,"PDFbkgE");
13631 }
13632 if (mode==2)
13633 {
13634 // Creation of the observed signal energy histo
13635 fSigEmode="SigE";
13636 TH1F* hSigEprofile=new TH1F("hSigEprofile","Archival data of observed signal energies",nb,xmin,xmax);
13637 fBurstHistos.Add(hSigEprofile);
13638 hSigEprofile->GetXaxis()->SetTitle("^{10}log(Energy) in GeV");
13639 hSigEprofile->GetYaxis()->SetTitle("Counts");
13640 fBurstParameters->AddNamedSlot("PDFsigE");
13641 fBurstParameters->SetSignal(0,"PDFsigE");
13642 fBurstParameters->SetSignal(0,"Ezcor");
13643 }
13644 }
13645
13646 // Get pointer to the relevant histogram
13647 if (abs(mode)==1) Edist=(TH1*)fBurstHistos.FindObject("hBkgEprofile");
13648 if (abs(mode)==2) Edist=(TH1*)fBurstHistos.FindObject("hSigEprofile");
13649
13650 Int_t nE=0;
13651 Double_t logE=0;
13652 Double_t dec=0;
13653 TLeaf* lx=0;
13654 for (Int_t ien=0; ien<nen; ien++)
13655 {
13656 data.GetEntry(ien);
13657
13658 lx=data.GetLeaf(name1.Data());
13659 if (!lx) continue;
13660
13661 logE=lx->GetValue();
13662
13663 lx=data.GetLeaf(name2.Data());
13664 if (!lx) continue;
13665
13666 dec=lx->GetValue();
13667
13668 // Convert declination to degrees if needed
13669 dec=ConvertAngle(dec,u,"deg");
13670
13671 if (dec>=fDeclmin && dec<=fDeclmax)
13672 {
13673 Edist->Fill(logE);
13674 nE++;
13675 }
13676 }
13677
13678 TString smode="";
13679 if (abs(mode)==1) smode="archival background";
13680 if (abs(mode)==2) smode="archival signal";
13681
13682 if (mode>0)
13683 {
13684 cout << " *" << ClassName() << "::MakeBurstEnergydist* A new " << smode
13685 << " energy distribution has been created." << endl;
13686 }
13687 else
13688 {
13689 cout << " *" << ClassName() << "::MakeBurstEnergydist* Statistics of the existing " << smode
13690 << " energy distribution have been increased." << endl;
13691 }
13692
13693 cout << " " << nE << " energy values have been obtained from variable:" << name1
13694 << " of Tree:" << tree << " in file(s):" << file << endl;
13695}
13696
13697void NcAstrolab::MakeBurstRecoAngresdist(TString file,TString tree,TString name1,TString name2,TString ua,TString name3,TString ud,Double_t Emin,Double_t Emax,Int_t nbe,Int_t nba)
13698{
13746
13747 Float_t fDeclmin=fBurstParameters->GetSignal("Declmin");
13748 Float_t fDeclmax=fBurstParameters->GetSignal("Declmax");
13749
13750 if (Emin<=0) Emin=1e-10;
13751
13752 if (Emax<=Emin)
13753 {
13754 cout << " *" << ClassName() << "::MakeBurstRecoAngresdist* Inconsistent data: Emin=" << Emin << " Emax=" << Emax << endl;
13755 return;
13756 }
13757
13758 // Convert the energy boundaries to the log10 scale of the X-axis
13759 Double_t xmin=log10(Emin);
13760 Double_t xmax=log10(Emax);
13761
13762 // The Tree containing the burst data
13763 TChain data(tree.Data());
13764 data.Add(file.Data());
13765
13766 Int_t nen=data.GetEntries();
13767
13768 if (!nen || !data.FindLeaf(name1.Data()) || !data.FindLeaf(name2.Data()) || !data.FindLeaf(name3.Data()))
13769 {
13770 cout << " *" << ClassName() << "::MakeBurstRecoAngresdist* Missing information for tree variable:" << name1
13771 << " and/or tree variable:" << name2 << " and/or tree variable:" << name3 << endl;
13772 cout << " of Tree:" << tree << " with " << nen << " entries in file:" << file << endl;
13773 return;
13774 }
13775
13776 // Create a new distribution in case a reconstruction angle resolution vs. energy distribution is not yet present
13777 TH2* Angresdist=(TH2*)fBurstHistos.FindObject("hAngresE");
13778 if (!Angresdist)
13779 {
13780 // Creation of the observed reconstruction angle resolution vs. energy histo
13781 TH2F* hAngresE=new TH2F("hAngresE","Archival data of observed reconstruction angle resolution vs. energy",
13782 nbe,xmin,xmax,nba,0,180.1);
13783 fBurstHistos.Add(hAngresE);
13784 hAngresE->GetXaxis()->SetTitle("^{10}log(Energy) in GeV");
13785 hAngresE->GetYaxis()->SetTitle("Angular resolution in degrees");
13786 }
13787
13788 // Get pointer to the relevant histogram
13789 TH2* hAngresE=(TH2*)fBurstHistos.FindObject("hAngresE");
13790
13791 Int_t nE=0;
13792 Double_t logE=0;
13793 Double_t dec=0;
13794 Double_t dang=0;
13795 TLeaf* lx=0;
13796 for (Int_t ien=0; ien<nen; ien++)
13797 {
13798 data.GetEntry(ien);
13799
13800 lx=data.GetLeaf(name1.Data());
13801 if (!lx) continue;
13802
13803 logE=lx->GetValue();
13804
13805 lx=data.GetLeaf(name2.Data());
13806 if (!lx) continue;
13807
13808 dang=lx->GetValue();
13809
13810 // Convert declination to degrees if needed
13811 dang=ConvertAngle(dang,ua,"deg");
13812
13813 lx=data.GetLeaf(name3.Data());
13814 if (!lx) continue;
13815
13816 dec=lx->GetValue();
13817
13818 // Convert declination to degrees if needed
13819 dec=ConvertAngle(dec,ud,"deg");
13820
13821 if (dec>=fDeclmin && dec<=fDeclmax)
13822 {
13823 hAngresE->Fill(logE,dang);
13824 nE++;
13825 }
13826 }
13827
13828 cout << " *" << ClassName() << "::MakeBurstRecoAngresdist* " << nE << " archival entries have been obtained for variables:" << name2
13829 << " vs. " << name1 << " of Tree:" << tree << " in file(s):" << file << endl;
13830}
13831
13832Double_t NcAstrolab::GetBurstSignalEnergy(Double_t Emin,Double_t Emax) const
13833{
13851
13852 Double_t E=-1;
13853
13854 // Get pointer to the relevant histogram
13855 TH1* hSigEprofile=(TH1*)fBurstHistos.FindObject("hSigEprofile");
13856
13857 if (!hSigEprofile) return E;
13858
13859 Int_t nbins=hSigEprofile->GetNbinsX();
13860 Int_t nentries=hSigEprofile->GetEntries();
13861
13862 if (nbins<=0 || nentries<=0) return E;
13863
13864 TAxis* xaxis=hSigEprofile->GetXaxis();
13865
13866 if (!xaxis) return E;
13867
13868 Double_t xlow=xaxis->GetBinLowEdge(1);
13869 Double_t xup=xaxis->GetBinUpEdge(nbins);
13870
13871 Double_t logEmin=0;
13872 if (Emin<=0)
13873 {
13874 logEmin=xlow;
13875 }
13876 else
13877 {
13878 logEmin=log10(Emin);
13879 }
13880
13881 Double_t logEmax=0;
13882 if (Emax<=0)
13883 {
13884 logEmax=xup;
13885 }
13886 else
13887 {
13888 logEmax=log10(Emax);
13889 }
13890
13891 if (logEmax<=logEmin || logEmin>=xup || logEmax<=xlow) return E;
13892
13893 while (E<logEmin || E>logEmax)
13894 {
13895 E=hSigEprofile->GetRandom();
13896 }
13897
13898 E=pow(float(10),E);
13899
13900 return E;
13901}
13902
13903Double_t NcAstrolab::GetBurstBackgroundEnergy(Double_t Emin,Double_t Emax) const
13904{
13922
13923 Double_t E=-1;
13924
13925 // Get pointer to the relevant histogram
13926 TH1* hBkgEprofile=(TH1*)fBurstHistos.FindObject("hBkgEprofile");
13927
13928 if (!hBkgEprofile) return E;
13929
13930 Int_t nbins=hBkgEprofile->GetNbinsX();
13931 Int_t nentries=hBkgEprofile->GetEntries();
13932
13933 if (nbins<=0 || nentries<=0) return E;
13934
13935 TAxis* xaxis=hBkgEprofile->GetXaxis();
13936
13937 if (!xaxis) return E;
13938
13939 Double_t xlow=xaxis->GetBinLowEdge(1);
13940 Double_t xup=xaxis->GetBinUpEdge(nbins);
13941
13942 Double_t logEmin=0;
13943 if (Emin<=0)
13944 {
13945 logEmin=xlow;
13946 }
13947 else
13948 {
13949 logEmin=log10(Emin);
13950 }
13951
13952 Double_t logEmax=0;
13953 if (Emax<=0)
13954 {
13955 logEmax=xup;
13956 }
13957 else
13958 {
13959 logEmax=log10(Emax);
13960 }
13961
13962 if (logEmax<=logEmin || logEmin>=xup || logEmax<=xlow) return E;
13963
13964 while (E<logEmin || E>logEmax)
13965 {
13966 E=hBkgEprofile->GetRandom();
13967 }
13968
13969 E=pow(float(10),E);
13970
13971 return E;
13972}
13973
13974Double_t NcAstrolab::GetBurstRecoAngres(Double_t Emin,Double_t Emax,Double_t Amin,Double_t Amax) const
13975{
13999
14000 Double_t dang=-1;
14001
14002 if (Amin<0) Amin=0;
14003
14004 Int_t fRecoangle=TMath::Nint(fBurstParameters->GetSignal("Recoangle"));
14005 Float_t fAngresfix=fBurstParameters->GetSignal("Angresfix");
14006
14007 // The user requested a fixed angular resolution value "Angresfix"
14008 if (!fRecoangle)
14009 {
14010 dang=fAngresfix;
14011 return dang;
14012 }
14013
14014 // The user requested an angular resolution based on a distribution
14015
14016 // Get pointer to the reco angle resolution vs. energy distribution histogram
14017 TH2* hAngresE=(TH2*)fBurstHistos.FindObject("hAngresE");
14018
14019 // No distribution available -> Return the user provided "Angresfix" value
14020 if (!hAngresE)
14021 {
14022 dang=fAngresfix;
14023 return dang;
14024 }
14025
14026 // Obtain the projected reco angle resolution distribution within the [Emin,Emax] interval
14027
14028 Int_t nbins=hAngresE->GetNbinsX();
14029 Int_t nentries=hAngresE->GetEntries();
14030
14031 if (nbins<=0 || nentries<=0) return dang;
14032
14033 TAxis* xaxis=hAngresE->GetXaxis();
14034
14035 if (!xaxis) return dang;
14036
14037 Double_t xlow=xaxis->GetBinLowEdge(1);
14038 Double_t xup=xaxis->GetBinUpEdge(nbins);
14039
14040 Double_t logEmin=0;
14041 if (Emin<=0)
14042 {
14043 logEmin=xlow;
14044 }
14045 else
14046 {
14047 logEmin=log10(Emin);
14048 }
14049
14050 Double_t logEmax=0;
14051 if (Emax<=0)
14052 {
14053 logEmax=xup;
14054 }
14055 else
14056 {
14057 logEmax=log10(Emax);
14058 }
14059
14060 if (logEmax<logEmin || logEmin>=xup || logEmax<=xlow) return dang;
14061
14062 Int_t ilow=xaxis->FindBin(logEmin);
14063 Int_t iup=xaxis->FindBin(logEmax);
14064
14065 TH1D* hproj=hAngresE->ProjectionY("hproj",ilow,iup);
14066
14067 if (!hproj) return dang;
14068
14069 nbins=hproj->GetNbinsX();
14070 nentries=hproj->GetEntries();
14071
14072 if (nbins<=0 || nentries<=0) return dang;
14073
14074 if (fRecoangle==1) dang=hproj->GetMean();
14075
14076 if (fRecoangle==2)
14077 {
14078 NcSample q;
14079 dang=q.GetMedian(hproj);
14080 }
14081
14082 if (fRecoangle==3)
14083 {
14084 xaxis=hproj->GetXaxis();
14085
14086 if (!xaxis) return dang;
14087
14088 xlow=xaxis->GetBinLowEdge(1);
14089 xup=xaxis->GetBinUpEdge(nbins);
14090
14091 if (Amax<=Amin || Amin>=xup || Amax<=xlow) return dang;
14092
14093 dang=Amin-1.;
14094 while (dang<Amin || dang>Amax)
14095 {
14096 dang=hproj->GetRandom();
14097 }
14098 }
14099
14100 if (hproj) delete hproj;
14101
14102 return dang;
14103}
14104
14106{
14125
14126 // Signal and background generation can only be performed for a user defined fixed time window size
14127 Float_t fTmin=fBurstParameters->GetSignal("Tmin");
14128 Float_t fTmax=fBurstParameters->GetSignal("Tmax");
14129 if (fTmax<=fTmin)
14130 {
14131 printf("\n *%-s::GenBurstSignals* Error : [Tmin,Tmax]=[%-g,%-g] whereas Tmin<Tmax is required. \n",ClassName(),fTmin,fTmax);
14132 return;
14133 }
14134
14135 // If needed, initialise the randomiser with a "date/time driven" seed
14136 // using the timestamp of the moment of this invokation of the member function.
14137 // This will ensure different random sequences if the user repeats analyses
14138 // with identical measurements and reference signals without explicit initialisation
14139 // of the randomiser by the user at the start of the analysis.
14140 if (!fRan) fRan=new NcRandom(-1);
14141
14143 // Initialise the final sample histograms //
14145
14147
14148 // Retrieve the needed parameters
14149 Float_t fRAmin=fBurstParameters->GetSignal("RAmin");
14150 Float_t fRAmax=fBurstParameters->GetSignal("RAmax");
14151 Float_t fDeclmin=fBurstParameters->GetSignal("Declmin");
14152 Float_t fDeclmax=fBurstParameters->GetSignal("Declmax");
14153 Float_t fOmegaDecl=fBurstParameters->GetSignal("OmegaDecl");
14154 Float_t fTimres=fBurstParameters->GetSignal("Timres");
14155 Int_t fEzcor=TMath::Nint(fBurstParameters->GetSignal("Ezcor"));
14156 Int_t fPDFsigE=TMath::Nint(fBurstParameters->GetSignal("PDFsigE"));
14157 Float_t fEmin=fBurstParameters->GetSignal("Emin");
14158 Float_t fEmax=fBurstParameters->GetSignal("Emax");
14159 Int_t fKinangle=TMath::Nint(fBurstParameters->GetSignal("Kinangle"));
14160 Float_t fAngresmin=fBurstParameters->GetSignal("Angresmin");
14161 Float_t fAngresmax=fBurstParameters->GetSignal("Angresmax");
14162 Float_t fAngresfix=fBurstParameters->GetSignal("Angresfix");
14163 Int_t fRecoangle=TMath::Nint(fBurstParameters->GetSignal("Recoangle"));
14164 Int_t fSumsigmas=TMath::Nint(fBurstParameters->GetSignal("Sumsigmas"));
14165 Float_t fTfact=fBurstParameters->GetSignal("Tfact");
14166 Float_t fDtwin=fBurstParameters->GetSignal("Dtwin");
14167 Float_t fDawin=fBurstParameters->GetSignal("Dawin");
14168 Int_t fDatype=TMath::Nint(fBurstParameters->GetSignal("Datype"));
14169 Float_t fGrbnu=fBurstParameters->GetSignal("Grbnu");
14170 Int_t fInburst=TMath::Nint(fBurstParameters->GetSignal("Inburst"));
14171 Float_t fDtnu=fBurstParameters->GetSignal("Dtnu");
14172 Float_t fDtnus=fBurstParameters->GetSignal("Dtnus");
14173 Int_t fNbkg=TMath::Nint(fBurstParameters->GetSignal("Nbkg"));
14174 Int_t fDweight=TMath::Nint(fBurstParameters->GetSignal("Dweight"));
14175 Float_t fDweightSum=fBurstParameters->GetSignal("DweightSum");
14176
14177 // Deactivate redshift correction for source signal events from archival observed data
14178 if (!fPDFsigE)
14179 {
14180 fEzcor=0;
14181 fBurstParameters->SetSignal(0,"Ezcor");
14182 }
14183
14184 // Derived parameters
14185 Float_t fMaxsigmatot=fBurstParameters->GetSignal("Maxsigmatot");
14186 Float_t fNbkgWin=fBurstParameters->GetSignal("NbkgWin");
14187
14189 // Some Burst statistics from the loaded data //
14191
14192 Int_t fNgrbs=GetNsignals(0);
14193
14194 TH1* hSigmaReco=(TH1*)fBurstHistos.FindObject("hSigmaReco");
14195 TH1* hSigE=(TH1*)fBurstHistos.FindObject("hSigE");
14196 TH1* hSigEzcor=(TH1*)fBurstHistos.FindObject("hSigEzcor");
14197 TH2* hAeffProfile=(TH2*)fBurstHistos.FindObject("hAeffProfile");
14198 TH2* hSigNuCountProfile=(TH2*)fBurstHistos.FindObject("hSigNuCountProfile");
14199 TH2* hBkgNuCountProfile=(TH2*)fBurstHistos.FindObject("hBkgNuCountProfile");
14200
14202 // Generation of the signal and background observations //
14203 // based on the provided user settings //
14205
14206 NcSignal* sx=0;
14207 Float_t zgrb=0;
14208 Double_t dgrb=0;
14209 Float_t t90grb=0;
14210 Float_t sigmagrb=0;
14211 NcPosition rgrb;
14212 Float_t nbkg=0; // The mean number of recordable background events in the time window for the treated GRB
14213 Float_t nsig=0; // The mean number of recordable signal events for the treated GRB
14214 Float_t dweight=1; // Distance weight for the observed Fluence or Flux from the treated GRB
14215 Int_t nmu;
14216 Double_t thetagrb,phigrb;
14217 Double_t dmu,thetamu,phimu;
14218 Float_t dt=0;
14219 NcPosition rgrb2; // Unknown actual GRB position from which the neutrinos/muons arrive
14220 NcPosition rmu;
14221 Float_t dang;
14222 Float_t dangmax=0;
14223 Float_t dangmaxon=0;
14224 Float_t dangmaxoff=0;
14225 Float_t thlow,thup;
14226 Float_t ranlow,ranup;
14227 Int_t nmugrb=0;
14228 NcTimestamp* tx=0;
14229 NcTimestamp tmu;
14230 Float_t solidangle=0;
14231 Float_t ramu,decmu; // Temporary RA and DEC of muon for background creation
14232 Double_t E=0;
14233 Double_t ang=0;
14234 Double_t sigmareco=0;
14235 Float_t sigmatot=0;
14236 TString name;
14237 Int_t fixedwinset=0; // Flag to indicate whether a fixed angular search window is set (1) or not (0) for this burst
14238
14239 // Storage for total on-source and off-source observed and signal injected energies
14240 fBurstParameters->AddNamedSlot("EnergyOn");
14241 fBurstParameters->AddNamedSlot("EnergyOff");
14242 fBurstParameters->AddNamedSlot("EnergySig");
14243
14244 // The bin numbers and Aeff value in the AeffProfile for the (E,theta) of the track
14245 Int_t nbinsA=0;
14246 if (hAeffProfile) nbinsA=(hAeffProfile->GetNbinsX())*(hAeffProfile->GetNbinsY());
14247 Double_t Aeff=0;
14248 Double_t Fluence=0;
14249
14250 TAxis* xaxis=0;
14251 TAxis* yaxis=0;
14252 Int_t nbinsx=0;
14253 Int_t nbinsy=0;
14254 Int_t xbin=0;
14255 Int_t ybin=0;
14256 Int_t zbin=0;
14257 Int_t gbin=0; // The global bin number in the histogram
14258 Float_t LogElow=0;
14259 Float_t LogEup=0;
14260 Float_t elow=0;
14261 Float_t eup=0;
14262 Float_t CosZenlow=0;
14263 Float_t CosZenup=0;
14264 Float_t CosZen=0;
14265
14266 Double_t pi=acos(-1.);
14267
14268 // Loop over the (fictative) GRB space-time positions in the declination acceptance
14269 for (Int_t igrb=0; igrb<fNgrbs; igrb++)
14270 {
14271 sx=GetSignal(igrb+1);
14272
14273 if (!sx) continue;
14274
14275 tx=sx->GetTimestamp();
14276 zgrb=sx->GetSignal("z");
14277 t90grb=sx->GetSignal("T90");
14278 sigmagrb=sx->GetSignal("csigma");
14279
14280 dangmax=-1;
14281 if (!fDatype) dangmax=fabs(fDawin);
14282 if (fDatype==1)
14283 {
14284 dangmax=0;
14285 if (fMaxsigmatot>0) dangmax=fabs(fDawin*fMaxsigmatot);
14286 }
14287
14288 if (fDatype==2)
14289 {
14290 if (!fSumsigmas) dangmax=fabs(fDawin*sigmagrb);
14291 if (!fRecoangle)
14292 {
14293 sigmatot=-1;
14294 if (fSumsigmas==-1) sigmatot=fAngresfix;
14295 if (fSumsigmas==1) sigmatot=sigmagrb+fAngresfix;
14296 if (fSumsigmas==2) sigmatot=sqrt(sigmagrb*sigmagrb+fAngresfix*fAngresfix);
14297 if (sigmatot>=0) dangmax=fabs(fDawin*sigmatot);
14298 }
14299 }
14300
14301 fixedwinset=1;
14302 if (dangmax<0) fixedwinset=0;
14303
14304 // Indicate incompatible input for sigma summation
14305 if (fDatype==1 && fMaxsigmatot<0) dangmax=-1;
14306
14307 // New signal slots for storage of maximum angular differences and corresponding solid angles
14308 name="fixedwinset";
14309 sx->AddNamedSlot(name);
14310 sx->SetSignal(fixedwinset,name);
14311 name="dangmaxOn";
14312 sx->AddNamedSlot(name);
14313 sx->SetSignal(-1,name);
14314 name="dangmaxOff";
14315 sx->AddNamedSlot(name);
14316 sx->SetSignal(-1,name);
14317 name="OmegaOn";
14318 sx->AddNamedSlot(name);
14319 sx->SetSignal(0,name);
14320 name="OmegaOff";
14321 sx->AddNamedSlot(name);
14322 sx->SetSignal(0,name);
14323
14324 // Store the On-source and Off-source maximum (solid) angles for this burst
14325 if (fixedwinset && dangmax>=0)
14326 {
14327 if (fDawin<0) // Local zenith band centered at the GRB position at its trigger time
14328 {
14329 GetSignal(dgrb,thetagrb,"deg",phigrb,"deg","loc",tx,igrb+1);
14330 thlow=thetagrb-0.5*dangmax;
14331 thup=thetagrb+0.5*dangmax;
14332 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
14333 }
14334 else // Circle around GRB position
14335 {
14336 thlow=0;
14337 thup=dangmax;
14338 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
14339 }
14340 sx->SetSignal(dangmax,"dangmaxOn");
14341 sx->SetSignal(solidangle,"OmegaOn");
14342 sx->SetSignal(dangmax,"dangmaxOff");
14343 sx->SetSignal(solidangle*float(fNbkg),"OmegaOff");
14344 }
14345 else // Initialize the encountered dynamic On-source and Off-source maximum angles for this burst
14346 {
14347 dangmaxon=0;
14348 if (fSumsigmas==0 || fSumsigmas==1 || fSumsigmas==2) dangmaxon=fabs(fDawin*sigmagrb);
14349 dangmaxoff=dangmaxon;
14350 }
14351
14352 // Generate the background events in the search time window
14353 // for both this GRB angular cone and the corresponding background bkg patch(es)
14354 for (Int_t bkgpatch=0; bkgpatch<=fNbkg; bkgpatch++)
14355 {
14356
14357 if (fBkgEmode=="BkgE") // Background rate set via user provided burst parameter "Bkgrate"
14358 {
14359 nmu=int(fRan->Poisson(fNbkgWin)); // nmu is the number of backgound events in the time window
14360 // Use the full energy range as provided by the user
14361 elow=-1;
14362 eup=-1;
14363 nbkg=1;
14364 }
14365 else // Neutrino background strength set via user provided Fluence, Flux or Intensity
14366 {
14367 xaxis=0;
14368 yaxis=0;
14369 nbinsx=0;
14370 nbinsy=0;
14371 if (hBkgNuCountProfile)
14372 {
14373 xaxis=hBkgNuCountProfile->GetXaxis();
14374 yaxis=hBkgNuCountProfile->GetYaxis();
14375 nbinsx=xaxis->GetNbins();
14376 nbinsy=yaxis->GetNbins();
14377 }
14378 nmu=nbinsx*nbinsy; // nmu will loop over all the cos(theta) vs. energy bins
14379 }
14380
14381 for (Int_t imu=0; imu<nmu; imu++)
14382 {
14383 // Check for a possible background event in case a Fluence, Flux or Intensity was specified
14384 if (fBkgEmode!="BkgE" && hBkgNuCountProfile)
14385 {
14386 // Investigate whether one or more background events will result at this (energy,theta) location
14387 gbin=imu+1;
14388 nbkg=hBkgNuCountProfile->GetBinContent(gbin);
14389
14390 if (nbkg<=0) continue;
14391
14392 // Obtain the corresponding X-axis and Y-axis bins
14393 hBkgNuCountProfile->GetBinXYZ(gbin,xbin,ybin,zbin);
14394
14395 // Boundaries of this Log(energy) bin to provide a random energy below
14396 LogElow=xaxis->GetBinLowEdge(xbin);
14397 LogEup=xaxis->GetBinUpEdge(xbin);
14398 elow=pow(10,LogElow);
14399 eup=pow(10,LogEup);
14400
14401 // Boundaries of this cos(zenith) bin to provide a random theta below
14402 CosZenlow=yaxis->GetBinLowEdge(ybin);
14403 CosZenup=yaxis->GetBinUpEdge(ybin);
14404
14405 // A steady flux is assumed during the complete obervation time
14406 if (fBkgEmode!="BkgS") nbkg=nbkg*fDtwin*fTfact;
14407
14408 // An isotropic diffuse flux is assumed when an Intensity was specified
14409 if (fBkgEmode=="BkgI") nbkg=nbkg*fOmegaDecl;
14410
14411 // Allow Poisson fluctuations
14412 if (nbkg>0) nbkg=fRan->Poisson(nbkg);
14413 }
14414
14415 // Process all background events for this (energy,theta) location in the CountProfile
14416 // or just the next of "nmu" background events as provided via the burst parameter "Bkgrate"
14417 for (Int_t ibkg=0; ibkg<int(nbkg); ibkg++)
14418 {
14419 // The energy of the background signal
14420 E=GetBurstBackgroundEnergy(elow,eup);
14421
14422 if (E<0 || E<fEmin || E>fEmax) continue;
14423
14424 // Obtain a random event time within the search time window
14425 ranlow=fTmin;
14426 ranup=fTmax;
14427 dt=fRan->Uniform(ranlow,ranup);
14428 tmu=*tx;
14429 tmu.AddSec(dt*fTfact);
14430
14431 if (fBkgEmode=="BkgE")
14432 {
14433 // Create a random background event within the user selected burst RA and Dec interval
14434 // and convert to local detector coordinates.
14435 // For the conversion, a single, re-usable temp. reference signal will be created, since measurements may get scrambled when stored.
14436 thlow=90.-fDeclmax; // Lower theta angle in overall Earth spherical coordinates (North Pole is theta=0)
14437 thup=90.-fDeclmin; // Upper theta angle in overall Earth spherical coordinates (North Pole is theta=0)
14438 RandomPosition(rmu,thlow,thup,fRAmin,fRAmax);
14439 decmu=90.-rmu.GetX(2,"sph","deg");
14440 ramu=rmu.GetX(3,"sph","deg");
14441 SetSignal(1,ramu,"deg",decmu,"deg","equ",&tmu,fNgrbs+1,"J","bkgtemp",0);
14442 GetSignal(dmu,thetamu,"deg",phimu,"deg","loc",&tmu,fNgrbs+1);
14443 }
14444 else
14445 {
14446 // Create a background event in local coordinates at this cos(zenith) position
14447 CosZen=fRan->Uniform(CosZenlow,CosZenup);
14448 thetamu=acos(CosZen)*180./pi;
14449 phimu=fRan->Uniform(0.,2.*pi);
14450 }
14451
14452 rmu.SetPosition(1,thetamu,phimu,"sph","deg");
14453
14454 if (fDawin<0) // Local zenith band centered at the GRB position at its trigger time
14455 {
14456 dang=fabs(thetagrb-thetamu);
14457 }
14458 else // Circle around the GRB local position at the muon observation time
14459 {
14460 GetSignal(dgrb,thetagrb,"deg",phigrb,"deg","loc",&tmu,igrb+1);
14461 rgrb.SetPosition(1,thetagrb,phigrb,"sph","deg");
14462 dang=rgrb.GetOpeningAngle(rmu,"deg");
14463 }
14464
14465 // Check if event lies outside the allowed angular area
14466 if (fDatype>=0 && fixedwinset && dang>dangmax) continue;
14467
14468 // The reconstruction angular resolution of the background signal
14469 sigmareco=GetBurstRecoAngres(E,E);
14470 if (sigmareco<0) sigmareco=fAngresfix;
14471
14472 if (sigmareco<fAngresmin || sigmareco>fAngresmax) continue;
14473
14474 if (hSigmaReco) hSigmaReco->Fill(sigmareco);
14475
14476 sigmatot=-1;
14477 if (fSumsigmas==-1) sigmatot=sigmareco;
14478 if (fSumsigmas==0) sigmatot=sigmagrb;
14479 if (fSumsigmas==1) sigmatot=sigmagrb+sigmareco;
14480 if (fSumsigmas==2) sigmatot=sqrt(sigmagrb*sigmagrb+sigmareco*sigmareco);
14481
14482 // Determine the dynamic angular window including the track reco uncertainty
14483 if (!fixedwinset)
14484 {
14485 dangmax=-1;
14486 if (sigmatot>=0) dangmax=fabs(fDawin*sigmatot);
14487 }
14488
14489 if (fDatype>=0 && dang>dangmax) continue;
14490
14491 if (!bkgpatch) // On-source patch
14492 {
14493 if (dangmax>dangmaxon) dangmaxon=dangmax;
14494 fBurstOnReco.Enter(zgrb,sigmagrb,sigmareco,sigmatot);
14495 fBurstOnMatch.Enter(E,dt,dang,dt/(zgrb+1.));
14496 fBurstParameters->AddSignal(E,"EnergyOn");
14497 if (hAeffProfile)
14498 {
14499 thetamu=rmu.GetX(2,"sph","rad");
14500 gbin=hAeffProfile->FindFixBin(log10(E),cos(thetamu));
14501 if (gbin>0 && gbin<nbinsA+1)
14502 {
14503 Aeff=hAeffProfile->GetBinContent(gbin);
14504 if (Aeff>0)
14505 {
14506 Fluence=1./Aeff;
14507 fBurstOnAeff.Enter(Aeff,Fluence,E,dang);
14508 }
14509 }
14510 }
14511 }
14512 else // Off-source patch
14513 {
14514 if (dangmax>dangmaxoff) dangmaxoff=dangmax;
14515 fBurstOffReco.Enter(zgrb,sigmagrb,sigmareco,sigmatot);
14516 fBurstOffMatch.Enter(E,dt,dang,dt/(zgrb+1.));
14517 fBurstParameters->AddSignal(E,"EnergyOff");
14518 if (hAeffProfile)
14519 {
14520 thetamu=rmu.GetX(2,"sph","rad");
14521 gbin=hAeffProfile->FindFixBin(log10(E),cos(thetamu));
14522 if (gbin>0 && gbin<nbinsA+1)
14523 {
14524 Aeff=hAeffProfile->GetBinContent(gbin);
14525 if (Aeff>0)
14526 {
14527 Fluence=1./Aeff;
14528 fBurstOffAeff.Enter(Aeff,Fluence,E,dang);
14529 }
14530 }
14531 }
14532 }
14533 } // End of nbkg loop
14534 } // End of background nmu
14535 } // End of loop over the patches for recording background events
14536
14537 // Generate the GRB related signal event(s) in the search window.
14538 // The GRB position gets Gaussian smeared to reflect the actual position.
14539 // The time difference between the gammas and the neutrinos gets corrected
14540 // for the GRB redshift and smeared by the detector time resolution.
14541 // The muon direction gets modified to account for the kinematical opening angle
14542 // w.r.t. the neutrino direction and Gaussian smeared by the detector angular resolution.
14543
14544 // Prevent statistical overfluctuation in number of GRB signal events if requested by fGrbnu<0
14545 if ((fSigEmode=="SigE" && (fGrbnu>=0 || nmugrb<int(fabs(fGrbnu)*float(fNgrbs)))) || fSigEmode!="SigE")
14546 {
14547 // The real GRB position
14548
14549 if (fSigEmode=="SigE") // Signal strength set via user provided burst parameter "Grbnu"
14550 {
14551 // nsig is the average number of signal events for this burst
14552 nsig=fabs(fGrbnu);
14553
14554 // Apply Poisson fluctuations, if selected by the user
14555 if (fGrbnu>0) nsig=fRan->Poisson(nsig);
14556
14557 nmu=int(nsig);
14558 if (nsig>0 && !nmu && fRan->Uniform()<fabs(fGrbnu)) nmu=1;
14559
14560 // Use the full energy range as provided by the user
14561 elow=-1;
14562 eup=-1;
14563 nsig=1;
14564 GetSignal(dgrb,thetagrb,"deg",phigrb,"deg","loc",tx,igrb+1); //$$$$$$$$$$$
14565 }
14566 else // Signal strength set via user provided Fluence, Flux or Intensity
14567 {
14568 xaxis=0;
14569 yaxis=0;
14570 nbinsx=0;
14571 nbinsy=0;
14572 if (hSigNuCountProfile)
14573 {
14574 xaxis=hSigNuCountProfile->GetXaxis();
14575 yaxis=hSigNuCountProfile->GetYaxis();
14576 nbinsx=xaxis->GetNbins();
14577 nbinsy=yaxis->GetNbins();
14578 }
14579 nmu=nbinsx; // nmu will loop over all the energy bins for this GRB at the corresponding theta position
14580
14581 // Obtain the GRB position in local coordinates at the signal detection time
14582 if (!fInburst) // Neutrino and gamma production decoupled
14583 {
14584 dt=fDtnu;
14585 dt=dt*(zgrb+1.);
14586 }
14587 else // Coupled neutrino and gamma production
14588 {
14589 dt=fDtnu*t90grb;
14590 }
14591 tmu=*tx;
14592 tmu.AddSec(dt);
14593 GetSignal(dgrb,thetagrb,"deg",phigrb,"deg","loc",&tmu,igrb+1);
14594 }
14595
14596 rgrb.SetPosition(1,thetagrb,phigrb,"sph","deg");
14597
14598 // The real GRB position (rgrb2) in local coordinates
14599 rgrb2.Load(rgrb);
14600 SmearPosition(rgrb2,sigmagrb);
14601
14602 for (Int_t imu=0; imu<nmu; imu++)
14603 {
14604 // Check for possible signal in case a Fluence, Flux or Intensity was specified
14605 if (fSigEmode!="SigE" && hSigNuCountProfile)
14606 {
14607 ybin=yaxis->FindFixBin(cos(thetagrb*pi/180.));
14608 if (ybin<1 || ybin>nbinsy) continue;
14609
14610 // Investigate whether a signal will result at this energy
14611 nsig=hSigNuCountProfile->GetBinContent(imu+1,ybin);
14612
14613 if (nsig<=0) continue;
14614
14615 // Boundaries of this energy bin to provide a random energy below
14616 elow=xaxis->GetBinLowEdge(imu+1);
14617 eup=xaxis->GetBinUpEdge(imu+1);
14618 elow=pow(10,elow);
14619 eup=pow(10,eup);
14620
14621 // A steady flux is assumed during the complete obervation time
14622 if (fSigEmode!="SigS") nsig=nsig*fDtwin*fTfact;
14623
14624 // An isotropic diffuse flux is assumed when an Intensity was specified
14625 if (fSigEmode=="SigI") nsig=nsig*fOmegaDecl;
14626
14627 // Apply a distance weight, if requested by the user
14628 if (fDweight && fDweightSum>0)
14629 {
14630 dweight=sx->GetSignal("Dweight");
14631 nsig=nsig*float(fNgrbs)*dweight/fDweightSum;
14632 }
14633
14634 // Apply Poisson fluctuations, if selected by the user
14635 if (nsig>0 && fGrbnu>0) nsig=fRan->Poisson(nsig);
14636
14637 if (nsig>0 && nsig<1)
14638 {
14639 if (fRan->Uniform()<nsig) nsig=1;
14640 }
14641 }
14642
14643 // Process all signal events for this (energy,theta) location in the CountProfile
14644 // or just the next of "nmu" signal events as provided via the burst parameter "Grbnu"
14645 for (Int_t isig=0; isig<int(nsig); isig++)
14646 {
14647 if (!fInburst) // Neutrino and gamma production decoupled
14648 {
14649 if (fDtnus<0) // Sigma in units of T90
14650 {
14651 dt=fRan->Gauss(fDtnu,fabs(fDtnus)*t90grb);
14652 }
14653 else // Sigma in seconds
14654 {
14655 dt=fRan->Gauss(fDtnu,fDtnus);
14656 }
14657 dt=dt*(zgrb+1.);
14658 }
14659 else // Coupled neutrino and gamma production
14660 {
14661 if (fDtnus<0) // Sigma in units of T90
14662 {
14663 dt=fRan->Gauss(fDtnu*t90grb,fabs(fDtnus)*t90grb);
14664 }
14665 else // Sigma in seconds
14666 {
14667 dt=fRan->Gauss(fDtnu*t90grb,fDtnus);
14668 }
14669 }
14670 if (fTimres>0) dt=fRan->Gauss(dt,fTimres);
14671
14672 // Convert dt from seconds to the selected Tunit
14673 dt=dt/fTfact;
14674
14675 // The real direction of the GRB signal
14676 rmu.Load(rgrb2);
14677
14678 // Obtain a random energy from the GRB signal energy profile
14679 E=GetBurstSignalEnergy(elow,eup);
14680
14681 nmugrb++;
14682
14683 if (fSigEmode=="SigE")
14684 {
14685 // Injected energy at the source
14686 if (hSigE) hSigE->Fill(E);
14687
14688 // Reduce the energy due to the cosmological redshift effect
14689 if (fEzcor) E=E/(zgrb+1.);
14690 }
14691
14692 if (hSigEzcor) hSigEzcor->Fill(E);
14693
14694 if (E<0 || E<fEmin || E>fEmax) continue;
14695
14696 // Modification to account for the neutrino-lepton kinematic opening angle
14697 if (fKinangle>0)
14698 {
14699 Int_t mode=fKinangle-1;
14700 ang=GetNeutrinoAngle(E,"deg",mode);
14701 if (ang>0) ShiftPosition(rmu,ang);
14702 }
14703
14704 // Smearing according to the reconstruction angular resolution
14705 sigmareco=GetBurstRecoAngres(E,E);
14706 if (sigmareco<0) sigmareco=fAngresfix;
14707
14708 if (sigmareco<fAngresmin || sigmareco>fAngresmax) continue;
14709
14710 if (hSigmaReco) hSigmaReco->Fill(sigmareco);
14711
14712 SmearPosition(rmu,sigmareco);
14713
14714 // Determine angular difference w.r.t. the presumed GRB position
14715 dang=rgrb.GetOpeningAngle(rmu,"deg");
14716
14717 sigmatot=-1;
14718 if (fSumsigmas==-1) sigmatot=sigmareco;
14719 if (fSumsigmas==0) sigmatot=sigmagrb;
14720 if (fSumsigmas==1) sigmatot=sigmagrb+sigmareco;
14721 if (fSumsigmas==2) sigmatot=sqrt(sigmagrb*sigmagrb+sigmareco*sigmareco);
14722
14723 // Determine the dynamic angular window including the track reco uncertainty
14724 if (!fixedwinset)
14725 {
14726 dangmax=-1;
14727 if (sigmatot>=0) dangmax=fabs(fDawin*sigmatot);
14728 }
14729
14730 if (fDatype>=0 && dang>dangmax) continue;
14731
14732 if (dangmax>dangmaxon) dangmaxon=dangmax;
14733 fBurstOnReco.Enter(zgrb,sigmagrb,sigmareco,sigmatot);
14734 fBurstOnMatch.Enter(E,dt,dang,dt/(zgrb+1.));
14735 fBurstSigReco.Enter(zgrb,sigmagrb,sigmareco,sigmatot);
14736 fBurstSignal.Enter(E,dt,dang,dt/(zgrb+1.));
14737 fBurstParameters->AddSignal(E,"EnergyOn");
14738 fBurstParameters->AddSignal(E,"EnergySig");
14739 if (hAeffProfile)
14740 {
14741 thetamu=rmu.GetX(2,"sph","rad");
14742 gbin=hAeffProfile->FindFixBin(log10(E),cos(thetamu));
14743 if (gbin>0 && gbin<nbinsA+1)
14744 {
14745 Aeff=hAeffProfile->GetBinContent(gbin);
14746 if (Aeff>0)
14747 {
14748 Fluence=1./Aeff;
14749 fBurstOnAeff.Enter(Aeff,Fluence,E,dang);
14750 fBurstSigAeff.Enter(Aeff,Fluence,E,dang);
14751 }
14752 }
14753 }
14754 } // End of nsig loop
14755 } // End of signal nmu loop
14756 } // End of processing of the signal events of this burst
14757
14758 if (fixedwinset) continue;
14759
14760 // Store the dynamic On-source and Off-source maximum (solid) angles that are encountered for this burst
14761 if (fDawin<0) // Local zenith band centered at the GRB position at its trigger time
14762 {
14763 GetSignal(dgrb,thetagrb,"deg",phigrb,"deg","loc",tx,igrb+1);
14764 thlow=thetagrb-0.5*dangmaxon;
14765 thup=thetagrb+0.5*dangmaxon;
14766 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
14767 sx->SetSignal(dangmaxon,"dangmaxOn");
14768 sx->SetSignal(solidangle,"OmegaOn");
14769 thlow=thetagrb-0.5*dangmaxoff;
14770 thup=thetagrb+0.5*dangmaxoff;
14771 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
14772 sx->SetSignal(dangmaxoff,"dangmaxOff");
14773 sx->SetSignal(solidangle*float(fNbkg),"OmegaOff");
14774 }
14775 else // Circle around GRB position
14776 {
14777 thlow=0;
14778 thup=dangmaxon;
14779 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
14780 sx->SetSignal(solidangle,"OmegaOn");
14781 sx->SetSignal(dangmaxon,"dangmaxOn");
14782 thup=dangmaxoff;
14783 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
14784 sx->SetSignal(dangmaxoff,"dangmaxOff");
14785 sx->SetSignal(solidangle*float(fNbkg),"OmegaOff");
14786 }
14787 } // End of loop over the individual GRBs
14788
14789 // Remove the temporary storage of the background event
14790 if (fNgrbs>0) RemoveSignal(fNgrbs+1,0,0);
14791
14792 // Compensate statistical underfluctuation in number of GRB signal events if requested by fGrbnu<0
14793 if (fGrbnu<0 && fSigEmode=="SigE") BurstCompensate(nmugrb);
14794
14795 // Determine the On-source and Off-source total stacked solid angles that have been encountered
14796 name="SolidangleOn";
14797 fBurstParameters->AddNamedSlot(name);
14798 fBurstParameters->SetSignal(0,name);
14799 name="SolidangleOff";
14800 fBurstParameters->AddNamedSlot(name);
14801 fBurstParameters->SetSignal(0,name);
14802 for (Int_t igrb=1; igrb<=fNgrbs; igrb++)
14803 {
14804 sx=GetSignal(igrb);
14805
14806 if (!sx) continue;
14807
14808 solidangle=sx->GetSignal("OmegaOn");
14809 fBurstParameters->AddSignal(solidangle,"SolidangleOn");
14810 solidangle=sx->GetSignal("OmegaOff");
14811 fBurstParameters->AddSignal(solidangle,"SolidangleOff");
14812 }
14813
14814 // Determine and list the burst statistics
14815 MakeBurstDataStats(0,nmugrb);
14816}
14817
14818void NcAstrolab::MakeBurstDataStats(Int_t mode,Int_t nmugrb)
14819{
14834
14835 Double_t pi=acos(-1.);
14836
14837 // Retrieve the needed parameters
14838 Int_t fNgrbs=TMath::Nint(fBurstParameters->GetSignal("Ngrbs"));
14839 Int_t fNbkg=TMath::Nint(fBurstParameters->GetSignal("Nbkg"));
14840 Int_t fTunits=TMath::Nint(fBurstParameters->GetSignal("Tunits"));
14841 Float_t fTfact=fBurstParameters->GetSignal("Tfact");
14842 Float_t fTmin=fBurstParameters->GetSignal("Tmin");
14843 Float_t fTmax=fBurstParameters->GetSignal("Tmax");
14844 Int_t fTbint90=TMath::Nint(fBurstParameters->GetSignal("Tbint90"));
14845 Float_t fTbin=fBurstParameters->GetSignal("Tbin");
14846 Float_t fVarTbin=fBurstParameters->GetSignal("VarTbin");
14847 Float_t fAbin=fBurstParameters->GetSignal("Abin");
14848 Float_t fAvgrbz=fBurstParameters->GetSignal("Avgrbz");
14849 Float_t fAvgrbt90=fBurstParameters->GetSignal("Avgrbt90");
14850 Float_t fRbkgDecl=fBurstParameters->GetSignal("RbkgDecl");
14851 Float_t fSolidangleOn=fBurstParameters->GetSignal("SolidangleOn");
14852 Float_t fSolidangleOff=fBurstParameters->GetSignal("SolidangleOff");
14853 Float_t fEnergyOn=fBurstParameters->GetSignal("EnergyOn");
14854 Float_t fEnergyOff=fBurstParameters->GetSignal("EnergyOff");
14855 Float_t fEnergySig=fBurstParameters->GetSignal("EnergySig");
14856 Float_t fEnergyBkg=fEnergyOn-fEnergySig;
14857 Float_t fSensarea=fBurstParameters->GetSignal("Sensarea");
14858 Float_t fOmegaDecl=fBurstParameters->GetSignal("OmegaDecl");
14859
14860 TString tu="days";
14861 if (fTunits==1) tu="hours";
14862 if (fTunits==2) tu="sec";
14863 if (fTunits==3) tu="ns";
14864 if (fTunits==4) tu="ps";
14865
14866 Int_t non=fBurstOnMatch.GetN();
14867 Int_t noff=fBurstOffMatch.GetN();
14868 Int_t nsig=fBurstSignal.GetN();
14869 Double_t TminOn=fTmin;
14870 Double_t TmaxOn=fTmax;
14871 Double_t TminOff=fTmin;
14872 Double_t TmaxOff=fTmax;
14873
14874 if (fTmax<=fTmin)
14875 {
14876 TminOn=fBurstOnMatch.GetMinimum("dtime");
14877 TmaxOn=fBurstOnMatch.GetMaximum("dtime");
14878 TminOff=fBurstOffMatch.GetMinimum("dtime");
14879 TmaxOff=fBurstOffMatch.GetMaximum("dtime");
14880 }
14881
14882 Double_t AminOn=fBurstOnMatch.GetMinimum("dang");
14883 Double_t AmaxOn=fBurstOnMatch.GetMaximum("dang");
14884 Double_t AminOff=fBurstOffMatch.GetMinimum("dang");
14885 Double_t AmaxOff=fBurstOffMatch.GetMaximum("dang");
14886
14887 // Update the time window sizes and the average number of background events in them
14888 Float_t DtwinOn=TmaxOn-TminOn;
14889 Float_t DtwinOff=TmaxOff-TminOff;
14890 Float_t NbkgWinOn=fRbkgDecl*DtwinOn*fTfact;
14891 Float_t NbkgWinOff=fRbkgDecl*DtwinOff*fTfact;
14892
14893 TString title;
14894 TString name;
14895 TString s;
14896 Float_t xmin=0;
14897 Float_t xmax=0;
14898 TAxis* axis=0;
14899 Int_t nbins=0;
14900 Double_t binsize=0;
14901 Double_t binsizecos=0;
14902 Int_t nabinsOn=0;
14903 Double_t abinsizeOn=0;
14904 Int_t nabinsOff=0;
14905 Double_t abinsizeOff=0;
14906
14907 // The source redshift, position and reconstruction uncertainty histograms
14908 TH1F* hOnSourceZ=0;
14909 TH1F* hOffSourceZ=0;
14910 TH1F* hOnSigSourceZ=0;
14911 TH1F* hOnSigmaSource=0;
14912 TH1F* hOffSigmaSource=0;
14913 TH1F* hOnSigSigmaSource=0;
14914 TH1F* hOnSigmaReco=0;
14915 TH1F* hOffSigmaReco=0;
14916 TH1F* hOnSigSigmaReco=0;
14917 TH1F* hOnSigmaComb=0;
14918 TH1F* hOffSigmaComb=0;
14919 TH1F* hOnSigSigmaComb=0;
14920 nbins=100;
14921 if (fBurstOnReco.GetN())
14922 {
14923 title.Form("On-Source object redshifts with matching event(s);Redshift;Counts");
14924 hOnSourceZ=new TH1F("hOnSourceZ",title,nbins,1,0);
14925 hOnSourceZ->SetBuffer(non);
14926
14927 title.Form("On-Source object position uncertainties with matching event(s);Object position angular uncertainty (sigma in degrees);Counts");
14928 hOnSigmaSource=new TH1F("hOnSigmaSource",title,nbins,1,0);
14929 hOnSigmaSource->SetBuffer(non);
14930
14931 title.Form("On-source event reconstruction uncertainties in the final sample;Event angular reconstruction uncertainty (sigma in degrees);Counts");
14932 hOnSigmaReco=new TH1F("hOnSigmaReco",title,nbins,1,0);
14933 hOnSigmaReco->SetBuffer(non);
14934
14935 title.Form("On-source combined object position and event reconstruction uncertainty;Combined object position and event reco angular uncertainty (sigma in degrees);Counts");
14936 hOnSigmaComb=new TH1F("hOnSigmaComb",title,nbins,1,0);
14937 hOnSigmaComb->SetBuffer(non);
14938 }
14939
14940 if (fBurstOffReco.GetN())
14941 {
14942 title.Form("Off-Source object redshifts with matching event(s);Redshift;Counts");
14943 hOffSourceZ=new TH1F("hOffSourceZ",title,nbins,1,0);
14944 hOffSourceZ->SetBuffer(noff);
14945
14946 title.Form("Off-Source object position uncertainties with matching event(s);Object position angular uncertainty (sigma in degrees);Counts");
14947 hOffSigmaSource=new TH1F("hOffSigmaSource",title,nbins,1,0);
14948 hOffSigmaSource->SetBuffer(noff);
14949
14950 title.Form("Off-source event reconstruction uncertainties in the final sample;Event angular reconstruction uncertainty (sigma in degrees);Counts");
14951 hOffSigmaReco=new TH1F("hOffSigmaReco",title,nbins,1,0);
14952 hOffSigmaReco->SetBuffer(noff);
14953
14954 title.Form("Off-source combined object position and event reconstruction uncertainty;Combined object position and event reco angular uncertainty (sigma in degrees);Counts");
14955 hOffSigmaComb=new TH1F("hOffSigmaComb",title,nbins,1,0);
14956 hOffSigmaComb->SetBuffer(noff);
14957 }
14958
14959 if (fBurstSigReco.GetN())
14960 {
14961 title.Form("On-Source object redshifts with matching simulated signal event(s);Redshift;Counts");
14962 hOnSigSourceZ=new TH1F("hOnSigSourceZ",title,nbins,1,0);
14963 hOnSigSourceZ->SetBuffer(nsig);
14964
14965 title.Form("On-Source object position uncertainties with matching simulated signal event(s);Object position angular uncertainty (sigma in degrees);Counts");
14966 hOnSigSigmaSource=new TH1F("hOnSigSigmaSource",title,nbins,1,0);
14967 hOnSigSigmaSource->SetBuffer(nsig);
14968
14969 title.Form("On-source simulated signal event reconstruction uncertainties in the final sample;Event angular reconstruction uncertainty (sigma in degrees);Counts");
14970 hOnSigSigmaReco=new TH1F("hOnSigSigmaReco",title,nbins,1,0);
14971 hOnSigSigmaReco->SetBuffer(nsig);
14972
14973 title.Form("On-source combined object position and simulated signal event reconstruction uncertainty;Combined object position and event reco angular uncertainty (sigma in degrees);Counts");
14974 hOnSigSigmaComb=new TH1F("hOnSigSigmaComb",title,nbins,1,0);
14975 hOnSigSigmaComb->SetBuffer(nsig);
14976 }
14977
14978 // The energy histograms
14979 TH1F* hOnE=0;
14980 TH1F* hOffE=0;
14981 TH1F* hOnSigE=0;
14982 nbins=1000;
14983 if (non)
14984 {
14985 title.Form("On-source reconstructed event energy in the final sample;Event energy in GeV;Counts");
14986 if (!mode) title.ReplaceAll("reconstructed","simulated");
14987 hOnE=new TH1F("hOnE",title,nbins,1,0);
14988 }
14989 if (noff)
14990 {
14991 title.Form("Off-source reconstructed event energy in the final sample;Event energy in GeV;Counts");
14992 if (!mode) title.ReplaceAll("reconstructed","simulated");
14993 hOffE=new TH1F("hOffE",title,nbins,1,0);
14994 }
14995 if (nsig)
14996 {
14997 title.Form("On-source simulated signal event energy in the final sample;Event energy in GeV;Counts");
14998 hOnSigE=new TH1F("hOnSigE",title,nbins,1,0);
14999 }
15000
15001 // Additional text for histo titles to indicate scrambling of the corresponding data
15002 TString scrt=""; // Time scrambling
15003 TString scrp=""; // Position scrambling
15004 if (fTscmode>0) scrt="(scrambled)";
15005 if (fRscmode>0 || fTscmode==3) scrp="(scrambled)";
15006
15007 // Create the angular separation histograms
15008 TH1F* hOna=0;
15009 TH1F* hOffa=0;
15010 TH1F* hOnSiga=0;
15011 TH1F* hOnCosa=0;
15012 TH1F* hOffCosa=0;
15013 TH1F* hOnSigcosa=0;
15014 if (non && fAbin)
15015 {
15016 if (fAbin>0)
15017 {
15018 binsize=fAbin;
15019 nbins=int((AmaxOn-AminOn)/binsize);
15020 }
15021 else
15022 {
15023 nbins=int(((AmaxOn-AminOn)/180.)*NbkgWinOn*float(fNgrbs)/fabs(fAbin));
15024 if (nbins) binsize=(AmaxOn-AminOn)/float(nbins);
15025 }
15026 if (nbins)
15027 {
15028 title.Form("Reconstructed %-s opening angle of on-source events in time window;Opening angle (degrees);Counts per %-.3g degrees",scrp.Data(),binsize);
15029 hOna=new TH1F("hOna",title,nbins+1,AminOn,AmaxOn+binsize);
15030 }
15031 else
15032 {
15033 nbins=100;
15034 binsize=AmaxOn/float(nbins);
15035 title.Form("Reconstructed %-s opening angle of on-source events in time window;Opening angle (degrees);Counts per %-.3g degrees",scrp.Data(),binsize);
15036 hOna=new TH1F("hOna",title,nbins+2,AminOn-binsize,AmaxOn+binsize);
15037 }
15038 nabinsOn=nbins;
15039 abinsizeOn=binsize;
15040 if (nbins) binsizecos=(cos(AminOn*pi/180.)-cos(AmaxOn*pi/180.))/float(nbins);
15041 if (binsizecos>0)
15042 {
15043 title.Form("Reconstructed %-s cos(opening angle) of on-source events in time window;cos(opening angle);Counts per %-.3g",scrp.Data(),binsizecos);
15044 hOnCosa=new TH1F("hOnCosa",title,nbins+1,cos(AmaxOn*pi/180.),cos(AminOn*pi/180.)+binsizecos);
15045 }
15046 else
15047 {
15048 nbins=100;
15049 binsizecos=fabs(cos(AmaxOn*pi/180.))/float(nbins);
15050 title.Form("Reconstructed %-s cos(opening angle) of on-source events in time window;cos(opening angle);Counts per %-.3g",scrp.Data(),binsizecos);
15051 hOnCosa=new TH1F("hOnCosa",title,nbins+2,cos(AmaxOn*pi/180.)-binsizecos,cos(AminOn*pi/180.)+binsizecos);
15052 }
15053 }
15054 if (nsig && nbins)
15055 {
15056 title.Form("Reconstructed opening angle of on-source simulated signal events in time window;Opening angle (degrees);Counts per %-.3g degrees",binsize);
15057 hOnSiga=new TH1F("hOnSiga",title,nbins+2,AminOn-binsize,AmaxOn+binsize);
15058 title.Form("Reconstructed cos(opening angle) of on-source simulated signal events in time window;cos(opening angle);Counts per %-.3g",binsizecos);
15059 hOnSigcosa=new TH1F("hOnSigcosa",title,nbins+2,cos(AmaxOn*pi/180.)-binsizecos,cos(AminOn*pi/180.)+binsizecos);
15060 }
15061 nbins=0;
15062 binsize=0;
15063 binsizecos=0;
15064 if (noff && fAbin)
15065 {
15066 if (fAbin>0)
15067 {
15068 binsize=fAbin;
15069 nbins=int((AmaxOff-AminOff)/binsize);
15070 }
15071 else
15072 {
15073 nbins=int(((AmaxOff-AminOff)/180.)*NbkgWinOff*float(fNgrbs)*float(fNbkg)/fabs(fAbin));
15074 if (nbins) binsize=(AmaxOff-AminOff)/float(nbins);
15075 }
15076 if (nbins)
15077 {
15078 title.Form("Reconstructed opening angle of off-source events in time window;Opening angle (degrees);Counts per %-.3g degrees",binsize);
15079 hOffa=new TH1F("hOffa",title,nbins+1,AminOff,AmaxOff+binsize);
15080 }
15081 else
15082 {
15083 nbins=100;
15084 binsize=AmaxOff/float(nbins);
15085 title.Form("Reconstructed opening angle of off-source events in time window;Opening angle (degrees);Counts per %-.3g degrees",binsize);
15086 hOffa=new TH1F("hOffa",title,nbins+2,AminOff-binsize,AmaxOff+binsize);
15087 }
15088 nabinsOff=nbins;
15089 abinsizeOff=binsize;
15090 if (nbins) binsizecos=(cos(AminOff*pi/180.)-cos(AmaxOff*pi/180.))/float(nbins);
15091 if (binsizecos>0)
15092 {
15093 title.Form("Reconstructed cos(opening angle) of off-source events in time window;cos(opening angle);Counts per %-.3g",binsizecos);
15094 hOffCosa=new TH1F("hOffCosa",title,nbins+1,cos(AmaxOff*pi/180.),cos(AminOff*pi/180.)+binsizecos);
15095 }
15096 else
15097 {
15098 nbins=100;
15099 binsizecos=fabs(cos(AmaxOff*pi/180.))/float(nbins);
15100 title.Form("Reconstructed cos(opening angle) of off-source events in time window;cos(opening angle);Counts per %-.3g",binsizecos);
15101 hOffCosa=new TH1F("hOffCosa",title,nbins+2,cos(AmaxOff*pi/180.)-binsizecos,cos(AminOff*pi/180.)+binsizecos);
15102 }
15103 }
15104
15105 // Create the arrival time histograms
15106 TH1F* hOnt=0;
15107 TH1F* hOfft=0;
15108 TH1F* hOnSigt=0;
15109 TH2F* hOnta=0;
15110 TH2F* hOffta=0;
15111 TH2F* hOnSigta=0;
15112 TH2F* hOnZta=0;
15113 TH2F* hOffZta=0;
15114 TH2F* hOnSigZta=0;
15115
15116 // The redshift corrected arrival time histograms
15117 TH1F* hOnZt=0;
15118 TH1F* hOffZt=0;
15119 TH1F* hOnSigZt=0;
15120
15121 nbins=0;
15122 binsize=0;
15123 TString addtitle;
15124 addtitle.Form(" (=%-g*<T90>)",fTbin);
15125 if (fTbin<0) addtitle.Form(" (~%-g counts/bin)",fabs(fTbin));
15126 if (fabs(fTbin)>0) // Fixed time bins
15127 {
15128 // Automatic time binning to get the specified maximal bkg counts per bin
15129 nbins=int(NbkgWinOn*float(fNgrbs)/fabs(fTbin));
15130 Int_t temp=int(NbkgWinOff*float(fNgrbs)*float(fNbkg)/fabs(fTbin));
15131 if (temp>nbins) nbins=temp;
15132 if (nbins) binsize=DtwinOn/float(nbins);
15133
15134 if (fTbin>0) // User defined time bin size
15135 {
15136 binsize=fTbin;
15137 if (fTbint90) binsize=fTbin*fabs(fAvgrbt90)/fTfact;
15138 nbins=DtwinOn/binsize;
15139 }
15140 if (nbins && non)
15141 {
15142 title.Form("Arrival times %-s of on-source events in time window;Event arrival time (in %-s) w.r.t. burst trigger;Counts per %-.3g %-s",scrt.Data(),tu.Data(),binsize,tu.Data());
15143 if (fTbint90 || fTbin<0) title+=addtitle;
15144 hOnt=new TH1F("hOnt",title,nbins+2,TminOn-binsize,TmaxOn+binsize);
15145 title.Form("Arrival time %-s vs. reconstructed %-s opening angle of on-source events in time window;Opening angle (degrees);Event arrival time (in %-s) w.r.t. burst trigger",scrt.Data(),scrp.Data(),tu.Data());
15146 hOnta=new TH2F("hOnta",title,nabinsOn+2,AminOn-abinsizeOn,AmaxOn+abinsizeOn,nbins+2,TminOn-binsize,TmaxOn+binsize);
15147 title.Form("Redshift corrected arrival times %-s of on-source events in time window;Event arrival time (in %-s) w.r.t. burst trigger;Counts per %-.3g %-s",scrt.Data(),tu.Data(),binsize,tu.Data());
15148 if (fTbint90 || fTbin<0) title+=addtitle;
15149 hOnZt=new TH1F("hOnZt",title,nbins+2,TminOn-binsize,TmaxOn+binsize);
15150 title.Form("Redshift corrected %-s arrival time vs. reconstructed %-s opening angle of on-source events in time window;Opening angle (degrees);Event arrival time (in %-s) w.r.t. burst trigger",scrt.Data(),scrp.Data(),tu.Data());
15151 hOnZta=new TH2F("hOnZta",title,nabinsOn+2,AminOn-abinsizeOn,AmaxOn+abinsizeOn,nbins+2,TminOn-binsize,TmaxOn+binsize);
15152 }
15153 if (nbins && nsig)
15154 {
15155 title.Form("Arrival times of on-source simulated signal events in time window;Event arrival time (in %-s) w.r.t. burst trigger;Counts per %-.3g %-s",tu.Data(),binsize,tu.Data());
15156 if (fTbint90 || fTbin<0) title+=addtitle;
15157 hOnSigt=new TH1F("hOnSigt",title,nbins+2,TminOn-binsize,TmaxOn+binsize);
15158 title.Form("Arrival time vs. reconstructed opening angle of on-source simulated signal events in time window;Opening angle (degrees);Event arrival time (in %-s) w.r.t. burst trigger",tu.Data());
15159 hOnSigta=new TH2F("hOnSigta",title,nabinsOn+2,AminOn-abinsizeOn,AmaxOn+abinsizeOn,nbins+2,TminOn-binsize,TmaxOn+binsize);
15160 title.Form("Redshift corrected arrival times of on-source simulated signal events in time window;Event arrival time (in %-s) w.r.t. burst trigger;Counts per %-.3g %-s",tu.Data(),binsize,tu.Data());
15161 if (fTbint90 || fTbin<0) title+=addtitle;
15162 hOnSigZt=new TH1F("hOnSigZt",title,nbins+2,TminOn-binsize,TmaxOn+binsize);
15163 title.Form("Redshift corrected arrival time vs. reconstructed opening angle of on-source simulated signal events in time window;Opening angle (degrees);Event arrival time (in %-s) w.r.t. burst trigger",tu.Data());
15164 hOnSigZta=new TH2F("hOnSigZta",title,nabinsOn+2,AminOn-abinsizeOn,AmaxOn+abinsizeOn,nbins+2,TminOn-binsize,TmaxOn+binsize);
15165 }
15166
15167 if (fTbin>0) // User defined time bin size
15168 {
15169 binsize=fTbin;
15170 if (fTbint90) binsize=fTbin*fabs(fAvgrbt90)/fTfact;
15171 nbins=DtwinOff/binsize;
15172 }
15173 if (nbins && noff)
15174 {
15175 title.Form("Arrival times of off-source events in time window;Event arrival time (in %-s) w.r.t. burst trigger;Counts per %-.3g %-s",tu.Data(),binsize,tu.Data());
15176 if (fTbint90 || fTbin<0) title+=addtitle;
15177 hOfft=new TH1F("hOfft",title,nbins+2,TminOff-binsize,TmaxOff+binsize);
15178 title.Form("Arrival time vs. reconstructed opening angle of off-source events in time window;Opening angle (degrees);Event arrival time (in %-s) w.r.t. burst trigger",tu.Data());
15179 hOffta=new TH2F("hOffta",title,nabinsOff+2,AminOff-abinsizeOff,AmaxOff+abinsizeOff,nbins+2,TminOff-binsize,TmaxOff+binsize);
15180 title.Form("Redshift corrected arrival times of off-source events in time window;Event arrival time (in %-s) w.r.t. burst trigger;Counts per %-.3g %-s",tu.Data(),binsize,tu.Data());
15181 if (fTbint90 || fTbin<0) title+=addtitle;
15182 hOffZt=new TH1F("hOffZt",title,nbins+2,TminOff-binsize,TmaxOff+binsize);
15183 title.Form("Redshift corrected arrival time vs. reconstructed opening angle of off-source events in time window;Opening angle (degrees);Event arrival time (in %-s) w.r.t. burst trigger",tu.Data());
15184 hOffZta=new TH2F("hOffZta",title,nabinsOff+2,AminOff-abinsizeOff,AmaxOff+abinsizeOff,nbins+2,TminOff-binsize,TmaxOff+binsize);
15185 }
15186 }
15187 else // Variable time bins
15188 {
15189 Double_t* binarr=0;
15190 Int_t nbx=int(DtwinOn/fVarTbin);
15191 Float_t gamma=fabs(fAvgrbz)+1.;
15192 Float_t* bins=new Float_t[nbx];
15193 nbins=0;
15194 Float_t xlow=0,xup=0,size=fVarTbin;
15195 for (Int_t i=0; i<nbx-1; i++)
15196 {
15197 xup=xlow+size;
15198 if (xup>DtwinOn/2.) // Store the last lowerbound
15199 {
15200 bins[i]=xlow;
15201 nbins++;
15202 break;
15203 }
15204 bins[i]=xlow;
15205 nbins++;
15206 xlow=xup;
15207 size=xlow*gamma;
15208 }
15209 binarr=new Double_t[2*nbins-1];
15210 for (Int_t j=nbins; j>0; j--)
15211 {
15212 binarr[nbins-j]=-bins[j-1];
15213 binarr[nbins+j-2]=bins[j-1];
15214 }
15215 nbins=2*nbins-2;
15216 if (nbins && non)
15217 {
15218 title.Form("Arrival times %-s of on-source events in time window;Event arrival time (in %-s) w.r.t. burst trigger;Counts per time bin",scrt.Data(),tu.Data());
15219 hOnt=new TH1F("hOnt",title,nbins,binarr);
15220 if (nabinsOn)
15221 {
15222 title.Form("Arrival time %-s vs. reconstructed %-s opening angle of on-source events in time window;Opening angle (degrees);Event arrival time (in %-s) w.r.t. burst trigger",scrt.Data(),scrp.Data(),tu.Data());
15223 hOnta=new TH2F("hOnta",title,nabinsOn,AminOn,AmaxOn,nbins,binarr);
15224 }
15225 }
15226 if (nbins && noff)
15227 {
15228 title.Form("Arrival times of off-source events in time window;Event arrival time (in %-s) w.r.t. burst trigger;Counts per time bin",tu.Data());
15229 hOfft=new TH1F("hOfft",title,nbins,binarr);
15230 if (nabinsOff)
15231 {
15232 title.Form("Arrival time vs. reconstructed opening angle of off-source events in time window;Opening angle (degrees);Event arrival time (in %-s) w.r.t. burst trigger",tu.Data());
15233 hOffta=new TH2F("hOffta",title,nabinsOff,AminOff,AmaxOff,nbins,binarr);
15234 }
15235 }
15236 if (nbins && nsig)
15237 {
15238 title.Form("Arrival times of on-source simulated signal events in time window;Event arrival time (in %-s) w.r.t. burst trigger;Counts per time bin",tu.Data());
15239 hOnSigt=new TH1F("hOnSigt",title,nbins,binarr);
15240 if (nabinsOn)
15241 {
15242 title.Form("Arrival time vs. reconstructed opening angle of on-source simulated signal events in time window;Opening angle (degrees);Event arrival time (in %-s) w.r.t. burst trigger",tu.Data());
15243 hOnSigta=new TH2F("hOnSigta",title,nabinsOn,AminOn,AmaxOn,nbins,binarr);
15244 }
15245 }
15246
15247 delete[] binarr;
15248 }
15249
15250 // Fill the histograms
15251 Double_t value1=0;
15252 Double_t value2=0;
15253 Double_t value3=0;
15254 Double_t value4=0;
15255
15256 // The on-source data
15257 for (Int_t i=1; i<=fBurstOnReco.GetN(); i++)
15258 {
15259 value1=fBurstOnReco.GetEntry(i,"zburst");
15260 value2=fBurstOnReco.GetEntry(i,"sigmaburst");
15261 value3=fBurstOnReco.GetEntry(i,"sigmareco");
15262 value4=fBurstOnReco.GetEntry(i,"sigmacomb");
15263 if (hOnSourceZ) hOnSourceZ->Fill(value1);
15264 if (hOnSigmaSource) hOnSigmaSource->Fill(value2);
15265 if (hOnSigmaReco) hOnSigmaReco->Fill(value3);
15266 if (hOnSigmaComb) hOnSigmaComb->Fill(value4);
15267 }
15268
15269 for (Int_t i=1; i<=fBurstOnMatch.GetN(); i++)
15270 {
15271 value1=fBurstOnMatch.GetEntry(i,"E");
15272 value2=fBurstOnMatch.GetEntry(i,"dang");
15273 value3=fBurstOnMatch.GetEntry(i,"dtime");
15274 value4=fBurstOnMatch.GetEntry(i,"dtimez");
15275 if (hOnE) hOnE->Fill(value1);
15276 if (hOna) hOna->Fill(value2);
15277 if (hOnCosa) hOnCosa->Fill(cos(value2*pi/180.));
15278 if (hOnt) hOnt->Fill(value3);
15279 if (hOnta) hOnta->Fill(value2,value3);
15280 if (hOnZt) hOnZt->Fill(value4);
15281 if (hOnZta) hOnZta->Fill(value2,value4);
15282 }
15283
15284 // The off-source data
15285 for (Int_t i=1; i<=fBurstOffReco.GetN(); i++)
15286 {
15287 value1=fBurstOffReco.GetEntry(i,"zburst");
15288 value2=fBurstOffReco.GetEntry(i,"sigmaburst");
15289 value3=fBurstOffReco.GetEntry(i,"sigmareco");
15290 value4=fBurstOffReco.GetEntry(i,"sigmacomb");
15291 if (hOffSourceZ) hOffSourceZ->Fill(value1);
15292 if (hOffSigmaSource) hOffSigmaSource->Fill(value2);
15293 if (hOffSigmaReco) hOffSigmaReco->Fill(value3);
15294 if (hOffSigmaComb) hOffSigmaComb->Fill(value4);
15295 }
15296
15297 for (Int_t i=1; i<=fBurstOffMatch.GetN(); i++)
15298 {
15299 value1=fBurstOffMatch.GetEntry(i,"E");
15300 value2=fBurstOffMatch.GetEntry(i,"dang");
15301 value3=fBurstOffMatch.GetEntry(i,"dtime");
15302 value4=fBurstOffMatch.GetEntry(i,"dtimez");
15303 if (hOffE) hOffE->Fill(value1);
15304 if (hOffa) hOffa->Fill(value2);
15305 if (hOffCosa) hOffCosa->Fill(cos(value2*pi/180.));
15306 if (hOfft) hOfft->Fill(value3);
15307 if (hOffta) hOffta->Fill(value2,value3);
15308 if (hOffZt) hOffZt->Fill(value4);
15309 if (hOffZta) hOffZta->Fill(value2,value4);
15310 }
15311
15312 // The simulated signal data
15313 for (Int_t i=1; i<=fBurstSigReco.GetN(); i++)
15314 {
15315 value1=fBurstSigReco.GetEntry(i,"zburst");
15316 value2=fBurstSigReco.GetEntry(i,"sigmaburst");
15317 value3=fBurstSigReco.GetEntry(i,"sigmareco");
15318 value4=fBurstSigReco.GetEntry(i,"sigmacomb");
15319 if (hOnSigSourceZ) hOnSigSourceZ->Fill(value1);
15320 if (hOnSigSigmaSource) hOnSigSigmaSource->Fill(value2);
15321 if (hOnSigSigmaReco) hOnSigSigmaReco->Fill(value3);
15322 if (hOnSigSigmaComb) hOnSigSigmaComb->Fill(value4);
15323 }
15324
15325 for (Int_t i=1; i<=fBurstSignal.GetN(); i++)
15326 {
15327 value1=fBurstSignal.GetEntry(i,"E");
15328 value2=fBurstSignal.GetEntry(i,"dang");
15329 value3=fBurstSignal.GetEntry(i,"dtime");
15330 value4=fBurstSignal.GetEntry(i,"dtimez");
15331 if (hOnSigE) hOnSigE->Fill(value1);
15332 if (hOnSiga) hOnSiga->Fill(value2);
15333 if (hOnSigcosa) hOnSigcosa->Fill(cos(value2*pi/180.));
15334 if (hOnSigt) hOnSigt->Fill(value3);
15335 if (hOnSigta) hOnSigta->Fill(value2,value3);
15336 if (hOnSigZt) hOnSigZt->Fill(value4);
15337 if (hOnSigZta) hOnSigZta->Fill(value2,value4);
15338 }
15339
15340 // Bayesian block analysis of the arrival times
15341 NcBlocks BB;
15342 TH1F hOnBBt;
15343 TH1F hOnBBzt;
15344 if (fBurstOnMatch.GetN())
15345 {
15346 BB.GetBlocks(fBurstOnMatch,"dtime",0.05,&hOnBBt);
15347 title.Form("Bayesian blocks for on-source arrival times %-s;Event arrival time (in %-s) w.r.t. burst trigger;Event rate (%-s^{-1}) for %-i stacked time windows",scrt.Data(),tu.Data(),tu.Data(),fNgrbs);
15348 title.ReplaceAll("days^","day^");
15349 title.ReplaceAll("hours^","hour^");
15350 hOnBBt.SetNameTitle("hOnBBt",title);
15351 BB.GetBlocks(fBurstOnMatch,"dtimez",0.05,&hOnBBzt);
15352 title.Form("Bayesian blocks for redshift corrected on-source arrival times %-s;Event arrival time (in %-s) w.r.t. burst trigger;Event rate (%-s^{-1}) for %-i stacked time windows",scrt.Data(),tu.Data(),tu.Data(),fNgrbs);
15353 title.ReplaceAll("days^","day^");
15354 title.ReplaceAll("hours^","hour^");
15355 hOnBBzt.SetNameTitle("hOnBBzt",title);
15356 }
15357 TH1F hOffBBt;
15358 TH1F hOffBBzt;
15359 if (fBurstOffMatch.GetN())
15360 {
15361 BB.GetBlocks(fBurstOffMatch,"dtime",0.05,&hOffBBt);
15362 title.Form("Bayesian blocks for off-source arrival times;Event arrival time (in %-s) w.r.t. burst trigger;Event rate (%-s^{-1}) for %-i stacked time windows",tu.Data(),tu.Data(),fNgrbs*fNbkg);
15363 title.ReplaceAll("days^","day^");
15364 title.ReplaceAll("hours^","hour^");
15365 hOffBBt.SetNameTitle("hOffBBt",title);
15366 BB.GetBlocks(fBurstOffMatch,"dtimez",0.05,&hOffBBzt);
15367 title.Form("Bayesian blocks for redshift corrected off-source arrival times;Event arrival time (in %-s) w.r.t. burst trigger;Event rate (%-s^{-1}) for %-i stacked time windows",tu.Data(),tu.Data(),fNgrbs*fNbkg);
15368 title.ReplaceAll("days^","day^");
15369 title.ReplaceAll("hours^","hour^");
15370 hOffBBzt.SetNameTitle("hOffBBzt",title);
15371 }
15372
15373 // Ratio On/Off for the Bayesian Block histograms
15374 Float_t temp=0;
15375 Int_t nb1=0;
15376 Int_t nb2=0;
15377
15378 axis=hOnBBt.GetXaxis();
15379 xmin=axis->GetXmin();
15380 xmax=axis->GetXmax();
15381 axis=hOffBBt.GetXaxis();
15382 temp=axis->GetXmin();
15383 if (temp<xmin) xmin=temp;
15384 temp=axis->GetXmax();
15385 if (temp>xmax) xmax=temp;
15386
15387 TH1F hOnUBBt;
15388 TH1F hOffUBBt;
15389 TH1F hRatUBBt;
15390 title.Form("Event rate (%-s^{-1}) scaled per time window",tu.Data());
15391 title.ReplaceAll("days^","day^");
15392 title.ReplaceAll("hours^","hour^");
15393 nb1=BB.Rebin(&hOnBBt,&hOnUBBt,kFALSE,0,xmin,xmax);
15394 nb2=BB.Rebin(&hOffBBt,&hOffUBBt,kFALSE,0,xmin,xmax);
15395 if (nb2>nb1) BB.Rebin(&hOnBBt,&hOnUBBt,kFALSE,nb2,xmin,xmax);
15396 hOnUBBt.SetName("hOnUBBt");
15397 hOffUBBt.SetName("hOffUBBt");
15398 if (fNgrbs>1) hOnUBBt.Scale(1./float(fNgrbs));
15399 if (fNgrbs*fNbkg>1) hOffUBBt.Scale(1./float(fNgrbs*fNbkg));
15400 hOnUBBt.SetYTitle(title);
15401 hOffUBBt.SetYTitle(title);
15402 BB.Divide(&hOnUBBt,&hOffUBBt,&hRatUBBt,kFALSE,1);
15403 hRatUBBt.SetName("hRatUBBt");
15404 hRatUBBt.SetYTitle("Ratio");
15405
15406 nbins=hOnBBzt.GetNbinsX();
15407 if (hOffBBzt.GetNbinsX()>nbins) nbins=hOffBBzt.GetNbinsX();
15408 axis=hOnBBzt.GetXaxis();
15409 xmin=axis->GetXmin();
15410 xmax=axis->GetXmax();
15411 axis=hOffBBzt.GetXaxis();
15412 temp=axis->GetXmin();
15413 if (temp<xmin) xmin=temp;
15414 temp=axis->GetXmax();
15415 if (temp>xmax) xmax=temp;
15416
15417 TH1F hOnUBBzt;
15418 TH1F hOffUBBzt;
15419 TH1F hRatUBBzt;
15420 nb1=BB.Rebin(&hOnBBzt,&hOnUBBzt,kFALSE,0,xmin,xmax);
15421 nb2=BB.Rebin(&hOffBBzt,&hOffUBBzt,kFALSE,0,xmin,xmax);
15422 if (nb2>nb1) BB.Rebin(&hOnBBzt,&hOnUBBzt,kFALSE,nb2,xmin,xmax);
15423 hOnUBBzt.SetName("hOnUBBzt");
15424 hOffUBBzt.SetName("hOffUBBzt");
15425 if (fNgrbs>1) hOnUBBzt.Scale(1./float(fNgrbs));
15426 if (fNgrbs*fNbkg>1) hOffUBBzt.Scale(1./float(fNgrbs*fNbkg));
15427 hOnUBBzt.SetYTitle(title);
15428 hOffUBBzt.SetYTitle(title);
15429 BB.Divide(&hOnUBBzt,&hOffUBBzt,&hRatUBBzt,kFALSE,1);
15430 hRatUBBzt.SetName("hRatUBBzt");
15431 hRatUBBzt.SetYTitle("Ratio");
15432
15433 // Store the produced histograms
15434 if (hOnSourceZ) fBurstHistos.Add(hOnSourceZ);
15435 if (hOffSourceZ) fBurstHistos.Add(hOffSourceZ);
15436 if (hOnSigSourceZ) fBurstHistos.Add(hOnSigSourceZ);
15437 if (hOnSigmaSource) fBurstHistos.Add(hOnSigmaSource);
15438 if (hOffSigmaSource) fBurstHistos.Add(hOffSigmaSource);
15439 if (hOnSigSigmaSource) fBurstHistos.Add(hOnSigSigmaSource);
15440 if (hOnSigmaReco) fBurstHistos.Add(hOnSigmaReco);
15441 if (hOffSigmaReco) fBurstHistos.Add(hOffSigmaReco);
15442 if (hOnSigSigmaReco) fBurstHistos.Add(hOnSigSigmaReco);
15443 if (hOnSigmaComb) fBurstHistos.Add(hOnSigmaComb);
15444 if (hOffSigmaComb) fBurstHistos.Add(hOffSigmaComb);
15445 if (hOnSigSigmaComb) fBurstHistos.Add(hOnSigSigmaComb);
15446 if (hOnE) fBurstHistos.Add(hOnE);
15447 if (hOffE) fBurstHistos.Add(hOffE);
15448 if (hOnSigE) fBurstHistos.Add(hOnSigE);
15449 if (hOna) fBurstHistos.Add(hOna);
15450 if (hOffa) fBurstHistos.Add(hOffa);
15451 if (hOnSiga) fBurstHistos.Add(hOnSiga);
15452 if (hOnCosa) fBurstHistos.Add(hOnCosa);
15453 if (hOffCosa) fBurstHistos.Add(hOffCosa);
15454 if (hOnSigcosa) fBurstHistos.Add(hOnSigcosa);
15455 if (hOnt) fBurstHistos.Add(hOnt);
15456 if (hOfft) fBurstHistos.Add(hOfft);
15457 if (hOnSigt) fBurstHistos.Add(hOnSigt);
15458 if (hOnta) fBurstHistos.Add(hOnta);
15459 if (hOffta) fBurstHistos.Add(hOffta);
15460 if (hOnSigta)fBurstHistos.Add(hOnSigta);
15461 if (hOnt && hOnBBt.GetEntries()) fBurstHistos.Add(hOnBBt.Clone());
15462 if (hOfft && hOffBBt.GetEntries()) fBurstHistos.Add(hOffBBt.Clone());
15463 if (hOnt && hOnUBBt.GetEntries()) fBurstHistos.Add(hOnUBBt.Clone());
15464 if (hOfft && hOffUBBt.GetEntries()) fBurstHistos.Add(hOffUBBt.Clone());
15465 if (hOnt && hOfft && hRatUBBt.GetEntries()) fBurstHistos.Add(hRatUBBt.Clone());
15466 if (hOnZt) fBurstHistos.Add(hOnZt);
15467 if (hOffZt) fBurstHistos.Add(hOffZt);
15468 if (hOnSigZt) fBurstHistos.Add(hOnSigZt);
15469 if (hOnZta) fBurstHistos.Add(hOnZta);
15470 if (hOffZta) fBurstHistos.Add(hOffZta);
15471 if (hOnSigZta) fBurstHistos.Add(hOnSigZta);
15472 if (hOnZt && hOnBBzt.GetEntries()) fBurstHistos.Add(hOnBBzt.Clone());
15473 if (hOffZt && hOffBBzt.GetEntries()) fBurstHistos.Add(hOffBBzt.Clone());
15474 if (hOnZt && hOnUBBzt.GetEntries()) fBurstHistos.Add(hOnUBBzt.Clone());
15475 if (hOffZt && hOffUBBzt.GetEntries()) fBurstHistos.Add(hOffUBBzt.Clone());
15476 if (hOnZt && hOffZt && hRatUBBzt.GetEntries()) fBurstHistos.Add(hRatUBBzt.Clone());
15477
15478 // Make sure that also the auto-binned histograms have their axes ranges set
15479 Int_t nh=fBurstHistos.GetEntries();
15480 for (Int_t ih=0; ih<nh; ih++)
15481 {
15482 TH1* hx=(TH1*)fBurstHistos.At(ih);
15483 if (!hx) continue;
15484 hx->BufferEmpty(1);
15485
15486 name=hx->GetName();
15487
15488 if (name=="hTdiff")
15489 {
15490 binsize=hx->GetBinWidth(1);
15491 s.Form("Counts per %-.3g %-s",binsize,tu.Data());
15492 axis=hx->GetYaxis();
15493 if (axis) axis->SetTitle(s);
15494 }
15495
15496 if (name=="hAdiff" || name.Contains("Sigma"))
15497 {
15498 binsize=hx->GetBinWidth(1);
15499 s.Form("Counts per %-.3g degrees",binsize);
15500 axis=hx->GetYaxis();
15501 if (axis) axis->SetTitle(s);
15502 }
15503
15504 if (name=="hOnE" || name=="hOffE" || name=="hOnSigE")
15505 {
15506 binsize=hx->GetBinWidth(1);
15507 s.Form("Counts per %-.3g GeV",binsize);
15508 axis=hx->GetYaxis();
15509 if (axis) axis->SetTitle(s);
15510 }
15511 }
15512
15513 // Determination of the on-source and off-source event rates
15514 Float_t nOn=non;
15515 Float_t nOff=noff;
15516 Float_t nsigOn=nsig;
15517 Float_t nbkgOn=nOn-nsigOn;
15518 Float_t Ton=DtwinOn*fTfact*float(fNgrbs); // Total on-source exposure time in seconds
15519 Float_t Toff=DtwinOff*fTfact*float(fNgrbs)*float(fNbkg); // Total off-source exposure time in seconds
15520 Float_t rateOn=nOn/(DtwinOn*fTfact);
15521 Float_t rateOff=nOff/(DtwinOff*fTfact);
15522
15523 // (Average) values per patch
15524 Float_t TwinOn=DtwinOn*fTfact;
15525 Float_t TwinOff=DtwinOff*fTfact;
15526 Float_t AvSolidangleOn=0;
15527 Float_t AvSolidangleOff=0;
15528 Float_t AvNon=0;
15529 Float_t AvNoff=0;
15530 Float_t AvRon=0;
15531 Float_t AvRoff=0;
15532 Float_t AvEon=0;
15533 Float_t AvEoff=0;
15534 Float_t AvNsigOn=0;
15535 Float_t AvNbkgOn=0;
15536 Float_t AvRsigOn=0;
15537 Float_t AvRbkgOn=0;
15538 Float_t AvEsigOn=0;
15539 Float_t AvEbkgOn=0;
15540 Float_t scale=fNgrbs;
15541 if (scale)
15542 {
15543 AvSolidangleOn=fSolidangleOn/scale;
15544 AvNon=nOn/scale;
15545 AvRon=nOn/Ton;
15546 AvEon=fEnergyOn/scale;
15547 AvNsigOn=nsigOn/scale;
15548 AvNbkgOn=nbkgOn/scale;
15549 AvRsigOn=nsigOn/Ton;
15550 AvRbkgOn=nbkgOn/Ton;
15551 AvEsigOn=fEnergySig/scale;
15552 AvEbkgOn=fEnergyBkg/scale;
15553 }
15554 scale=fNgrbs*fNbkg;
15555 if (scale)
15556 {
15557 AvSolidangleOff=fSolidangleOff/scale;
15558 AvNoff=nOff/scale;
15559 AvRoff=nOff/Toff;
15560 AvEoff=fEnergyOff/scale;
15561 }
15562
15563 // Statistics of the stacked event samples
15564 printf("\n *%-s::MakeBurstDataStats* Statistics of the stacked observed event samples. \n",ClassName());
15565 printf(" Solid angle coverage corresponding to the selected RA and DEC range : %-g steradian \n",fOmegaDecl);
15566 printf(" Integrated on-source exposure time of the %-i stacked time windows : %-g %-s \n",fNgrbs,Ton/fTfact,tu.Data());
15567 printf(" Integrated off-source exposure time of the %-i*%-i stacked time windows : %-g %-s \n",fNgrbs,fNbkg,Toff/fTfact,tu.Data());
15568 printf(" Total accumulated on-source solid angle : %-g sr in %-i stacked patches --> Average per patch : %-g sr \n",fSolidangleOn,fNgrbs,AvSolidangleOn);
15569 printf(" Total accumulated off-source solid angle : %-g sr in %-i*%-i stacked patches --> Average per patch : %-g sr \n",fSolidangleOff,fNgrbs,fNbkg,AvSolidangleOff);
15570 if (fSensarea>0) printf(" Area covered c.q. overlooked by the detector sensors : %-g m^2. \n",fSensarea);
15571 fSensarea*=1e4; // Convert to cm^2
15572
15573 printf(" *On source* Total number of recorded on-source events : %-g --> Average per patch : %-g events. \n",nOn,AvNon);
15574 printf(" --- Average recorded values per on-source patch --- \n");
15575 printf(" Steady event rate during the time window : %-g Hz",AvRon);
15576 if (AvSolidangleOn) printf(" --> %-g Hz sr^-1",AvRon/AvSolidangleOn);
15577 printf("\n");
15578 if (fSensarea>0)
15579 {
15580 printf(" Particle fluence : %-g cm^-2",AvNon/fSensarea);
15581 if (AvSolidangleOn) printf(" --> %-g cm^-2 sr^-1",AvNon/(fSensarea*AvSolidangleOn));
15582 printf("\n");
15583 printf(" Particle flux : %-g cm^-2 s^-1",AvRon/fSensarea);
15584 if (AvSolidangleOn) printf(" --> Intensity : %-g cm^-2 s^-1 sr^-1",AvRon/(fSensarea*AvSolidangleOn));
15585 printf("\n");
15586 }
15587 printf(" Cumulated energy : %-g GeV",AvEon);
15588 if (AvSolidangleOn) printf(" --> %-g GeV sr^-1",AvEon/AvSolidangleOn);
15589 printf("\n");
15590 printf(" Power : %-g GeV/s",AvEon/TwinOn);
15591 if (AvSolidangleOn) printf(" --> %-g GeV s^-1 sr^-1",AvEon/(TwinOn*AvSolidangleOn));
15592 printf("\n");
15593 if (fSensarea>0)
15594 {
15595 printf(" Energy fluence : %-g GeV cm^-2",AvEon/fSensarea);
15596 if (AvSolidangleOn) printf(" --> %-g GeV cm^-2 sr^-1",AvEon/(fSensarea*AvSolidangleOn));
15597 printf("\n");
15598 printf(" Energy flux : %-g GeV cm^-2 s^-1",AvEon/(fSensarea*TwinOn));
15599 if (AvSolidangleOn) printf(" --> Intensity : %-g GeV cm^-2 s^-1 sr^-1",AvEon/(fSensarea*TwinOn*AvSolidangleOn));
15600 printf("\n");
15601 }
15602
15603 if (fNbkg)
15604 {
15605 printf(" *Off source* Total number of recorded off-source (background) events : %-g --> Average per patch : %-g events. \n",nOff,AvNoff);
15606 printf(" --- Average recorded values per off-source patch --- \n");
15607 printf(" Steady event rate during the time window : %-g Hz",AvRoff);
15608 if (AvSolidangleOff) printf(" --> %-g Hz sr^-1",AvRoff/AvSolidangleOff);
15609 printf("\n");
15610 if (fSensarea>0)
15611 {
15612 printf(" Particle fluence : %-g cm^-2",AvNoff/fSensarea);
15613 if (AvSolidangleOff) printf(" --> %-g cm^-2 sr^-1",AvNoff/(fSensarea*AvSolidangleOff));
15614 printf("\n");
15615 printf(" Particle flux : %-g cm^-2 s^-1",AvRoff/fSensarea);
15616 if (AvSolidangleOff) printf(" --> Intensity : %-g cm^-2 s^-1 sr^-1",AvRoff/(fSensarea*AvSolidangleOff));
15617 printf("\n");
15618 }
15619 printf(" Cumulated energy : %-g GeV",AvEoff);
15620 if (AvSolidangleOff) printf(" --> %-g GeV sr^-1",AvEoff/AvSolidangleOff);
15621 printf("\n");
15622 printf(" Power : %-g GeV/s",AvEoff/TwinOff);
15623 if (AvSolidangleOff) printf(" --> %-g GeV s^-1 sr^-1",AvEoff/(TwinOn*AvSolidangleOff));
15624 printf("\n");
15625 if (fSensarea>0)
15626 {
15627 printf(" Energy fluence : %-g GeV cm^-2",AvEoff/fSensarea);
15628 if (AvSolidangleOff) printf(" --> %-g GeV cm^-2 sr^-1",AvEoff/(fSensarea*AvSolidangleOff));
15629 printf("\n");
15630 printf(" Energy flux : %-g GeV cm^-2 s^-1",AvEoff/(fSensarea*TwinOff));
15631 if (AvSolidangleOff) printf(" --> Intensity : %-g GeV cm^-2 s^-1 sr^-1",AvEoff/(fSensarea*TwinOff*AvSolidangleOff));
15632 printf("\n");
15633 }
15634 }
15635
15636 // On-source signal and background info is only available for simulated data
15637 if (!mode)
15638 {
15639 printf(" -(Unknown)- Total number of injected on-source signal events : %-i",nmugrb);
15640 if (fNgrbs) printf(" --> Average per patch : %-g events.",float(nmugrb)/float(fNgrbs));
15641 printf("\n");
15642 printf(" Total number of recorded on-source signal events : %-g",nsigOn);
15643 if (fNgrbs) printf(" --> Average per patch : %-g events.",nsigOn/float(fNgrbs));
15644 printf("\n");
15645 printf(" Total number of recorded on-source bkg events : %-g",nbkgOn);
15646 if (fNgrbs) printf(" --> Average per patch : %-g events.",nbkgOn/float(fNgrbs));
15647 printf("\n");
15648
15649 printf(" --- Average signal values per on-source patch --- \n");
15650 printf(" Steady event rate during the time window : %-g Hz",AvRsigOn);
15651 if (AvSolidangleOn) printf(" --> %-g Hz sr^-1",AvRsigOn/AvSolidangleOn);
15652 printf("\n");
15653 if (fSensarea>0)
15654 {
15655 printf(" Particle fluence : %-g cm^-2",AvNsigOn/fSensarea);
15656 if (AvSolidangleOn) printf(" --> %-g cm^-2 sr^-1",AvNsigOn/(fSensarea*AvSolidangleOn));
15657 printf("\n");
15658 printf(" Particle flux : %-g cm^-2 s^-1",AvRsigOn/fSensarea);
15659 if (AvSolidangleOn) printf(" --> Intensity : %-g cm^-2 s^-1 sr^-1",AvRsigOn/(fSensarea*AvSolidangleOn));
15660 printf("\n");
15661 }
15662 printf(" Cumulated energy : %-g GeV",AvEsigOn);
15663 if (AvSolidangleOn) printf(" --> %-g GeV sr^-1",AvEsigOn/AvSolidangleOn);
15664 printf("\n");
15665 printf(" Power : %-g GeV/s",AvEsigOn/TwinOn);
15666 if (AvSolidangleOn) printf(" --> %-g GeV s^-1 sr^-1",AvEsigOn/(TwinOn*AvSolidangleOn));
15667 printf("\n");
15668 if (fSensarea>0)
15669 {
15670 printf(" Energy fluence : %-g GeV cm^-2",AvEsigOn/fSensarea);
15671 if (AvSolidangleOn) printf(" --> %-g GeV cm^-2 sr^-1",AvEsigOn/(fSensarea*AvSolidangleOn));
15672 printf("\n");
15673 printf(" Energy flux : %-g GeV cm^-2 s^-1",AvEsigOn/(fSensarea*TwinOn));
15674 if (AvSolidangleOn) printf(" --> Intensity : %-g GeV cm^-2 s^-1 sr^-1",AvEsigOn/(fSensarea*TwinOn*AvSolidangleOn));
15675 printf("\n");
15676 }
15677 printf(" --- Average background values per on-source patch --- \n");
15678 printf(" Steady event rate during the time window : %-g Hz",AvRbkgOn);
15679 if (AvSolidangleOn) printf(" --> %-g Hz sr^-1",AvRbkgOn/AvSolidangleOn);
15680 printf("\n");
15681 if (fSensarea>0)
15682 {
15683 printf(" Particle fluence : %-g cm^-2",AvNbkgOn/fSensarea);
15684 if (AvSolidangleOn) printf(" --> %-g cm^-2 sr^-1",AvNbkgOn/(fSensarea*AvSolidangleOn));
15685 printf("\n");
15686 printf(" Particle flux : %-g cm^-2 s^-1",AvRbkgOn/fSensarea);
15687 if (AvSolidangleOn) printf(" --> Intensity : %-g cm^-2 s^-1 sr^-1",AvRbkgOn/(fSensarea*AvSolidangleOn));
15688 printf("\n");
15689 }
15690 printf(" Cumulated energy : %-g GeV",AvEbkgOn);
15691 if (AvSolidangleOn) printf(" --> %-g GeV sr^-1",AvEbkgOn/AvSolidangleOn);
15692 printf("\n");
15693 printf(" Power : %-g GeV/s",AvEbkgOn/TwinOn);
15694 if (AvSolidangleOn) printf(" --> %-g GeV s^-1 sr^-1",AvEbkgOn/(TwinOn*AvSolidangleOn));
15695 printf("\n");
15696 if (fSensarea>0)
15697 {
15698 printf(" Energy fluence : %-g GeV cm^-2",AvEbkgOn/fSensarea);
15699 if (AvSolidangleOn) printf(" --> %-g GeV cm^-2 sr^-1",AvEbkgOn/(fSensarea*AvSolidangleOn));
15700 printf("\n");
15701 printf(" Energy flux : %-g GeV cm^-2 s^-1",AvEbkgOn/(fSensarea*TwinOn));
15702 if (AvSolidangleOn) printf(" --> Intensity : %-g GeV cm^-2 s^-1 sr^-1",AvEbkgOn/(fSensarea*TwinOn*AvSolidangleOn));
15703 printf("\n");
15704 }
15705 }
15706 printf("\n");
15707
15708 // Create the simulated incoming signal Fluence vs. E histogram
15709 nsig=fBurstSigAeff.GetN();
15710 if (nsig && Ton)
15711 {
15712 TString nameS,titleS,nameF,titleF,nameE2F,titleE2F;
15713 nameS="hSigFluence";
15714 titleS="Stacked simulated incoming signal Fluence;Event energy [GeV];dN/dE [GeV^{-1} cm^{-2}]";
15715 nameF="hSigFlux";
15716 titleF="Simulated incoming signal Flux for a steady rate;Event energy [GeV];dN/dE [GeV^{-1} cm^{-2} s^{-1}]";
15717 nameE2F="hSigE2Flux";
15718 titleE2F="E-scaled simulated incoming signal Flux for a steady rate;Event energy [GeV];E^{2}dN/dE [GeV cm^{-2} s^{-1}]";
15719 TH1F* hS=(TH1F*)fBurstHistos.FindObject(nameS);
15720 TH1F* hF=(TH1F*)fBurstHistos.FindObject(nameF);
15721 TH1F* hE2F=(TH1F*)fBurstHistos.FindObject(nameE2F);
15722 if (hS)
15723 {
15724 delete hS;
15725 hS=new TH1F(nameS,titleS,100,0,-1);
15726 delete hF;
15727 hF=new TH1F(nameF,titleF,100,0,-1);
15728 delete hE2F;
15729 hE2F=new TH1F(nameE2F,titleE2F,100,0,-1);
15730 }
15731 else
15732 {
15733 hS=new TH1F(nameS,titleS,100,0,-1);
15734 fBurstHistos.Add(hS);
15735 hF=new TH1F(nameF,titleF,100,0,-1);
15736 fBurstHistos.Add(hF);
15737 hE2F=new TH1F(nameE2F,titleE2F,100,0,-1);
15738 fBurstHistos.Add(hE2F);
15739 }
15740
15741 hS->Sumw2();
15742 hF->Sumw2();
15743 hE2F->Sumw2();
15744
15745 Float_t E=0;
15746 Float_t Fluence=0;
15747 for (Int_t i=1; i<=nsig; i++)
15748 {
15749 Fluence=fBurstSigAeff.GetEntry(i,"Fluence");
15750 E=fBurstSigAeff.GetEntry(i,"E");
15751 if (Fluence>0)
15752 {
15753 hS->Fill(E,Fluence);
15754 hF->Fill(E,Fluence/Ton);
15755 hE2F->Fill(E,pow(E,2)*Fluence/Ton);
15756 }
15757 }
15758
15759 // Convert the histogram data into dN/dE
15760 // Flush the storage buffers to actually fill the histograms
15761 hS->BufferEmpty(1);
15762 hF->BufferEmpty(1);
15763 hE2F->BufferEmpty(1);
15764 Float_t binwidth=hS->GetBinWidth(1);
15765 if (binwidth>0)
15766 {
15767 hS->Scale(1./binwidth);
15768 hF->Scale(1./binwidth);
15769 hE2F->Scale(1./binwidth);
15770 }
15771 }
15772
15773 // Update internal statistics
15774 fBurstParameters->AddNamedSlot("TminOn");
15775 fBurstParameters->SetSignal(TminOn,"TminOn");
15776 fBurstParameters->AddNamedSlot("TmaxOn");
15777 fBurstParameters->SetSignal(TmaxOn,"TmaxOn");
15778 fBurstParameters->AddNamedSlot("TminOff");
15779 fBurstParameters->SetSignal(TminOff,"TminOff");
15780 fBurstParameters->AddNamedSlot("TmaxOff");
15781 fBurstParameters->SetSignal(TmaxOff,"TmaxOff");
15782 fBurstParameters->AddNamedSlot("DtwinOn");
15783 fBurstParameters->SetSignal(DtwinOn,"DtwinOn");
15784 fBurstParameters->AddNamedSlot("DtwinOff");
15785 fBurstParameters->SetSignal(DtwinOff,"DtwinOff");
15786 fBurstParameters->AddNamedSlot("NbkgWinOn");
15787 fBurstParameters->SetSignal(NbkgWinOn,"NbkgWinOn");
15788 fBurstParameters->AddNamedSlot("NbkgWinOff");
15789 fBurstParameters->SetSignal(NbkgWinOff,"NbkgWinOff");
15790 fBurstParameters->AddNamedSlot("TtotOn"); // The on-source total exposure time in sec.
15791 fBurstParameters->SetSignal(Ton,"TtotOn");
15792 fBurstParameters->AddNamedSlot("TtotOff"); // The off-source total exposure time ins sec.
15793 fBurstParameters->SetSignal(Toff,"TtotOff");
15794 fBurstParameters->AddNamedSlot("AvSolidangleOn"); // The average on-source solid angle
15795 fBurstParameters->SetSignal(AvSolidangleOn,"AvSolidangleOn");
15796 fBurstParameters->AddNamedSlot("AvSolidangleOff"); // The average off-source solid angle
15797 fBurstParameters->SetSignal(AvSolidangleOff,"AvSolidangleOff");
15798
15799 fBurstParameters->AddNamedSlot("rateOn");
15800 fBurstParameters->SetSignal(rateOn,"rateOn");
15801 fBurstParameters->AddNamedSlot("rateOff");
15802 fBurstParameters->SetSignal(rateOff,"rateOff");
15803
15804 // Update old parameters
15805 fBurstParameters->SetSignal(TminOn,"Tmin");
15806 fBurstParameters->SetSignal(TmaxOn,"Tmax");
15807 fBurstParameters->SetSignal(DtwinOn,"Dtwin");
15808 fBurstParameters->SetSignal(NbkgWinOn,"NbkgWin");
15809}
15810
15811void NcAstrolab::MatchBurstData(NcDevice& matches,Int_t i1,Int_t i2,Int_t itype,Int_t j1,Int_t j2,Int_t jtype)
15812{
15907
15908 Float_t fAngresfix=fBurstParameters->GetSignal("Angresfix");
15909 Int_t fRecoangle=TMath::Nint(fBurstParameters->GetSignal("Recoangle"));
15910 Int_t fSumsigmas=TMath::Nint(fBurstParameters->GetSignal("Sumsigmas"));
15911 Int_t fTunits=TMath::Nint(fBurstParameters->GetSignal("Tunits"));
15912 Float_t fTmin=fBurstParameters->GetSignal("Tmin");
15913 Float_t fTmax=fBurstParameters->GetSignal("Tmax");
15914 Float_t fDawin=fBurstParameters->GetSignal("Dawin");
15915 Int_t fDatype=TMath::Nint(fBurstParameters->GetSignal("Datype"));
15916 Float_t fMaxsigmatot=fBurstParameters->GetSignal("Maxsigmatot");
15917 Int_t fNbkg=TMath::Nint(fBurstParameters->GetSignal("Nbkg"));
15918
15919 // Update internal statistics to account for objects introduced by hand
15920 Int_t fNgrbs=GetNsignals(0);
15921 Int_t fNevts=GetNsignals(1);
15922 fBurstParameters->AddNamedSlot("Ngrbs");
15923 fBurstParameters->AddNamedSlot("Nevts");
15924 fBurstParameters->SetSignal(fNgrbs,"Ngrbs");
15925 fBurstParameters->SetSignal(fNevts,"Nevts");
15926
15927 // Initialize generic histograms for analysis
15929
15930 TString tu="d";
15931 if (fTunits==1) tu="hrs";
15932 if (fTunits==2) tu="s";
15933 if (fTunits==3) tu="ns";
15934 if (fTunits==4) tu="ps";
15935
15936 // Initialize the Device/Hit structure to contain the correlation info
15937 matches.Reset(1);
15938 matches.SetHitCopy(1);
15939
15940 TString name="Matches";
15941 TString title="Space and time matchings of NcAstrolab stored signals";
15942 matches.SetNameTitle(name,title);
15943 TString tux=tu;
15944 if (tu=="d") tux="days";
15945 if (tu=="hrs") tux="hours";
15946 if (tu=="s") tux="sec";
15947 TString namedamin="psimin in deg";
15948 TString namedtmin="dtmin in ";
15949 namedtmin+=tux;
15950 matches.AddNamedSlot(namedamin);
15951 matches.AddNamedSlot(namedtmin);
15952 matches.AddNamedSlot("ipsi");
15953 matches.AddNamedSlot("idt");
15954
15955 NcSignal data;
15956 TString nameda="psi in deg";
15957 TString namedt="t2-t1 in ";
15958 namedt+=tux;
15959 data.AddNamedSlot("type1");
15960 data.AddNamedSlot("index1");
15961 data.AddNamedSlot("type2");
15962 data.AddNamedSlot("index2");
15963 data.AddNamedSlot(nameda);
15964 data.AddNamedSlot(namedt);
15965
15966 if ((!itype || !jtype) && !fRefs)
15967 {
15968 printf(" *%-s::MatchBurstData* Error: itype=%-i jtype=%-i but no reference signals are present. \n",ClassName(),itype,jtype);
15969 return;
15970 }
15971
15972 if ((itype || jtype) && !fSigs)
15973 {
15974 printf(" *%-s::MatchBurstData* Error: itype=%-i jtype=%-i but no measurements are present. \n",ClassName(),itype,jtype);
15975 return;
15976 }
15977
15978 Int_t nrefs=0;
15979 if (fRefs) nrefs=fRefs->GetSize();
15980 Int_t nsigs=0;
15981 if (fSigs) nsigs=fSigs->GetSize();
15982
15983 // Make input data consistent with conventions
15984 if (itype) itype=1;
15985 if (jtype) jtype=1;
15986 if (!itype)
15987 {
15988 if (i2<1 || i2>nrefs) i2=nrefs;
15989 }
15990 else
15991 {
15992 if (i2<1 || i2>nsigs) i2=nsigs;
15993 }
15994 if (!jtype)
15995 {
15996 if (j2<1 || j2>nrefs) j2=nrefs;
15997 }
15998 else
15999 {
16000 if (j2<1 || j2>nsigs) j2=nsigs;
16001 }
16002
16003 if (i1<1 || j1<1 || i1>i2 || j1>j2)
16004 {
16005 printf(" *%-s::MatchBurstData* Inconsistent parameters: i1=%-i i2=%-i itype=%-i j1=%-i j2=%-i jtype=%-i. \n",ClassName(),i1,i2,itype,j1,j2,jtype);
16006 return;
16007 }
16008
16009 if (fDatype==1 && fMaxsigmatot<0)
16010 {
16011 printf(" *%-s::MatchBurstData* Incompatible parameter settings Datype=%-i Maxsigmatot=%-g \n",ClassName(),fDatype,fMaxsigmatot);
16012 printf(" === No matching analysis will be performed === \n");
16013 }
16014
16015 // The number of actually stored items
16016 Int_t ni=GetNsignals(itype);
16017 Int_t nj=GetNsignals(jtype);
16018
16019 // Additional text for histo titles to indicate scrambling of the corresponding data
16020 TString scrt=""; // Time scrambling
16021 TString scrp=""; // Position scrambling
16022 if (fTscmode>0) scrt="(scrambled)";
16023 if (fRscmode>0 || fTscmode==3) scrp="(scrambled)";
16024
16025 // The auto binned event-burst time difference histo for the full selected sample
16026 Int_t nbins=10000;
16027 title.Form("Time difference %-s between events and bursts for the full selected dataset;Tevent-Tburst in %-s;Counts",scrt.Data(),tux.Data());
16028 TH1F* hTdiff=new TH1F("hTdiff",title,nbins,1,0);
16029 if (ni && nj) hTdiff->SetBuffer(ni*nj);
16030
16031 // The auto binned event-burst angular difference histo for the full selected sample
16032 nbins=100;
16033 title.Form("Angular separation %-s between events and bursts for the full selected dataset;Opening angle in degrees;Counts",scrp.Data());
16034 TH1F* hAdiff=new TH1F("hAdiff",title,nbins,1,0);
16035 if (ni && nj) hAdiff->SetBuffer(ni*nj);
16036
16037 // Recording of the cumulated on-source reconstructed event energy
16038 fBurstParameters->AddNamedSlot("EnergyOn");
16039 fBurstParameters->AddNamedSlot("EnergyOff");
16040
16041 Double_t dang,dtime,diftheta;
16042 Int_t ix=0;
16043 Int_t jx=0;
16044 NcSignal* sxi=0;
16045 NcSignal* sxj=0;
16046 NcSignal* sxgrb=0;
16047 NcSignal* sxevt=0;
16048 Float_t sigmai=0;
16049 Float_t sigmaj=0;
16050 Float_t sigmagrb=0;
16051 Float_t sigmareco=0;
16052 Float_t sigmatot=0;
16053 Int_t id=0;
16054 Double_t dangmin=0;
16055 Double_t dtmin=0;
16056 Int_t idamin=0;
16057 Int_t idtmin=0;
16058 Bool_t first=kTRUE;
16059 Double_t dangmax=-1;
16060 Float_t Ereco=0;
16061 Float_t thlow=0;
16062 Float_t thup=0;
16063 Float_t thetagrb=0;
16064 Float_t solidangle=0;
16065 Int_t grbtype=0;
16066 Int_t evttype=0;
16067 Int_t k1=0;
16068 Int_t k2=0;
16069 Float_t zgrb=0;
16070 Int_t idx=0;
16071 NcTimestamp* tx=0;
16072 Nc3Vector rmu;
16073 Float_t thetamu=0;
16074 TH2* hAeffProfile=(TH2*)fBurstHistos.FindObject("hAeffProfile");
16075 Int_t gbin=0;
16076 Double_t Aeff=0;
16077 Double_t Fluence=0;
16078 for (Int_t bkgpatch=0; bkgpatch<=fNbkg; bkgpatch++) // On-source and Off-source patches
16079 {
16080 if (bkgpatch && !fTscmode && !fRscmode) break; // No background data without time and/or position scrambling
16081
16082 for (Int_t i=i1; i<=i2; i++)
16083 {
16084 sxi=GetSignal(i,itype);
16085 if (!sxi) continue;
16086
16087 sigmai=sxi->GetSignal("csigma");
16088
16089 if (itype && !fRecoangle) sigmai=fAngresfix;
16090
16091 for (Int_t j=j1; j<=j2; j++)
16092 {
16093 // Skip matching a signal with itself
16094 if (itype==jtype && i==j) continue;
16095
16096 sxj=GetSignal(j,jtype);
16097 if (!sxj) continue;
16098
16099 sigmaj=sxj->GetSignal("csigma");
16100
16101 if (jtype && !fRecoangle) sigmaj=fAngresfix;
16102
16103 if (itype==jtype) // Self correlations
16104 {
16105 sigmagrb=sigmai;
16106 sxgrb=sxi;
16107 grbtype=itype;
16108 sigmareco=sigmaj;
16109 sxevt=sxj;
16110 evttype=jtype;
16111 }
16112 else // Correlations between sources and measurements
16113 {
16114 if (itype)
16115 {
16116 sigmareco=sigmai;
16117 sxevt=sxi;
16118 evttype=itype;
16119 sigmagrb=sigmaj;
16120 sxgrb=sxj;
16121 grbtype=jtype;
16122 }
16123 else
16124 {
16125 sigmagrb=sigmai;
16126 sxgrb=sxi;
16127 grbtype=itype;
16128 sigmareco=sigmaj;
16129 sxevt=sxj;
16130 evttype=jtype;
16131 }
16132 }
16133
16134 sigmatot=-1;
16135 if (fSumsigmas==-1) sigmatot=sigmareco;
16136 if (fSumsigmas==0) sigmatot=sigmagrb;
16137 if (fSumsigmas==1) sigmatot=sigmagrb+sigmareco;
16138 if (fSumsigmas==2) sigmatot=sqrt(sigmagrb*sigmagrb+sigmareco*sigmareco);
16139
16140 dangmax=-1;
16141 if (!fDatype) dangmax=fabs(fDawin);
16142 if (fDatype==1)
16143 {
16144 dangmax=0;
16145 if (fMaxsigmatot>0) dangmax=fabs(fDawin*fMaxsigmatot);
16146 }
16147 if (fDatype==2)
16148 {
16149 if (sigmatot>=0) dangmax=fabs(fDawin*sigmatot);
16150 }
16151
16152 // Flag incompatible input for sigma summation
16153 if (fDatype==1 && fMaxsigmatot<0) dangmax=-1;
16154
16155 ix=i;
16156 if (itype) ix=-i;
16157 jx=j;
16158 if (jtype) jx=-j;
16159
16160 if (tu!="hrs")
16161 {
16162 dang=GetSeparation(ix,jx,"deg",dtime,tu,1,bkgpatch,&diftheta);
16163 }
16164 else
16165 {
16166 dang=GetSeparation(ix,jx,"deg",dtime,"s",1,bkgpatch,&diftheta);
16167 dtime=dtime/3600.;
16168 }
16169
16170 if (!bkgpatch) // On-source data
16171 {
16172 // Fill the time difference histogram for full selected dataset
16173 if (hTdiff) hTdiff->Fill(dtime);
16174
16175 // Fill the angular difference histogram for full selected dataset
16176 if (hAdiff) hAdiff->Fill(dang);
16177
16178 // Initialize the On-source total solid angle for this source
16179 if (dangmax>=0 && !(sxgrb->GetSlotIndex("OmegaOn")))
16180 {
16181 sxgrb->AddNamedSlot("OmegaOn");
16182 if (fDawin<0) // Local zenith band
16183 {
16184 thlow=thetagrb-0.5*dangmax;
16185 thup=thetagrb+0.5*dangmax;
16186 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
16187 }
16188 else // Circle around GRB position
16189 {
16190 thlow=0;
16191 thup=dangmax;
16192 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
16193 }
16194 sxgrb->SetSignal(solidangle,"OmegaOn");
16195 }
16196 }
16197 else // Off-source c.q. background data
16198 {
16199 // Initialize the Off-source total solid angle for this source
16200 if (dangmax>=0 && !(sxgrb->GetSlotIndex("OmegaOff")))
16201 {
16202 sxgrb->AddNamedSlot("OmegaOff");
16203 if (fDawin<0) // Local zenith band
16204 {
16205 thlow=thetagrb-0.5*dangmax;
16206 thup=thetagrb+0.5*dangmax;
16207 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
16208 }
16209 else // Circle around GRB position
16210 {
16211 thlow=0;
16212 thup=dangmax;
16213 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
16214 }
16215 sxgrb->SetSignal(solidangle,"OmegaOff");
16216 }
16217 }
16218
16219 if (fDatype>=0)
16220 {
16221 if (fDawin<0) // Declination band
16222 {
16223 if (diftheta<thlow || diftheta>thup) continue;
16224 }
16225 else // Circle around the GRB
16226 {
16227 if (fabs(dang)>dangmax) continue;
16228 }
16229 }
16230
16231 if (fTmax>fTmin && (dtime<fTmin || dtime>fTmax)) continue;
16232
16233 if (!bkgpatch) // On-source data
16234 {
16235 // Tag this source of having an on-source matching event
16236 if (!(sxgrb->GetSlotIndex("HasMatchOn")))
16237 {
16238 sxgrb->AddNamedSlot("HasMatchOn");
16239 sxgrb->SetSignal(1,"HasMatchOn");
16240 }
16241
16242 data.Reset();
16243 name="Object1=";
16244 name+=sxi->GetName();
16245 title="Object2=";
16246 title+=sxj->GetName();
16247 id++;
16248 data.SetNameTitle(name,title);
16249 data.SetUniqueID(id);
16250 data.SetSignal(itype,"type1");
16251 data.SetSignal(i,"index1");
16252 data.SetSignal(jtype,"type2");
16253 data.SetSignal(j,"index2");
16254 data.SetSignal(dtime,namedt);
16255 data.SetSignal(dang,nameda);
16256 matches.AddHit(data);
16257
16258 // Update the maximum encountered dynamic On-source solid angle for this source
16259 if (fDatype==2)
16260 {
16261 if (fDawin<0) // Local zenith band
16262 {
16263 thlow=thetagrb-0.5*dangmax;
16264 thup=thetagrb+0.5*dangmax;
16265 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
16266 }
16267 else // Circle around GRB position
16268 {
16269 thlow=0;
16270 thup=dangmax;
16271 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
16272 }
16273 if (solidangle>sxgrb->GetSignal("OmegaOn")) sxgrb->SetSignal(solidangle,"OmegaOn");
16274 }
16275 }
16276 else // Off-source c.q. background data
16277 {
16278 // Tag this source of having an off-source matching event
16279 if (!(sxgrb->GetSlotIndex("HasMatchOff")))
16280 {
16281 sxgrb->AddNamedSlot("HasMatchOff");
16282 sxgrb->SetSignal(1,"HasMatchOff");
16283 }
16284
16285 // Update the maximum encountered dynamic Off-source solid angle for this source
16286 if (fDatype==2)
16287 {
16288 if (fDawin<0) // Local zenith band
16289 {
16290 thlow=thetagrb-0.5*dangmax;
16291 thup=thetagrb+0.5*dangmax;
16292 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
16293 }
16294 else // Circle around GRB position
16295 {
16296 thlow=0;
16297 thup=dangmax;
16298 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
16299 }
16300 if (solidangle>sxgrb->GetSignal("OmegaOff")) sxgrb->SetSignal(solidangle,"OmegaOff");
16301 }
16302 }
16303
16304 // Fill the histograms for the matching data
16305 if (!bkgpatch) // On-source data
16306 {
16307 Ereco=sxevt->GetSignal("E");
16308 zgrb=sxgrb->GetSignal("z");
16309 fBurstOnReco.Enter(zgrb,sigmagrb,sigmareco,sigmatot);
16310 fBurstOnMatch.Enter(Ereco,dtime,dang,dtime/(zgrb+1.));
16311 fBurstParameters->AddSignal(Ereco,"EnergyOn");
16312 if (hAeffProfile)
16313 {
16314 nbins=(hAeffProfile->GetNbinsX())*(hAeffProfile->GetNbinsY());
16315 idx=GetSignalIndex(sxevt,evttype);
16316 if (idx>0)
16317 {
16318 tx=sxevt->GetTimestamp();
16319 GetSignal(rmu,"loc","T",tx,idx,evttype);
16320 thetamu=rmu.GetX(2,"sph","rad");
16321 gbin=hAeffProfile->FindFixBin(log10(Ereco),cos(thetamu));
16322 if (gbin>0 && gbin<nbins+1)
16323 {
16324 Aeff=hAeffProfile->GetBinContent(gbin);
16325 if (Aeff>0)
16326 {
16327 Fluence=1./Aeff;
16328 fBurstOnAeff.Enter(Aeff,Fluence,Ereco,dang);
16329 }
16330 }
16331 }
16332 }
16333
16334 // Record the data for the minimal encountered opening angle
16335 if (first || fabs(dang)<dangmin)
16336 {
16337 dangmin=fabs(dang);
16338 idamin=id;
16339 }
16340
16341 // Record the data for the minimal encountered time difference
16342 if (first || fabs(dtime)<fabs(dtmin))
16343 {
16344 dtmin=dtime;
16345 idtmin=id;
16346 }
16347
16348 first=kFALSE;
16349 }
16350 else // Off-source c.q. backgound data
16351 {
16352 Ereco=sxevt->GetSignal("E");
16353 zgrb=sxgrb->GetSignal("z");
16354 fBurstOffReco.Enter(zgrb,sigmagrb,sigmareco,sigmatot);
16355 fBurstOffMatch.Enter(Ereco,dtime,dang,dtime/(zgrb+1.));
16356 fBurstParameters->AddSignal(Ereco,"EnergyOff");
16357 if (hAeffProfile)
16358 {
16359 nbins=(hAeffProfile->GetNbinsX())*(hAeffProfile->GetNbinsY());
16360 idx=GetSignalIndex(sxevt,evttype);
16361 if (idx>0)
16362 {
16363 tx=sxevt->GetTimestamp();
16364 GetSignal(rmu,"loc","T",tx,idx,evttype);
16365 thetamu=rmu.GetX(2,"sph","rad");
16366 gbin=hAeffProfile->FindFixBin(log10(Ereco),cos(thetamu));
16367 if (gbin>0 && gbin<nbins+1)
16368 {
16369 Aeff=hAeffProfile->GetBinContent(gbin);
16370 if (Aeff>0)
16371 {
16372 Fluence=1./Aeff;
16373 fBurstOffAeff.Enter(Aeff,Fluence,Ereco,dang);
16374 }
16375 }
16376 }
16377 }
16378 }
16379 } // End of the j-loop
16380 } // End of the i-loop
16381 } // End of loop over the patches
16382
16383 // Store the filled histograms in the storage container
16384 if (hTdiff->GetEntries()) fBurstHistos.Add(hTdiff);
16385 if (hAdiff->GetEntries()) fBurstHistos.Add(hAdiff);
16386
16387 // Recording of the On-source and Off-source total stacked solid angles
16388 name="SolidangleOn";
16389 fBurstParameters->AddNamedSlot(name);
16390 fBurstParameters->SetSignal(0,name);
16391 name="SolidangleOff";
16392 fBurstParameters->AddNamedSlot(name);
16393 fBurstParameters->SetSignal(0,name);
16394 if (itype==jtype) // Self correlations
16395 {
16396 grbtype=itype;
16397 k1=i1;
16398 k2=i2;
16399 }
16400 else // Correlations between sources and measurements
16401 {
16402 if (itype)
16403 {
16404 grbtype=jtype;
16405 k1=j1;
16406 k2=j2;
16407 }
16408 else
16409 {
16410 grbtype=itype;
16411 k1=i1;
16412 k2=i2;
16413 }
16414 }
16415 // Loop over all grbs in the selection
16416 for (Int_t k=k1; k<=k2; k++)
16417 {
16418 sxgrb=GetSignal(k,grbtype);
16419 if (!sxgrb) continue;
16420
16421 solidangle=sxgrb->GetSignal("OmegaOn");
16422 fBurstParameters->AddSignal(solidangle,"SolidangleOn");
16423
16424 solidangle=sxgrb->GetSignal("OmegaOff");
16425 fBurstParameters->AddSignal(solidangle*float(fNbkg),"SolidangleOff");
16426 }
16427
16428 // Store the data for the minimal encountered opening angle and time difference
16429 matches.SetSignal(dangmin,namedamin);
16430 matches.SetSignal(dtmin,namedtmin);
16431 matches.SetSignal(idamin,"ipsi");
16432 matches.SetSignal(idtmin,"idt");
16433
16434 // Determine and list the burst statistics
16436}
16437
16438void NcAstrolab::MatchBurstData(NcDevice& matches,TString name,Int_t itype,Int_t j1,Int_t j2,Int_t jtype)
16439{
16538
16539 Int_t i=GetSignalIndex(name,itype);
16540
16541 if (i==-1) // Add the info for the requested Solar system object if not already stored
16542 {
16543 SetSolarSystem(name,0,itype);
16544 i=GetSignalIndex(name,itype);
16545 if (i>0) fSolUpdate=1;
16546 }
16547
16548 if (i<1)
16549 {
16550 printf(" *%-s::MatchBurstData* Object %-s not found for itype=%-i. \n",ClassName(),name.Data(),itype);
16551 }
16552 else
16553 {
16554 MatchBurstData(matches,i,i,itype,j1,j2,jtype);
16555 }
16556
16557 fSolUpdate=0;
16558}
16559
16561{
16574
16575 // Retreive the needed parameters
16576 Float_t fT90min=fBurstParameters->GetSignal("T90min");
16577 Float_t fT90max=fBurstParameters->GetSignal("T90max");
16578 Float_t fAlphasig=fBurstParameters->GetSignal("Alphasig");
16579 Float_t fAlphabkg=fBurstParameters->GetSignal("Alphabkg");
16580 Float_t fAvgrbz=fBurstParameters->GetSignal("Avgrbz");
16581 Float_t fAvgrbt90=fBurstParameters->GetSignal("Avgrbt90");
16582 Int_t fTunits=TMath::Nint(fBurstParameters->GetSignal("Tunits"));
16583
16584 TString tu="days";
16585 if (fTunits==1) tu="hours";
16586 if (fTunits==2) tu="sec";
16587 if (fTunits==3) tu="ns";
16588 if (fTunits==4) tu="ps";
16589
16590 TString title;
16591 TString s;
16592
16593 // Initialize the On-source and Off-source data samples
16594 fBurstOnReco.Reset();
16595 fBurstOnMatch.Reset();
16596 fBurstSigReco.Reset();
16597 fBurstSignal.Reset();
16598 fBurstOffReco.Reset();
16599 fBurstOffMatch.Reset();
16600 fBurstOnReco.SetNameTitle("BurstOnReco","On-source reco data");
16601 fBurstOnReco.SetStoreMode();
16602 fBurstOnReco.SetNames("zburst","sigmaburst","sigmareco","sigmacomb");
16603 fBurstOnMatch.SetNameTitle("BurstOnMatch","On-source matching data");
16604 fBurstOnMatch.SetStoreMode();
16605 fBurstOnMatch.SetNames("E","dtime","dang","dtimez");
16606 fBurstSigReco.SetNameTitle("BurstSigReco","Simulated signal reco data");
16607 fBurstSigReco.SetStoreMode();
16608 fBurstSigReco.SetNames("zburst","sigmaburst","sigmareco","sigmacomb");
16609 fBurstSignal.SetNameTitle("BurstSignal","Simulated signal events");
16610 fBurstSignal.SetStoreMode();
16611 fBurstSignal.SetNames("E","dtime","dang","dtimez");
16612 fBurstOffReco.SetNameTitle("BurstOffReco","Off-source reco data");
16613 fBurstOffReco.SetStoreMode();
16614 fBurstOffReco.SetNames("zburst","sigmaburst","sigmareco","sigmacomb");
16615 fBurstOffMatch.SetNameTitle("BurstOffMatch","Off-source matching data");
16616 fBurstOffMatch.SetStoreMode();
16617 fBurstOffMatch.SetNames("E","dtime","dang","dtimez");
16618 fBurstOnAeff.Reset();
16619 fBurstOffAeff.Reset();
16620 fBurstSigAeff.Reset();
16621 fBurstOnAeff.SetNameTitle("BurstOnAeff","On-source track Aeff, E and dang data");
16622 fBurstOnAeff.SetStoreMode();
16623 fBurstOnAeff.SetNames("Aeff","Fluence","E","dang");
16624 fBurstOffAeff.SetNameTitle("BurstOffAeff","Off-source track Aeff, E and dang data");
16625 fBurstOffAeff.SetStoreMode();
16626 fBurstOffAeff.SetNames("Aeff","Fluence","E","dang");
16627 fBurstSigAeff.SetNameTitle("BurstSigAeff","Simulated signal track Aeff, E and dang data");
16628 fBurstSigAeff.SetStoreMode();
16629 fBurstSigAeff.SetNames("Aeff","Fluence","E","dang");
16630
16631 // Set default simulation signal and background energy spectra if needed
16632 if (!mode)
16633 {
16634 TH1* edist=0;
16635 edist=(TH1*)fBurstHistos.FindObject("hSigEprofile");
16636 if (!edist) MakeBurstEnergydist("SigE",fAlphasig,10000);
16637 edist=(TH1*)fBurstHistos.FindObject("hBkgEprofile");
16638 if (!edist) MakeBurstEnergydist("BkgE",fAlphabkg,10000);
16639 }
16640
16642 // Some statistics from the loaded data //
16644
16645 Int_t fNgrbs=GetNsignals(0);
16646 Int_t fNevts=GetNsignals(1);
16647
16648 Float_t xmin=0;
16649 Float_t xmax=0;
16650 Float_t range=0;
16651 Int_t nbins=100;
16652 Float_t binsize=0;
16653 Int_t srcbufsize=10000;
16654 if (fNgrbs && fNgrbs<srcbufsize) srcbufsize=fNgrbs;
16655 Int_t evtbufsize=10000;
16656 if (fNevts && fNevts<evtbufsize) evtbufsize=fNevts;
16657
16658 // Creation of the burst redshift histo
16659 title.Form("Redshifts for the selected source sample;Redshift;Counts");
16660 TH1F* hSourceZ=new TH1F("hSourceZ",title,nbins,1,0);
16661 hSourceZ->SetBuffer(srcbufsize);
16662
16663 // Creation of the corresponding physical distance histo
16664 nbins=100;
16665 title.Form("Distances for the selected source sample derived from the redshifts;Physical distance in Mpc;Counts");
16666 TH1F* hSourceD=new TH1F("hSourceD",title,nbins,xmin,xmax);
16667 hSourceD->SetBuffer(srcbufsize);
16668
16669 // Creation of the burst t90 duration histo
16670 xmin=-5;
16671 if (fabs(fT90min)>0) xmin=log10(fabs(fT90min));
16672 xmax=5;
16673 if (fT90max>0) xmax=log10(fT90max);
16674 range=xmax-xmin;
16675 binsize=0.2; // Bins of 0.2
16676 nbins=TMath::Nint(range/binsize);
16677 if (nbins<1)
16678 {
16679 xmin=xmin-1.;
16680 xmax=xmax+1.;
16681 nbins=10;
16682 }
16683 title.Form("Burst durations for the selected source sample;Burst duration ^{10}log(T90) in sec.;Counts");
16684 TH1F* hBurstT90=new TH1F("hBurstT90",title,nbins,xmin,xmax);
16685
16686 // Creation of the full selected sample burst position uncertainty histo with automatic binning
16687 nbins=100;
16688 title.Form("Position uncertainties for the selected source sample;Position angular uncertainty (sigma in degrees);Counts");
16689 TH1F* hSigmaSource=new TH1F("hSigmaSource",title,nbins,1,0);
16690 hSigmaSource->SetBuffer(srcbufsize);
16691
16692 // Creation of the real event reconstructed energy histo with automatic binning
16693 TH1F* hEreco=0;
16694 nbins=1000;
16695 if (mode==1)
16696 {
16697 title.Form("Reconstructed energy for the full selected real event sample;Reconstructed event energy in GeV;Counts");
16698 hEreco=new TH1F("hEreco",title,nbins,1,0);
16699 hEreco->SetBuffer(evtbufsize);
16700 }
16701
16702 // Creation of the injected source signal event energy histo with automatic binning
16703 TH1F* hSigE=0;
16704 TH1F* hSigEzcor=0;
16705 nbins=1000;
16706 if (mode==0)
16707 {
16708 title.Form("Injected signal energy at the source;Event energy in GeV;Counts");
16709 hSigE=new TH1F("hSigE",title,nbins,1,0);
16710 fBurstHistos.Add(hSigE);
16711 title.Form("(Redshift corrected) injected signal energy arriving at Earth;Event energy in GeV;Counts");
16712 hSigEzcor=new TH1F("hSigEzcor",title,nbins,1,0);
16713 fBurstHistos.Add(hSigEzcor);
16714 }
16715
16716 // Creation of the full selected sample event reconstruction uncertainty histo with automatic binning
16717 TH1F* hSigmaReco=0;
16718 nbins=100;
16719 title.Form("Event reconstruction uncertainties for the full selected sample;Event angular reconstruction uncertainty (sigma in degrees);Counts");
16720 hSigmaReco=new TH1F("hSigmaReco",title,nbins,1,0);
16721 hSigmaReco->SetBuffer(evtbufsize);
16722
16723 // Fill the generic source c.q. burst histograms
16724 NcSignal* sx=0;
16725 Float_t zgrb=0;
16726 Double_t dgrb=0;
16727 Float_t t90grb=0;
16728 Float_t sigmagrb=0;
16729 NcSample zsample;
16730 zsample.SetStoreMode();
16731 NcSample t90sample;
16732 t90sample.SetStoreMode();
16733 NcSample sigmasample;
16734 sigmasample.SetStoreMode();
16735 Int_t nsig=GetNsignals(0,1);
16736 for (Int_t i=1; i<=nsig; i++)
16737 {
16738 sx=GetSignal(i,0);
16739
16740 if (!sx) continue;
16741
16742 zgrb=sx->GetSignal("z");
16743 dgrb=GetPhysicalDistance(zgrb);
16744 t90grb=sx->GetSignal("T90");
16745 sigmagrb=sx->GetSignal("csigma");
16746
16747 hSourceZ->Fill(zgrb);
16748 hSourceD->Fill(dgrb);
16749 if (t90grb>0) hBurstT90->Fill(log10(t90grb));
16750 hSigmaSource->Fill(sigmagrb);
16751
16752 if (fAvgrbz<0) zsample.Enter(zgrb);
16753 if (fAvgrbt90<0) t90sample.Enter(t90grb);
16754 sigmasample.Enter(sigmagrb);
16755 }
16756
16757 // Add the filled histograms to the storage container
16758 if (hSourceZ->GetEntries()) fBurstHistos.Add(hSourceZ);
16759 if (hSourceD->GetEntries()) fBurstHistos.Add(hSourceD);
16760 if (hBurstT90->GetEntries()) fBurstHistos.Add(hBurstT90);
16761 if (hSigmaSource->GetEntries()) fBurstHistos.Add(hSigmaSource);
16762
16763 // Determine median redshift if requested
16764 if (fAvgrbz<0)
16765 {
16766 fAvgrbz=zsample.GetMedian(1);
16767 fAvgrbz*=-1.;
16768 }
16769
16770 // Determine median T90 duration if requested
16771 if (fAvgrbt90<0)
16772 {
16773 fAvgrbt90=t90sample.GetMedian(1);
16774 fAvgrbt90*=-1.;
16775 }
16776
16777 Float_t fAvgrbsigma=sigmasample.GetMedian(1);
16778
16779 // Fill the generic event histograms
16780 Float_t sigmareco=0;
16781 Float_t Ereco=0;
16782 nsig=GetNsignals(1,1);
16783 for (Int_t i=1; i<=nsig; i++)
16784 {
16785 sx=GetSignal(i,1);
16786
16787 if (!sx) continue;
16788
16789 sigmareco=sx->GetSignal("csigma");
16790 Ereco=sx->GetSignal("E");
16791
16792 if (hSigmaReco) hSigmaReco->Fill(sigmareco);
16793 if (hEreco) hEreco->Fill(Ereco);
16794 }
16795
16796 // Add the filled histograms to the storage container
16797 if (hSigmaReco->GetEntries()) fBurstHistos.Add(hSigmaReco);
16798 if (hEreco)
16799 {
16800 if (hEreco->GetEntries()) fBurstHistos.Add(hEreco);
16801 }
16802
16803 // Update internal statistics
16804 fBurstParameters->SetSignal(fAvgrbz,"Avgrbz");
16805 fBurstParameters->SetSignal(fAvgrbt90,"Avgrbt90");
16806 fBurstParameters->AddNamedSlot("Avgrbsigma");
16807 fBurstParameters->SetSignal(fAvgrbsigma,"Avgrbsigma");
16808}
16809
16811{
16817
16818 // Retreive the needed parameters
16819 Float_t fGrbnu=fBurstParameters->GetSignal("Grbnu");
16820 Int_t fNgrbs=TMath::Nint(fBurstParameters->GetSignal("Ngrbs"));
16821 Int_t fInburst=TMath::Nint(fBurstParameters->GetSignal("Inburst"));
16822 Float_t fDtnu=fBurstParameters->GetSignal("Dtnu");
16823 Float_t fDtnus=fBurstParameters->GetSignal("Dtnus");
16824 Float_t fTimres=fBurstParameters->GetSignal("Timres");
16825 Int_t fDatype=TMath::Nint(fBurstParameters->GetSignal("Datype"));
16826 Float_t fDawin=fBurstParameters->GetSignal("Dawin");
16827 Float_t fTfact=fBurstParameters->GetSignal("Tfact");
16828 Int_t fEzcor=TMath::Nint(fBurstParameters->GetSignal("Ezcor"));
16829 Int_t fPDFsigE=TMath::Nint(fBurstParameters->GetSignal("PDFsigE"));
16830 Float_t fEmin=fBurstParameters->GetSignal("Emin");
16831 Float_t fEmax=fBurstParameters->GetSignal("Emax");
16832 Int_t fKinangle=TMath::Nint(fBurstParameters->GetSignal("Kinangle"));
16833 Float_t fAngresmin=fBurstParameters->GetSignal("Angresmin");
16834 Float_t fAngresmax=fBurstParameters->GetSignal("Angresmax");
16835 Float_t fAngresfix=fBurstParameters->GetSignal("Angresfix");
16836 Int_t fSumsigmas=TMath::Nint(fBurstParameters->GetSignal("Sumsigmas"));
16837
16838 // Deactivate redshift correction for source signal events from archival observed data
16839 if (!fPDFsigE)
16840 {
16841 fEzcor=0;
16842 fBurstParameters->SetSignal(0,"Ezcor");
16843 }
16844
16845 Int_t nmu=int(fabs(fGrbnu)*float(fNgrbs));
16846 Int_t jgrb=0;
16847 NcSignal* sx=0;
16848 NcTimestamp* tx=0;
16849 Float_t t90grb=0;
16850 Float_t zgrb=0;
16851 Float_t sigmagrb=0;
16852 NcPosition rgrb;
16853 NcPosition rgrb2;
16854 Float_t dt=0;
16855 Double_t dgrb=0;
16856 Double_t thetagrb=0;
16857 Double_t phigrb=0;
16858 Float_t dang=0;
16859 Float_t dangmax=0;
16860 Float_t dangmaxOn=0;
16861 NcPosition rmu;
16862 Double_t E=0;
16863 Double_t sigmareco=0;
16864 Float_t sigmatot=0;
16865 Float_t OmegaOn=0; // The current on-source solid angle probed for a certain GRB
16866 Float_t thlow=0;
16867 Float_t thup=0;
16868 Float_t solidangle=0;
16869 Int_t fixedwinset=0; // Flag to indicate whether a fixed angular search window was set (1) or not (0) for this burst
16870
16871 TH1* hSigE=(TH1*)fBurstHistos.FindObject("hSigE");
16872 TH1* hSigEzcor=(TH1*)fBurstHistos.FindObject("hSigEzcor");
16873 TH2* hAeffProfile=(TH2*)fBurstHistos.FindObject("hAeffProfile");
16874
16875 // The bin numbers and Aeff value in the AeffProfile for the (E,theta) of the track
16876 Int_t nbins=0;
16877 if (hAeffProfile) nbins=(hAeffProfile->GetNbinsX())*(hAeffProfile->GetNbinsY());
16878 Int_t gbin=0; // The global bin number in the histogram
16879 Double_t Aeff=0;
16880 Double_t Fluence=0;
16881 Double_t thetamu=0;
16882
16883 while (nmugrb<nmu)
16884 {
16885 // Pick randomly one of the stored GRBs
16886 jgrb=int(fRan->Uniform(0.,float(fNgrbs)));
16887 if (jgrb==0) jgrb=1;
16888 sx=GetSignal(jgrb);
16889
16890 if (!sx) continue;
16891
16892 tx=sx->GetTimestamp();
16893 GetSignal(dgrb,thetagrb,"deg",phigrb,"deg","loc",tx,jgrb);
16894 rgrb.SetPosition(1,thetagrb,phigrb,"sph","deg");
16895 zgrb=sx->GetSignal("z");
16896 t90grb=sx->GetSignal("T90");
16897 sigmagrb=sx->GetSignal("csigma");
16898 fixedwinset=TMath::Nint(sx->GetSignal("fixedwinset"));
16899 dangmaxOn=sx->GetSignal("dangmaxOn");
16900 OmegaOn=sx->GetSignal("OmegaOn");
16901
16902 dangmax=dangmaxOn;
16903
16904 // Obtain real GRB position
16905 rgrb2.Load(rgrb);
16906 SmearPosition(rgrb2,sigmagrb);
16907
16908 nmugrb++;
16909
16910 if (!fInburst) // Neutrino and gamma production decoupled
16911 {
16912 if (fDtnus<0) // Sigma in units of T90
16913 {
16914 dt=fRan->Gauss(fDtnu,fabs(fDtnus)*t90grb);
16915 }
16916 else // Sigma in seconds
16917 {
16918 dt=fRan->Gauss(fDtnu,fDtnus);
16919 }
16920 dt=dt*(zgrb+1.);
16921 }
16922 else // Coupled neutrino and gamma production
16923 {
16924 if (fDtnus<0) // Sigma in units of T90
16925 {
16926 dt=fRan->Gauss(fDtnu*t90grb,fabs(fDtnus)*t90grb);
16927 }
16928 else // Sigma in seconds
16929 {
16930 dt=fRan->Gauss(fDtnu*t90grb,fDtnus);
16931 }
16932 }
16933 if (fTimres>0) dt=fRan->Gauss(dt,fTimres);
16934
16935 // Convert dt from seconds to the selected Tunits
16936 dt=dt/fTfact;
16937
16938 // The direction of the GRB signal
16939 rmu.Load(rgrb2);
16940
16941 // The energy of the GRB signal
16943
16944 if (hSigE) hSigE->Fill(E);
16945
16946 // Reduce the energy due to the cosmological redshift effect
16947 if (fEzcor) E=E/(zgrb+1.);
16948
16949 if (hSigEzcor) hSigEzcor->Fill(E);
16950
16951 if (E<0 || E<fEmin || E>fEmax) continue;
16952
16953 // Modification to account for the neutrino-lepton kinematic opening angle
16954 if (fKinangle>0)
16955 {
16956 Int_t mode=fKinangle-1;
16957 Double_t ang=GetNeutrinoAngle(E,"deg",mode);
16958 if (ang>0) ShiftPosition(rmu,ang);
16959 }
16960
16961 // Smearing according to the reconstruction angular resolution
16962 sigmareco=GetBurstRecoAngres(E,E);
16963 if (sigmareco<0) sigmareco=fAngresfix;
16964
16965 if (sigmareco<fAngresmin || sigmareco>fAngresmax) continue;
16966
16967 SmearPosition(rmu,sigmareco);
16968
16969 // Determine angular difference w.r.t. the presumed GRB position
16970 dang=rgrb.GetOpeningAngle(rmu,"deg");
16971
16972 sigmatot=-1;
16973 if (fSumsigmas==-1) sigmatot=sigmareco;
16974 if (fSumsigmas==0) sigmatot=sigmagrb;
16975 if (fSumsigmas==1) sigmatot=sigmagrb+sigmareco;
16976 if (fSumsigmas==2) sigmatot=sqrt(sigmagrb*sigmagrb+sigmareco*sigmareco);
16977
16978 // Determine the dynamic angular window including the track reco uncertainty
16979 if (!fixedwinset)
16980 {
16981 dangmax=-1;
16982 if (sigmatot>=0) dangmax=fabs(fDawin*sigmatot);
16983 }
16984
16985 if (fDatype>=0 && dang>dangmax) continue;
16986
16987 fBurstOnReco.Enter(zgrb,sigmagrb,sigmareco,sigmatot);
16988 fBurstOnMatch.Enter(E,dt,dang,dt/(zgrb+1.));
16989 fBurstSigReco.Enter(zgrb,sigmagrb,sigmareco,sigmatot);
16990 fBurstSignal.Enter(E,dt,dang,dt/(zgrb+1.));
16991 fBurstParameters->AddSignal(E,"EnergyOn");
16992 fBurstParameters->AddSignal(E,"EnergySig");
16993 if (hAeffProfile)
16994 {
16995 thetamu=rmu.GetX(2,"sph","rad");
16996 gbin=hAeffProfile->FindFixBin(log10(E),cos(thetamu));
16997 if (gbin>0 && gbin<nbins+1)
16998 {
16999 Aeff=hAeffProfile->GetBinContent(gbin);
17000 if (Aeff>0)
17001 {
17002 Fluence=1./Aeff;
17003 fBurstOnAeff.Enter(Aeff,Fluence,E,dang);
17004 fBurstSigAeff.Enter(Aeff,Fluence,E,dang);
17005 }
17006 }
17007 }
17008
17009 if (fixedwinset) continue;
17010
17011 // Update the dynamic On-source maximum (solid) angle that is encountered for this burst
17012 if (fDawin<0) // Local zenith band centered at the GRB position at its trigger time
17013 {
17014 thlow=thetagrb-0.5*dangmax;
17015 thup=thetagrb+0.5*dangmax;
17016 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
17017 }
17018 else // Circle around GRB position
17019 {
17020 thlow=0;
17021 thup=dangmax;
17022 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
17023 }
17024 if (dangmax>dangmaxOn) sx->SetSignal(dangmax,"dangmaxOn");
17025 if (solidangle>OmegaOn) sx->SetSignal(solidangle,"OmegaOn");
17026 }
17027}
17028
17029TH1* NcAstrolab::GetBurstBayesianSignalRate(Double_t p,Double_t& rlow,Double_t& rup,Int_t n)
17030{
17061
17062 rlow=0;
17063 rup=0;
17064
17065 // The number of on-source and off-source patches
17066 Int_t fNgrbs=GetNsignals(0);
17067 Int_t fNbkg=TMath::Nint(fBurstParameters->GetSignal("Nbkg"));
17068
17069 // The recorded (stacked) on-source and off-source number of events
17070 Double_t Non=fBurstOnMatch.GetN();
17071 Double_t Noff=fBurstOffMatch.GetN();
17072
17073 if (fNgrbs<=0 || fNbkg<=0 || Non<=0 || Noff<=0)
17074 {
17075 printf(" \n *%-s::GetBurstBayesianSignalRate* \n",ClassName());
17076 if (fNgrbs<=0 || Non<=0) printf(" === No on-source data available === \n");
17077 if (fNbkg<=0 || Noff<=0) printf(" === No off-source data available === \n");
17078 return 0;
17079 }
17080
17081 Int_t fTunits=TMath::Nint(fBurstParameters->GetSignal("Tunits"));
17082 Float_t fTfact=fBurstParameters->GetSignal("Tfact");
17083
17084 TString tu="days";
17085 if (fTunits==1) tu="hours";
17086 if (fTunits==2) tu="sec";
17087 if (fTunits==3) tu="ns";
17088 if (fTunits==4) tu="ps";
17089
17090 // Solid angle of the selected RA and DEC range
17091 Float_t fOmegaDecl=fBurstParameters->GetSignal("OmegaDecl");
17092
17093 // The (stacked) on-source and off-source solid angles that were probed
17094 Double_t fSolidangleOn=fBurstParameters->GetSignal("SolidangleOn");
17095 Double_t fSolidangleOff=fBurstParameters->GetSignal("SolidangleOff");
17096 Double_t fAvSolidangleOn=fBurstParameters->GetSignal("AvSolidangleOn");
17097 Double_t fAvSolidangleOff=fBurstParameters->GetSignal("AvSolidangleOff");
17098 Double_t Ra=-1;
17099 if (fAvSolidangleOff) Ra=fAvSolidangleOn/fAvSolidangleOff;
17100
17101 // The integrated on-source and off-source exposure times in seconds
17102 Double_t Ton=fBurstParameters->GetSignal("TtotOn");
17103 Double_t Toff=fBurstParameters->GetSignal("TtotOff");
17104
17105 // The Bayesian posterior background and signal rate PDFs
17106 TF1 fbkgrpdf=GetBackgroundRatePDF(Noff,Toff);
17107 TF1 fsigrpdf=GetSignalRatePDF(Non,Ton,Noff,Toff,Ra);
17108
17109 Double_t rmode=fsigrpdf.GetMaximumX();
17110 Double_t bkgrmode=fbkgrpdf.GetMaximumX();
17111
17112 // Determine the "p%" credible interval for the signal rate
17113 Float_t frac=0;
17114 frac=GetCredibleInterval(fsigrpdf,p,rlow,rup,n);
17115
17116 // Provide the signal and background rate PDFs as histograms in the output file
17117 fbkgrpdf.SetRange(0,3.*Noff/Toff);
17118 fbkgrpdf.SetNpx(n);
17119 TH1* hBkgRatePDF=(TH1*)fbkgrpdf.GetHistogram()->Clone();
17120 hBkgRatePDF->SetName("hBkgRatePDF");
17121 fBurstHistos.Add(hBkgRatePDF);
17122 fsigrpdf.SetRange(0,3.*Non/Ton);
17123 fsigrpdf.SetNpx(n);
17124 TH1* hSigRatePDF=(TH1*)fsigrpdf.GetHistogram()->Clone();
17125 hSigRatePDF->SetName("hSigRatePDF");
17126 fBurstHistos.Add(hSigRatePDF);
17127
17128 printf("\n *%-s::GetBurstBayesianSignalRate* Credible interval [rlow,rup] for p=%-g%% with a precision of 1/%-i \n",ClassName(),p,n);
17129
17130 // Issue a warning in case variable angular cones based on actual track reco sigmas were used.
17131 // This can induce large variations in the on-source and off-source event counts
17132 Int_t fDatype=TMath::Nint(fBurstParameters->GetSignal("Datype"));
17133 Int_t fRecoangle=TMath::Nint(fBurstParameters->GetSignal("Recoangle"));
17134 Int_t fSumsigmas=TMath::Nint(fBurstParameters->GetSignal("Sumsigmas"));
17135
17136 if (fRecoangle && fSumsigmas && fDatype==2)
17137 {
17138 printf(" === Warning: Variable angular cones based on actual track reconstruction sigmas were used. \n");
17139 printf(" Large variations between the on-source and off-source background counts may be present. \n");
17140 }
17141
17142 printf(" The %-g%% credible interval from the Bayesian posterior signal pdf : [%-g,%-g] Hz \n",100.*frac,rlow,rup);
17143 printf(" Modes of the on-source posterior PDFs : Signal=%-g Hz Background=%-g Hz",rmode,bkgrmode);
17144 if (bkgrmode) printf(" Signal/Background=%-g",rmode/bkgrmode);
17145 printf("\n");
17146 printf(" The following signal and background rate PDF histograms have been generated : \n");
17147 printf(" ... %-s : %-s \n",hSigRatePDF->GetName(),hSigRatePDF->GetTitle());
17148 printf(" ... %-s : %-s \n",hBkgRatePDF->GetName(),hBkgRatePDF->GetTitle());
17149
17150 // The area covered c.q. overlooked by the detector sensors
17151 Float_t fSensarea=fBurstParameters->GetSignal("Sensarea");
17152 fSensarea*=1e4; // Convert to cm^2
17153
17154 printf(" Solid angle coverage corresponding to the selected RA and DEC range : %-g steradian \n",fOmegaDecl);
17155 printf(" Integrated on-source exposure time of the %-i stacked time windows : %-g %-s \n",fNgrbs,Ton/fTfact,tu.Data());
17156 printf(" Integrated off-source exposure time of the %-i*%-i stacked time windows : %-g %-s \n",fNgrbs,fNbkg,Toff/fTfact,tu.Data());
17157 printf(" Total accumulated on-source solid angle : %-g sr in %-i stacked patches --> Average per patch : %-g sr \n",fSolidangleOn,fNgrbs,fAvSolidangleOn);
17158 printf(" Total accumulated off-source solid angle : %-g sr in %-i*%-i stacked patches --> Average per patch : %-g sr \n",fSolidangleOff,fNgrbs,fNbkg,fAvSolidangleOff);
17159 if (fSensarea>0) printf(" Area covered c.q. overlooked by the detector sensors : %-g cm^2. \n",fSensarea);
17160
17161 printf(" Total number of recorded on-source events : %-g --> Average per patch : %-g events. \n",Non,Non/float(fNgrbs));
17162 printf(" Total number of recorded off-source events : %-g --> Average per patch : %-g events. \n",Noff,Noff/float(fNgrbs*fNbkg));
17163
17164 // Provide statistics for the signal rate PDF mode, lower and upper boundaries as well as the mode of the background PDF
17165 for (Int_t i=1; i<3; i++)
17166 {
17167 printf(" ********************************************************************** \n");
17168 if (i==1)
17169 {
17170 printf(" * Accumulated (stacked) on-source values based on the posterior PDFs * \n");
17171 }
17172 else
17173 {
17174 printf(" * Average values per on-source patch based on the posterior PDFs * \n");
17175 }
17176 printf(" ********************************************************************** \n");
17177
17178 TString text;
17179
17180 printf(" *Lower bound* Steady signal event rate during each time window : %-g Hz",rlow);
17181 if (fAvSolidangleOn) printf(" --> %-g Hz sr^-1",rlow/fAvSolidangleOn);
17182 printf("\n");
17183 text.Form("CL%-iLower",TMath::Nint(p));
17184 ListBurstSignalStats(rlow,i,text);
17185
17186 printf(" *Mode* Steady signal event rate during each time window : %-g Hz",rmode);
17187 if (fAvSolidangleOn) printf(" --> %-g Hz sr^-1",rmode/fAvSolidangleOn);
17188 printf("\n");
17189 ListBurstSignalStats(rmode,i,"Mode");
17190
17191 printf(" *Upper bound* Steady signal event rate during each time window : %-g Hz",rup);
17192 if (fAvSolidangleOn) printf(" --> %-g Hz sr^-1",rup/fAvSolidangleOn);
17193 printf("\n");
17194 text.Form("CL%-iUpper",TMath::Nint(p));
17195 ListBurstSignalStats(rup,i,text);
17196
17197 printf(" *Background* Steady background event rate during each time window : %-g Hz",bkgrmode);
17198 if (fAvSolidangleOn) printf(" --> %-g Hz sr^-1",bkgrmode/fAvSolidangleOn);
17199 printf("\n");
17200
17201 ListBurstSignalStats(bkgrmode,-i);
17202 }
17203 return hSigRatePDF;
17204}
17205
17206Double_t NcAstrolab::GetBurstTotalFluence(Double_t nsig,TString str)
17207{
17223
17224 Double_t Ton=fBurstParameters->GetSignal("TtotOn");
17225
17226 Double_t Fluence=-1;
17227
17228 Int_t n=TMath::Nint(nsig);
17229
17230 if (n<1 || Ton<=0) return -1;
17231
17232 Int_t nen=fBurstOnAeff.GetN();
17233
17234 if (n>nen) n=nen; // Only stored values should be used
17235
17236 // Take the Fluence sum of the "nsig" values ordered by increasing angular separation.
17237 // The assumption is that the closest tracks represent signal tracks.
17238 // Also an incoming Fluence vs. E histogram will be created for each "signal track".
17239 Double_t E=0;
17240 Double_t Stot=0;
17241 TString nameS,titleS,nameF,titleF,nameE2F,titleE2F;
17242 nameS.Form("h%-sFluence",str.Data());
17243 titleS.Form("Stacked incoming signal Fluence for Bayesian %s rate;Event energy [GeV];dN/dE [GeV^{-1} cm^{-2}]",str.Data());
17244 nameF.Form("h%-sFlux",str.Data());
17245 titleF.Form("Incoming signal Flux for a steady Bayesian %s rate;Event energy [GeV];dN/dE [GeV^{-1} cm^{-2} s^{-1}]",str.Data());
17246 nameE2F.Form("h%-sE2Flux",str.Data());
17247 titleE2F.Form("E-Scaled incoming signal Flux for a steady Bayesian %s rate;Event energy [GeV];E^{2}dN/dE [GeV cm^{-2} s^{-1}]",str.Data());
17248 TH1F* hS=0;
17249 TH1F* hF=0;
17250 TH1F* hE2F=0;
17251
17252 if (str!="-")
17253 {
17254 hS=(TH1F*)fBurstHistos.FindObject(nameS);
17255 hF=(TH1F*)fBurstHistos.FindObject(nameF);
17256 hE2F=(TH1F*)fBurstHistos.FindObject(nameE2F);
17257 if (hS)
17258 {
17259 delete hS;
17260 hS=new TH1F(nameS,titleS,100,0,-1);
17261 delete hF;
17262 hF=new TH1F(nameF,titleF,100,0,-1);
17263 delete hE2F;
17264 hE2F=new TH1F(nameE2F,titleE2F,100,0,-1);
17265 }
17266 else
17267 {
17268 hS=new TH1F(nameS,titleS,100,0,-1);
17269 fBurstHistos.Add(hS);
17270 hF=new TH1F(nameF,titleF,100,0,-1);
17271 fBurstHistos.Add(hF);
17272 hE2F=new TH1F(nameE2F,titleE2F,100,0,-1);
17273 fBurstHistos.Add(hE2F);
17274 }
17275
17276 hS->Sumw2();
17277 hF->Sumw2();
17278 hE2F->Sumw2();
17279 }
17280
17281 for (Int_t i=1; i<=n; i++)
17282 {
17283 Fluence=fBurstOnAeff.GetEntry(i,"Fluence",1,"dang");
17284 E=fBurstOnAeff.GetEntry(i,"E",1,"dang");
17285 Stot+=Fluence;
17286 if (Fluence>0 && hS)
17287 {
17288 hS->Fill(E,Fluence);
17289 hF->Fill(E,Fluence/Ton);
17290 hE2F->Fill(E,pow(E,2)*Fluence/Ton);
17291 }
17292 }
17293
17294 // Convert the histogram data into dN/dE
17295 if (hS)
17296 {
17297 // Flush the storage buffers to actually fill the histograms
17298 hS->BufferEmpty(1);
17299 hF->BufferEmpty(1);
17300 hE2F->BufferEmpty(1);
17301 Float_t binwidth=hS->GetBinWidth(1);
17302 if (binwidth>0)
17303 {
17304 hS->Scale(1./binwidth);
17305 hF->Scale(1./binwidth);
17306 hE2F->Scale(1./binwidth);
17307 }
17308 }
17309
17310 return Stot;
17311}
17312
17313void NcAstrolab::ListBurstSignalStats(Double_t Rate,Int_t mode,TString str)
17314{
17333
17334 // The number of on-source patches
17335 Int_t fNgrbs=GetNsignals(0);
17336
17337 // The integrated on-source exposure time in seconds
17338 Float_t Ton=fBurstParameters->GetSignal("TtotOn");
17339 Float_t TwinOn=Ton/float(fNgrbs); // The average time window in seconds
17340
17341 // The (stacked) on-source solid angle that was probed
17342 Float_t fSolidangleOn=fBurstParameters->GetSignal("SolidangleOn");
17343 Float_t fAvSolidangleOn=fBurstParameters->GetSignal("AvSolidangleOn");
17344
17345 // The area covered c.q. overlooked by the detector sensors
17346 Float_t fSensarea=fBurstParameters->GetSignal("Sensarea");
17347 fSensarea*=1e4; // Convert to cm^2
17348
17349 // The total accumulated on-source values
17350 Float_t Time=Ton;
17351 Float_t Omega=fSolidangleOn;
17352
17353 // Use the (averaged) observation values per patch
17354 if (abs(mode)==2)
17355 {
17356 Time=TwinOn;
17357 Omega=fAvSolidangleOn;
17358 }
17359
17360 // Determine the corresponding expected number of events
17361 Float_t Nevt=Rate*Time;
17362
17363 Float_t Fluence=-1;
17364 if (mode==1)
17365 {
17366 Fluence=GetBurstTotalFluence(Nevt,str);
17367 }
17368 if (mode==2)
17369 {
17370 Fluence=GetBurstTotalFluence(Nevt*float(fNgrbs),"-");
17371 Fluence=Fluence/float(fNgrbs);
17372 }
17373
17374 TString type="signal";
17375 if (mode<0) type="background";
17376
17377 printf(" Expected recorded number of %-s events : %-g",type.Data(),Nevt);
17378 if (Omega) printf(" --> %-g events/sr",Nevt/Omega);
17379 printf("\n");
17380 if (fSensarea>0)
17381 {
17382 printf(" Expected recorded %-s particle fluence : %-g cm^-2",type.Data(),Nevt/fSensarea);
17383 if (Omega) printf(" --> %-g cm^-2 sr^-1",Nevt/(fSensarea*Omega));
17384 printf("\n");
17385 printf(" Expected recorded %-s particle flux : %-g cm^-2 s^-1",type.Data(),Rate/fSensarea);
17386 if (Omega) printf(" --> Intensity : %-g cm^-2 s^-1 sr^-1",Rate/(fSensarea*Omega));
17387 printf("\n");
17388 }
17389 if (Fluence>0)
17390 {
17391 printf(" Expected incoming %-s particle fluence : %-g cm^-2",type.Data(),Fluence);
17392 if (Omega) printf(" --> %-g cm^-2 sr^-1",Fluence/Omega);
17393 printf("\n");
17394 printf(" Expected incoming %-s particle flux : %-g cm^-2 s^-1",type.Data(),Fluence/Time);
17395 if (Omega) printf(" --> Intensity : %-g cm^-2 s^-1 sr^-1",Fluence/(Time*Omega));
17396 printf("\n");
17397 }
17398}
17399
17401{
17414
17415 Double_t sigma=0;
17416
17417 // The recorded (stacked) "on source" and "off source" number of events
17418 Double_t Non=fBurstOnMatch.GetN();
17419 Double_t Noff=fBurstOffMatch.GetN();
17420
17421 if (Non<=0 || Noff<=0)
17422 {
17423 printf(" \n *%-s::GetBurstLiMaSignificance* \n",ClassName());
17424 if (Non<=0) printf(" === No on source data available === \n");
17425 if (Noff<=0) printf(" === No off source data available === \n");
17426 return 0;
17427 }
17428
17429 // The (stacked) "on source" and "off source" solid angles that were probed
17430 Double_t fAvSolidangleOn=fBurstParameters->GetSignal("AvSolidangleOn");
17431 Double_t fAvSolidangleOff=fBurstParameters->GetSignal("AvSolidangleOff");
17432 Double_t Ra=-1;
17433 if (fAvSolidangleOff) Ra=fAvSolidangleOn/fAvSolidangleOff;
17434
17435 // The (stacked) "on source" and "off source" exposure times
17436 Double_t Ton=fBurstParameters->GetSignal("TtotOn");
17437 Double_t Toff=fBurstParameters->GetSignal("TtotOff");
17438
17439 NcMath m;
17440 sigma=m.LiMaSignificance(Non,Ton,Noff,Toff,Ra);
17441
17442 printf("\n *%-s::GetBurstLiMaSignificance* The Li-Ma signal significance is : %-g \n",ClassName(),sigma);
17443
17444 // Issue a warning in case variable angular cones based on actual track reco sigmas were used.
17445 // This can induce large variations in the on-source and off-source event counts
17446 Int_t fDatype=TMath::Nint(fBurstParameters->GetSignal("Datype"));
17447 Int_t fRecoangle=TMath::Nint(fBurstParameters->GetSignal("Recoangle"));
17448 Int_t fSumsigmas=TMath::Nint(fBurstParameters->GetSignal("Sumsigmas"));
17449
17450 if (fRecoangle && fSumsigmas && fDatype==2)
17451 {
17452 printf(" === Warning: Variable angular cones based on actual track reconstruction sigmas were used. \n");
17453 printf(" Large variations between the on-source and off-source background counts may be present. \n");
17454 }
17455
17456 return sigma;
17457}
17458
17459void NcAstrolab::GetBurstBayesianPsiStatistics(TString type,Double_t nr,Int_t ncut,Int_t ndt,Bool_t zcor,Int_t freq)
17460{
17530
17531 NcMath math;
17532
17533 TString text="none";
17534 if (type=="time") text="arrival time";
17535 if (type=="BBtime") text="Bayesian Block event rate";
17536 if (type=="BBrat") text="normalized On-source/Off-source Bayesian Block event rate ratio";
17537 if (type=="angle") text="opening angle";
17538 if (type=="cosa") text="cos(opening angle)";
17539 if (type=="dt") text="arrival time interval";
17540
17541 if (zcor)
17542 {
17543 text.ReplaceAll("arrival time","redshift corrected arrival time");
17544 text.ReplaceAll("event rate","redshift corrected event rate");
17545 }
17546
17547 cout << endl;
17548 if (text=="none")
17549 {
17550 cout << " *" << ClassName() << "::GetBurstBayesianPsiStatistics* Unknown statistics type : " << type << endl;
17551 return;
17552 }
17553 else
17554 {
17555 cout << " *" << ClassName() << "::GetBurstBayesianPsiStatistics* Analysis of " << text << " statistics" << endl;
17556 }
17557
17558 Int_t fTunits=TMath::Nint(fBurstParameters->GetSignal("Tunits"));
17559 TString tu="days";
17560 if (fTunits==1) tu="hours";
17561 if (fTunits==2) tu="sec";
17562 if (fTunits==3) tu="ns";
17563 if (fTunits==4) tu="ps";
17564
17565 TH1* tot=0;
17566 TH1* bkg=0;
17567 TH1* rat=0;
17568
17569 Double_t psitot=-1, psibkg=-1, psirat=-1;
17570 Float_t psidif=0;
17571 Float_t psimintot=-1, psimaxtot=-1, psifractot=0;
17572 Float_t psiminbkg=-1, psimaxbkg=-1, psifracbkg=0;
17573 Float_t psiminrat=-1, psimaxrat=-1, psifracrat=0;
17574 Double_t nrxtot=-1, nrxbkg=-1, nrxrat=-1;
17575 Double_t pvaluetot=-1, pvaluebkg=-1, pvaluerat=-1;
17576
17577 TH1F* hPsiOn=0;
17578 TH1F* hPsiOff=0;
17579 TH1F* hPsiRat=0;
17580 TH1F* rtot=0;
17581 TH1F* rbkg=0;
17582 TH1F* rrat=0;
17583
17585 // Arrival time histo Bayesian statistics //
17587 if (type=="time")
17588 {
17589 if (!zcor) // Plain observed arrival times
17590 {
17591 tot=(TH1*)fBurstHistos.FindObject("hOnt");
17592 bkg=(TH1*)fBurstHistos.FindObject("hOfft");
17593 }
17594 else // Redshift corrected arrival times
17595 {
17596 tot=(TH1*)fBurstHistos.FindObject("hOnZt");
17597 bkg=(TH1*)fBurstHistos.FindObject("hOffZt");
17598 }
17599
17600 if (!tot) printf(" === No on source data available === \n");
17601 if (!bkg) printf(" === No off source data available === \n");
17602
17603 if (!tot && !bkg) return;
17604
17605 if (tot) psitot=math.PsiValue(tot,0,0,freq);
17606 if (bkg) psibkg=math.PsiValue(bkg,0,0,freq);
17607 psidif=psitot-psibkg;
17608
17609 // Extreme Psi values for a pure background hypothesis of the recorded arrival time entries
17610 if (tot)
17611 {
17612 psimintot=math.PsiExtreme(tot,0,0,-2);
17613 if (psitot<psimintot) psimintot=psitot;
17614 psimaxtot=math.PsiExtreme(tot,0,0,-1);
17615 if (psimaxtot>psimintot) psifractot=(psimaxtot-psitot)/(psimaxtot-psimintot);
17616 }
17617 if (bkg)
17618 {
17619 psiminbkg=math.PsiExtreme(bkg,0,0,-2);
17620 if (psibkg<psiminbkg) psiminbkg=psibkg;
17621 psimaxbkg=math.PsiExtreme(bkg,0,0,-1);
17622 if (psimaxbkg>psiminbkg) psifracbkg=(psimaxbkg-psibkg)/(psimaxbkg-psiminbkg);
17623 }
17624
17625 // P-value determination
17626 if (nr>=0)
17627 {
17628 if (!zcor) // Plain observed arrival times
17629 {
17630 hPsiOn=(TH1F*)fBurstHistos.FindObject("hPsiOnt");
17631 hPsiOff=(TH1F*)fBurstHistos.FindObject("hPsiOfft");
17632 }
17633 else // Redshift corrected arrival times
17634 {
17635 hPsiOn=(TH1F*)fBurstHistos.FindObject("hPsiOnZt");
17636 hPsiOff=(TH1F*)fBurstHistos.FindObject("hPsiOffZt");
17637 }
17638
17639 if (hPsiOn)
17640 {
17641 rtot=(TH1F*)hPsiOn->Clone();
17642 rtot->Reset();
17643 }
17644 else
17645 {
17646 if (tot)
17647 {
17648 if (!zcor) rtot=new TH1F("hPsiOnt","Psi distr. for bkg hypothesis of on-source arrival time data",100,psimintot-1.,psimaxtot+1.);
17649 if (zcor) rtot=new TH1F("hPsiOnZt","Psi distr. for bkg hypothesis of redshift corrected on-source arrival time data",100,psimintot-1.,psimaxtot+1.);
17650 }
17651 }
17652
17653 if (hPsiOff)
17654 {
17655 rbkg=(TH1F*)hPsiOff->Clone();
17656 rbkg->Reset();
17657 }
17658 else
17659 {
17660 if (bkg)
17661 {
17662 if (!zcor) rbkg=new TH1F("hPsiOfft","Psi distr. for bkg hypothesis of off-source arrival time data",100,psiminbkg-1.,psimaxbkg+1.);
17663 if (zcor) rbkg=new TH1F("hPsiOffZt","Psi distr. for bkg hypothesis of redshift corrected off-source arrival time data",100,psiminbkg-1.,psimaxbkg+1.);
17664 }
17665 }
17666
17667 if (tot)
17668 {
17669 pvaluetot=math.PsiPvalue(-1,nr,tot,0,0,freq,0,rtot,ncut,&nrxtot);
17670 fBurstHistos.Add(rtot);
17671 }
17672 if (bkg)
17673 {
17674 pvaluebkg=math.PsiPvalue(-1,nr,bkg,0,0,freq,0,rbkg,ncut,&nrxbkg);
17675 fBurstHistos.Add(rbkg);
17676 }
17677
17678 cout << " The following randomised Psi histograms have been generated :" << endl;
17679 if (rtot) cout << " ... " << rtot->GetName() << " : " << rtot->GetTitle() << endl;
17680 if (rbkg) cout << " ... " << rbkg->GetName() << " : " << rbkg->GetTitle() << endl;
17681 }
17682 }
17683
17685 // Event rate histo Bayesian statistics //
17687 if (type=="BBtime")
17688 {
17689 if (!zcor) // Plain observed arrival times
17690 {
17691 tot=(TH1*)fBurstHistos.FindObject("hOnBBt");
17692 bkg=(TH1*)fBurstHistos.FindObject("hOffBBt");
17693 }
17694 else // Redshift corrected arrival times
17695 {
17696 tot=(TH1*)fBurstHistos.FindObject("hOnBBzt");
17697 bkg=(TH1*)fBurstHistos.FindObject("hOffBBzt");
17698 }
17699
17700 if (!tot) printf(" === No on source data available === \n");
17701 if (!bkg) printf(" === No off source data available === \n");
17702
17703 if (!tot && !bkg) return;
17704
17705 // Temporarily offset the bin contents so that the lowest bin content is 1 for the psi analysis
17706 if (tot)
17707 {
17708 for (Int_t i=1; i<=tot->GetNbinsX(); i++)
17709 {
17710 tot->AddBinContent(i,1);
17711 }
17712 }
17713
17714 if (bkg)
17715 {
17716 for (Int_t i=1; i<=bkg->GetNbinsX(); i++)
17717 {
17718 bkg->AddBinContent(i,1);
17719 }
17720 }
17721
17722 if (tot) psitot=math.PsiValue(tot,0,0,freq);
17723 if (bkg) psibkg=math.PsiValue(bkg,0,0,freq);
17724 psidif=psitot-psibkg;
17725
17726 // Extreme Psi values for a pure background hypothesis of the recorded arrival time entries
17727 if (tot)
17728 {
17729 psimintot=math.PsiExtreme(tot,0,0,-2);
17730 if (psitot<psimintot) psimintot=psitot;
17731 psimaxtot=math.PsiExtreme(tot,0,0,-1);
17732 if (psimaxtot>psimintot) psifractot=(psimaxtot-psitot)/(psimaxtot-psimintot);
17733 }
17734 if (bkg)
17735 {
17736 psiminbkg=math.PsiExtreme(bkg,0,0,-2);
17737 if (psibkg<psiminbkg) psiminbkg=psibkg;
17738 psimaxbkg=math.PsiExtreme(bkg,0,0,-1);
17739 if (psimaxbkg>psiminbkg) psifracbkg=(psimaxbkg-psibkg)/(psimaxbkg-psiminbkg);
17740 }
17741
17742 // P-value determination
17743 if (nr>=0)
17744 {
17745 if (!zcor) // Plain observed arrival times
17746 {
17747 hPsiOn=(TH1F*)fBurstHistos.FindObject("hPsiOnBBt");
17748 hPsiOff=(TH1F*)fBurstHistos.FindObject("hPsiOffBBt");
17749 }
17750 else // Redshift corrected arrival times
17751 {
17752 hPsiOn=(TH1F*)fBurstHistos.FindObject("hPsiOnBBzt");
17753 hPsiOff=(TH1F*)fBurstHistos.FindObject("hPsiOffBBzt");
17754 }
17755
17756 if (hPsiOn)
17757 {
17758 rtot=(TH1F*)hPsiOn->Clone();
17759 rtot->Reset();
17760 }
17761 else
17762 {
17763 if (tot)
17764 {
17765 if (!zcor) rtot=new TH1F("hPsiOnBBt","Psi distr. for bkg hypothesis of on-source event rate Bayesian Block data",100,psimintot-1.,psimaxtot+1.);
17766 if (zcor) rtot=new TH1F("hPsiOnBBzt","Psi distr. for bkg hypothesis of redshift corrected on-source event rate Bayesian Block data",100,psimintot-1.,psimaxtot+1.);
17767 }
17768 }
17769
17770 if (hPsiOff)
17771 {
17772 rbkg=(TH1F*)hPsiOff->Clone();
17773 rbkg->Reset();
17774 }
17775 else
17776 {
17777 if (bkg)
17778 {
17779 if (!zcor) rbkg=new TH1F("hPsiOffBBt","Psi distr. for bkg hypothesis of off-source event rate Bayesian Block data",100,psiminbkg-1.,psimaxbkg+1.);
17780 if (zcor) rbkg=new TH1F("hPsiOffBBzt","Psi distr. for bkg hypothesis of redshift corrected off-source event rate Bayesian Block data",100,psiminbkg-1.,psimaxbkg+1.);
17781 }
17782 }
17783
17784 if (tot)
17785 {
17786 pvaluetot=math.PsiPvalue(-1,nr,tot,0,0,freq,0,rtot,ncut,&nrxtot);
17787 fBurstHistos.Add(rtot);
17788 }
17789 if (bkg)
17790 {
17791 pvaluebkg=math.PsiPvalue(-1,nr,bkg,0,0,freq,0,rbkg,ncut,&nrxbkg);
17792 fBurstHistos.Add(rbkg);
17793 }
17794
17795 cout << " The following randomised Psi histograms have been generated :" << endl;
17796 if (rtot) cout << " ... " << rtot->GetName() << " : " << rtot->GetTitle() << endl;
17797 if (rbkg) cout << " ... " << rbkg->GetName() << " : " << rbkg->GetTitle() << endl;
17798 }
17799
17800 // Restore the original histogram data
17801 if (tot)
17802 {
17803 for (Int_t i=1; i<=tot->GetNbinsX(); i++)
17804 {
17805 tot->AddBinContent(i,-1);
17806 }
17807 }
17808 if (bkg)
17809 {
17810 for (Int_t i=1; i<=bkg->GetNbinsX(); i++)
17811 {
17812 bkg->AddBinContent(i,-1);
17813 }
17814 }
17815 }
17816
17818 // On-source/Off-source event rate ratio histo Bayesian statistics //
17820 if (type=="BBrat")
17821 {
17822 if (!zcor) // Plain observed arrival times
17823 {
17824 rat=(TH1*)fBurstHistos.FindObject("hRatUBBt");
17825 }
17826 else // Redshift corrected arrival times
17827 {
17828 rat=(TH1*)fBurstHistos.FindObject("hRatUBBzt");
17829 }
17830
17831 if (!rat)
17832 {
17833 printf(" === No data available === \n");
17834 return;
17835 }
17836
17837 psirat=math.PsiValue(rat,0,0,freq);
17838 psidif=psitot-psibkg;
17839
17840 // Extreme Psi values for a pure background hypothesis of the recorded arrival time entries
17841 psiminrat=math.PsiExtreme(rat,0,0,-2);
17842 if (psirat<psiminrat) psiminrat=psirat;
17843 psimaxrat=math.PsiExtreme(rat,0,0,-1);
17844 if (psimaxrat>psiminrat) psifracrat=(psimaxrat-psirat)/(psimaxrat-psiminrat);
17845
17846 // P-value determination
17847 if (nr>=0)
17848 {
17849 if (!zcor) // Plain observed arrival times
17850 {
17851 hPsiRat=(TH1F*)fBurstHistos.FindObject("hPsiRatUBBt");
17852 }
17853 else // Redshift corrected arrival times
17854 {
17855 hPsiRat=(TH1F*)fBurstHistos.FindObject("hPsiRatUBBzt");
17856 }
17857
17858 if (hPsiRat)
17859 {
17860 rrat=(TH1F*)hPsiRat->Clone();
17861 rrat->Reset();
17862 }
17863 else
17864 {
17865 if (!zcor) rrat=new TH1F("hPsiRatUBBt","Psi distr. for bkg hypothesis of on/off source event rate Bayesian Block data",100,psiminrat-1.,psimaxrat+1.);
17866 if (zcor) rrat=new TH1F("hPsiRatUBBzt","Psi distr. for bkg hypothesis of redshift corrected on/off source event rate Bayesian Block data",100,psiminrat-1.,psimaxrat+1.);
17867 }
17868
17869 pvaluerat=math.PsiPvalue(-1,nr,rat,0,0,freq,0,rrat,ncut,&nrxrat);
17870 fBurstHistos.Add(rrat);
17871
17872 cout << " The following randomised Psi histograms have been generated :" << endl;
17873 if (rrat) cout << " ... " << rrat->GetName() << " : " << rrat->GetTitle() << endl;
17874 }
17875 }
17876
17878 // Opening angle histo Bayesian statistics //
17880 if (type=="angle")
17881 {
17882 tot=(TH1*)fBurstHistos.FindObject("hOna");
17883 bkg=(TH1*)fBurstHistos.FindObject("hOffa");
17884
17885 if (!tot) printf(" === No on source data available === \n");
17886 if (!bkg) printf(" === No off source data available === \n");
17887
17888 if (!tot && !bkg) return;
17889
17890 TF1 pdfa("pdfa","sin(x*acos(-1.)/180.)");
17891 if (tot) psitot=math.PsiValue(tot,0,&pdfa,freq);
17892 if (bkg) psibkg=math.PsiValue(bkg,0,&pdfa,freq);
17893 psidif=psitot-psibkg;
17894
17895 // Extreme Psi values for a pure background hypothesis of the recorded opening angle entries
17896 if (tot)
17897 {
17898 psimintot=math.PsiExtreme(tot,0,&pdfa,-2);
17899 if (psitot<psimintot) psimintot=psitot;
17900 psimaxtot=math.PsiExtreme(tot,0,&pdfa,-1);
17901 if (psimaxtot>psimintot) psifractot=(psimaxtot-psitot)/(psimaxtot-psimintot);
17902 }
17903 if (bkg)
17904 {
17905 psiminbkg=math.PsiExtreme(bkg,0,&pdfa,-2);
17906 if (psibkg<psiminbkg) psiminbkg=psibkg;
17907 psimaxbkg=math.PsiExtreme(bkg,0,&pdfa,-1);
17908 if (psimaxbkg>psiminbkg) psifracbkg=(psimaxbkg-psibkg)/(psimaxbkg-psiminbkg);
17909 }
17910
17911 // P-value determination
17912 if (nr>=0)
17913 {
17914 hPsiOn=(TH1F*)fBurstHistos.FindObject("hPsiOna");
17915 hPsiOff=(TH1F*)fBurstHistos.FindObject("hPsiOffa");
17916
17917 if (hPsiOn)
17918 {
17919 rtot=(TH1F*)hPsiOn->Clone();
17920 rtot->Reset();
17921 }
17922 else
17923 {
17924 if (tot) rtot=new TH1F("hPsiOna","Psi distr. for bkg hypothesis of on-source opening angle data",100,psimintot-1.,psimaxtot+1.);
17925 }
17926
17927 if (hPsiOff)
17928 {
17929 rbkg=(TH1F*)hPsiOff->Clone();
17930 rbkg->Reset();
17931 }
17932 else
17933 {
17934 if (bkg) rbkg=new TH1F("hPsiOffa","Psi distr. for bkg hypothesis of off-source opening angle data",100,psiminbkg-1.,psimaxbkg+1.);
17935 }
17936
17937 if (tot)
17938 {
17939 pvaluetot=math.PsiPvalue(-1,nr,tot,0,&pdfa,freq,0,rtot,ncut,&nrxtot);
17940 fBurstHistos.Add(rtot);
17941 }
17942 if (bkg)
17943 {
17944 pvaluebkg=math.PsiPvalue(-1,nr,bkg,0,&pdfa,freq,0,rbkg,ncut,&nrxbkg);
17945 fBurstHistos.Add(rbkg);
17946 }
17947
17948 cout << " The following randomised Psi histograms have been generated :" << endl;
17949 if (rtot) cout << " ... " << rtot->GetName() << " : " << rtot->GetTitle() << endl;
17950 if (rbkg) cout << " ... " << rbkg->GetName() << " : " << rbkg->GetTitle() << endl;
17951 }
17952 }
17953
17955 // Cosine of opening angle histo Bayesian statistics //
17957 if (type=="cosa")
17958 {
17959 tot=(TH1*)fBurstHistos.FindObject("hOnCosa");
17960 bkg=(TH1*)fBurstHistos.FindObject("hOffCosa");
17961
17962 if (!tot) printf(" === No on source data available === \n");
17963 if (!bkg) printf(" === No off source data available === \n");
17964
17965 if (!tot && !bkg) return;
17966
17967 if (tot) psitot=math.PsiValue(tot,0,0,freq);
17968 if (bkg) psibkg=math.PsiValue(bkg,0,0,freq);
17969 psidif=psitot-psibkg;
17970
17971 // Extreme Psi values for a pure background hypothesis of the recorded cos(opening angle) entries
17972 if (tot)
17973 {
17974 psimintot=math.PsiExtreme(tot,0,0,-2);
17975 if (psitot<psimintot) psimintot=psitot;
17976 psimaxtot=math.PsiExtreme(tot,0,0,-1);
17977 if (psimaxtot>psimintot) psifractot=(psimaxtot-psitot)/(psimaxtot-psimintot);
17978 }
17979 if (bkg)
17980 {
17981 psiminbkg=math.PsiExtreme(bkg,0,0,-2);
17982 if (psibkg<psiminbkg) psiminbkg=psibkg;
17983 psimaxbkg=math.PsiExtreme(bkg,0,0,-1);
17984 if (psimaxbkg>psiminbkg) psifracbkg=(psimaxbkg-psibkg)/(psimaxbkg-psiminbkg);
17985 }
17986
17987 // P-value determination
17988 if (nr>=0)
17989 {
17990 hPsiOn=(TH1F*)fBurstHistos.FindObject("hPsiOnCosa");
17991 hPsiOff=(TH1F*)fBurstHistos.FindObject("hPsiOffCosa");
17992
17993 if (hPsiOn)
17994 {
17995 rtot=(TH1F*)hPsiOn->Clone();
17996 rtot->Reset();
17997 }
17998 else
17999 {
18000 if (tot) rtot=new TH1F("hPsiOnCosa","Psi distr. for bkg hypothesis of on-source cos(opening angle) data",100,psimintot-1.,psimaxtot+1.);
18001 }
18002
18003 if (hPsiOff)
18004 {
18005 rbkg=(TH1F*)hPsiOff->Clone();
18006 rbkg->Reset();
18007 }
18008 else
18009 {
18010 if (bkg) rbkg=new TH1F("hPsiOffCosa","Psi distr. for bkg hypothesis of off-source cos(opening angle) data",100,psiminbkg-1.,psimaxbkg+1.);
18011 }
18012
18013 if (tot)
18014 {
18015 pvaluetot=math.PsiPvalue(-1,nr,tot,0,0,freq,0,rtot,ncut,&nrxtot);
18016 fBurstHistos.Add(rtot);
18017 }
18018 if (bkg)
18019 {
18020 pvaluebkg=math.PsiPvalue(-1,nr,bkg,0,0,freq,0,rbkg,ncut,&nrxbkg);
18021 fBurstHistos.Add(rbkg);
18022 }
18023
18024 cout << " The following randomised Psi histograms have been generated :" << endl;
18025 if (rtot) cout << " ... " << rtot->GetName() << " : " << rtot->GetTitle() << endl;
18026 if (rbkg) cout << " ... " << rbkg->GetName() << " : " << rbkg->GetTitle() << endl;
18027 }
18028 }
18029
18031 // Arrival time interval Bayesian statistics //
18033 if (type=="dt")
18034 {
18035 TH1F hOndt;
18036 TH1F hOffdt;
18037 TF1 pdfdttot;
18038 TF1 pdfdtbkg;
18039
18040 GetBurstDtDistributions(ndt,hOndt,pdfdttot,hOffdt,pdfdtbkg,zcor);
18041
18042 Int_t ntot=hOndt.GetEntries();
18043 Int_t nbkg=hOffdt.GetEntries();
18044
18045 if (!ntot) printf(" === No on source data available === \n");
18046 if (!nbkg) printf(" === No off source data available === \n");
18047
18048 if (!ntot && !nbkg) return;
18049
18050 if (ntot) psitot=math.PsiValue(&hOndt,0,&pdfdttot,freq);
18051 if (nbkg) psibkg=math.PsiValue(&hOffdt,0,&pdfdtbkg,freq);
18052 psidif=psitot-psibkg;
18053
18054 if (ntot)
18055 {
18056 psimintot=math.PsiExtreme(&hOndt,0,&pdfdttot,-2);
18057 if (psitot<psimintot) psimintot=psitot;
18058 psimaxtot=math.PsiExtreme(&hOndt,0,&pdfdttot,-1);
18059 if (psimaxtot>psimintot) psifractot=(psimaxtot-psitot)/(psimaxtot-psimintot);
18060 }
18061 if (nbkg)
18062 {
18063 psiminbkg=math.PsiExtreme(&hOffdt,0,&pdfdtbkg,-2);
18064 if (psibkg<psiminbkg) psiminbkg=psibkg;
18065 psimaxbkg=math.PsiExtreme(&hOffdt,0,&pdfdtbkg,-1);
18066 if (psimaxbkg>psiminbkg) psifracbkg=(psimaxbkg-psibkg)/(psimaxbkg-psiminbkg);
18067 }
18068
18069 // P-value determination
18070 if (nr>=0)
18071 {
18072 TString nametot;
18073 TString namebkg;
18074 if (!zcor)
18075 {
18076 nametot.Form("hPsiOndt%-i",ndt);
18077 namebkg.Form("hPsiOffdt%-i",ndt);
18078 }
18079 else
18080 {
18081 nametot.Form("hPsiOnZdt%-i",ndt);
18082 namebkg.Form("hPsiOffZdt%-i",ndt);
18083 }
18084
18085 TH1F* hPsiOn=(TH1F*)fBurstHistos.FindObject(nametot);
18086 TH1F* hPsiOff=(TH1F*)fBurstHistos.FindObject(namebkg);
18087
18088 TString title;
18089 if (hPsiOn)
18090 {
18091 rtot=(TH1F*)hPsiOn->Clone();
18092 rtot->Reset();
18093 }
18094 else
18095 {
18096 if (!zcor) title.Form("Psi distr. for bkg hypothesis of on-source dt data for n=%-i",ndt);
18097 if (zcor) title.Form("Psi distr. for bkg hypothesis of redshift corrected on-source dt data for n=%-i",ndt);
18098 if (ntot) rtot=new TH1F(nametot,title,100,psimintot-1.,psimaxtot+1.);
18099 }
18100
18101 if (hPsiOff)
18102 {
18103 rbkg=(TH1F*)hPsiOff->Clone();
18104 rbkg->Reset();
18105 }
18106 else
18107 {
18108 if (!zcor) title.Form("Psi distr. for bkg hypothesis of off-source dt data for n=%-i",ndt);
18109 if (zcor) title.Form("Psi distr. for bkg hypothesis of redshift corrected off-source dt data for n=%-i",ndt);
18110 if (nbkg) rbkg=new TH1F(namebkg,title,100,psiminbkg-1.,psimaxbkg+1.);
18111 }
18112
18113 if (ntot)
18114 {
18115 pvaluetot=math.PsiPvalue(-1,nr,&hOndt,0,&pdfdttot,freq,0,rtot,ncut,&nrxtot);
18116 fBurstHistos.Add(rtot);
18117 }
18118 if (nbkg)
18119 {
18120 pvaluebkg=math.PsiPvalue(-1,nr,&hOffdt,0,&pdfdtbkg,freq,0,rbkg,ncut,&nrxbkg);
18121 fBurstHistos.Add(rbkg);
18122 }
18123
18124 cout << " The following randomised Psi histograms have been (re)generated :" << endl;
18125 if (rtot) cout << " ... " << rtot->GetName() << " : " << rtot->GetTitle() << endl;
18126 if (rbkg) cout << " ... " << rbkg->GetName() << " : " << rbkg->GetTitle() << endl;
18127 }
18128 }
18129
18130 // Listing of the statistics results
18131 cout << " *** Observed Psi values (in dB) for the hypothesis of no burst signal ***" << endl;
18132 if (psitot>=0) cout << " For the on-source stacked patches : psi = " << psitot << endl;
18133 if (psibkg>=0) cout << " For the off-source stacked patches : psi = " << psibkg << endl;
18134 if (psitot>=0 && psibkg>=0) cout << " --> Difference between observed on-source and off-source psi values : " << psidif << endl;
18135 if (psirat>=0) cout << " For the on/off source event rate Bayesian Blocks : psi = " << psirat << endl;
18136 cout << " *** Extreme Psi values for the case of pure background ***" << endl;
18137 if (psimintot>=0) cout << " For on-source psimin : " << psimintot << " psimax : " << psimaxtot;
18138 if (psifractot>0) printf(" (psimax-psi)/range : %-g",psifractot);
18139 if (psimintot>=0 || psifractot>0) printf("\n");
18140 if (psiminbkg>=0) cout << " For off-source psimin : " << psiminbkg << " psimax : " << psimaxbkg;
18141 if (psifracbkg>0) printf(" (psimax-psi)/range : %-g",psifracbkg);
18142 if (psiminbkg>=0 || psifracbkg>0) printf("\n");
18143 if (psiminrat>=0) cout << " For on/off source event rate Bayesian Blocks psimin : " << psiminrat << " psimax : " << psimaxrat;
18144 if (psifracrat>0) printf(" (psimax-psi)/range : %-g",psifracrat);
18145 if (psiminrat>=0 || psifracrat>0) printf("\n");
18146
18147 if (nr>=0)
18148 {
18149 cout << " *** P-values of the observed on-source and off-source psi values ***" << endl;
18150 if (nrxtot>0) cout << " For the on-source stacked patches : P-value = " << pvaluetot << " Used number of randomisations : " << nrxtot << endl;
18151 if (nrxbkg>0) cout << " For the off-source stacked patches : P-value = " << pvaluebkg << " Used number of randomisations : " << nrxbkg << endl;
18152 if (nrxrat>0) cout << " For the on/off source event rate Bayesian Blocks : P-value = " << pvaluerat << " Used number of randomisations : " << nrxrat << endl;
18153 }
18154}
18155
18156void NcAstrolab::GetBurstChi2Statistics(TString type,Int_t ndt,Bool_t zcor)
18157{
18192
18193 NcMath math;
18194
18195 TString text="none";
18196 if (type=="time") text="arrival time";
18197 if (type=="BBtime") text="Bayesian Block event rate";
18198 if (type=="BBrat") text="normalized On-source/Off-source Bayesian Block event rate ratio";
18199 if (type=="angle") text="opening angle";
18200 if (type=="cosa") text="cos(opening angle)";
18201 if (type=="dt") text="arrival time interval";
18202
18203 if (zcor)
18204 {
18205 text.ReplaceAll("arrival time","redshift corrected arrival time");
18206 text.ReplaceAll("event rate","redshift corrected event rate");
18207 }
18208
18209 cout << endl;
18210 if (text=="none")
18211 {
18212 cout << " *" << ClassName() << "::GetBurstChi2Statistics* Unknown statistics type : " << type << endl;
18213 return;
18214 }
18215 else
18216 {
18217 cout << " *" << ClassName() << "::GetBurstChi2Statistics* Analysis of " << text << " statistics" << endl;
18218 }
18219
18220 TH1* tot=0;
18221 TH1* bkg=0;
18222 TH1* rat=0;
18223
18224 Int_t ndftot=0;
18225 Int_t ndfbkg=0;
18226 Int_t ndfrat=0;
18227 Float_t chitot=0;
18228 Float_t chibkg=0;
18229 Float_t chirat=0;
18230
18232 // Arrival time histo Chi-squared statistics //
18234 if (type=="time")
18235 {
18236 if (!zcor)
18237 {
18238 tot=(TH1*)fBurstHistos.FindObject("hOnt");
18239 bkg=(TH1*)fBurstHistos.FindObject("hOfft");
18240 }
18241 else
18242 {
18243 tot=(TH1*)fBurstHistos.FindObject("hOnZt");
18244 bkg=(TH1*)fBurstHistos.FindObject("hOffZt");
18245 }
18246
18247 if (!tot) printf(" === No on source data available === \n");
18248 if (!bkg) printf(" === No off source data available === \n");
18249
18250 if (!tot && !bkg) return;
18251
18252 if (tot) chitot=math.Chi2Value(tot,0,0,&ndftot);
18253 if (bkg) chibkg=math.Chi2Value(bkg,0,0,&ndfbkg);
18254 }
18255
18257 // Event rate histo Chi-squared statistics //
18259 if (type=="BBtime")
18260 {
18261 if (!zcor)
18262 {
18263 tot=(TH1*)fBurstHistos.FindObject("hOnBBt");
18264 bkg=(TH1*)fBurstHistos.FindObject("hOffBBt");
18265 }
18266 else
18267 {
18268 tot=(TH1*)fBurstHistos.FindObject("hOnBBzt");
18269 bkg=(TH1*)fBurstHistos.FindObject("hOffBBzt");
18270 }
18271
18272 if (!tot) printf(" === No on source data available === \n");
18273 if (!bkg) printf(" === No off source data available === \n");
18274
18275 if (!tot && !bkg) return;
18276
18277 if (tot) chitot=math.Chi2Value(tot,0,0,&ndftot);
18278 if (bkg) chibkg=math.Chi2Value(bkg,0,0,&ndfbkg);
18279 }
18280
18282 // On-source/Off-source event rate ratio histo Chi-squared statistics //
18284 if (type=="BBrat")
18285 {
18286 if (!zcor)
18287 {
18288 rat=(TH1*)fBurstHistos.FindObject("hRatUBBt");
18289 }
18290 else
18291 {
18292 rat=(TH1*)fBurstHistos.FindObject("hRatUBBzt");
18293 }
18294
18295 if (!rat)
18296 {
18297 printf(" === No data available === \n");
18298 return;
18299 }
18300
18301 chirat=math.Chi2Value(rat,0,0,&ndfrat);
18302 }
18303
18305 // Opening angle histo Chi-squared statistics //
18307 if (type=="angle")
18308 {
18309 tot=(TH1*)fBurstHistos.FindObject("hOna");
18310 bkg=(TH1*)fBurstHistos.FindObject("hOffa");
18311
18312 if (!tot) printf(" === No on source data available === \n");
18313 if (!bkg) printf(" === No off source data available === \n");
18314
18315 if (!tot && !bkg) return;
18316
18317 TF1 pdf("pdf","sin(x*acos(-1.)/180.)");
18318 if (tot) chitot=math.Chi2Value(tot,0,&pdf,&ndftot);
18319 if (bkg) chibkg=math.Chi2Value(bkg,0,&pdf,&ndfbkg);
18320 }
18321
18323 // Cosine of opening angle histo Chi-squared statistics //
18325 if (type=="cosa")
18326 {
18327 tot=(TH1*)fBurstHistos.FindObject("hOnCosa");
18328 bkg=(TH1*)fBurstHistos.FindObject("hOffCosa");
18329
18330 if (!tot) printf(" === No on source data available === \n");
18331 if (!bkg) printf(" === No off source data available === \n");
18332
18333 if (!tot && !bkg) return;
18334
18335 if (tot) chitot=math.Chi2Value(tot,0,0,&ndftot);
18336 if (bkg) chibkg=math.Chi2Value(bkg,0,0,&ndfbkg);
18337 }
18338
18340 // Arrival time interval Chi-squared statistics //
18342 if (type=="dt")
18343 {
18344 TH1F hOndt;
18345 TH1F hOffdt;
18346 TF1 pdfdttot;
18347 TF1 pdfdtbkg;
18348
18349 GetBurstDtDistributions(ndt,hOndt,pdfdttot,hOffdt,pdfdtbkg,zcor);
18350
18351 Int_t ntot=hOndt.GetEntries();
18352 Int_t nbkg=hOffdt.GetEntries();
18353
18354 if (!ntot) printf(" === No on source data available === \n");
18355 if (!nbkg) printf(" === No off source data available === \n");
18356
18357 if (!ntot && !nbkg) return;
18358
18359 if (ntot) chitot=math.Chi2Value(&hOndt,0,&pdfdttot,&ndftot);
18360 if (nbkg) chibkg=math.Chi2Value(&hOffdt,0,&pdfdtbkg,&ndfbkg);
18361 }
18362
18363 // Listing of the statistics results
18364 Float_t chidif=chitot-chibkg;
18365 cout << " *** Observed Chi-squared values for the hypothesis of no burst signal ***" << endl;
18366 if (chitot>0) cout << " For the on-source stacked patches : chi2 = " << chitot << " ndf = " << ndftot << endl;
18367 if (chibkg>0) cout << " For the off-source stacked patches : chi2 = " << chibkg << " ndf = " << ndfbkg << endl;
18368 if (chitot>0 && chibkg>0) cout << " --> Difference between observed on-source and off-source chi2 values : " << chidif << endl;
18369 if (chirat>0) cout << " For the on/off source event rate Bayesian Blocks : chi2 = " << chirat << " ndf = " << ndfrat << endl;
18370
18371 Float_t ptot=-1;
18372 Float_t sigmatot=-1;
18373 Float_t pbkg=-1;
18374 Float_t sigmabkg=-1;
18375 Float_t prat=-1;
18376 Float_t sigmarat=-1;
18377
18378 if (chitot)
18379 {
18380 ptot=math.Chi2Pvalue(chitot,ndftot);
18381 sigmatot=math.Chi2Pvalue(chitot,ndftot,0,1);
18382 }
18383 if (chibkg)
18384 {
18385 pbkg=math.Chi2Pvalue(chibkg,ndfbkg);
18386 sigmabkg=math.Chi2Pvalue(chibkg,ndfbkg,0,1);
18387 }
18388 if (chirat)
18389 {
18390 prat=math.Chi2Pvalue(chirat,ndfrat);
18391 sigmarat=math.Chi2Pvalue(chirat,ndfrat,0,1);
18392 }
18393
18394 cout << " *** P-values of the observed on-source and off-source chi2 values ***" << endl;
18395 if (ptot>=0) cout << " For the on-source stacked patches : P-value = " << ptot << " (" << sigmatot << " sigma)" << endl;
18396 if (pbkg>=0) cout << " For the off-source stacked patches : P-value = " << pbkg << " (" << sigmabkg << " sigma)" << endl;
18397 if (prat>=0) cout << " For the on/off source event rate Bayesian Blocks : P-value = " << prat << " (" << sigmarat << " sigma)" << endl;
18398}
18399
18400void NcAstrolab::GetBurstDtDistributions(Int_t ndt,TH1F& hisdtOn,TF1& pdfdtOn,TH1F& hisdtOff,TF1& pdfdtOff,Bool_t zcor)
18401{
18420
18421
18422 hisdtOn.Reset();
18423 hisdtOff.Reset();
18424
18425 Int_t fTunits=TMath::Nint(fBurstParameters->GetSignal("Tunits"));
18426 TString tu="days";
18427 if (fTunits==1) tu="hours";
18428 if (fTunits==2) tu="sec";
18429 if (fTunits==3) tu="ns";
18430 if (fTunits==4) tu="ps";
18431
18432 Float_t fTfact=fBurstParameters->GetSignal("Tfact");
18433
18434 TString nametot;
18435 TString namebkg;
18436 TString varname;
18437
18438 // Create the automatically binned delta t histograms
18439 if (!zcor)
18440 {
18441 nametot.Form("hOndt%-i",ndt);
18442 namebkg.Form("hOffdt%-i",ndt);
18443 varname="dtime";
18444 }
18445 else
18446 {
18447 nametot.Form("hOnZdt%-i",ndt);
18448 namebkg.Form("hOffZdt%-i",ndt);
18449 varname="dtimez";
18450 }
18451 TH1F* hOndt=(TH1F*)fBurstHistos.FindObject(nametot);
18452 TH1F* hOffdt=(TH1F*)fBurstHistos.FindObject(namebkg);
18453
18454 TString title;
18455 Double_t deltatbin=0;
18456 Int_t nOndt=0;
18457 Int_t nOffdt=0;
18458
18459 if (!hOndt)
18460 {
18461 NcSample sOndt=fBurstOnMatch.GetDtSample(varname,ndt);
18462 nOndt=sOndt.GetN();
18463
18464 if (nOndt)
18465 {
18466 hOndt=new TH1F(nametot,"histo",10000,1,0);
18467
18468 hOndt->SetBuffer(nOndt);
18469
18470 for (Int_t i=1; i<=nOndt; i++)
18471 {
18472 hOndt->Fill(sOndt.GetEntry(i,1));
18473 }
18474
18475 hOndt->BufferEmpty(1);
18476
18477 // Create title and labels for this delta t histograms
18478 deltatbin=hOndt->GetXaxis()->GetBinWidth(1);
18479 if (!zcor) title.Form("Time intervals between %-i consecutive events in the on-source time window;dt in %-s;Counts per %-.3g %-s",(ndt+1),tu.Data(),deltatbin,tu.Data());
18480 if (zcor) title.Form("Time intervals between %-i consecutive events in the redshift corrected on-source time window;dt in %-s;Counts per %-.3g %-s",(ndt+1),tu.Data(),deltatbin,tu.Data());
18481 hOndt->SetTitle(title);
18482
18483 fBurstHistos.Add(hOndt);
18484 }
18485 }
18486
18487 if (!hOffdt)
18488 {
18489 NcSample sOffdt=fBurstOffMatch.GetDtSample(varname,ndt);
18490 nOffdt=sOffdt.GetN();
18491
18492 if (nOffdt)
18493 {
18494 hOffdt=new TH1F(namebkg,"histo",10000,1,0);
18495
18496 hOffdt->SetBuffer(nOffdt);
18497
18498 for (Int_t i=1; i<=nOffdt; i++)
18499 {
18500 hOffdt->Fill(sOffdt.GetEntry(i,1));
18501 }
18502
18503 hOffdt->BufferEmpty(1);
18504
18505 // Create title and labels for this delta t histograms
18506 deltatbin=hOffdt->GetXaxis()->GetBinWidth(1);
18507 if (!zcor) title.Form("Time intervals between %-i consecutive events in the off-source time window;dt in %-s;Counts per %-.3g %-s",(ndt+1),tu.Data(),deltatbin,tu.Data());
18508 if (zcor) title.Form("Time intervals between %-i consecutive events in the redshift corrected off-source time window;dt in %-s;Counts per %-.3g %-s",(ndt+1),tu.Data(),deltatbin,tu.Data());
18509 hOffdt->SetTitle(title);
18510
18511 fBurstHistos.Add(hOffdt);
18512 }
18513 }
18514
18515 if (hOndt || hOffdt) cout << " The following arrival time interval (dt) histograms have been generated :" << endl;
18516 if (hOndt) cout << " ... " << hOndt->GetName() << " : " << hOndt->GetTitle() << endl;
18517 if (hOffdt) cout << " ... " << hOffdt->GetName() << " : " << hOffdt->GetTitle() << endl;
18518
18519 if (hOndt) hisdtOn=*hOndt;
18520 if (hOffdt) hisdtOff=*hOffdt;
18521
18522 // Creation of the Poisson based dt PDFs from the observed data for a background only hypothesis
18523
18524 Double_t rateOn=fBurstParameters->GetSignal("rateOn");
18525 Double_t rateOff=fBurstParameters->GetSignal("rateOff");
18526
18527 // Convert the event rates into the correct units
18528 rateOn*=fTfact;
18529 rateOff*=fTfact;
18530
18531 if (zcor) // Redshift corrected arrival times
18532 {
18533 Double_t nevt=fBurstOnMatch.GetN();
18534 Double_t tmin=fBurstOnMatch.GetMinimum(varname);
18535 Double_t tmax=fBurstOnMatch.GetMaximum(varname);
18536 Double_t twin=tmax-tmin;
18537 rateOn=0;
18538 if (twin) rateOn=nevt/twin;
18539 nevt=fBurstOffMatch.GetN();
18540 tmin=fBurstOffMatch.GetMinimum(varname);
18541 tmax=fBurstOffMatch.GetMaximum(varname);
18542 twin=tmax-tmin;
18543 rateOff=0;
18544 if (twin) rateOff=nevt/twin;
18545 }
18546
18547 // Determine the corresponding dt PDFs based on Poisson statistics
18548 // Only the bkg dt PDF is used, since this may be obtained from off-source measurements.
18549 // Using the total dt PDF would artificially lower the sensitivity due to possible signal events.
18550
18551 NcMath math;
18552 pdfdtOn=math.PoissonDtDist(rateOn,ndt); // Poisson dt pdf for the observed on source event rate
18553 pdfdtOff=math.PoissonDtDist(rateOff,ndt); // Poisson dt pdf for the observed off source event rate
18554
18555 if (!zcor)
18556 {
18557 nametot.Form("hpdfOndt%-i",ndt);
18558 namebkg.Form("hpdfOffdt%-i",ndt);
18559 }
18560 else
18561 {
18562 nametot.Form("hpdfOnZdt%-i",ndt);
18563 namebkg.Form("hpdfOffZdt%-i",ndt);
18564 }
18565 TH1* hpdfOndt=(TH1*)fBurstHistos.FindObject(nametot);
18566 TH1* hpdfOffdt=(TH1*)fBurstHistos.FindObject(namebkg);
18567
18568 Double_t xmaxfdt=1;
18569 Double_t deltatmax=0;
18570 if (hOndt)
18571 {
18572 deltatmax=hOndt->GetXaxis()->GetXmax();
18573 xmaxfdt=deltatmax;
18574 }
18575 if (hOffdt)
18576 {
18577 deltatmax=hOffdt->GetXaxis()->GetXmax();
18578 if (deltatmax>xmaxfdt) xmaxfdt=deltatmax;
18579 }
18580 Int_t npx=10000;
18581 pdfdtOn.SetRange(0,xmaxfdt);
18582 pdfdtOn.SetNpx(npx);
18583 pdfdtOff.SetRange(0,xmaxfdt);
18584 pdfdtOff.SetNpx(npx);
18585
18586 // Provide the dt PDFs as histograms in the output file
18587 if (!hpdfOndt && nOndt)
18588 {
18589 hpdfOndt=(TH1*)pdfdtOn.GetHistogram()->Clone();
18590 hpdfOndt->SetName(nametot.Data());
18591 title.Form("dt in %-s",tu.Data());
18592 hpdfOndt->GetXaxis()->SetTitle(title);
18593 fBurstHistos.Add(hpdfOndt);
18594 }
18595
18596 if (!hpdfOffdt && nOffdt)
18597 {
18598 hpdfOffdt=(TH1*)pdfdtOff.GetHistogram()->Clone();
18599 hpdfOffdt->SetName(namebkg.Data());
18600 hpdfOffdt->GetXaxis()->SetTitle(title);
18601 fBurstHistos.Add(hpdfOffdt);
18602 }
18603
18604 if (hpdfOndt || hpdfOffdt) cout << " The following arrival time interval (dt) PDFs have been generated :" << endl;
18605 if (hpdfOndt) cout << " ... " << hpdfOndt->GetName() << " : " << hpdfOndt->GetTitle() << endl;
18606 if (hpdfOffdt) cout << " ... " << hpdfOffdt->GetName() << " : " << hpdfOffdt->GetTitle() << endl;
18607}
18608
18610{
18620
18621 Int_t nh=fBurstHistos.GetEntries();
18622 cout << endl;
18623 cout << " =============== The following " << nh << " histograms have been generated ===============" << endl;
18624 for (Int_t ih=0; ih<nh; ih++)
18625 {
18626 TH1* hx=(TH1*)fBurstHistos.At(ih);
18627 if (!hx) continue;
18628 if (!hx->GetEntries()) continue;
18629 cout << " " << hx->GetName() << " : " << hx->GetTitle() << endl;
18630 }
18631 cout << " ===============================================================================" << endl;
18632}
18633
18635{
18645
18646 // The output file for the produced histograms
18647 TFile fout(filename.Data(),"RECREATE","NcAstrolab analysis results");
18648
18649 // Write all the histos to the output file
18650 Int_t nh=fBurstHistos.GetEntries();
18651 for (Int_t ih=0; ih<nh; ih++)
18652 {
18653 TH1* hx=(TH1*)fBurstHistos.At(ih);
18654 if (!hx) continue;
18655 if (!hx->GetEntries()) continue;
18656 hx->Write();
18657 }
18658
18659 fout.Write();
18660
18661 cout << endl;
18662 cout << " *" << ClassName() << "::WriteBurstHistograms* All generated histograms have been written to file " << filename << endl;
18664}
18665
18667{
18676
18677 if (gROOT->IsBatch())
18678 {
18679 printf("\n *%-s::SkyMapPanel* GUI is not available in batch mode. \n",ClassName());
18680 return;
18681 }
18682
18683 // Select the lab timestamp as default
18684 fMapTS.SetMJD(fMJD,fJsec,fJns,fJps,"A");
18685
18686 // Import current Lab settings
18687 Double_t l=0;
18688 Double_t b=0;
18689 GetLabPosition(l,b,"deg");
18690 fMapLabLocL=l;
18691 fMapLabLocB=b;
18694 // Get the lab timestamp data in the text box
18695 UInt_t year=0;
18696 UInt_t month=0;
18697 UInt_t day=0;
18698 GetDate(kTRUE,0,&year,&month,&day);
18699 GetDayTimeString("UTC",3,0,0,&fMapTime);
18700 fMapDate.Form("%02i-%02i-%-i",day,month,year);
18701 fMapTime.ReplaceAll(" UTC","");
18703 fMapDateTime+="/";
18705
18706 // Re-invokation of the SkyMapPanel
18707 if (fSkyMapPanel)
18708 {
18709 // Import the current lab settings
18710 Int_t idx=1;
18711 TString names[9]={"User","IceCube","RNO-G","ARA","Amanda","WSRT","Astron","Greenwich","ARCA"};
18712 for (Int_t i=1; i<=9; i++)
18713 {
18714 if (names[i-1]==fExperiment) idx=i;
18715 }
18716 fMapLabE->Select(idx,kTRUE);
18717
18718 MapLocEnter();
18719
18720 // The Lab UTC time
18721 fMapTStimetype->Select(1,kTRUE);
18722 MapTimeType(10);
18723
18724 // Map all subwindows of main frame
18725 fSkyMapPanel->MapSubwindows();
18726
18727 // Initialize the layout algorithm
18728 fSkyMapPanel->Resize(fSkyMapPanel->GetDefaultSize());
18729
18730 // Map main frame
18731 fSkyMapPanel->MapWindow();
18732
18733 return;
18734 }
18735
18736 // New initialization of the SkyMapPanel
18737 UInt_t border=5;
18738 fSkyMapPanel=new TGMainFrame(gClient->GetRoot());
18739 fSkyMapPanel->SetWindowName("SkyMapPanel");
18740 fSkyMapPanel->Connect("CloseWindow()","NcAstrolab",this,"MapClose()");
18741
18742 // Define the various sub-frames and fill them with the various panels
18743 TGCompositeFrame* frames[4]={0,0,0,0};
18744 TGLayoutHints* layouts[4]={0,0,0,0};
18745
18746 // The Lab specification and timestamp frame
18747 frames[0]=new TGCompositeFrame(fSkyMapPanel,1,1,kHorizontalFrame|kSunkenFrame);
18748 layouts[0]=new TGLayoutHints(kLHintsExpandX,border,border,0,0);
18749 LabLocationPanel(frames[0]);
18750 TimestampPanel(frames[0]);
18751
18752 // The local reference and info frame
18753 frames[1]=new TGCompositeFrame(fSkyMapPanel,1,1,kHorizontalFrame|kSunkenFrame);
18754 layouts[1]=new TGLayoutHints(kLHintsExpandX,border,border,0,0);
18755 LabLocalFramePanel(frames[1]);
18756 InfoPanel(frames[1]);
18757
18758 // The entries frame
18759 frames[2]=new TGCompositeFrame(fSkyMapPanel,1,1,kHorizontalFrame|kSunkenFrame);
18760 layouts[2]=new TGLayoutHints(kLHintsExpandX,border,border,0,0);
18761 EntriesPanel(frames[2]);
18762
18763 // The drawing/listing options and command buttons frame
18764 frames[3]=new TGCompositeFrame(fSkyMapPanel,1,1,kHorizontalFrame|kSunkenFrame);
18765 layouts[3]=new TGLayoutHints(kLHintsExpandX,border,border,0,0);
18766 MapListOptionsPanel(frames[3]);
18767 CommandPanel(frames[3]);
18768
18769 // Add all subframes to the mainframe
18770 for (Int_t i=0; i<4; i++)
18771 {
18772 if (frames[i]) fSkyMapPanel->AddFrame(frames[i],layouts[i]);
18773 }
18774
18775 // Map all subwindows of main frame
18776 fSkyMapPanel->MapSubwindows();
18777
18778 // Initialize the layout algorithm
18779 fSkyMapPanel->Resize(fSkyMapPanel->GetDefaultSize());
18780
18781 // Map main frame
18782 fSkyMapPanel->MapWindow();
18783}
18784
18785void NcAstrolab::LabLocationPanel(TGCompositeFrame* frame)
18786{
18792
18793 if (!frame) return;
18794
18795 TGGroupFrame* panel=new TGGroupFrame(frame,"Lab longitude, latitude, experiment site and detector ID",kHorizontalFrame);
18796 panel->SetTitlePos(TGGroupFrame::kCenter);
18797 frame->AddFrame(panel);
18798
18799 // The lab longitude entry field
18800 fMapLabLBI[0]=new TGNumberEntryField(panel,-1,fMapLabLocL);
18801 fMapLabLBI[0]->SetToolTipText("Longitude");
18802 fMapLabLBI[0]->Connect("TextChanged(const char*)","NcAstrolab",this,"MapLocl(const char*)");
18803 fMapLabLBI[0]->Resize(65,20);
18804 panel->AddFrame(fMapLabLBI[0]);
18805
18806 // The lab latitude entry field
18807 fMapLabLBI[1]=new TGNumberEntryField(panel,-1,fMapLabLocB);
18808 fMapLabLBI[1]->SetToolTipText("Latitude");
18809 fMapLabLBI[1]->Connect("TextChanged(const char*)","NcAstrolab",this,"MapLocb(const char*)");
18810 fMapLabLBI[1]->Resize(65,20);
18811 panel->AddFrame(fMapLabLBI[1]);
18812
18813 // The lab longitude and latitude type selection box
18814 fMapLabU=new TGComboBox(panel);
18815 fMapLabU->Connect("Selected(Int_t)","NcAstrolab",this,"MapUloc(Int_t)");
18816 fMapLabU->AddEntry("deg",1);
18817 fMapLabU->AddEntry("dms",2);
18818 fMapLabU->AddEntry("hms",3);
18819 fMapLabU->AddEntry("rad",4);
18820 fMapLabU->Resize(50,20);
18821 panel->AddFrame(fMapLabU);
18822 fMapLabU->Select(1,kTRUE);
18823
18824 // The experiment name selection box
18825 fMapLabE=new TGComboBox(panel);
18826 fMapLabE->Connect("Selected(Int_t)","NcAstrolab",this,"MapExperiment(Int_t)");
18827 Int_t idx=1;
18828 TString names[9]={"User","IceCube","RNO-G","ARA","Amanda","WSRT","Astron","Greenwich","ARCA"};
18829 for (Int_t i=1; i<=9; i++)
18830 {
18831 fMapLabE->AddEntry(names[i-1],i);
18832 if (names[i-1]==fExperiment) idx=i;
18833 }
18834 fMapLabE->Resize(90,20);
18835 panel->AddFrame(fMapLabE);
18836 fMapLabE->Select(idx,kTRUE);
18837
18838 // The detector element ID field
18839 fMapLabLBI[2]=new TGNumberEntryField(panel,-1,fLabId,TGNumberFormat::kNESInteger);
18840 fMapLabLBI[2]->SetToolTipText("The (optional) detector element ID (0=global)");
18841 fMapLabLBI[2]->Connect("TextChanged(const char*)","NcAstrolab",this,"MapLocId(const char*)");
18842 fMapLabLBI[2]->Resize(40,20);
18843 panel->AddFrame(fMapLabLBI[2]);
18844
18845 // The button to enter the provided data
18846 TGTextButton* enter=new TGTextButton(panel,"Enter");
18847 enter->SetToolTipText("Enter the provided data");
18848 enter->Connect("Clicked()","NcAstrolab",this,"MapLocEnter()");
18849 TGLayoutHints* Lenter=new TGLayoutHints(kLHintsCenterX,10,0,0,0);
18850 panel->AddFrame(enter,Lenter);
18851
18852 MapLocEnter();
18853}
18854
18855void NcAstrolab::MapLocl(const char* text)
18856{
18862
18863 TString s=text;
18864 fMapLabLocL=s.Atof();
18865}
18866
18867void NcAstrolab::MapLocb(const char* text)
18868{
18874
18875 TString s=text;
18876 fMapLabLocB=s.Atof();
18877}
18878
18880{
18886
18887 TString s[4]={"deg","dms","hms","rad"};
18888 if (i<=4) fMapLabLocU=s[i-1];
18889}
18890
18892{
18898
18899 TString s[9]={"User","IceCube","RNO-G","ARA","Amanda","WSRT","Astron","Greenwich","ARCA"};
18900 if (i<=9) fMapLabExpName=s[i-1];
18901}
18902
18903void NcAstrolab::MapLocId(const char* text)
18904{
18910
18911 TString s=text;
18912 fMapLabId=s.Atoi();
18913}
18914
18916{
18922
18923 fSkyMapPanel->RequestFocus();
18924
18926
18927 if (fMapLabExpName=="User")
18928 {
18929 SetNameTitle("User","Virtual Lab for general use");
18930 MapLocId("0");
18931 printf("\n *** Settings adopted for a virtual lab for general use. *** \n");
18932 }
18933 else
18934 {
18937 // Update the longitude, latitude and detector ID selection boxes
18939 TString s;
18940 s.Form("%-.3f",fMapLabLocL);
18941 fMapLabLBI[0]->SetText(s);
18942 s.Form("%-.3f",fMapLabLocB);
18943 fMapLabLBI[1]->SetText(s);
18944 fMapLabU->Select(1,kTRUE);
18945 MapUloc(1);
18946 s.Form("%-i",fMapLabId);
18947 fMapLabLBI[2]->SetText(s);
18948 printf("\n *** Lab settings adopted for the %-s location. *** \n",fMapLabExpName.Data());
18949 }
18950
18951 // Update the local frame data for the selected lab
18952 TString val;
18953 for (Int_t i=0; i<6; i++)
18954 {
18955 val.Form("%-.2f",fAxes[i]);
18956 if (fMapLabLframe[i]) fMapLabLframe[i]->SetText(val);
18957 }
18958}
18959
18960void NcAstrolab::TimestampPanel(TGCompositeFrame* frame)
18961{
18967
18968 if (!frame) return;
18969
18970 TGGroupFrame* panel=new TGGroupFrame(frame,"Timestamp to be used for Entries, List and Map",kHorizontalFrame);
18971 panel->SetTitlePos(TGGroupFrame::kCenter);
18972 frame->AddFrame(panel);
18973
18974 // The Date/Time textbox
18975 fMapTSdatetime=new TGTextEntry(panel,fMapDateTime.Data());
18976 fMapTSdatetime->SetToolTipText("Date/Time as dd-mm-yyyy/hh:mm:ss.sss or MJD");
18977 fMapTSdatetime->Connect("TextChanged(const char*)","NcAstrolab",this,"MapDateTime(const char*)");
18978 fMapTSdatetime->SetAlignment(kTextRight);
18979 fMapTSdatetime->Resize(170,20);
18980 panel->AddFrame(fMapTSdatetime);
18981
18982 // The Time type selection box
18983 fMapTStimetype=new TGComboBox(panel);
18984 fMapTStimetype->Connect("Selected(Int_t)","NcAstrolab",this,"MapTimeType(Int_t)");
18985 fMapTStimetype->AddEntry("UTC",1);
18986 fMapTStimetype->AddEntry("LMT",2);
18987 fMapTStimetype->AddEntry("UT1",3);
18988 fMapTStimetype->AddEntry("MJD",4);
18989 fMapTStimetype->AddEntry("JD",5);
18990 fMapTStimetype->AddEntry("TJD",6);
18991 fMapTStimetype->AddEntry("Unix",7);
18992 fMapTStimetype->AddEntry("GPS",8);
18993 fMapTStimetype->AddEntry("TAI",9);
18994 fMapTStimetype->AddEntry("TT",10);
18995 fMapTStimetype->AddEntry("SysClock",11);
18996 fMapTStimetype->AddEntry("Lab",12);
18997 fMapTStimetype->AddEntry("EntryName",13);
18998 fMapTStimetype->Resize(100,20);
18999 panel->AddFrame(fMapTStimetype);
19000 fMapTStimetype->Select(1,kTRUE);
19001 MapTimeType(1);
19002
19003 // The Lab TS modification button
19004 TGTextButton* labTS=new TGTextButton(panel,"Store as Lab TS");
19005 labTS->SetToolTipText("Store the current selection as Lab timestamp");
19006 labTS->Connect("Clicked()","NcAstrolab",this,"MapLabTS()");
19007 TGLayoutHints* LlabTS=new TGLayoutHints(kLHintsCenterX,10,0,0,0);
19008 panel->AddFrame(labTS,LlabTS);
19009}
19010
19011void NcAstrolab::MapDateTime(const char* text)
19012{
19018
19019 fMapDateTime=text;
19020}
19021
19023{
19029
19030 TString s[13]={"UTC","LMT","UT1","MJD","JD","TJD","Unix","GPS","TAI","TT","SysClock","Lab","EntryName"};
19031
19032 if (i<=13) fMapTimeType=s[i-1];
19033
19034 if (fMapTimeType=="SysClock" || fMapTimeType=="Lab") SetMapTS();
19035 if (fMapTimeType=="MJD" || fMapTimeType=="JD" || fMapTimeType=="TJD" || fMapTimeType=="Unix" || fMapTimeType.Contains("Name")) fMapTSdatetime->SetText("");
19036}
19037
19039{
19045
19046 SetMapTS();
19047
19048 fSkyMapPanel->RequestFocus();
19049
19050 Int_t mjd,sec,ns;
19051 fMapTS.GetMJD(mjd,sec,ns);
19052 Int_t ps=fMapTS.GetPs();
19053 this->SetMJD(mjd,sec,ns,ps,"U");
19054
19055 printf("\n *** Lab timestamp modified *** \n");
19056}
19057
19058void NcAstrolab::LabLocalFramePanel(TGCompositeFrame* frame)
19059{
19065
19066 if (!frame) return;
19067
19068 TGGroupFrame* panel=new TGGroupFrame(frame,"Local frame axes orientations w.r.t. X0=South, Y0=East, Z0=Zenith)",kHorizontalFrame);
19069 panel->SetTitlePos(TGGroupFrame::kCenter);
19070 frame->AddFrame(panel);
19071
19072 // The local X-axis theta (=zenith) angle w.r.t. the MRF
19073 fMapLabLframe[0]=new TGNumberEntryField(panel,-1,fAxes[0]);
19074 fMapLabLframe[0]->SetToolTipText("Local X-axis zenith angle in deg");
19075 fMapLabLframe[0]->Resize(55,20);
19076 panel->AddFrame(fMapLabLframe[0]);
19077
19078 // The local X-axis phi angle w.r.t. the MRF
19079 fMapLabLframe[1]=new TGNumberEntryField(panel,-1,fAxes[1]);
19080 fMapLabLframe[1]->SetToolTipText("Local X-axis phi angle in deg");
19081 fMapLabLframe[1]->Resize(55,20);
19082 panel->AddFrame(fMapLabLframe[1]);
19083
19084 // The local Y-axis theta (=zenith) angle w.r.t. the MRF
19085 fMapLabLframe[2]=new TGNumberEntryField(panel,-1,fAxes[2]);
19086 fMapLabLframe[2]->SetToolTipText("Local Y-axis zenith angle in deg");
19087 fMapLabLframe[2]->Resize(55,20);
19088 panel->AddFrame(fMapLabLframe[2]);
19089
19090 // The local Y-axis phi angle w.r.t. the MRF
19091 fMapLabLframe[3]=new TGNumberEntryField(panel,-1,fAxes[3]);
19092 fMapLabLframe[3]->SetToolTipText("Local Y-axis phi angle in deg");
19093 fMapLabLframe[3]->Resize(55,20);
19094 panel->AddFrame(fMapLabLframe[3]);
19095
19096 // The local Z-axis theta (=zenith) angle w.r.t. the MRF
19097 fMapLabLframe[4]=new TGNumberEntryField(panel,-1,fAxes[4]);
19098 fMapLabLframe[4]->SetToolTipText("Local Z-axis zenith angle in deg");
19099 fMapLabLframe[4]->Resize(55,20);
19100 panel->AddFrame(fMapLabLframe[4]);
19101
19102 // The local Z-axis phi angle w.r.t. the MRF
19103 fMapLabLframe[5]=new TGNumberEntryField(panel,-1,fAxes[5]);
19104 fMapLabLframe[5]->SetToolTipText("Local Z-axis phi angle in deg");
19105 fMapLabLframe[5]->Resize(55,20);
19106 panel->AddFrame(fMapLabLframe[5]);
19107
19109
19110 // The button to enter the provided data
19111 TGTextButton* enter=new TGTextButton(panel,"Enter");
19112 enter->SetToolTipText("Enter the provided data");
19113 enter->Connect("Clicked()","NcAstrolab",this,"MapLabLframeEnter()");
19114 TGLayoutHints* Lenter=new TGLayoutHints(kLHintsLeft,10,0,0,0);
19115 panel->AddFrame(enter,Lenter);
19116}
19117
19119{
19127
19128 fSkyMapPanel->RequestFocus();
19129
19130 if (fMapLabExpName=="IceCube" || fMapLabExpName=="RNO-G" || fMapLabExpName=="Amanda")
19131 {
19132 printf("\n *** Local frame will NOT be changed for experiment site %-s *** \n",fMapLabExpName.Data());
19133
19134 // Update the local frame data for the selected lab
19135 TString val;
19136 for (Int_t i=0; i<6; i++)
19137 {
19138 val.Form("%-.2f",fAxes[i]);
19139 if (fMapLabLframe[i]) fMapLabLframe[i]->SetText(val);
19140 }
19141 return;
19142 }
19143
19144 for (Int_t i=0; i<6; i++)
19145 {
19146 fAxes[i]=fMapLabLframe[i]->GetNumber();
19147 }
19148
19149 SetLocalFrame(fAxes[0],fAxes[1],fAxes[2],fAxes[3],fAxes[4],fAxes[5]);
19150}
19151
19152void NcAstrolab::InfoPanel(TGCompositeFrame* frame)
19153{
19159
19160 if (!frame) return;
19161
19162 TGGroupFrame* panel=new TGGroupFrame(frame,"Informative output",kHorizontalFrame);
19163 panel->SetTitlePos(TGGroupFrame::kCenter);
19164 frame->AddFrame(panel);
19165
19166 // The info category selection box
19167 TGComboBox* cinfo=new TGComboBox(panel);
19168 cinfo->Connect("Selected(Int_t)","NcAstrolab",this,"MapCinfo(Int_t)");
19169 cinfo->AddEntry("Lab",1);
19170 cinfo->AddEntry("TSbox",2);
19171 cinfo->AddEntry("Entry",3);
19172 cinfo->AddEntry("Nstore",4);
19173 cinfo->Resize(60,20);
19174 panel->AddFrame(cinfo);
19175 cinfo->Select(1,kTRUE);
19176 MapCinfo(1);
19177
19178 // The lab info time type selection box
19179 TGComboBox* tinfo=new TGComboBox(panel);
19180 tinfo->Connect("Selected(Int_t)","NcAstrolab",this,"MapTinfo(Int_t)");
19181 tinfo->AddEntry("LAT/LAST",1);
19182 tinfo->AddEntry("LMT/LMST",2);
19183 tinfo->AddEntry("Julian",3);
19184 tinfo->AddEntry("UT1",4);
19185 tinfo->AddEntry("UTC",5);
19186 tinfo->AddEntry("TAI",6);
19187 tinfo->AddEntry("GPS",7);
19188 tinfo->AddEntry("TT",8);
19189 tinfo->AddEntry("Unix",9);
19190 tinfo->Resize(85,20);
19191 panel->AddFrame(tinfo);
19192 tinfo->Select(1,kTRUE);
19193 MapTinfo(1);
19194
19195 // The lab info longitude and latitude type selection box
19196 TGComboBox* uinfo=new TGComboBox(panel);
19197 uinfo->Connect("Selected(Int_t)","NcAstrolab",this,"MapUinfo(Int_t)");
19198 uinfo->AddEntry("deg",1);
19199 uinfo->AddEntry("dms",2);
19200 uinfo->AddEntry("hms",3);
19201 uinfo->AddEntry("rad",4);
19202 uinfo->Resize(50,20);
19203 panel->AddFrame(uinfo);
19204 uinfo->Select(1,kTRUE);
19205 MapUinfo(1);
19206
19207 // The entry name textbox
19208 TGTextEntry* mapiname=new TGTextEntry(panel,"");
19209 mapiname->SetToolTipText("Stored entry name for info");
19210 mapiname->Connect("TextChanged(const char*)","NcAstrolab",this,"MapIname(const char*)");
19211 mapiname->SetAlignment(kTextRight);
19212 mapiname->Resize(100,20);
19213 panel->AddFrame(mapiname);
19214
19215 // The info button
19216 TGTextButton* info=new TGTextButton(panel,"Info");
19217 info->Connect("Clicked()","NcAstrolab",this,"MapInfo()");
19218 info->SetToolTipText("Provide info on the specified item");
19219 TGLayoutHints* Linfo=new TGLayoutHints(kLHintsLeft,10,0,0,0);
19220 panel->AddFrame(info,Linfo);
19221}
19222
19224{
19230
19231 TString s[4]={"Lab","TS box","EntryName","Nstore"};
19232 if (i<=4) fMapCinfo=s[i-1];
19233}
19234
19236{
19242
19243 if (i==1)
19244 {
19245 fMapTinfo=-1;
19246 }
19247 else
19248 {
19249 fMapTinfo=i-1;
19250 }
19251}
19252
19254{
19260
19261 TString s[4]={"deg","dms","hms","rad"};
19262 if (i<=4) fMapUinfo=s[i-1];
19263}
19264
19265void NcAstrolab::MapIname(const char* text)
19266{
19272
19273 fMapIname=text;
19274}
19275
19277{
19283
19284 SetMapTS();
19285
19286 TString modes[9]={"LAT/LAST","LMT/LMST","Julian","UT1","UTC","TAI","GPS","TT","Unix"};
19287 TString datetime;
19288
19289 if (fMapCinfo=="Nstore")
19290 {
19291 Int_t nref=GetNsignals(0);
19292 Int_t nmeas=GetNsignals(1);
19293 Int_t ntot=nref+nmeas;
19294 printf("\n *** Info about the stored entries *** \n");
19295 printf(" Ntotal=%-i Nrefs=%-i Nmeas=%-i \n",ntot,nref,nmeas);
19296 }
19297 else if (fMapCinfo=="Lab")
19298 {
19299 if (fMapTinfo<3)
19300 {
19301 printf("\n *** Info about the current Lab settings *** \n");
19303 }
19304 else
19305 {
19306 printf("\n *** Info for the Lab timestamp *** \n");
19307 if (fMapTinfo==8)
19308 {
19309 printf(" Unix time : %-.12f \n",GetUnixTime());
19310 }
19311 else
19312 {
19313 datetime=GetDayTimeString(modes[fMapTinfo],12);
19314 printf(" %-s \n",datetime.Data());
19315 }
19316 }
19317 }
19318 else if (fMapCinfo.Contains("TS"))
19319 {
19320 printf("\n *** Info for the timestamp in the user selection box *** \n");
19321 if (fMapTinfo<3)
19322 {
19323 printf(" Lab time offset w.r.t. UT : "); PrintTime(fToffset,12); printf("\n");
19325 fMapTS.Date(4);
19326 }
19327 else
19328 {
19329 if (fMapTinfo==8)
19330 {
19331 printf(" Unix time : %-.12f \n",fMapTS.GetUnixTime());
19332 }
19333 else
19334 {
19335 datetime=fMapTS.GetDayTimeString(modes[fMapTinfo],12);
19336 printf(" %-s \n",datetime.Data());
19337 }
19338 }
19339 }
19340 else // Information of the specified entry name
19341 {
19342 NcSignal* sx=0;
19343 NcTimestamp* tx=0;
19344 sx=GetSignal(fMapIname,0);
19345 if(!sx) sx=GetSignal(fMapIname,1);
19346 if (sx)
19347 {
19348 printf("\n *** Info for entry : %-s *** \n",fMapIname.Data());
19349 sx->Data("sph",fMapUinfo);
19350 tx=sx->GetTimestamp();
19351 if (tx)
19352 {
19353 NcTimestamp tx2(*tx);
19355 if (fMapTinfo<3)
19356 {
19357 printf(" Lab time offset w.r.t. UT : "); PrintTime(fToffset,12); printf("\n");
19358 tx2.Date(fMapTinfo,fToffset);
19359 tx2.Date(4);
19360 }
19361 else
19362 {
19363 if (fMapTinfo==8)
19364 {
19365 printf(" Unix time : %-.12f \n",tx2.GetUnixTime());
19366 }
19367 else
19368 {
19369 datetime=tx2.GetDayTimeString(modes[fMapTinfo],12);
19370 printf(" %-s \n",datetime.Data());
19371 }
19372 }
19373 }
19374 }
19375 else
19376 {
19377 printf("\n *** No entry found with name : %-s *** \n",fMapIname.Data());
19378 }
19379 }
19380}
19381
19382void NcAstrolab::EntriesPanel(TGCompositeFrame* frame)
19383{
19389
19390 if (!frame) return;
19391
19392 TGGroupFrame* panel=new TGGroupFrame(frame,"Entries in (a,b) coordinates",kHorizontalFrame);
19393 panel->SetTitlePos(TGGroupFrame::kCenter);
19394 frame->AddFrame(panel);
19395
19396 // The a coordinate entry field
19397 TGNumberEntryField* ea=new TGNumberEntryField(panel,-1,0);
19398 ea->SetToolTipText("Angle a");
19399 ea->Connect("TextChanged(const char*)","NcAstrolab",this,"MapEa(const char*)");
19400 ea->Resize(100,20);
19401 panel->AddFrame(ea);
19402 MapEa("0");
19403
19404 // The a coordinate type selection box
19405 TGComboBox* ua=new TGComboBox(panel);
19406 ua->Connect("Selected(Int_t)","NcAstrolab",this,"MapUa(Int_t)");
19407 ua->AddEntry("deg",1);
19408 ua->AddEntry("dms",2);
19409 ua->AddEntry("hms",3);
19410 ua->AddEntry("rad",4);
19411 ua->AddEntry("hrs",5);
19412 ua->Resize(50,20);
19413 panel->AddFrame(ua);
19414 ua->Select(1,kTRUE);
19415 MapUa(1);
19416
19417 // The b coordinate entry field
19418 TGNumberEntryField* eb=new TGNumberEntryField(panel,-1,0);
19419 eb->SetToolTipText("Angle b");
19420 eb->Connect("TextChanged(const char*)","NcAstrolab",this,"MapEb(const char*)");
19421 eb->Resize(100,20);
19422 panel->AddFrame(eb);
19423 MapEb("0");
19424
19425 // The b coordinate type selection box
19426 TGComboBox* ub=new TGComboBox(panel);
19427 ub->Connect("Selected(Int_t)","NcAstrolab",this,"MapUb(Int_t)");
19428 ub->AddEntry("deg",1);
19429 ub->AddEntry("dms",2);
19430 ub->AddEntry("hms",3);
19431 ub->AddEntry("rad",4);
19432 ub->AddEntry("hrs",5);
19433 ub->Resize(50,20);
19434 panel->AddFrame(ub);
19435 ub->Select(1,kTRUE);
19436 MapUb(1);
19437
19438 TGComboBox* ecoords=new TGComboBox(panel);
19439 ecoords->Connect("Selected(Int_t)","NcAstrolab",this,"MapEcoord(Int_t)");
19440 ecoords->AddEntry("(ra,dec) (J2000)",1);
19441 ecoords->AddEntry("(ra,dec) (Mean)",2);
19442 ecoords->AddEntry("(ra,dec) (True)",3);
19443 ecoords->AddEntry("(ra,dec) (B1950)",4);
19444 ecoords->AddEntry("Galactic (l,b)",5);
19445 ecoords->AddEntry("Ecliptic (l,b)",6);
19446 ecoords->AddEntry("Horizon (azi,zen)",7);
19447 ecoords->AddEntry("ICR (l,b)",8);
19448 ecoords->AddEntry("Local (theta,phi)",9);
19449 ecoords->AddEntry("pdir (theta,phi)",10);
19450 ecoords->Resize(125,20);
19451 panel->AddFrame(ecoords);
19452 ecoords->Select(1,kTRUE);
19453 MapEcoord(1);
19454
19455 // The signal type
19456 TGComboBox* etypes=new TGComboBox(panel);
19457 etypes->Connect("Selected(Int_t)","NcAstrolab",this,"MapEtype(Int_t)");
19458 etypes->AddEntry("Meas",1);
19459 etypes->AddEntry("Ref",2);
19460 etypes->Resize(55,20);
19461 panel->AddFrame(etypes);
19462 etypes->Select(1,kTRUE);
19463 MapEtype(1);
19464
19465 // The (optional) signal name
19466 TGTextEntry* ename=new TGTextEntry(panel,"");
19467 ename->SetToolTipText("The (optional) entry name");
19468 ename->Connect("TextChanged(const char*)","NcAstrolab",this,"MapEname(const char*)");
19469 ename->SetAlignment(kTextRight);
19470 ename->Resize(100,20);
19471 panel->AddFrame(ename);
19472
19473 // The button to Enter the entry
19474 TGTextButton* enter=new TGTextButton(panel,"Enter");
19475 enter->SetToolTipText("Enter the provided entry");
19476 enter->Connect("Clicked()","NcAstrolab",this,"MapEnter()");
19477 TGLayoutHints* Lenter=new TGLayoutHints(kLHintsCenterX,10,0,0,0);
19478 panel->AddFrame(enter,Lenter);
19479
19480 // The button to Remove the entry
19481 TGTextButton* remove=new TGTextButton(panel,"Remove");
19482 remove->SetToolTipText("Remove the entry specified by type and name pattern (name=* means all)");
19483 remove->Connect("Clicked()","NcAstrolab",this,"MapRemove()");
19484 TGLayoutHints* Lremove=new TGLayoutHints(kLHintsCenterX,10,0,0,0);
19485 panel->AddFrame(remove,Lremove);
19486}
19487
19488void NcAstrolab::MapEa(const char* text)
19489{
19495
19496 TString s=text;
19497 fMapEa=s.Atof();
19498}
19499
19501{
19507
19508 TString s[5]={"deg","dms","hms","rad","hrs"};
19509 if (i<=5) fMapEua=s[i-1];
19510}
19511
19512void NcAstrolab::MapEb(const char* text)
19513{
19519
19520 TString s=text;
19521 fMapEb=s.Atof();
19522}
19523
19525{
19531
19532 TString s[5]={"deg","dms","hms","rad","hrs"};
19533 if (i<=5) fMapEub=s[i-1];
19534}
19535
19537{
19543
19544 TString system[10]={"equ","equ","equ","equ","gal","ecl","hor","icr","loc","pdir"};
19545 TString mode[4]={"J","M","T","B"};
19546
19547 if (i<=10) fMapEcoord=system[i-1];
19548
19549 if (i<=4) fMapEmode=mode[i-1];
19550}
19551
19553{
19559
19560 fMapEtype=1;
19561 if (i==2) fMapEtype=0;
19562}
19563
19564void NcAstrolab::MapEname(const char* text)
19565{
19571
19572 fMapEname=text;
19573}
19574
19576{
19582
19583 SetMapTS(); // Set the selected timestamp
19584
19585 fSkyMapPanel->RequestFocus();
19586
19588
19589 printf("\n *** Specified entry stored *** \n");
19590}
19591
19593{
19599
19600 SetMapTS(); // Set the selected timestamp
19601
19602 fSkyMapPanel->RequestFocus();
19603
19604 Int_t nrem=0;
19606
19607 printf("\n *** Number of specified entries have been removed : %-i *** \n",nrem);
19608}
19609
19610void NcAstrolab::MapListOptionsPanel(TGCompositeFrame* frame)
19611{
19617
19618 if (!frame) return;
19619
19620 TGGroupFrame* panel=new TGGroupFrame(frame,"Map/List options for the (a,b) coordinates",kHorizontalFrame);
19621 panel->SetTitlePos(TGGroupFrame::kCenter);
19622 frame->AddFrame(panel);
19623
19624 // A frame with various additional settings
19625 TGVerticalFrame* render=new TGVerticalFrame(panel,1,1);
19626 panel->AddFrame(render);
19627
19628 // The coordinate system selection box
19629 TGGroupFrame* coordsys=new TGGroupFrame(render,"Coordinate system",kHorizontalFrame);
19630 coordsys->SetTitlePos(TGGroupFrame::kCenter);
19631 render->AddFrame(coordsys);
19632 TGComboBox* dcoords=new TGComboBox(coordsys);
19633 dcoords->Connect("Selected(Int_t)","NcAstrolab",this,"MapDcoord(Int_t)");
19634 dcoords->AddEntry("Equatorial (J2000)",1);
19635 dcoords->AddEntry("Equatorial (Mean)",2);
19636 dcoords->AddEntry("Equatorial (True)",3);
19637 dcoords->AddEntry("Equatorial (B1950)",4);
19638 dcoords->AddEntry("Galactic",5);
19639 dcoords->AddEntry("Ecliptic",6);
19640 dcoords->AddEntry("Horizon",7);
19641 dcoords->AddEntry("ICR",8);
19642 dcoords->AddEntry("Local",9);
19643 dcoords->Resize(140,20);
19644 coordsys->AddFrame(dcoords);
19645 dcoords->Select(1,kTRUE);
19646 MapDcoord(1);
19647
19648 // The Map representation selection box
19649 TGGroupFrame* mapview=new TGGroupFrame(render,"Map representation",kHorizontalFrame);
19650 mapview->SetTitlePos(TGGroupFrame::kCenter);
19651 render->AddFrame(mapview);
19652 TGComboBox* projs=new TGComboBox(mapview);
19653 projs->Connect("Selected(Int_t)","NcAstrolab",this,"MapProj(Int_t)");
19654 projs->AddEntry("Hammer projection",1);
19655 projs->AddEntry("Aitoff projection",2);
19656 projs->AddEntry("Mercator projection",3);
19657 projs->AddEntry("sin(b) vs. a",4);
19658 projs->AddEntry("b vs. a",5);
19659 projs->AddEntry("b vs. UT (0-24 hrs)",6);
19660 projs->AddEntry("b vs. LT (0-24 hrs)",7);
19661 projs->AddEntry("b vs. GST (0-24 hrs)",8);
19662 projs->AddEntry("b vs. LST (0-24 hrs)",9);
19663 projs->AddEntry("b vs. Day at UT",10);
19664 projs->AddEntry("b vs. Day at LT",11);
19665 projs->AddEntry("b vs. Day at GST",12);
19666 projs->AddEntry("b vs. Day at LST",13);
19667 projs->Resize(150,20);
19668 mapview->AddFrame(projs);
19669 projs->Select(1,kTRUE);
19670 MapProj(1);
19671
19672 // The meridian representation options
19673 TGGroupFrame* meridian=new TGGroupFrame(render,"Meridian ordering",kHorizontalFrame);
19674 meridian->SetTitlePos(TGGroupFrame::kCenter);
19675 render->AddFrame(meridian);
19676
19677 // The meridian mode selection box
19678 TGComboBox* mermode=new TGComboBox(meridian);
19679 mermode->Connect("Selected(Int_t)","NcAstrolab",this,"MapMerMode(Int_t)");
19680 mermode->AddEntry("Auto",1);
19681 mermode->AddEntry("---->",2);
19682 mermode->AddEntry("<----",3);
19683 mermode->Resize(55,20);
19684 meridian->AddFrame(mermode);
19685 mermode->Select(1,kTRUE);
19686 MapMerMode(1);
19687
19688 // The meridian central value
19689 TGNumberEntryField* merc=new TGNumberEntryField(meridian,-1,0);
19690 merc->SetToolTipText("Central meridian position");
19691 merc->Connect("TextChanged(const char*)","NcAstrolab",this,"MapMerC(const char*)");
19692 merc->Resize(65,20);
19693 meridian->AddFrame(merc);
19694 MapMerC("0");
19695
19696 // The meridian central value type selection box
19697 TGComboBox* meruc=new TGComboBox(meridian);
19698 meruc->Connect("Selected(Int_t)","NcAstrolab",this,"MapMerUc(Int_t)");
19699 meruc->AddEntry("deg",1);
19700 meruc->AddEntry("dms",2);
19701 meruc->AddEntry("hms",3);
19702 meruc->AddEntry("rad",4);
19703 meruc->Resize(50,20);
19704 meridian->AddFrame(meruc);
19705 meruc->Select(1,kTRUE);
19706 MapMerUc(1);
19707
19708 // The options group
19709 TGVButtonGroup* options=new TGVButtonGroup(panel,"Options");
19710 options->SetTitlePos(TGGroupFrame::kCenter);
19711 options->Connect("Clicked(Int_t)","NcAstrolab",this,"MapDoptions(Int_t)");
19712 TGCheckButton* bhist=new TGCheckButton(options,"Hist");
19713 bhist->SetToolTipText("Project data in a histogram");
19714 TGCheckButton* bclr=new TGCheckButton(options,"Clr");
19715 bclr->SetToolTipText("Clear display before drawing");
19716 TGCheckButton* bref=new TGCheckButton(options,"Ref");
19717 bref->SetToolTipText("Display reference signals");
19718 TGCheckButton* bmeas=new TGCheckButton(options,"Meas");
19719 bmeas->SetToolTipText("Display measured signals");
19720 TGCheckButton* brefts=new TGCheckButton(options,"RefTS");
19721 brefts->SetToolTipText("Display/list each reference signal using its actual recorded timestamp");
19722 panel->AddFrame(options);
19723 options->Show();
19724 options->SetButton(1,kFALSE);
19725 options->SetButton(2,kTRUE);
19726 options->SetButton(3,kTRUE);
19727 options->SetButton(4,kTRUE);
19728 options->SetButton(5,kFALSE);
19729 fMapDoptions[0]=kFALSE;
19730 fMapDoptions[1]=kTRUE;
19731 fMapDoptions[2]=kTRUE;
19732 fMapDoptions[3]=kTRUE;
19733 fMapDoptions[4]=kFALSE;
19734
19735 // The Nmax entry field
19736 TGNumberEntryField* nmax=new TGNumberEntryField(options,-1,-1,TGNumberFormat::kNESInteger);
19737 nmax->SetToolTipText("Max. number of Drawn/Listed entries per type (-1=all)");
19738 nmax->Connect("TextChanged(const char*)","NcAstrolab",this,"MapNmax(const char*)");
19739 nmax->Resize(40,20);
19740 options->AddFrame(nmax);
19741 MapNmax("-1");
19742
19743 // The signal name pattern for matching
19744 TGTextEntry* sname=new TGTextEntry(options,"*");
19745 sname->SetToolTipText("The requested entry name pattern (*=all)");
19746 sname->Connect("TextChanged(const char*)","NcAstrolab",this,"MapDname(const char*)");
19747 sname->SetAlignment(kTextRight);
19748 sname->Resize(100,20);
19749 TGLayoutHints* Lsname=new TGLayoutHints(kLHintsLeft,0,0,5,0);
19750 options->AddFrame(sname,Lsname);
19751 MapDname("*");
19752
19753 // The Ndigs entry field
19754 TGNumberEntryField* ndigs=new TGNumberEntryField(options,-1,1,TGNumberFormat::kNESInteger);
19755 ndigs->SetToolTipText("Number of digits for the listed entries");
19756 ndigs->Connect("TextChanged(const char*)","NcAstrolab",this,"MapNdigs(const char*)");
19757 ndigs->Resize(40,20);
19758 options->AddFrame(ndigs);
19759 MapNdigs("1");
19760
19761 // A frame with various additional settings
19762 TGVerticalFrame* others=new TGVerticalFrame(panel,1,1);
19763 panel->AddFrame(others);
19764
19765 // The Marker size frame
19766 TGGroupFrame* markers=new TGGroupFrame(others,"Marker settings",kHorizontalFrame);
19767 markers->SetTitlePos(TGGroupFrame::kCenter);
19768 others->AddFrame(markers);
19769
19770 // The marker size
19771 TGNumberEntryField* marksize=new TGNumberEntryField(markers,-1,1);
19772 marksize->SetToolTipText("Marker size");
19773 marksize->Connect("TextChanged(const char*)","NcAstrolab",this,"MapMarkSize(const char*)");
19774 marksize->Resize(40,20);
19775 markers->AddFrame(marksize);
19776 MapMarkSize("1");
19777
19778 // The marker style
19779 TGComboBox* markstyle=new TGComboBox(markers);
19780 markstyle->Connect("Selected(Int_t)","NcAstrolab",this,"MapMarkStyle(Int_t)");
19781 markstyle->AddEntry("Dot",1);
19782 markstyle->AddEntry("Star",2);
19783 markstyle->AddEntry("Square",3);
19784 markstyle->AddEntry("Utriangle",4);
19785 markstyle->AddEntry("Dtriangle",5);
19786 markstyle->AddEntry("Diamond",6);
19787 markstyle->AddEntry("Cross",7);
19788 markstyle->AddEntry("Ast",8);
19789 markstyle->AddEntry("Plus",9);
19790 markstyle->AddEntry("Times",10);
19791 markstyle->AddEntry("Circle",11);
19792 markstyle->AddEntry("oStar",12);
19793 markstyle->AddEntry("oSquare",13);
19794 markstyle->AddEntry("oUtriangle",14);
19795 markstyle->AddEntry("oDtriangle",15);
19796 markstyle->AddEntry("oDiamond",16);
19797 markstyle->AddEntry("oCross",17);
19798 markstyle->Resize(90,20);
19799 markers->AddFrame(markstyle);
19800 markstyle->Select(1,kTRUE);
19801 MapMarkStyle(1);
19802
19803 // The marker color selection box
19804 TGComboBox* markcolor=new TGComboBox(markers);
19805 markcolor->Connect("Selected(Int_t)","NcAstrolab",this,"MapMarkColor(Int_t)");
19806 markcolor->AddEntry("Black",1);
19807 markcolor->AddEntry("Red",2);
19808 markcolor->AddEntry("Blue",3);
19809 markcolor->AddEntry("Green",4);
19810 markcolor->AddEntry("Yellow",5);
19811 markcolor->AddEntry("Magenta",6);
19812 markcolor->AddEntry("Cyan",7);
19813 markcolor->AddEntry("Orange",8);
19814 markcolor->AddEntry("Violet",9);
19815 markcolor->AddEntry("Pink",10);
19816 markcolor->AddEntry("Azure",11);
19817 markcolor->AddEntry("Spring",12);
19818 markcolor->AddEntry("Teal",13);
19819 markcolor->AddEntry("Gray",14);
19820 markcolor->AddEntry("White",15);
19821 markcolor->Resize(80,20);
19822 markers->AddFrame(markcolor);
19823 markcolor->Select(3,kTRUE);
19824 MapMarkColor(3);
19825
19826 // The marker type selection box
19827 TGComboBox* marktype=new TGComboBox(markers);
19828 marktype->Connect("Selected(Int_t)","NcAstrolab",this,"MapMarkType(Int_t)");
19829 marktype->AddEntry("Ref",1);
19830 marktype->AddEntry("Meas",2);
19831 marktype->AddEntry("GC",3);
19832 marktype->AddEntry("Grid",4);
19833 marktype->Resize(55,20);
19834 markers->AddFrame(marktype);
19835 marktype->Select(2,kTRUE);
19836 MapMarkType(2);
19837
19838 // The Solar system group
19839 TGGroupFrame* solar=new TGGroupFrame(others,"Selection of Solar system reference objects",kHorizontalFrame);
19840 solar->SetTitlePos(TGGroupFrame::kCenter);
19841 others->AddFrame(solar);
19842
19843 TGButtonGroup* Ssolar=new TGButtonGroup(solar,0,3,5);
19844 Ssolar->SetTitlePos(TGGroupFrame::kCenter);
19845 Ssolar->Connect("Clicked(Int_t)","NcAstrolab",this,"MapSolar(Int_t)");
19846 TGCheckButton* bsun=new TGCheckButton(Ssolar,"Sun");
19847 bsun->SetToolTipText("Enter/Remove the Sun as a reference entry");
19848 TGCheckButton* bmoon=new TGCheckButton(Ssolar,"Moon");
19849 bmoon->SetToolTipText("Enter/Remove the Moon as a reference entry");
19850 TGCheckButton* bmercury=new TGCheckButton(Ssolar,"Mercury");
19851 bmercury->SetToolTipText("Enter/Remove Mercury as a reference entry");
19852 TGCheckButton* bvenus=new TGCheckButton(Ssolar,"Venus");
19853 bvenus->SetToolTipText("Enter/Remove Venus as a reference entry");
19854 TGCheckButton* bearth=new TGCheckButton(Ssolar,"Earth");
19855 bearth->SetToolTipText("Enter/Remove the Earth as a reference entry");
19856 TGCheckButton* bmars=new TGCheckButton(Ssolar,"Mars");
19857 bmars->SetToolTipText("Enter/Remove Mars as a reference entry");
19858 TGCheckButton* bjupiter=new TGCheckButton(Ssolar,"Jupiter");
19859 bjupiter->SetToolTipText("Enter/Remove Jupiter as a reference entry");
19860 TGCheckButton* bsaturn=new TGCheckButton(Ssolar,"Saturn");
19861 bsaturn->SetToolTipText("Enter/Remove Saturn as a reference entry");
19862 TGCheckButton* buranus=new TGCheckButton(Ssolar,"Uranus");
19863 buranus->SetToolTipText("Enter/Remove Uranus as a reference entry");
19864 TGCheckButton* bneptune=new TGCheckButton(Ssolar,"Neptune");
19865 bneptune->SetToolTipText("Enter/Remove Neptune as a reference entry");
19866 solar->AddFrame(Ssolar);
19867 Ssolar->Show();
19868 Ssolar->SetButton(1,kFALSE);
19869 Ssolar->SetButton(2,kFALSE);
19870 Ssolar->SetButton(3,kFALSE);
19871 Ssolar->SetButton(4,kFALSE);
19872 Ssolar->SetButton(5,kFALSE);
19873 Ssolar->SetButton(6,kFALSE);
19874 Ssolar->SetButton(7,kFALSE);
19875 Ssolar->SetButton(8,kFALSE);
19876 Ssolar->SetButton(9,kFALSE);
19877 Ssolar->SetButton(10,kFALSE);
19878 for (Int_t i=0; i<10; i++)
19879 {
19880 fMapSolar[i]=kFALSE;
19881 }
19882
19883 // The Solar system Enter and Remove command buttons
19884 TGVerticalFrame* comms=new TGVerticalFrame(solar,1,1);
19885 TGLayoutHints* Lcomms=new TGLayoutHints(kLHintsLeft,10,0,15,0);
19886 solar->AddFrame(comms,Lcomms); // Command buttons
19887
19888 // The button to Enter the solar system entries
19889 TGTextButton* enter=new TGTextButton(comms,"Enter");
19890 enter->SetToolTipText("Enter the selected Solar system objects as reference signals");
19891 enter->Connect("Clicked()","NcAstrolab",this,"MapEnterSolar()");
19892 TGLayoutHints* Lenter=new TGLayoutHints(kLHintsCenterX,0,0,10,15);
19893 comms->AddFrame(enter,Lenter);
19894
19895 // The button to Remove the solar system entries
19896 TGTextButton* remove=new TGTextButton(comms,"Remove");
19897 remove->SetToolTipText("Remove the selected Solar system objects from the reference signals");
19898 remove->Connect("Clicked()","NcAstrolab",this,"MapRemoveSolar()");
19899 TGLayoutHints* Lremove=new TGLayoutHints(kLHintsCenterX,0,0,0,0);
19900 comms->AddFrame(remove,Lremove);
19901}
19902
19904{
19910
19911 TString system[9]={"equ","equ","equ","equ","gal","ecl","hor","icr","loc"};
19912 TString mode[4]={"J","M","T","B"};
19913
19914 if (i<=9) fMapDcoord=system[i-1];
19915
19916 if (i<=4) fMapDmode=mode[i-1];
19917}
19918
19920{
19926
19927 TString s[13]={"ham","ait","mer","ang","cyl","UTh","LTh","GSTh","LSTh","UYh","LYh","GSYh","LSYh"};
19928 TString sh[13]={"hamh","aith","merh","angh","cylh","UTh","LTh","GSTh","LSTh","UYh","LYh","GSYh","LSYh"};
19929 if (!fMapDoptions[0] && i<13) fMapProj=s[i-1];
19930 if (fMapDoptions[0] && i<13) fMapProj=sh[i-1];
19931 for (Int_t k=0; k<13; k++)
19932 {
19933 if (fMapDoptions[0] && fMapProj==s[k]) fMapProj=sh[k];
19934 if (!fMapDoptions[0] && fMapProj==sh[k]) fMapProj=s[k];
19935 }
19936}
19937
19939{
19945
19946 Int_t modes[3]={0,1,-1};
19947 if (i<=3) fMapMerMode=modes[i-1];
19948}
19949
19950void NcAstrolab::MapMerC(const char* text)
19951{
19957
19958 TString s=text;
19959 fMapMerC=s.Atof();
19960}
19961
19963{
19969
19970 TString s[4]={"deg","dms","hms","rad"};
19971 if (i<=4) fMapMerUc=s[i-1];
19972}
19973
19975{
19981
19982 if (i>5) return;
19983
19984 if (!fMapDoptions[i-1])
19985 {
19986 fMapDoptions[i-1]=1;
19987 }
19988 else
19989 {
19990 fMapDoptions[i-1]=0;
19991 }
19992 if (i==1) MapProj(14); // Set histogram selection
19993}
19994
19995void NcAstrolab::MapNmax(const char* text)
19996{
20002
20003 TString s=text;
20004 fMapNmax=s.Atoi();
20005}
20006
20007void NcAstrolab::MapNdigs(const char* text)
20008{
20014
20015 TString s=text;
20016 fMapNdigs=s.Atoi();
20017}
20018
20019void NcAstrolab::MapDname(const char* text)
20020{
20026
20027 fMapDname=text;
20028}
20029
20030void NcAstrolab::MapMarkSize(const char* text)
20031{
20037
20038 TString s=text;
20039 fMapMarkSize=s.Atof();
20040}
20041
20043{
20049
20050 Int_t styles[17]={8,29,21,22,23,33,34,31,2,5,24,30,25,26,32,27,28};
20051
20052 if (i>17) return;
20053
20054 fMapMarkStyle=styles[i-1];
20055}
20056
20058{
20064
20065 Int_t colors[15]={kBlack,kRed,kBlue,kGreen,kYellow,kMagenta,kCyan,kOrange,kViolet,kPink,kAzure,kSpring,kTeal,kGray,kWhite};
20066
20067 if (i>15) return;
20068
20069 fMapMarkColor=colors[i-1];
20070}
20071
20073{
20079
20080 if (i<=4) fMapMarkType=i-1;
20081}
20082
20084{
20090
20091 if (i>10) return;
20092
20093 if (!fMapSolar[i-1])
20094 {
20095 fMapSolar[i-1]=1;
20096 }
20097 else
20098 {
20099 fMapSolar[i-1]=0;
20100 }
20101}
20102
20104{
20110
20111 TString names[10]={"Sun","Moon","Mercury","Venus","Earth","Mars","Jupiter","Saturn","Uranus","Neptune"};
20112
20113 SetMapTS(); // Get the selected timestamp
20114
20115 fSkyMapPanel->RequestFocus();
20116
20117 for (Int_t i=0; i<10; i++)
20118 {
20119 if (fMapSolar[i]) GetSignal(names[i],0,&fMapTS);
20120 }
20121 printf("\n *** Selected Solar system object(s) entered *** \n");
20122}
20123
20125{
20131
20132 TString names[10]={"Sun","Moon","Mercury","Venus","Earth","Mars","Jupiter","Saturn","Uranus","Neptune"};
20133
20134 SetMapTS(); // Get the selected timestamp
20135
20136 fSkyMapPanel->RequestFocus();
20137
20138 Int_t nrem=0;
20139 Int_t nremx=0;
20140 for (Int_t i=0; i<10; i++)
20141 {
20142 if (fMapSolar[i])
20143 {
20144 nremx=RemoveSignal(names[i],0,1);
20145 if (nremx) nrem++;
20146 }
20147 }
20148
20149 printf("\n *** Number of Solar system object that have been removed : %-i *** \n",nrem);
20150}
20151
20152void NcAstrolab::CommandPanel(TGCompositeFrame* frame)
20153{
20159
20160 if (!frame) return;
20161
20162 TGGroupFrame* panel=new TGGroupFrame(frame,"Commands",kVerticalFrame);
20163 panel->SetTitlePos(TGGroupFrame::kCenter);
20164 frame->AddFrame(panel);
20165
20166 TGTextButton* list=new TGTextButton(panel,"List");
20167 list->Connect("Clicked()","NcAstrolab",this,"MapList()");
20168 list->SetToolTipText("List the selected entries");
20169 TGLayoutHints* Llist=new TGLayoutHints(kLHintsCenterX,0,0,10,10);
20170 panel->AddFrame(list,Llist);
20171
20172 TGTextButton* map=new TGTextButton(panel,"Map");
20173 map->Connect("Clicked()","NcAstrolab",this,"MapDraw()");
20174 map->SetToolTipText("Display the selected entries");
20175 TGLayoutHints* Lmap=new TGLayoutHints(kLHintsCenterX,0,0,10,10);
20176 panel->AddFrame(map,Lmap);
20177
20178 TGTextButton* close=new TGTextButton(panel,"Close");
20179 close->Connect("Clicked()","NcAstrolab",this,"MapClose()");
20180 close->SetToolTipText("Close this panel window");
20181 TGLayoutHints* Lclose=new TGLayoutHints(kLHintsCenterX,0,0,10,10);
20182 panel->AddFrame(close,Lclose);
20183
20184 TGTextButton* exit=new TGTextButton(panel,"Exit");
20185 exit->Connect("Clicked()","NcAstrolab",this,"MapExit()");
20186 exit->SetToolTipText("Exit this ROOT session");
20187 TGLayoutHints* Lexit=new TGLayoutHints(kLHintsCenterX,0,0,10,10);
20188 panel->AddFrame(exit,Lexit);
20189}
20190
20192{
20198
20199 SetMapTS(); // Set the skymap timestamp
20200
20201 fSkyMapPanel->RequestFocus();
20202
20203 Int_t type=0;
20204 if (fMapDoptions[3]) type=1;
20205 if (fMapDoptions[2] && fMapDoptions[3]) type=-1;
20206
20207 NcTimestamp* ts=&fMapTS; // User selected timestamp
20208 if (fMapLabTS) ts=0; // To get Lab timestamp notification in listings
20209
20210 Int_t j=0;
20211 if (fMapDoptions[4]) j=-1; // Individual reference timestamps
20212
20213 printf("\n");
20215}
20216
20218{
20224
20225 SetMapTS(); // Set the skymap timestamp
20226
20227 fSkyMapPanel->RequestFocus();
20228
20229 Int_t type=0;
20230 if (fMapDoptions[3]) type=1;
20231 if (fMapDoptions[2] && fMapDoptions[3]) type=-1;
20232
20233 NcTimestamp* ts=&fMapTS; // User selected timestamp
20234 if (fMapLabTS) ts=0; // To get Lab timestamp notification in listings
20235
20236 Int_t j=0;
20237 if (fMapDoptions[4]) j=-1; // Individual reference timestamps
20238
20243
20245}
20246
20248{
20254
20255 // De-activate all automatic CloseWindow() actions of the system window manager
20256 // in order to fully control it in this function
20257 fSkyMapPanel->DontCallClose();
20258
20259 // To prevent crash when the cursor is still left active in a TextEntry
20260 fSkyMapPanel->RequestFocus();
20261
20262 // Unmap the display window
20263 fSkyMapPanel->UnmapWindow();
20264}
20265
20267{
20273
20274 fSkyMapPanel->RequestFocus();
20275 fSkyMapPanel->Cleanup();
20276 gApplication->Terminate(0);
20277}
20278
20280{
20286
20287 fMapLabTS=kFALSE;
20288 Int_t imjd=0;
20289 Int_t isec=0;
20290 Int_t ins=0;
20291 Int_t ips=0;
20292
20293 if (fMapTimeType=="SysClock") // Use the system clock time
20294 {
20295 fMapTS.SetSystemTime();
20296 }
20297 else if (fMapTimeType=="Lab") // Use the Lab timestamp
20298 {
20299 fMapTS.SetMJD(fMJD,fJsec,fJns,fJps);
20300 fMapLabTS=kTRUE;
20301 }
20302 else if (fMapTimeType=="MJD") // Modified Julian Date entry
20303 {
20304 Double_t mjd=fMapDateTime.Atof();
20305 fMapTS.SetMJD(mjd);
20306 }
20307 else if (fMapTimeType=="JD") // Julian Date entry
20308 {
20309 Double_t jd=fMapDateTime.Atof();
20310 fMapTS.SetJD(jd);
20311 }
20312 else if (fMapTimeType=="TJD") // Truncated Julian Date entry
20313 {
20314 Double_t tjd=fMapDateTime.Atof();
20315 fMapTS.SetTJD(tjd);
20316 }
20317 else if (fMapTimeType=="Unix") // Unix time
20318 {
20319 Double_t val=fMapDateTime.Atof();
20320 fMapTS.SetUnixTime(val);
20321 }
20322 else
20323 {
20324 if (fMapTimeType.Contains("Name")) // Get timestamp of the specified named entry
20325 {
20326 NcSignal* sx=0;
20327 NcTimestamp* tx=0;
20328 TString name=fMapDateTime;
20329 sx=GetSignal(name,1);
20330 if (!sx) sx=GetSignal(name,0);
20331 if (sx) tx=sx->GetTimestamp();
20332 if (tx) // Stored entry was found
20333 {
20334 tx->GetMJD(imjd,isec,ins);
20335 ips=tx->GetPs();
20336 fMapTS.SetMJD(imjd,isec,ins,ips);
20337 }
20338 else
20339 {
20340 printf("\n *** No stored entry with name %-s found --> Lab TS will be used *** \n",name.Data());
20341 GetMJD(imjd,isec,ins);
20342 ips=GetPs();
20343 fMapTS.SetMJD(imjd,isec,ins,ips);
20344 fMapLabTS=kTRUE;
20345 }
20346 fMapTS.GetDayTimeString("UTC",12,0,&fMapDate,&fMapTime,kFALSE);
20347 }
20348 else // Date/Time entry
20349 {
20351 fMapDate.Remove(fMapDateTime.Index("/"),fMapDateTime.Length());
20353 fMapTime.Remove(0,fMapDateTime.Index("/")+1);
20354 }
20355
20356 // Set the timestamp according to the date/time strings
20357 fMapTS.SetUT(fMapDate,fMapTime,0);
20358 if (fMapTimeType=="UT1") fMapTS.SetUT(fMapDate,fMapTime,0,"U");
20359 if (fMapTimeType=="LMT") fMapTS.SetLT(fToffset,fMapDate,fMapTime,0);
20360 if (fMapTimeType=="GPS" || fMapTimeType=="TAI" || fMapTimeType=="TT")
20361 {
20362 fMapTS.SetTAI(fMapTimeType,fMapDate,fMapTime,0,"A",0);
20363 }
20364 }
20365
20366 // Show the new timestamp in the textbox
20367 fMapTS.GetDayTimeString("UTC",3,0,&fMapDate,&fMapTime,kFALSE);
20369 fMapDateTime+="/";
20371 fMapTSdatetime->SetText(fMapDateTime);
20372
20373 // Adapt the timestamp type for the updated text window contents
20374 if (fMapTStimetype) fMapTStimetype->Select(1,kTRUE);
20375 MapTimeType(1);
20376}
20377
20378TObject* NcAstrolab::Clone(const char* name) const
20379{
20388
20389 NcAstrolab* lab=new NcAstrolab(*this);
20390 if (name)
20391 {
20392 if (strlen(name)) lab->SetName(name);
20393 }
20394 return lab;
20395}
20396
ClassImp(NcAstrolab)
Handling of 3-vectors in various reference frames.
Definition Nc3Vector.h:15
Double_t GetX(Int_t i, TString f, TString u="rad")
void GetErrors(Double_t *e, TString f, TString u="rad") const
void SetVector(Double_t *v, TString f, TString u="rad")
virtual void Load(Nc3Vector &q)
virtual void SetZero()
Nc3Vector Cross(Nc3Vector &q) const
void SetErrors(Double_t *e, TString f, TString u="rad")
virtual Double_t GetOpeningAngle(Nc3Vector &q, TString u="rad")
void GetVector(Double_t *v, TString f, TString u="rad") const
Int_t HasErrors() const
Nc3Vector GetPrimed(TRotMatrix *m) const
Int_t HasVector() const
Nc3Vector GetUnprimed(TRotMatrix *m) const
Double_t GetNorm()
Virtual lab to provide (astro)physical parameters, treat data and relate observations with astrophysi...
Definition NcAstrolab.h:47
Double_t fMW
Definition NcAstrolab.h:372
void MapMerUc(Int_t i)
void Precess(Nc3Vector &r, NcTimestamp *ts1, NcTimestamp *ts2)
void MapEname(const char *text)
void Nutate(Nc3Vector &r, NcTimestamp *ts)
void MakeBurstRecoAngresdist(TString file, TString tree, TString name1, TString name2, TString ua, TString name3, TString ud, Double_t Emin, Double_t Emax, Int_t nbe=100, Int_t nba=1000)
Double_t fMapMerC
! The GUI entered central meridian location for the Map
Definition NcAstrolab.h:356
void ProjectMercator(Double_t l, Double_t b, Double_t &x, Double_t &y)
Double_t fMeridian
! Central meridian (in rad) for the sky display
Definition NcAstrolab.h:302
Double_t GetTargetThickness(Double_t prob, Double_t lambda) const
Double_t fMp
Definition NcAstrolab.h:370
TRotMatrix fL
Definition NcAstrolab.h:266
virtual void LabLocationPanel(TGCompositeFrame *frame)
void GetBurstBayesianPsiStatistics(TString type, Double_t nr=-1, Int_t ncut=10, Int_t ndt=2, Bool_t zcor=kFALSE, Int_t freq=0)
void MapEnterSolar()
Double_t GetCredibleInterval(TF1 pdf, Double_t p, Double_t &xlow, Double_t &xup, Int_t n=1000)
void SetRandomiser(Int_t iseed, Int_t cnt1=0, Int_t cnt2=0, NcTimestamp *ts=0)
Double_t GetLT()
Double_t GetUpperLimit(TF1 pdf, Double_t p)
Double_t fGammaW
Definition NcAstrolab.h:373
Double_t fSpeedC
Definition NcAstrolab.h:364
TH1F GetDxHistogram(TH1 *hx, Int_t nc, Double_t dxbin=-1, Double_t dxmin=-1, Double_t dxmax=-1, Int_t mode=1, Double_t fact=1)
TString fDataFrame
Definition NcAstrolab.h:405
ULong64_t fNen[2]
Definition NcAstrolab.h:257
NcSample fBurstOffAeff
Definition NcAstrolab.h:425
Double_t fMapMarkSize
! The GUI entered marker size for the Map
Definition NcAstrolab.h:358
TF1 * fPhiscfunc
Definition NcAstrolab.h:281
void HelioToGeocentric(Double_t &R, Double_t &B, Double_t &L, NcTimestamp *ts, TString Bu="deg", TString Lu="deg")
void MapMarkType(Int_t i)
Int_t GetTimeScramble(Double_t *tmin=0, Double_t *tmax=0, TF1 *frndm=0)
TRotMatrix fP
! Matrix for precession correction
Definition NcAstrolab.h:260
Double_t fHbarc2
Definition NcAstrolab.h:394
Double_t fTscmin
Definition NcAstrolab.h:269
void MapCinfo(Int_t)
void MapEb(const char *text)
Double_t fAlphaEM
Definition NcAstrolab.h:376
void MatchSignals(NcDevice &matches, Double_t da, TString au, Double_t dt, TString tu, Int_t mode=1, Int_t i1=1, Int_t i2=0, Int_t itype=0, Int_t j1=1, Int_t j2=0, Int_t jtype=1)
TF1 fBkgEprofile
Definition NcAstrolab.h:413
TString fMapEcoord
! The GUI entered coordinate system of the entry
Definition NcAstrolab.h:344
Int_t SetSolarSystem(TString name, NcTimestamp *ts, Int_t type=0)
Double_t GetLightTravelDistance(Double_t z, TString u="Mpc") const
Double_t fMapLabLocB
! The GUI entered Lab latitude
Definition NcAstrolab.h:322
Double_t fToffset
Definition NcAstrolab.h:253
TString fMapEua
! The GUI entered angular units of a
Definition NcAstrolab.h:340
Double_t fOmegaR
Definition NcAstrolab.h:386
Double_t fThetascmin
Definition NcAstrolab.h:276
Double_t fAmu
Definition NcAstrolab.h:369
Int_t fSolUpdate
Definition NcAstrolab.h:297
void SetBurstParameter(TString name, Double_t value)
void MapProj(Int_t i)
TString fBkgEmode
Definition NcAstrolab.h:411
TObjArray * fSigs
Definition NcAstrolab.h:256
Double_t fDscmin
Definition NcAstrolab.h:273
NcObjMatrix fDataNames
Definition NcAstrolab.h:407
void SmearPosition(Nc3Vector &v, Double_t sigma)
Double_t GetLightTravelTime(Double_t z) const
Int_t GetPositionScramble(Double_t *dmin=0, Double_t *dmax=0, TF1 *df=0, Double_t *thmin=0, Double_t *thmax=0, TF1 *thf=0, Double_t *phimin=0, Double_t *phimax=0, TF1 *phif=0)
void ProjectCylindrical(Double_t l, Double_t b, Double_t &x, Double_t &y)
void MapExperiment(Int_t i)
void MapMarkSize(const char *text)
TRotMatrix fG
! Matrix for conversion of equatorial to galactic coordinates
Definition NcAstrolab.h:262
Float_t fMarkerSize[4]
Definition NcAstrolab.h:307
TString fMapTime
! The GUI entered time
Definition NcAstrolab.h:329
Double_t GetBurstRecoAngres(Double_t Emin=-1, Double_t Emax=-1, Double_t Amin=0, Double_t Amax=999) const
TString fExperiment
Definition NcAstrolab.h:251
TRotMatrix fB
! The frame bias matrix for conversion of ICRS to J2000 coordinates
Definition NcAstrolab.h:258
virtual void EntriesPanel(TGCompositeFrame *frame)
TH1 * GetBurstBayesianSignalRate(Double_t p, Double_t &rlow, Double_t &rup, Int_t n=1000)
Double_t ConvertAngle(Double_t a, TString in, TString out) const
TObjArray fBurstHistos
Definition NcAstrolab.h:417
void SetNmatrix(NcTimestamp *ts)
Double_t fGn
Definition NcAstrolab.h:381
Double_t fOmegaC
Definition NcAstrolab.h:389
Double_t fHbar
Definition NcAstrolab.h:392
void ProjectHammer(Double_t l, Double_t b, Double_t &x, Double_t &y)
Double_t GetDifference(Int_t jref, TString au, Double_t &dt, TString tu, Int_t mode=1, Int_t *ia=0, Int_t *it=0)
void ListSignals(TString frame, TString mode, Int_t ndig=1, TString emode="T", Int_t nmax=10, Int_t j=-1, Int_t type=-1, NcTimestamp *ts=0, TString name="*")
Double_t GetSourceAttributes(NcSignal *s, Float_t *z=0, Float_t *T90=0)
NcPosition fLabPos
Definition NcAstrolab.h:250
TString fProj
! Projection which is currently in use
Definition NcAstrolab.h:303
Double_t GetLuminosityDistance(Double_t z, TString u="Mpc") const
NcDevice * fBurstParameters
Definition NcAstrolab.h:416
TRotMatrix fH
! Matrix for conversion of equatorial to horizontal coordinates
Definition NcAstrolab.h:265
Int_t RemoveSignal(Int_t j, Int_t type, Int_t compress)
Double_t GetBurstBackgroundEnergy(Double_t Emin=-1, Double_t Emax=-1) const
void SetLabPosition(Nc3Vector &r)
void MapLabLframeEnter()
TString fMapTimeType
! The GUI entered time type
Definition NcAstrolab.h:330
TString GetExperiment() const
void MapDoptions(Int_t i)
Double_t GetLabTimeOffset() const
void GenBurstGCNdata(Int_t n, TString name="GRB", Bool_t scale=kFALSE)
Double_t GetComovingDistance(Double_t z, TString u="Mpc") const
Double_t fNewton
Definition NcAstrolab.h:380
TH2 * fHist[2]
! Temp. histograms for the sky display
Definition NcAstrolab.h:305
TGComboBox * fMapTStimetype
! The GUI TS time type selection box
Definition NcAstrolab.h:327
TString fMapCinfo
! The GUI selected info category
Definition NcAstrolab.h:335
Double_t fTscmax
Definition NcAstrolab.h:270
void MapMerMode(Int_t i)
TArrayI * fIndices
! Storage indices of the matching reference signals
Definition NcAstrolab.h:267
TH1 * GetBurstSigmaPosdist(TString name, TString type)
TString fMapProj
! The GUI selected projection for the Map
Definition NcAstrolab.h:348
Bool_t fMapLabTS
! The GUI selection to use the Lab timestamp for the List/Map
Definition NcAstrolab.h:333
void MapEcoord(Int_t i)
void GetLocalFrame(Float_t arr[6])
void LoadInputData(Bool_t src, TString file, TString tree, Int_t date1=0, Int_t date2=0, Int_t nmax=-1, TString type="-")
NcSample fBurstSigReco
Definition NcAstrolab.h:420
Double_t fGammaZ
Definition NcAstrolab.h:375
NcSample fBurstOnReco
Definition NcAstrolab.h:418
void InitBurstHistograms(Int_t mode)
TF1 * fThetascfunc
Definition NcAstrolab.h:278
TString fMapLabLocU
! The GUI entered Lab location angular units
Definition NcAstrolab.h:323
TCanvas * fCanvas
! The canvas for the skymap
Definition NcAstrolab.h:304
Double_t fOmegaM
Definition NcAstrolab.h:385
TF1 fSigEprofile
Definition NcAstrolab.h:412
void MapDname(const char *text)
void MapIname(const char *text)
NcAstrolab(const char *name="User", const char *title="Virtual Lab for general use")
Double_t GetBurstLiMaSignificance() const
virtual void SkyMapPanel()
Int_t GetSignalIndex(TString name, Int_t type=0)
TGTextEntry * fMapTSdatetime
! The GUI TS date/time specification
Definition NcAstrolab.h:326
void MapLocb(const char *text)
TRotMatrix fN
! Matrix for nutation correction
Definition NcAstrolab.h:261
void ListBurstParameters() const
TGNumberEntryField * fMapLabLBI[3]
! The GUI number entries for the Lab location specification
Definition NcAstrolab.h:318
void MapTinfo(Int_t)
void MapEa(const char *text)
Double_t GetMeanFreePath(Double_t sigma, Double_t rho, Int_t mode) const
NcPosition GetLabPosition() const
void SetPositionScramble(Int_t mode, Double_t dmin, Double_t dmax, TF1 *df=0, Double_t thmin=0, Double_t thmax=0, TF1 *thf=0, Double_t phimin=0, Double_t phimax=0, TF1 *phif=0)
void InitDataNames(Int_t dir, TString frame, TString mode="J")
Double_t GetHubbleParameter(Double_t z, TString u="Mpc") const
void MapEtype(Int_t i)
void LoadAeffData(TString file, TString hist)
Int_t fMapMarkStyle
! The GUI selected marker style for the Map
Definition NcAstrolab.h:359
Int_t SetSourceAttributes(NcSignal *s, Double_t sigmapos, TString u, Double_t z=-999, Double_t T90=-999)
void MapUa(Int_t i)
Double_t GetMaxDt() const
void SetTimeScramble(Int_t mode, Double_t tmin, Double_t tmax, TF1 *frndm=0)
TString fMapDcoord
! The GUI selected coordinate system for the Map/List
Definition NcAstrolab.h:347
void MapUinfo(Int_t)
void MapDcoord(Int_t i)
Double_t fPhiscmin
Definition NcAstrolab.h:279
Double_t fPhiscmax
Definition NcAstrolab.h:280
void SetPmatrix(NcTimestamp *ts)
void MakeBurstNuCountProfile(TString mode)
Double_t GetLAST()
Double_t fMapEb
! The GUI entered b coordinate of an entry
Definition NcAstrolab.h:341
TString fMapDate
! The GUI entered date
Definition NcAstrolab.h:328
TF1 GetSignalRatePDF(Double_t Non, Double_t Ton, Double_t Noff, Double_t Toff, Double_t Ra=1, Double_t Re=1, Double_t smax=-1, Double_t bmax=-1, Double_t prec=709)
Double_t fDscmax
Definition NcAstrolab.h:274
Double_t fMapLabLocL
! The GUI entered Lab longitude
Definition NcAstrolab.h:321
Int_t fMapMarkType
! The GUI selected entry type to apply the marker attributes on
Definition NcAstrolab.h:361
void MapMarkStyle(Int_t i)
Double_t fPc
Definition NcAstrolab.h:383
Double_t fMn
Definition NcAstrolab.h:371
void Project(Double_t l, Double_t b, TString proj, Double_t &x, Double_t &y)
Double_t fQe
Definition NcAstrolab.h:365
void MapUloc(Int_t i)
void SetBmatrix()
NcRandom * fRan
Definition NcAstrolab.h:282
void MapDateTime(const char *text)
Double_t GetBurstTotalFluence(Double_t nsig, TString str)
Double_t fThetascmax
Definition NcAstrolab.h:277
TString fMapDmode
! The GUI selected coordinate system mode for the Map/List
Definition NcAstrolab.h:349
Double_t GetShieldingThickness(Double_t prob, Double_t lambda) const
TString fMapEub
! The GUI entered angular units of b
Definition NcAstrolab.h:342
void MapMarkColor(Int_t i)
Double_t GetBackgroundRateProb(Double_t *vars, Double_t *pars)
Double_t GetInteractionProbability(Double_t x, Double_t lambda) const
void MakeBurstSigmaPosdist(TString file, TString tree, TString name, TString u, Int_t nb=900, Float_t xmin=0, Float_t xmax=90)
void MapNdigs(const char *text)
Int_t GetNRefSignals(Int_t mode=0) const
TH1F GetDifHistogram(TH1 *hin, Int_t mode, TString s="", TF1 *f=0) const
Int_t fMapEtype
! The GUI entered entry type
Definition NcAstrolab.h:343
TGComboBox * fMapLabU
! The GUI Lab location angular unit selection box
Definition NcAstrolab.h:319
Double_t fAu
Definition NcAstrolab.h:382
NcSample fBurstOffMatch
Definition NcAstrolab.h:423
void MapLocEnter()
void SetDataNames(TString obsname, TString varname, TString units="1", TString func="none")
TString fMapDname
! The GUI entered name pattern for entries to be shown in the Map/List
Definition NcAstrolab.h:353
TGNumberEntryField * fMapLabLframe[6]
! The GUI number entries for the local frame specification
Definition NcAstrolab.h:334
Double_t fOmegaL
Definition NcAstrolab.h:387
void GenBurstSignals()
void SetGmatrix(TString mode)
Double_t GetNeutrinoXsection(Int_t mode, Int_t type, Double_t egev, Double_t xscale=1, Double_t *eprimgev=0, Double_t *alpha=0) const
TH1 * GetBurstT90dist(TString name, TString type)
Double_t fMe
Definition NcAstrolab.h:366
NcDevice * GetBurstParameters()
void ListBurstHistograms() const
void MakeBurstEnergydist(Int_t mode, TString file, TString tree, TString name1, TString name2, TString u, Int_t nb=1000)
void SetLT(Int_t y, Int_t m, Int_t d, Int_t hh, Int_t mm, Int_t ss, Int_t ns=0, Int_t ps=0)
void MapSolar(Int_t i)
void MapLocl(const char *text)
Int_t fLabId
Definition NcAstrolab.h:252
void MakeBurstDataStats(Int_t mode, Int_t nmugrb=0)
void SetCentralMeridian(Int_t mode=0, Double_t phi=0, TString u="deg")
Int_t fGal
! Type indicator for fG values (0=uninitialised 1=B1950 2=J2000)
Definition NcAstrolab.h:263
NcSample fBurstSignal
Definition NcAstrolab.h:421
Int_t fMapLabId
! The GUI entered Lab detector Id
Definition NcAstrolab.h:325
void ListBurstSignalStats(Double_t rate, Int_t mode, TString str="-")
void SetEmatrix(NcTimestamp *ts)
Int_t RemoveRefSignal(Int_t j, Int_t compress)
Int_t fMapMarkColor
! The GUI selected marker color for the Map
Definition NcAstrolab.h:360
void MakeBurstT90dist(TString file, TString tree, TString name, Int_t nb=50, Float_t xmin=-5, Float_t xmax=5)
void MapRemoveSolar()
void MapUb(Int_t i)
void DisplaySignal(TString frame, TString mode, NcTimestamp *ts, Int_t j=-1, TString proj="ham", Int_t clr=0, TString name="")
virtual void TimestampPanel(TGCompositeFrame *frame)
void SetHmatrix(NcTimestamp *ts)
void PrintSignal(TString frame, TString mode, NcTimestamp *ts, Int_t ndig, Int_t jref=0, TString emode="T", Int_t type=0, Bool_t align=kFALSE)
void SetLabTimeOffset(Double_t dt)
TH1F GetCumulHistogram(TH1 *h, TString name, TString mode="F") const
virtual void MapListOptionsPanel(TGCompositeFrame *frame)
TObjArray * fMarkers
! Temp. array to hold the markers for the signal display
Definition NcAstrolab.h:306
TString fMapDateTime
! The GUI entered datetime
Definition NcAstrolab.h:331
Double_t GetSolidAngle(Double_t thetamin, Double_t thetamax, TString tu, Double_t phimin, Double_t phimax, TString pu) const
void SetMarkerColor(Int_t color, Int_t type)
Int_t fMapNdigs
! The GUI selected number of digits for the List output
Definition NcAstrolab.h:352
TRotMatrix fE
! Matrix for conversion of equatorial to ecliptic coordinates
Definition NcAstrolab.h:264
Double_t GetProperDistance(Double_t z, TString u="Mpc", Int_t t=1) const
TString fMapIname
! The GUI selected entry name for the info
Definition NcAstrolab.h:338
Double_t fMapEa
! The GUI entered a coordinate of an entry
Definition NcAstrolab.h:339
Double_t fFermi
Definition NcAstrolab.h:377
Double_t fAxes[6]
Definition NcAstrolab.h:254
Bool_t fMapSolar[10]
! The GUI selection of solar system objects
Definition NcAstrolab.h:354
TF1 * fTscfunc
Definition NcAstrolab.h:271
void GetBurstChi2Statistics(TString type, Int_t ndt=2, Bool_t zcor=kFALSE)
Double_t GetBurstSignalEnergy(Double_t Emin=-1, Double_t Emax=-1) const
void MapLocId(const char *text)
Bool_t fMapDoptions[5]
! The GUI Map/List options (histo, clr, ref, meas, refTS)
Definition NcAstrolab.h:350
Int_t fRscmode
Definition NcAstrolab.h:272
Int_t RemoveSignals(TString name, Int_t type, Int_t compress)
void SetPhysicalParameter(TString name, Double_t value)
Double_t fHubble
Definition NcAstrolab.h:384
Double_t fMmu
Definition NcAstrolab.h:367
void MatchBurstData(NcDevice &matches, Int_t i1=1, Int_t i2=0, Int_t itype=0, Int_t j1=1, Int_t j2=0, Int_t jtype=1)
void ShiftPosition(Nc3Vector &v, Double_t angle)
void MakeBurstZdist(TString file, TString tree, TString name, Int_t nb=200, Float_t zmin=0, Float_t zmax=20)
TString fDataMode
Definition NcAstrolab.h:406
TArrayI * MatchRefSignal(Double_t da, TString au, Double_t dt, TString tu, Int_t mode=1)
NcSample fBurstSigAeff
Definition NcAstrolab.h:426
void WriteBurstHistograms(TString filename)
void GeoToHeliocentric(Double_t &R, Double_t &B, Double_t &L, NcTimestamp *ts, TString Bu="deg", TString Lu="deg")
Double_t GetSignalRateProb(Double_t *vars, Double_t *pars)
Double_t GetNuclearMass(Int_t Z, Int_t N, Int_t mode=1) const
Int_t fTscmode
Definition NcAstrolab.h:268
virtual void InfoPanel(TGCompositeFrame *frame)
void BurstCompensate(Int_t &nmugrb)
void SetLocalFrame(Double_t t1, Double_t p1, Double_t t2, Double_t p2, Double_t t3, Double_t p3)
void Data(Int_t mode=1, TString u="deg", Bool_t utc=kTRUE)
void ProjectAitoff(Double_t l, Double_t b, Double_t &x, Double_t &y)
void SetMarkerSize(Float_t size, Int_t type)
TF1 * fDscfunc
Definition NcAstrolab.h:275
void DisplaySignals(TString frame, TString mode, NcTimestamp *ts, TString proj="ham", Int_t clr=0, Int_t nmax=-1, Int_t j=-1, Int_t type=-1, TString name="*")
NcSignal * GetSignal(Double_t &d, Double_t &a, TString au, Double_t &b, TString bu, TString frame, NcTimestamp *ts, Int_t jref, TString mode="T", Int_t type=0)
void ListDataNames()
virtual void LabLocalFramePanel(TGCompositeFrame *frame)
TString fMapMerUc
! The GUI selected angular units for the central meridian location
Definition NcAstrolab.h:357
NcSample fBurstOffReco
Definition NcAstrolab.h:422
TF1 * fNuAngle
Definition NcAstrolab.h:397
Int_t fMarkerStyle[4]
Definition NcAstrolab.h:308
Int_t fUsMeridian
Definition NcAstrolab.h:301
void SetExperiment(TString name, Int_t id=0)
TH1 * GetBurstZdist(TString name, TString type)
TString fMapUinfo
! The GUI selected angular units for the Lab info
Definition NcAstrolab.h:337
Double_t fMaxDt
Definition NcAstrolab.h:283
TString fMapEname
! The GUI entered name of the entry
Definition NcAstrolab.h:346
Int_t GetLabDetectorId() const
Double_t fMtau
Definition NcAstrolab.h:368
Double_t GetPhysicalParameter(TString name) const
virtual TObject * Clone(const char *name="") const
Double_t GetNeutrinoAngle(Double_t E, TString u, Int_t mode, TF1 *f=0)
Double_t fOmegaB
Definition NcAstrolab.h:388
TGMainFrame * fSkyMapPanel
! The main frame for the SkyMapPanel GUI
Definition NcAstrolab.h:317
Int_t GetNsignals(Int_t type, Int_t mode=0) const
Double_t fPlanck
Definition NcAstrolab.h:378
Double_t fBoltz
Definition NcAstrolab.h:379
void SetMarkerStyle(Int_t style, Int_t type)
NcSignal * SetSignal(Double_t d, Double_t a, TString au, Double_t b, TString bu, TString frame, NcTimestamp *ts, Int_t jref, TString mode="T", TString name="", Int_t type=0)
Int_t fDataDir
Definition NcAstrolab.h:404
Double_t GetLMST()
Int_t fMapMerMode
! The GUI selected meridian orientation for the Map
Definition NcAstrolab.h:355
void PrintAngle(Double_t a, TString in, TString out, Int_t ndig=1, Bool_t align=kFALSE) const
Int_t fMarkerColor[4]
Definition NcAstrolab.h:309
void MapMerC(const char *text)
Int_t fMapTinfo
! The GUI selected mode for the timestamp info
Definition NcAstrolab.h:336
void SetMaxDt(Double_t s)
TH1F GetLogHistogram(TH1 *hin, Int_t mode, TString s="") const
NcTimestamp fMapTS
! The GUI entered timestamp to be used for the List/Map
Definition NcAstrolab.h:332
Double_t GetPhysicalDistance(Double_t z, TString u="Mpc", Int_t t=1) const
void MapTimeType(Int_t i)
Double_t KolmogorovTest(TString mode, TH1 *h1, TH1 *h2=0, TF1 *pdf=0, Double_t nr=1000, TH1F *ksh=0, Int_t ncut=0, Double_t *nrx=0, Int_t mark=1)
TGComboBox * fMapLabE
! The GUI Lab experiment site selection box
Definition NcAstrolab.h:320
virtual void CommandPanel(TGCompositeFrame *frame)
Double_t GetSurvivalProbability(Double_t x, Double_t lambda) const
NcSample fBurstOnAeff
Definition NcAstrolab.h:424
Double_t GetHourAngle(TString mode, NcTimestamp *ts, Int_t jref=0, Int_t type=0)
Double_t GetRadiationLength(Double_t Z, Double_t A, Double_t rho=-1) const
Int_t fMapNmax
! The GUI selected max. number of signals of each type to Map/List
Definition NcAstrolab.h:351
Int_t fBias
! Initialisation flag for fB values (0=uninitialised 1=initialised)
Definition NcAstrolab.h:259
void RandomPosition(Nc3Vector &v, Double_t thetamin, Double_t thetamax, Double_t phimin, Double_t phimax)
TObjArray * fRefs
Definition NcAstrolab.h:255
TString fMapLabExpName
! The GUI entered Lab experimental site
Definition NcAstrolab.h:324
TF1 GetBackgroundRatePDF(Double_t Noff, Double_t Toff, Double_t bmax=-1, Double_t prec=709)
TString fMapEmode
! The GUI entered coordinate system mode of the entry
Definition NcAstrolab.h:345
NcRandom * GetRandomiser(Int_t &iseed, Int_t &cnt1, Int_t &cnt2) const
void GetBurstDtDistributions(Int_t ndt, TH1F &hisdtOn, TF1 &pdfdtOn, TH1F &hisdtOff, TF1 &pdfdtOff, Bool_t zcor)
void MapNmax(const char *text)
Double_t fMZ
Definition NcAstrolab.h:374
TH1F GetCountsHistogram(TF1 &spec, Int_t nbins, Double_t xmin, Double_t xmax, Int_t mode, TString s="") const
virtual ~NcAstrolab()
NcSample fBurstOnMatch
Definition NcAstrolab.h:419
Double_t fHbarc
Definition NcAstrolab.h:393
TString fSigEmode
Definition NcAstrolab.h:410
Double_t GetSeparation(TString name1, TString name2, TString au, Double_t *dt=0, TString tu="s", Int_t mode=1, Double_t *diftheta=0, Double_t *difphi=0)
void AddNamedSlot(TString s)
Int_t GetSlotIndex(TString name, Int_t opt=0) const
(Bayesian) Block treatment of sequential data.
Definition NcBlocks.h:17
Int_t Rebin(TH1 *hin, TH1 *hout, Bool_t scale, Int_t nbins=0, Double_t xmin=0, Double_t xmax=-1)
Int_t Divide(TH1 *h1, TH1 *h2, TH1 *hout, Bool_t scale, Double_t c, Double_t d=0)
Double_t GetBlocks(TH1 *hin, Double_t fpr, TH1 *hout, Int_t ntrig=0)
Definition NcBlocks.cxx:523
Signal (Hit) handling of a generic device.
Definition NcDevice.h:14
void AddHit(NcSignal &s)
Definition NcDevice.cxx:336
void SetHitCopy(Int_t j)
Definition NcDevice.cxx:237
virtual TObject * Clone(const char *name="") const
Int_t GetNhits() const
Definition NcDevice.cxx:437
NcSignal * GetHit(Int_t j) const
Definition NcDevice.cxx:489
virtual void Reset(Int_t mode=0)
Definition NcDevice.cxx:222
Various mathematical tools for scientific analysis.
Definition NcMath.h:26
Double_t PsiValue(Int_t m, Int_t *n, Double_t *p=0, Int_t f=0) const
Definition NcMath.cxx:2829
Double_t LnGamma(Double_t z) const
Definition NcMath.cxx:193
Double_t Chi2Pvalue(Double_t chi2, Int_t ndf, Int_t sides=0, Int_t sigma=0, Int_t mode=1) const
Definition NcMath.cxx:1784
Double_t LiMaSignificance(Double_t Non, Double_t Ton, Double_t Noff, Double_t Toff, Double_t Ra=1, Double_t Re=1) const
Definition NcMath.cxx:4172
Double_t Gamma(Double_t z) const
Definition NcMath.cxx:121
Double_t PsiExtreme(Double_t n, Int_t m, Double_t *p=0, Int_t k=0) const
Definition NcMath.cxx:3138
Double_t PsiPvalue(Double_t psi0, Double_t nr, Double_t n, Int_t m, Double_t *p=0, Int_t f=0, Double_t *na=0, TH1F *psih=0, Int_t ncut=0, Double_t *nrx=0, Int_t mark=1)
Definition NcMath.cxx:3528
TF1 PoissonDtDist(Double_t r, Int_t n) const
Definition NcMath.cxx:1260
Double_t Chi2Value(Int_t m, Int_t *n, Double_t *p=0, Int_t *ndf=0) const
Definition NcMath.cxx:3867
Handling of positions (with timestamps) in various reference frames.
Definition NcPosition.h:18
void GetPosition(Double_t *r, TString f, TString u="rad", Float_t s=-1) const
void SetPosition(Double_t *r, TString f, TString u="rad")
NcTimestamp * GetTimestamp()
void SetTimestamp(NcTimestamp &t)
Generate universal random numbers and sequences on all common machines.
Definition NcRandom.h:16
Sampling and statistics tools for various multi-dimensional data samples.
Definition NcSample.h:28
Int_t GetN() const
Double_t GetMedian(Int_t i)
void Enter(Double_t x)
Definition NcSample.cxx:357
void SetStoreMode(Int_t mode=1, Int_t nmax=0, Int_t i=0)
Double_t GetEntry(Int_t i, Int_t j, Int_t mode=0, Int_t k=0)
Generic handling of (extrapolated) detector signals.
Definition NcSignal.h:23
virtual void Reset(Int_t mode=0)
Definition NcSignal.cxx:334
virtual void SetSignal(Double_t sig, Int_t j=1)
Definition NcSignal.cxx:516
virtual Float_t GetSignal(Int_t j=1, Int_t mode=0) const
Definition NcSignal.cxx:651
virtual void Data(TString f="car", TString u="rad") const
Definition NcSignal.cxx:959
Double_t GetEpoch(TString mode)
Double_t GetMJD(Int_t y, Int_t m, Int_t d, Int_t hh, Int_t mm, Int_t ss, Int_t ns) const
void SetLT(Double_t dt, Int_t y, Int_t m, Int_t d, Int_t hh, Int_t mm, Int_t ss, Int_t ns=0, Int_t ps=0, TString utc="A", Int_t leap=0, Double_t dut=0)
Double_t GetJD(Int_t y, Int_t m, Int_t d, Int_t hh, Int_t mm, Int_t ss, Int_t ns) const
void GetUT(Int_t &hh, Int_t &mm, Int_t &ss, Int_t &ns, Int_t &ps)
TString GetDayTimeString(TString mode, Int_t ndig=0, Double_t offset=0, TString *date=0, TString *time=0, Bool_t full=kTRUE)
Double_t Almanac(Double_t *dpsi=0, Double_t *deps=0, Double_t *eps=0, Double_t *dl=0, TString name="", Double_t *el=0, Double_t *eb=0, Double_t *dr=0, Double_t *value=0, Int_t j=0)
Double_t GetLMST(Double_t offset)
Double_t GetMJD()
Int_t GetPs() const
Double_t GetLT(Double_t offset)
void GetGMST(Int_t &hh, Int_t &mm, Int_t &ss, Int_t &ns, Int_t &ps)
void SetEpoch(Double_t e, TString mode, TString utc="U", Int_t leap=0, Double_t dut=0)
Double_t GetGAST()
void SetUT(Int_t y, Int_t m, Int_t d, Int_t hh, Int_t mm, Int_t ss, Int_t ns=0, Int_t ps=0, TString utc="A", Int_t leap=0, Double_t dut=0)
void PrintTime(Double_t h, Int_t ndig=1) const
Double_t GetLAST(Double_t offset)
TTree * LoadUTCparameterFiles(TString leapfile="$(NCFS)/IERS/leap.txt", TString dutfile="$(NCFS)/IERS/dut.txt")
void SetTJD(Int_t tjd, Int_t sec, Int_t ns, Int_t ps=0, TString utc="U", Int_t leap=0, Double_t dut=0)
void SetMJD(Int_t mjd, Int_t sec, Int_t ns, Int_t ps=0, TString utc="U", Int_t leap=0, Double_t dut=0)
void SetJD(Int_t jd, Int_t sec, Int_t ns, Int_t ps=0, TString utc="U", Int_t leap=0, Double_t dut=0)
Double_t GetUnixTime()
void Add(Int_t d, Int_t s, Int_t ns, Int_t ps=0)
void Convert(Double_t date, Int_t &days, Int_t &secs, Int_t &ns) const
Int_t GetDifference(NcTimestamp *t, Int_t &days, Int_t &sec, Int_t &ns, Int_t &ps, TString type="UT")
void AddSec(Double_t seconds)
void Date(Int_t mode=3, Double_t offset=0)