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 // Storage for transient burst investigations
294
295 // Initialize the default values for the burst parameters
296 SetBurstParameter("*",0);
297
298 // Load the UTC parameters
300
301 // Set the default local frame convention
302 // X-axis pointing South (=Greenwich)
303 // Y-axis pointing East
304 // Z-axis pointing towards Zenith
305 SetLocalFrame(90,0,90,90,0,0);
306
307 // First initialization of the various SkyMapPanel GUI parameters.
308 // In case SkyMapPanel() is invoked, the current Lab settings will be imported.
309 fSkyMapPanel=0;
310 fMapTS.LoadUTCparameterFiles();
311 for (Int_t i=0; i<3; i++)
312 {
313 fMapLabLBI[i]=0;
314 }
315 fMapLabU=0;
316 fMapLabE=0;
317 fMapLabLocL=0;
318 fMapLabLocB=0;
319 fMapLabLocU="deg";
320 fMapLabExpName="User";
321 fMapLabId=0;
324 fMapDate="";
325 fMapTime="";
326 fMapTimeType="-";
327 fMapDateTime="";
328 fMapLabTS=kTRUE;
329 for (Int_t i=0; i<6; i++)
330 {
331 fMapLabLframe[i]=0;
332 }
333 fMapCinfo="Lab";
334 fMapTinfo=-1;
335 fMapUinfo="deg";
336 fMapIname="";
337 fMapEa=0;
338 fMapEua="deg";
339 fMapEb=0;
340 fMapEub="deg";
341 fMapEtype=1;
342 fMapEcoord="-";
343 fMapEmode="-";
344 fMapEname="";
345 fMapDcoord="-";
346 fMapProj="-";
347 fMapDmode="-";
348 for (Int_t i=0; i<5; i++)
349 {
350 fMapDoptions[i]=kFALSE;
351 }
352 fMapNmax=-1;
353 fMapNdigs=1;
354 fMapDname="";
355 for (Int_t i=0; i<10; i++)
356 {
357 fMapSolar[i]=kFALSE;
358 }
359 fMapMerMode=0;
360 fMapMerC=0;
361 fMapMerUc="deg";
362 fMapMarkSize=1;
363 fMapMarkStyle=23;
364 fMapMarkColor=kRed;
365 fMapMarkType=0;
366}
367
369{
375
376 if (fRefs)
377 {
378 delete fRefs;
379 fRefs=0;
380 }
381 if (fSigs)
382 {
383 delete fSigs;
384 fSigs=0;
385 }
386 if (fIndices)
387 {
388 delete fIndices;
389 fIndices=0;
390 }
391 for (Int_t i=0; i<2; i++)
392 {
393 if (fHist[i])
394 {
395 delete fHist[i];
396 fHist[i]=0;
397 }
398 }
399 if (fMarkers)
400 {
401 delete fMarkers;
402 fMarkers=0;
403 }
404 if (fCanvas)
405 {
406 if (gROOT->GetListOfCanvases()->FindObject("NcAstrolab")) delete fCanvas;
407 fCanvas=0;
408 }
409 if (fTscfunc)
410 {
411 delete fTscfunc;
412 fTscfunc=0;
413 }
414 if (fDscfunc)
415 {
416 delete fDscfunc;
417 fDscfunc=0;
418 }
419 if (fThetascfunc)
420 {
421 delete fThetascfunc;
422 fThetascfunc=0;
423 }
424 if (fPhiscfunc)
425 {
426 delete fPhiscfunc;
427 fPhiscfunc=0;
428 }
429 if (fRan)
430 {
431 delete fRan;
432 fRan=0;
433 }
434
435 if (fNuAngle)
436 {
437 delete fNuAngle;
438 fNuAngle=0;
439 }
440
442 {
443 delete fBurstParameters;
445 }
446
447 // Remove the subtasks from the internal TTask list without deleting them
448 if (fTasks) fTasks->Clear();
449}
450
452{
458
461 fLabId=t.fLabId;
462 fL=t.fL;
463 Int_t size=0;
464 fRefs=0;
465 if (t.fRefs)
466 {
467 size=t.fRefs->GetSize();
468 fRefs=new TObjArray(size);
469 for (Int_t i=0; i<size; i++)
470 {
471 NcSignal* sx=(NcSignal*)t.fRefs->At(i);
472 if (sx) fRefs->AddAt(sx->Clone(),i);
473 }
474 }
475 fSigs=0;
476 if (t.fSigs)
477 {
478 size=t.fSigs->GetSize();
479 fSigs=new TObjArray(size);
480 for (Int_t i=0; i<size; i++)
481 {
482 NcSignal* sx=(NcSignal*)t.fSigs->At(i);
483 if (sx) fSigs->AddAt(sx->Clone(),i);
484 }
485 }
486 fNen[0]=t.fNen[0];
487 fNen[1]=t.fNen[1];
488 fBias=0;
489 fGal=0;
490 fIndices=0;
491 fMeridian=-999;
492 fProj="none";
493 fCanvas=0;
494 for (Int_t ih=0; ih<2; ih++)
495 {
496 fHist[ih]=0;
497 }
498 fMarkers=0;
499 for (Int_t i=0; i<4; i++)
500 {
501 fMarkerSize[i]=t.fMarkerSize[i];
502 fMarkerStyle[i]=t.fMarkerStyle[i];
503 fMarkerColor[i]=t.fMarkerColor[i];
504 }
505
506 fTscmode=0;
507 fTscmin=0;
508 fTscmax=0;
509 fTscfunc=0;
510 SetTimeScramble(t.fTscmode,t.fTscmin,t.fTscmax,t.fTscfunc);
511
512 fRscmode=0;
513 fDscmin=0;
514 fDscmax=0;
515 fDscfunc=0;
516 fThetascmin=0;
517 fThetascmax=0;
518 fThetascfunc=0;
519 fPhiscmin=0;
520 fPhiscmax=0;
521 fPhiscfunc=0;
522 SetPositionScramble(t.fRscmode,t.fDscmin,t.fDscmax,t.fDscfunc,t.fThetascmin,t.fThetascmax,t.fThetascfunc,t.fPhiscmin,t.fPhiscmax,t.fPhiscfunc);
523
524 fRan=0;
525 NcRandom* ran=t.fRan;
526 if (ran) fRan=new NcRandom(*ran);
527
528 fMaxDt=t.fMaxDt;
529
530 TF1* fx=t.fNuAngle;
531 if (fx) fNuAngle=(TF1*)fx->Clone();
532
533 NcDevice* dx=t.fBurstParameters;
534 if (dx) fBurstParameters=(NcDevice*)dx->Clone();
535}
536
537void NcAstrolab::Data(Int_t mode,TString u,Bool_t utc)
538{
560
561 TString name=GetName();
562 TString title=GetTitle();
563 printf(" *%-s::Data*",ClassName());
564 if (name!="") printf(" Name : %-s",name.Data());
565 if (title!="") printf(" Title : %-s",title.Data());
566 printf("\n");
567
568 Double_t l,b;
569 GetLabPosition(l,b,"deg");
570 printf(" Position longitude : "); PrintAngle(l,"deg",u,3);
571 printf(" latitude : "); PrintAngle(b,"deg",u,3);
572 printf(" for detector ID : %-i \n",fLabId);
573 printf(" Local user reference frame orientation w.r.t X0=South, Y0=East and Z0=Zenith : \n");
574 printf(" (Note : At the Poles (e.g. IceCube) South means the Greenwich meridian) \n");
575 TString saxes[3]={"Local X-axis","Local Y-axis","Local Z-axis"};
576 for (Int_t i=0; i<5; i+=2)
577 {
578 printf(" %-s : zenith=",saxes[i/2].Data()); PrintAngle(fAxes[i],"deg",u,3,kTRUE);
579 printf(" | phi="); PrintAngle(fAxes[i+1],"deg",u,3,kTRUE);
580 printf("\n");
581 }
582 printf(" Lab time offset w.r.t. UT : "); PrintTime(fToffset,12);
583 printf("\n");
584
585 // UT and Local time info
586 Date(mode,fToffset);
587
588 // Add the UTC and TAI related date/time information if requested
589 if (utc && mode!=4) Date(4);
590
591 if (fTscmode)
592 {
593 printf(" ------------------ Time scrambling ----------------- \n");
594 if (fTscmode<0)
595 {
596 printf(" *** Scrambling is applied only for off-source patch (background) data generation in MatchBurstData() *** \n");
597 printf(" *** The actual stored source and measurement data are not modified *** \n");
598 printf("\n");
599 }
600 if (abs(fTscmode)==1)
601 {
602 printf(" *** Each obtained time difference will be scrambled (mode %-i) *** \n",fTscmode);
603 printf(" *** The angular differences are not affected *** \n");
604 printf(" --> Tailored for scrambling entries in a specific time window without affecting \n");
605 printf(" the event selection based on angular separation w.r.t. a source. \n");
606 }
607 if (abs(fTscmode)==2)
608 {
609 if (fTscmode>0)
610 {
611 printf(" *** Each measurement is stored with a scrambled timestamp (mode %-i) *** \n",fTscmode);
612 printf(" *** The data of the sources are not modified *** \n");
613 printf(" *** Off-source (background) data : At each source matching, the measurement is given a new scrambled fake timestamp *** \n");
614 printf(" --> Tailored for blind analyses without access to the unblinded measurement data \n");
615 }
616 else
617 {
618 printf(" *** At each source matching, the measurement is given a new scrambled fake timestamp (mode %-i) *** \n",fTscmode);
619 }
620 printf(" --> Possible patterns in the distribution of sources on the sky will stay intact \n");
621 }
622 if (abs(fTscmode)==3)
623 {
624 printf(" *** At each measurement matching, the source is retrieved from the storage with a scrambled fake timestamp (mode %-i) *** \n",fTscmode);
625 printf(" *** The measurements are not affected --> Detection efficiency is unaltered *** \n");
626 printf(" --> Both time and angular differences will be scrambled \n");
627 printf(" --> Possible patterns in the distribution of sources on the sky will be washed out \n");
628 }
629 TString sx="offsets";
630 if (abs(fTscmode)==1) sx="differences";
631 printf(" Time %-s are randomly drawn from the interval [%-g,%-g] sec. \n",sx.Data(),fTscmin,fTscmax);
632 if (fTscfunc)
633 {
634 printf(" Randomising TF1 function %-s is used. \n",fTscfunc->GetName());
635 }
636 else
637 {
638 printf(" Uniform randomisation is used. \n");
639 }
640 }
641
642 if (fRscmode)
643 {
644 printf(" ------------------ Position scrambling ------------------ \n");
645 if (fRscmode<0)
646 {
647 printf(" *** Scrambling is applied only for off-source patch (background) data generation in MatchBurstData() *** \n");
648 printf(" *** The actual stored source and measurement data are not modified *** \n");
649 }
650 else
651 {
652 printf(" *** The data of the sources and the measurement timestamps are not modified *** \n");
653 }
654 printf("\n");
655
656 if (abs(fRscmode)==1)
657 {
658 printf(" *** Each obtained angular difference will be scrambled (mode %-i) *** \n",fRscmode);
659 printf(" *** The time differences are not affected *** \n");
660 printf(" ---> Tailored for scrambling entries within a specific angular range w.r.t. a source,");
661 printf(" without affecting the event selection based on the time difference w.r.t. a transient source. \n");
662 printf(" Angular differences are randomly drawn from the interval [%-g,%-g] degrees. \n",fDscmin,fDscmax);
663 if (fDscfunc)
664 {
665 printf(" Randomising TF1 function %-s is used. \n",fDscfunc->GetName());
666 }
667 else
668 {
669 printf(" Homogeneous solid angle randomisation is used. \n");
670 }
671 }
672
673 if (fRscmode==2)
674 {
675 printf(" *** Each measurement is stored with a scrambled fake local position (mode %-i) *** \n",fRscmode);
676 printf(" *** Off-source (background) data : At each source matching, the measurement is given a new scrambled fake local position *** \n");
677 printf(" --> Tailored for blind analyses without access to the unblinded measurement data \n");
678 }
679
680 if (abs(fRscmode)==3 || fRscmode==-2)
681 {
682 printf(" *** At each source matching, the measurement is given a new scrambled fake local position (mode %-i) *** \n",fRscmode);
683 }
684
685 if (abs(fRscmode)>1)
686 {
687 printf(" The local coordinates (r,theta,phi) of the measurement are modified to (r+dr,theta+dtheta,phi+dphi) with : \n");
688
689 printf(" dr is randomly drawn from the interval [%-g,%-g] \n",fDscmin,fDscmax);
690 if (fDscfunc)
691 {
692 printf(" Randomising TF1 function %-s is used. \n",fDscfunc->GetName());
693 }
694 else
695 {
696 printf(" Uniform randomisation is used. \n");
697 }
698
699 printf(" dtheta is randomly drawn from the interval [%-g,%-g] degrees. \n",fThetascmin,fThetascmax);
700 if (fThetascfunc)
701 {
702 printf(" Randomising TF1 function %-s is used. \n",fThetascfunc->GetName());
703 }
704 else
705 {
706 printf(" Uniform cos(theta) randomisation is used. \n");
707 }
708
709 printf(" dphi is randomly drawn from the interval [%-g,%-g] degrees. \n",fPhiscmin,fPhiscmax);
710 if (fPhiscfunc)
711 {
712 printf(" Randomising TF1 function %-s is used. \n",fPhiscfunc->GetName());
713 }
714 else
715 {
716 printf(" Uniform phi randomisation is used. \n");
717 }
718 }
719 }
720
721 printf(" ------------------ \n");
722 if (fRan)
723 {
724 Int_t iseed,cnt1,cnt2;
725 GetRandomiser(iseed,cnt1,cnt2);
726 cout << " *** Current settings of the internal NcRandom randomiser : iseed=" << iseed << " cnt1=" << cnt1 << " cnt2=" << cnt2 << endl;
727 }
728 else
729 {
730 cout << " *** The internal NcRandom randomiser is currently not intialised ***" << endl;
731 cout << " Automatic initialisation will be performed with the actual timestamp at the first random number request." << endl;
732 cout << " This will ensure different random sequences for different NcAstrolab instances." << endl;
733 cout << " To obtain reproducible scrambled results, please invoke SetRandomiser() before the first SetSignal() invokation." << endl;
734 }
735 printf(" ------------------ \n");
736}
737
739{
760
761 fLabPos.SetPosition(p);
762
763 // Determine local time offset in fractional hours w.r.t. UT.
764 Double_t vec[3];
765 p.GetVector(vec,"sph","deg");
766 Double_t l=vec[2];
767 fToffset=l/15.;
768}
769
770void NcAstrolab::SetLabPosition(Double_t l,Double_t b,TString u)
771{
804
805 Double_t r=1,theta=0,phi=0;
806
807 l=ConvertAngle(l,u,"deg");
808 b=ConvertAngle(b,u,"deg");
809
810 Double_t offset=90.;
811
812 theta=offset-b;
813 phi=l;
814
815 Double_t p[3]={r,theta,phi};
816 fLabPos.SetPosition(p,"sph","deg");
817
818 // Local time offset in fractional hours w.r.t. UT.
819 fToffset=l/15.;
820}
821
822void NcAstrolab::SetExperiment(TString name,Int_t id)
823{
862
863 fExperiment="User";
864 fLabId=0;
865
866 Double_t l=0; // Longitude
867 Double_t b=0; // Lattitude
868
869 if (name=="User")
870 {
871 SetNameTitle("User","Virtual Lab for general use");
872 SetLabPosition(0,90,"deg"); // North Pole
873 // Right handed local grid frame has X-South (to Greenwich), Y-East and Z-Zenith
874 // which is the same as the Master Reference Frame (MRF)
875 SetLocalFrame(90,0,90,90,0,0);
876 fExperiment=name;
877 fLabId=id;
878 return;
879 }
880
881 if (name=="Greenwich")
882 {
883 // Exact location : 51d 28' 36.6672" (N) and 0d 0' 1.8000" (W)
884 SetNameTitle("Greenwich","The Royal Observatory in the UK");
885 l=-0.000500;
886 b=51.476852;
887 SetLabPosition(l,b,"deg"); // South Pole
888 // Right handed Greenwich local grid frame has X-South, Y-East and Z-Zenith
889 // which is the same as the Master Reference Frame (MRF)
890 SetLocalFrame(90,0,90,90,0,0);
891 fExperiment=name;
892 return;
893 }
894
895 if (name=="Amanda")
896 {
897 SetNameTitle("Amanda","Antarctic Muon And Neutrino Detector Array");
898 SetLabPosition(0,-90,"deg"); // South Pole
899 // Right handed Amanda local grid frame has Y-North (to Greenwich), X-East and Z-Zenith
900 SetLocalFrame(90,90,90,180,0,0);
901 fExperiment=name;
902 return;
903 }
904
905 if (name=="IceCube")
906 {
907 // Exact location : 89d 59' 23.977" (S) and 63d 37' 21.432" (W)
908 SetNameTitle("IceCube","The South Pole Neutrino Observatory");
909 l=-63.453056;
910 b=-89.99;
911 SetLabPosition(l,b,"deg"); // South Pole
912 // Right handed IceCube local grid frame has Y-North (to Greenwich), X-East and Z-Zenith
913 SetLocalFrame(90,90.+l,90,180.+l,0,0);
914 fExperiment=name;
915 return;
916 }
917
918 if (name=="WSRT")
919 {
920 SetNameTitle("WSRT","The Westerbork Synthesis Radio Telescope");
921 SetLabPosition(63612.74,525454.33,"dms");
922 // Right handed local grid frame has X-South, Y-East and Z-Zenith
923 // which is the same as the Master Reference Frame (MRF)
924 SetLocalFrame(90,0,90,90,0,0);
925 fExperiment=name;
926 return;
927 }
928
929 if (name=="Astron")
930 {
931 SetNameTitle("Astron","The Netherlands Institute for Radio Astronomy");
932 SetLabPosition(62346.23,524843.99,"dms");
933 // Right handed local grid frame has X-South, Y-East and Z-Zenith
934 // which is the same as the Master Reference Frame (MRF)
935 SetLocalFrame(90,0,90,90,0,0);
936 fExperiment=name;
937 return;
938 }
939
940 if (name=="ARA")
941 {
942 SetNameTitle("ARA","The Askaryan Radio Array at the South Pole");
943 SetLabPosition(0,-90,"deg"); // South Pole
944 // Right handed ARA local grid frame has Y-North (to Greenwich), X-East and Z-Zenith
945 SetLocalFrame(90,90,90,180,0,0);
946 fExperiment=name;
947 return;
948 }
949
950 if (name=="RNO-G")
951 {
952 SetNameTitle("RNO-G","The Greenland Radio Neutrino Observatory at Summit Station");
953 // Use the location of the Big House as global location
954 l=-38.4604;
955 b=72.57889;
956
957 // The locations of the various stations
958 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};
959 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*/
960 -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*/
961 -38.2963,-38.2900,-38.2838,-38.2662,-38.2599,-38.2537,-38.2474};
962 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*/
963 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*/
964 72.62347,72.63433,72.64518,72.61076,72.62161,72.63247,72.64332};
965
966 // Select a specific station, if requested
967 if (id)
968 {
969 for (Int_t i=0; i<35; i++)
970 {
971 if (id==ids[i])
972 {
973 l=ls[i];
974 b=bs[i];
975 fLabId=id;
976 break;
977 }
978 }
979 }
980
981 // Set the selected location
982 SetLabPosition(l,b,"deg"); // Summit Station
983 // Right handed RNO-G local grid frame has Y-North, X-East and Z-Zenith
984 SetLocalFrame(90,90,90,180,0,0);
985 fExperiment=name;
986 return;
987 }
988
989 if (name=="ARCA")
990 {
991 SetNameTitle("ARCA","The KM3NeT/ARCA Neutrino detector near Sicily");
992 SetLabPosition(155842.25,361748.34,"dms");
993 // Right handed ARCA local grid frame has Y-North, X-East and Z-Zenith
994 SetLocalFrame(90,90,90,180,0,0);
995 fExperiment=name;
996 return;
997 }
998
999 cout << " *" << ClassName() << "::SetExperiment* Unsupported experiment name : " << name.Data() << endl;
1000 printf(" Experiment is set to %-s with detector identifier %-i \n",fExperiment.Data(),fLabId);
1001}
1002
1004{
1014
1015 fToffset=dt;
1016}
1017
1019{
1028
1029 return fLabPos;
1030}
1031
1032void NcAstrolab::GetLabPosition(Double_t& l,Double_t& b,TString u) const
1033{
1049
1050 Double_t pi=acos(-1.);
1051
1052 Double_t offset=90.;
1053 if (u=="rad") offset=pi/2.;
1054
1055 Double_t p[3];
1056 fLabPos.GetPosition(p,"sph",u);
1057 b=offset-p[1];
1058 l=p[2];
1059}
1060
1062{
1068
1069 return fExperiment;
1070}
1071
1073{
1079
1080 return fLabId;
1081}
1082
1084{
1092
1093 return fToffset;
1094}
1095
1096void NcAstrolab::SetRandomiser(Int_t iseed,Int_t cnt1,Int_t cnt2,NcTimestamp* ts)
1097{
1141
1142 if (!ts) ts=(NcTimestamp*)this;
1143
1144 if (fRan) delete fRan;
1145
1146 fRan=new NcRandom(iseed,cnt1,cnt2,ts);
1147}
1148
1149NcRandom* NcAstrolab::GetRandomiser(Int_t& iseed,Int_t& cnt1,Int_t& cnt2) const
1150{
1160
1161 iseed=-1;
1162 cnt1=-1;
1163 cnt2=-1;
1164
1165 if (!fRan) return 0;
1166
1167 iseed=fRan->GetSeed();
1168 cnt1=fRan->GetCnt1();
1169 cnt2=fRan->GetCnt2();
1170
1171 return fRan;
1172}
1173
1174void NcAstrolab::SetMaxDt(Double_t s)
1175{
1187
1188 fMaxDt=s;
1189}
1190
1191Double_t NcAstrolab::GetMaxDt() const
1192{
1202
1203 return fMaxDt;
1204}
1205
1207{
1216
1217 Double_t h=GetLT(fToffset);
1218 return h;
1219}
1220
1222{
1234
1235 Double_t h=GetLMST(fToffset);
1236 return h;
1237}
1238
1240{
1252
1253 Double_t h=GetLAST(fToffset);
1254 return h;
1255}
1256
1257void NcAstrolab::PrintAngle(Double_t a,TString in,TString out,Int_t ndig,Bool_t align) const
1258{
1294
1295 Double_t b=ConvertAngle(a,in,out);
1296
1297 if (out=="deg" || out=="rad")
1298 {
1299 if (align)
1300 {
1301 printf("%*.*f %-s",5+ndig,ndig,b,out.Data());
1302 }
1303 else
1304 {
1305 printf("%-.*f %-s",ndig,b,out.Data());
1306 }
1307 return;
1308 }
1309
1310 Double_t epsilon=1.e-12; // Accuracy in (arc)seconds
1311 Int_t word=0,ddd=0,hh=0,mm=0,ss=0;
1312 Double_t s;
1313
1314 if (out=="dms")
1315 {
1316 word=Int_t(b);
1317 word=abs(word);
1318 ddd=word/10000;
1319 word=word%10000;
1320 mm=word/100;
1321 ss=word%100;
1322 s=fabs(b)-Double_t(ddd*10000+mm*100+ss);
1323 if (s>(1.-epsilon))
1324 {
1325 s=0.;
1326 ss++;
1327 }
1328 while (ss>=60)
1329 {
1330 ss-=60;
1331 mm++;
1332 }
1333 while (mm>=60)
1334 {
1335 mm-=60;
1336 ddd++;
1337 }
1338 while (ddd>=360)
1339 {
1340 ddd-=360;
1341 }
1342 if (b<0) ddd=-ddd;
1343 s+=double(ss);
1344 if (align)
1345 {
1346 if (!ddd && b<0)
1347 {
1348 printf(" -0d %02i' %0*.*f\"",mm,3+ndig,ndig,s);
1349 }
1350 else
1351 {
1352 printf("%4id %02i' %0*.*f\"",ddd,mm,3+ndig,ndig,s);
1353 }
1354 }
1355 else
1356 {
1357 if (!ddd && b<0)
1358 {
1359 printf("-0d %-i' %-.*f\"",mm,ndig,s);
1360 }
1361 else
1362 {
1363 printf("%-id %-i' %-.*f\"",ddd,mm,ndig,s);
1364 }
1365 }
1366 return;
1367 }
1368
1369 if (out=="hms")
1370 {
1371 word=Int_t(b);
1372 word=abs(word);
1373 hh=word/10000;
1374 word=word%10000;
1375 mm=word/100;
1376 ss=word%100;
1377 s=fabs(b)-Double_t(hh*10000+mm*100+ss);
1378 if (s>(1.-epsilon))
1379 {
1380 s=0.;
1381 ss++;
1382 }
1383 while (ss>=60)
1384 {
1385 ss-=60;
1386 mm++;
1387 }
1388 while (mm>=60)
1389 {
1390 mm-=60;
1391 hh++;
1392 }
1393 while (hh>=24)
1394 {
1395 hh-=24;
1396 }
1397 if (b<0) hh=-hh;
1398 s+=double(ss);
1399 if (align)
1400 {
1401 if (!hh && b<0)
1402 {
1403 printf(" -0h %02im %0*.*fs",mm,3+ndig,ndig,s);
1404 }
1405 else
1406 {
1407 printf("%3ih %02im %0*.*fs",hh,mm,3+ndig,ndig,s);
1408 }
1409 }
1410 else
1411 {
1412 if (!hh && b<0)
1413 {
1414 printf("-0h %-im %-.*fs",mm,ndig,s);
1415 }
1416 else
1417 {
1418 printf("%-ih %-im %-.*fs",hh,mm,ndig,s);
1419 }
1420 }
1421 return;
1422 }
1423}
1424
1425NcSignal* NcAstrolab::SetSignal(Nc3Vector* r,TString frame,TString mode,NcTimestamp* ts,Int_t jref,TString name,Int_t type)
1426{
1498
1499 // Cope with the (obsolete) jref=0 specification
1500 if (!jref)
1501 {
1502 type=1;
1503 jref=1;
1504 delete fSigs;
1505 fSigs=0;
1506 }
1507
1508 if (!r) return 0;
1509
1510 if (!r->HasVector()) return 0;
1511
1512 if (frame!="equ" && frame!="gal" && frame!="ecl" && frame!="hor" && frame!="icr" && frame!="loc") return 0;
1513
1514 if (frame=="equ" && mode!="M" && mode!="m" && mode!="T" && mode!="t" && mode!="B" && mode!="b" && mode!="J" && mode!="j") return 0;
1515
1516 NcSignal* sx=0;
1517
1518 if (!ts) ts=(NcTimestamp*)this;
1519
1520 // Make a local copy of the timestamp to make sure that the newly stored
1521 // signal will never contain the Tree with the UTCparameter data.
1522 NcTimestamp ts2;
1523 Int_t mjd=0;
1524 Int_t isec=0;
1525 Int_t ins=0;
1526 Int_t ips=0;
1527 ts->GetMJD(mjd,isec,ins);
1528 ips=ts->GetPs();
1529 ts2.SetMJD(mjd,isec,ins,ips);
1530
1531 Double_t vec[3];
1532 vec[0]=r->GetX(1,"sph","rad");
1533 vec[1]=r->GetX(2,"sph","rad");
1534 vec[2]=r->GetX(3,"sph","rad");
1535 Nc3Vector q;
1536 q.SetVector(vec,"sph","rad");
1537
1538 // Recursive invokation in case of local coordinates
1539 if (frame=="loc")
1540 {
1541 // Convert to horizontal coordinates
1542 q=q.GetUnprimed(&fL);
1543
1544 // Store the signal
1545 sx=SetSignal(&q,"hor",mode,&ts2,jref,name,type);
1546 return sx;
1547 }
1548
1549 // If needed, initialise the randomiser with a "date/time driven" seed
1550 // using the timestamp of the moment of this invokation of the member function.
1551 // This will ensure different random sequences if the user repeats analyses
1552 // with identical measurements and reference signals without explicit initialisation
1553 // of the randomiser by the user at the start of the analysis.
1554 if (!fRan && type && (fTscmode==2 || fRscmode==2)) fRan=new NcRandom(-1);
1555
1556 // Local timestamp copy to allow time scrambling
1557 NcTimestamp tx(ts2);
1558
1559 // Perform time scrambling (measurements only) if requested
1560 if (type && fTscmode==2)
1561 {
1562 Double_t dt=0;
1563
1564 // Allow for specific offset studies
1565 if (fTscmin==fTscmax) dt=fTscmin;
1566
1567 // Go for randomly scrambled values
1568 if (fTscfunc)
1569 {
1570 if (fTscmax>fTscmin)
1571 {
1572 dt=fTscfunc->GetRandom(fTscmin,fTscmax);
1573 }
1574 }
1575 else
1576 {
1577 if (fTscmax>fTscmin) dt=fRan->Uniform(fTscmin,fTscmax);
1578 }
1579 tx.AddSec(dt);
1580 }
1581
1582 // Construct the corresponding ICRS position vector to be stored
1583 if (frame=="equ")
1584 {
1585 // Convert to "mean" values at specified epoch
1586 if (mode=="T" || mode=="t")
1587 {
1588 SetNmatrix(&tx);
1589 q=q.GetUnprimed(&fN);
1590 }
1591
1592 // Convert to "mean" values at J2000
1593 if (mode=="T" || mode=="t" || mode=="M" || mode=="m")
1594 {
1595 SetPmatrix(&tx);
1596 }
1597 else
1598 {
1599 NcTimestamp te;
1600 if (mode=="B" || mode=="b") te.SetEpoch(1950,"B");
1601 if (mode=="J" || mode=="j") te.SetEpoch(2000,"J");
1602 SetPmatrix(&te);
1603 }
1604 q=q.GetUnprimed(&fP);
1605
1606 // Convert to ICRS values
1607 if (!fBias) SetBmatrix();
1608 q=q.GetUnprimed(&fB);
1609 }
1610
1611 if (frame=="gal")
1612 {
1613 // Convert to J2000 equatorial mean coordinates
1614 if (fGal != 2) SetGmatrix("J");
1615 q=q.GetUnprimed(&fG);
1616
1617 // Convert to ICRS values
1618 if (!fBias) SetBmatrix();
1619 q=q.GetUnprimed(&fB);
1620 }
1621
1622 if (frame=="ecl")
1623 {
1624 // Convert to mean equatorial values at specified epoch
1625 SetEmatrix(&tx);
1626 q=q.GetUnprimed(&fE);
1627
1628 // Convert to "mean" values at J2000
1629 SetPmatrix(&tx);
1630 q=q.GetUnprimed(&fP);
1631
1632 // Convert to ICRS values
1633 if (!fBias) SetBmatrix();
1634 q=q.GetUnprimed(&fB);
1635 }
1636
1637 if (frame=="hor")
1638 {
1639 // Convert to "true" equatorial values at the specified timestamp
1640 SetHmatrix(&tx);
1641 q=q.GetUnprimed(&fH);
1642
1643 // Convert to "mean" values at specified timestamp
1644 SetNmatrix(&tx);
1645 q=q.GetUnprimed(&fN);
1646
1647 // Convert to "mean" values at J2000
1648 SetPmatrix(&tx);
1649 q=q.GetUnprimed(&fP);
1650
1651 // Convert to ICRS values
1652 if (!fBias) SetBmatrix();
1653 q=q.GetUnprimed(&fB);
1654 }
1655
1656 // Store the signal in ICRS coordinates
1657 Int_t size=0;
1658 Int_t jmax=0;
1659 Int_t jlast=0;
1660 if (type) // Storage of a measurement
1661 {
1662 NcSignal* sxsig=0;
1663 if (!fSigs)
1664 {
1665 fSigs=new TObjArray();
1666 fSigs->SetOwner();
1667 }
1668 // Expand array size if needed
1669 size=fSigs->GetSize();
1670 jmax=size-1;
1671 jlast=fSigs->GetLast();
1672 if (jref>0)
1673 {
1674 if (jref>size) fSigs->Expand(jref);
1675 }
1676 else
1677 {
1678 if (jlast==jmax) fSigs->Expand(size+1);
1679 }
1680 sxsig=GetSignal(jref,type);
1681 if (!sxsig)
1682 {
1683 sxsig=new NcSignal();
1684 }
1685 else
1686 {
1687 sxsig->Reset(1);
1688 }
1689 if (name=="") // Generate a corresponding measurement name
1690 {
1691 fNen[1]++;
1692 name="Meas";
1693 name+=fNen[1];
1694 name+="#";
1695 }
1696 sxsig->SetName(name);
1697 sxsig->SetTitle("Observed event in ICRS coordinates");
1698 sxsig->SetTimestamp(tx);
1699 sxsig->SetPosition(q);
1700 if (jref<0)
1701 {
1702 fSigs->Add(sxsig);
1703 }
1704 else
1705 {
1706 fSigs->AddAt(sxsig,jref-1);
1707 }
1708 sx=sxsig;
1709 }
1710 else // Storage of a reference signal
1711 {
1712 NcSignal* sxref=0;
1713 if (!fRefs)
1714 {
1715 fRefs=new TObjArray();
1716 fRefs->SetOwner();
1717 }
1718 // Expand array size if needed
1719 size=fRefs->GetSize();
1720 jmax=size-1;
1721 jlast=fRefs->GetLast();
1722 if (jref>0)
1723 {
1724 if (jref>size) fRefs->Expand(jref);
1725 }
1726 else
1727 {
1728 if (jlast==jmax) fRefs->Expand(size+1);
1729 }
1730 sxref=GetSignal(jref,type);
1731 if (!sxref)
1732 {
1733 sxref=new NcSignal();
1734 }
1735 else
1736 {
1737 sxref->Reset(1);
1738 }
1739 if (name=="") // Generate a corresponding reference name
1740 {
1741 fNen[0]++;
1742 name="Ref";
1743 name+=fNen[0];
1744 name+="#";
1745 }
1746 sxref->SetName(name);
1747 sxref->SetTitle("Reference event in ICRS coordinates");
1748 sxref->SetTimestamp(tx);
1749 sxref->SetPosition(q);
1750 if (jref<0)
1751 {
1752 fRefs->Add(sxref);
1753 }
1754 else
1755 {
1756 fRefs->AddAt(sxref,jref-1);
1757 }
1758 sx=sxref;
1759 }
1760
1761 if (fRscmode !=2 || !type) return sx;
1762
1764 // Perform position scrambling (measurements only) if requested //
1766
1767 // Get the measurement in local coordinates
1768 Int_t index=fSigs->IndexOf(sx);
1769 index++; // First storage is at index=1 and not index=0
1770 GetSignal(q,"loc",mode,&tx,index,type);
1771
1772 q.GetVector(vec,"sph","deg");
1773
1774 Double_t dd=0;
1775 Double_t dtheta=0;
1776 Double_t dphi=0;
1777
1778 // Allow specific offset studies
1779 if (fDscmin==fDscmax) dd=fDscmin;
1780 if (fThetascmin==fThetascmax) dtheta=fThetascmin;
1781 if (fPhiscmin==fPhiscmax) dphi=fPhiscmin;
1782
1783 // Go for randomly scrambled values
1784 if (fDscfunc)
1785 {
1786 if (fDscmax>fDscmin)
1787 {
1788 dd=fDscfunc->GetRandom(fDscmin,fDscmax);
1789 }
1790 }
1791 else
1792 {
1793 if (fDscmax>fDscmin) dd=fRan->Uniform(fDscmin,fDscmax);
1794 }
1795
1796 if (fThetascfunc)
1797 {
1799 {
1800 dtheta=fThetascfunc->GetRandom(fThetascmin,fThetascmax);
1801 }
1802 }
1803 else if (fThetascmax>fThetascmin)
1804 {
1805 Double_t pi=acos(-1.);
1806 Float_t cosmin=cos(fThetascmin*pi/180.);
1807 Float_t cosmax=cos(fThetascmax*pi/180.);
1808 if (cosmin>cosmax)
1809 {
1810 Float_t temp=cosmin;
1811 cosmin=cosmax;
1812 cosmax=temp;
1813 }
1814 Double_t cosang=fRan->Uniform(cosmin,cosmax);
1815 dtheta=acos(cosang)*180./pi;
1816 }
1817
1818 if (fPhiscfunc)
1819 {
1820 if (fPhiscmax>fPhiscmin)
1821 {
1822 dphi=fPhiscfunc->GetRandom(fPhiscmin,fPhiscmax);
1823 }
1824 }
1825 else
1826 {
1827 if (fPhiscmax>fPhiscmin) dphi=fRan->Uniform(fPhiscmin,fPhiscmax);
1828 }
1829
1830 vec[0]+=dd;
1831 if (vec[0]<=0) vec[0]=1e-20; // Keep a physical situation
1832 vec[1]+=dtheta;
1833 vec[2]+=dphi;
1834 q.SetVector(vec,"sph","deg");
1835
1837 // Construct the corresponding ICRS position vector to be stored //
1839
1840 // Convert to horizontal coordinates
1841 q=q.GetUnprimed(&fL);
1842
1843 // Convert to "true" equatorial values at the specified timestamp
1844 SetHmatrix(&tx);
1845 q=q.GetUnprimed(&fH);
1846
1847 // Convert to "mean" values at specified timestamp
1848 SetNmatrix(&tx);
1849 q=q.GetUnprimed(&fN);
1850
1851 // Convert to "mean" values at J2000
1852 SetPmatrix(&tx);
1853 q=q.GetUnprimed(&fP);
1854
1855 // Convert to ICRS values
1856 if (!fBias) SetBmatrix();
1857 q=q.GetUnprimed(&fB);
1858
1859 // Store the measurement position
1860 sx->SetPosition(q);
1861
1862 return sx;
1863}
1864
1865Int_t NcAstrolab::SetSolarSystem(TString name,NcTimestamp* ts,Int_t type)
1866{
1892
1893 // Only geocentric positions are allowed
1894 if (name.Contains("*")) return 0;
1895
1896 if (!ts) ts=(NcTimestamp*)this;
1897
1898 Double_t lx=0; // Geocentric ecliptic longitude of the object in degrees
1899 Double_t bx=0; // Geocentric ecliptic latitude of the object in degrees
1900 Double_t rx=0; // Distance (AU for planets, km for the Moon) between the object and the Earth.
1901
1902 Int_t set=0; // Flag to indicate that a location has been set
1903
1904 ts->Almanac(0,0,0,0,name,&lx,&bx,&rx);
1905
1906 if (rx>0) set=1;
1907
1908 // Replace c.q. store the object data as a reference or measured signal according to "type".
1909 // In case the object wasn't stored yet, jref=-1 and the object will be
1910 // added to the list of stored signals of "type".
1911 Int_t jref=GetSignalIndex(name,type);
1912 if (set && jref) SetSignal(rx,lx,"deg",bx,"deg","ecl",ts,jref,"M",name,type);
1913
1914 return set;
1915}
1916
1917NcSignal* 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)
1918{
1997
1998 // Assure physical value for the norm of the location vector
1999 if (d<=0) d=1;
2000
2001 // Convert angular coordinates to fractional degrees.
2002 a=ConvertAngle(a,au,"deg");
2003 b=ConvertAngle(b,bu,"deg");
2004
2005 Nc3Vector r;
2006 Double_t vec[3]={0,0,0};
2007 vec[0]=d;
2008
2009 // Equatorial coordinates
2010 if (frame=="equ")
2011 {
2012 if (mode!="M" && mode!="m" && mode!="T" && mode!="t" && mode!="B" && mode!="b" && mode!="J" && mode!="j") return 0;
2013 vec[1]=90.-b;
2014 vec[2]=a;
2015 }
2016
2017 // Galactic coordinates
2018 if (frame=="gal")
2019 {
2020 vec[1]=90.-b;
2021 vec[2]=a;
2022 }
2023
2024 // Geocentric ecliptic coordinates
2025 if (frame=="ecl")
2026 {
2027 vec[1]=90.-b;
2028 vec[2]=a;
2029 }
2030
2031 // Horizontal coordinates
2032 if (frame=="hor")
2033 {
2034 vec[1]=b;
2035 vec[2]=180.-a;
2036 }
2037
2038 // ICRS coordinates
2039 if (frame=="icr")
2040 {
2041 vec[1]=90.-b;
2042 vec[2]=a;
2043 }
2044
2045 // Local coordinates
2046 if (frame=="loc" || frame=="pdir")
2047 {
2048 vec[1]=a;
2049 vec[2]=b;
2050 }
2051
2052 if (!ts) ts=(NcTimestamp*)this;
2053
2054 r.SetVector(vec,"sph","deg");
2055
2056 // Revert momentum direction in order to get the source direction
2057 if (frame=="pdir")
2058 {
2059 r*=-1.;
2060 frame="loc";
2061 }
2062
2063 NcSignal* sx=SetSignal(&r,frame,mode,ts,jref,name,type);
2064 return sx;
2065}
2066
2067NcSignal* 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)
2068{
2150
2151 NcTimestamp tx;
2152 tx.SetEpoch(e,s);
2153
2154 NcSignal* sx=SetSignal(d,a,au,b,bu,frame,&tx,jref,mode,name,type);
2155 return sx;
2156}
2157
2158Int_t NcAstrolab::SetSourceAttributes(NcSignal* s,Double_t sigmapos,TString u,Double_t z,Double_t T90)
2159{
2186
2187 if (!s) return 0;
2188
2189 Int_t n=3;
2190
2191 if (sigmapos<0)
2192 {
2193 sigmapos=-999;
2194 n--;
2195 }
2196 if (z<0)
2197 {
2198 z=-999;
2199 n--;
2200 }
2201 if (T90<0)
2202 {
2203 T90=-999;
2204 n--;
2205 }
2206
2207 // Convert the position uncertainty into degrees
2208 Double_t sigma=ConvertAngle(sigmapos,u,"deg");
2209
2210 s->AddNamedSlot("csigma");
2211 s->AddNamedSlot("z");
2212 s->AddNamedSlot("T90");
2213 s->SetSignal(sigma,"csigma");
2214 s->SetSignal(z,"z");
2215 s->SetSignal(T90,"T90");
2216
2217 return n;
2218}
2219
2220Double_t NcAstrolab::GetSourceAttributes(NcSignal* s,Float_t* z,Float_t* T90)
2221{
2240
2241 if (!s) return -999;
2242
2243 Double_t sigma=s->GetSignal("csigma");
2244 if (z) *z=s->GetSignal("z");
2245 if (T90) *T90=s->GetSignal("T90");
2246
2247 return sigma;
2248}
2249
2250Int_t NcAstrolab::GetNRefSignals(Int_t mode) const
2251{
2277
2278 Int_t n=GetNsignals(0,mode);
2279 return n;
2280}
2281
2282Int_t NcAstrolab::GetNsignals(Int_t type,Int_t mode) const
2283{
2307
2308 TObjArray* arr=fRefs;
2309 if (type) arr=fSigs;
2310
2311 if (!arr) return 0;
2312
2313 Int_t n=0;
2314 if (!mode)
2315 {
2316 n=arr->GetEntries();
2317 }
2318 else
2319 {
2320 n=arr->GetSize();
2321 }
2322 return n;
2323}
2324
2325NcSignal* NcAstrolab::GetSignal(Nc3Vector& r,TString frame,TString mode,NcTimestamp* ts,Int_t jref,Int_t type)
2326{
2385
2386 r.SetZero();
2387
2388 if (frame!="equ" && frame!="gal" && frame!="ecl" && frame!="hor" && frame!="icr" && frame!="loc") return 0;
2389
2390 if (frame=="equ" && mode!="M" && mode!="m" && mode!="T" && mode!="t" && mode!="B" && mode!="b" && mode!="J" && mode!="j") return 0;
2391
2392 // For backward compatibility
2393 if (!jref)
2394 {
2395 jref=1;
2396 type=1;
2397 }
2398
2399 NcSignal* sx=GetSignal(jref,type);
2400
2401 if (!sx) return 0;
2402
2403 if (!ts) ts=(NcTimestamp*)this;
2404
2405 // Check on maximum time difference
2406 if (fMaxDt>0)
2407 {
2408 NcTimestamp* tx=sx->GetTimestamp();
2409 if (!tx) return 0;
2410 Double_t dt=tx->GetDifference(ts,"s",1);
2411 if (fabs(dt)>fMaxDt) return 0;
2412 }
2413
2414 // Update coordinates for Solar system objects
2415 TString name=sx->GetName();
2416 SetSolarSystem(name,ts,type);
2417
2418 Double_t vec[3];
2419 sx->GetPosition(vec,"sph","rad");
2420 Nc3Vector q;
2421 q.SetVector(vec,"sph","rad");
2422
2423 if (frame=="icr")
2424 {
2425 r.Load(q);
2426 return sx;
2427 }
2428
2429 // Convert from ICRS to equatorial J2000 coordinates
2430 if (!fBias) SetBmatrix();
2431 q=q.GetPrimed(&fB);
2432
2433 if (frame=="equ" && mode!="J" && mode!="j")
2434 {
2435 // Precess to specified timestamp
2436 NcTimestamp ts1;
2437 ts1.SetEpoch(2000,"J");
2438 if (mode!="B" && mode!="b")
2439 {
2440 Precess(q,&ts1,ts);
2441 }
2442 else
2443 {
2444 NcTimestamp ts2;
2445 ts2.SetEpoch(1950,"B");
2446 Precess(q,&ts1,&ts2);
2447 }
2448
2449 // Nutation correction if requested
2450 if (mode=="T" || mode=="t") Nutate(q,ts);
2451 }
2452
2453 if (frame=="gal")
2454 {
2455 // Convert from equatorial J2000 to galactic
2456 if (fGal != 2) SetGmatrix("J");
2457 q=q.GetPrimed(&fG);
2458 }
2459
2460 if (frame=="ecl")
2461 {
2462 // Precess to specified timestamp
2463 NcTimestamp ts1;
2464 ts1.SetEpoch(2000,"J");
2465 Precess(q,&ts1,ts);
2466
2467 // Convert from equatorial to ecliptic coordinates
2468 SetEmatrix(ts);
2469 q=q.GetPrimed(&fE);
2470 }
2471
2472 if (frame=="hor")
2473 {
2474 // Precess to specified timestamp
2475 NcTimestamp ts1;
2476 ts1.SetEpoch(2000,"J");
2477 Precess(q,&ts1,ts);
2478
2479 // Nutation correction
2480 Nutate(q,ts);
2481
2482 // Convert from equatorial to horizontal coordinates
2483 SetHmatrix(ts);
2484 q=q.GetPrimed(&fH);
2485 }
2486
2487 if (frame=="loc")
2488 {
2489 // Get the signal in horizontal coordinates
2490 GetSignal(q,"hor",mode,ts,jref,type);
2491
2492 // Convert from horizontal to local-frame coordinates
2493 q=q.GetPrimed(&fL);
2494 }
2495
2496 r.Load(q);
2497 return sx;
2498}
2499
2500void NcAstrolab::GeoToHeliocentric(Double_t& R,Double_t& B,Double_t& L,NcTimestamp* ts,TString Bu,TString Lu)
2501{
2535
2536 if (!ts) ts=(NcTimestamp*)this;
2537
2538 // Convert the angles into radians
2539 B=ConvertAngle(B,Bu,"rad");
2540 L=ConvertAngle(L,Lu,"rad");
2541
2542 // The Carthesian Geocentric ecliptic coordinates of the object
2543 Double_t xg=R*cos(B)*cos(L);
2544 Double_t yg=R*cos(B)*sin(L);
2545 Double_t zg=R*sin(B);
2546
2547 // Get the Heliocentric ecliptic coordinates of the Earth
2548 Double_t r0,b0,l0;
2549 ts->Almanac(0,0,0,0,"Earth*",&l0,&b0,&r0);
2550
2551 l0=ConvertAngle(l0,"deg","rad");
2552 b0=ConvertAngle(b0,"deg","rad");
2553
2554 Double_t x0=r0*cos(b0)*cos(l0);
2555 Double_t y0=r0*cos(b0)*sin(l0);
2556 Double_t z0=r0*sin(b0);
2557
2558 // The Heliocentric Carthesian ecliptic coordinates of the object
2559 Double_t xh=xg+x0;
2560 Double_t yh=yg+y0;
2561 Double_t zh=zg+z0;
2562
2563 // Convert to Heliocentric distance, latitude and longitude
2564 Double_t Rh=sqrt(xh*xh+yh*yh+zh*zh);
2565 Double_t Bh=atan2(zh,sqrt(xh*xh+yh*yh));
2566 Double_t Lh=atan2(yh,xh);
2567
2568 Double_t twopi=2.*acos(-1.);
2569 while (Lh<0) { Lh+=twopi; }
2570 while (Lh>twopi) { Lh-=twopi; }
2571
2572 // Return the Heliocentric values in the original units
2573 R=Rh;
2574 B=ConvertAngle(Bh,"rad",Bu);
2575 L=ConvertAngle(Lh,"rad",Lu);
2576}
2577
2578void NcAstrolab::HelioToGeocentric(Double_t& R,Double_t& B,Double_t& L,NcTimestamp* ts,TString Bu,TString Lu)
2579{
2613
2614 if (!ts) ts=(NcTimestamp*)this;
2615
2616 // Convert the angles into radians
2617 B=ConvertAngle(B,Bu,"rad");
2618 L=ConvertAngle(L,Lu,"rad");
2619
2620 // The Carthesian Heliocentric ecliptic coordinates of the object
2621 Double_t xh=R*cos(B)*cos(L);
2622 Double_t yh=R*cos(B)*sin(L);
2623 Double_t zh=R*sin(B);
2624
2625 // Get the Heliocentric ecliptic coordinates of the Earth
2626 Double_t r0,b0,l0;
2627 ts->Almanac(0,0,0,0,"Earth*",&l0,&b0,&r0);
2628
2629 l0=ConvertAngle(l0,"deg","rad");
2630 b0=ConvertAngle(b0,"deg","rad");
2631
2632 Double_t x0=r0*cos(b0)*cos(l0);
2633 Double_t y0=r0*cos(b0)*sin(l0);
2634 Double_t z0=r0*sin(b0);
2635
2636 // The Geocentric Carthesian ecliptic coordinates of the object
2637 Double_t xg=xh-x0;
2638 Double_t yg=yh-y0;
2639 Double_t zg=zh-z0;
2640
2641 // Convert to Geocentric distance, latitude and longitude
2642 Double_t Rg=sqrt(xg*xg+yg*yg+zg*zg);
2643 Double_t Bg=atan2(zg,sqrt(xg*xg+yg*yg));
2644 Double_t Lg=atan2(yg,xg);
2645
2646 Double_t twopi=2.*acos(-1.);
2647 while (Lg<0) { Lg+=twopi; }
2648 while (Lg>twopi) { Lg-=twopi; }
2649
2650 // Return the Geocentric values in the original units
2651 R=Rg;
2652 B=ConvertAngle(Bg,"rad",Bu);
2653 L=ConvertAngle(Lg,"rad",Lu);
2654}
2655
2656NcSignal* 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)
2657{
2728
2729 d=0;
2730 a=0;
2731 b=0;
2732
2733 Nc3Vector r;
2734 NcSignal* sx=GetSignal(r,frame,mode,ts,jref,type);
2735
2736 if (!sx) return 0;
2737
2738 // Retrieve the requested (a,d) values in the correct format
2739 Double_t vec[3];
2740 r.GetVector(vec,"sph","deg");
2741
2742 d=vec[0];
2743 if (d<=0) d=1;
2744 b=vec[1];
2745 a=vec[2];
2746
2747 if (frame=="equ" || frame=="gal" || frame=="ecl" || frame=="icr")
2748 {
2749 b=90.-vec[1];
2750 while (b<-90.)
2751 {
2752 b+=90.;
2753 }
2754 while (b>90.)
2755 {
2756 b-=90.;
2757 }
2758 }
2759
2760 if (frame=="hor")
2761 {
2762 a=180.-vec[2];
2763 }
2764
2765 while (a<-360.)
2766 {
2767 a+=360.;
2768 }
2769 while (a>360.)
2770 {
2771 a-=360.;
2772 }
2773
2774 // Interchange a and b to represent theta and phi, respectively, for local coordinates
2775 if (frame=="loc")
2776 {
2777 Double_t temp=a;
2778 a=b;
2779 b=temp;
2780 }
2781
2782 // Convert coordinates to appropriate format
2783 a=ConvertAngle(a,"deg",au);
2784 b=ConvertAngle(b,"deg",bu);
2785
2786 return sx;
2787}
2788
2789NcSignal* 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)
2790{
2862
2863 // Set c.q. update coordinates for Solar system objects
2864 SetSolarSystem(name,ts,type);
2865
2866 NcSignal* sx=0;
2867 Int_t j=GetSignalIndex(name,type);
2868 if (j>=0) sx=GetSignal(d,a,au,b,bu,frame,ts,j,mode,type);
2869 return sx;
2870}
2871
2872NcSignal* 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)
2873{
2948
2949 d=0;
2950 a=0;
2951 b=0;
2952
2953 if (s!="B" && s!="b" && s!="J" && s!="j") return 0;
2954
2955 NcTimestamp tx;
2956 tx.SetEpoch(e,s);
2957
2958 NcSignal* sx=GetSignal(d,a,au,b,bu,frame,&tx,jref,mode,type);
2959 return sx;
2960}
2961
2962NcSignal* 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)
2963{
3039
3040 // Set c.q. update coordinates for Solar system objects
3041 NcTimestamp tx;
3042 tx.SetEpoch(e,s);
3043 SetSolarSystem(name,&tx,type);
3044
3045 NcSignal* sx=0;
3046 Int_t j=GetSignalIndex(name,type);
3047 if (j>=0) sx=GetSignal(d,a,au,b,bu,frame,s,e,j,mode,type);
3048 return sx;
3049}
3050
3051NcSignal* NcAstrolab::GetSignal(Int_t jref,Int_t type)
3052{
3073
3074 if (jref<0) return 0;
3075
3076 if (!jref) // For backward compatibility
3077 {
3078 jref=1;
3079 type=1;
3080 }
3081
3082 if (!type && !fRefs) return 0;
3083 if (type && !fSigs) return 0;
3084
3085 NcSignal* sx=0;
3086 if (type)
3087 {
3088 if (jref<=fSigs->GetSize()) sx=(NcSignal*)fSigs->At(jref-1);
3089 }
3090 else
3091 {
3092 if (jref<=fRefs->GetSize()) sx=(NcSignal*)fRefs->At(jref-1);
3093 }
3094 return sx;
3095}
3096
3097NcSignal* NcAstrolab::GetSignal(TString name,Int_t type,NcTimestamp* ts)
3098{
3117
3118 NcSignal* sx=0;
3119 Int_t j=GetSignalIndex(name,type);
3120
3121 if (j==-1) // Set and store info for the requested Solar system object if not already stored
3122 {
3123 SetSolarSystem(name,ts,type);
3124 j=GetSignalIndex(name,type);
3125 }
3126
3127 if (j>=0) sx=GetSignal(j,type);
3128 return sx;
3129}
3130
3131Int_t NcAstrolab::RemoveRefSignal(Int_t j,Int_t compress)
3132{
3154
3155 Int_t nrem=0;
3156
3157 if (!fRefs) return 0;
3158
3159 // Clearing of the complete storage
3160 if (!j)
3161 {
3162 nrem=fRefs->GetEntries();
3163 delete fRefs;
3164 fRefs=0;
3165 return nrem;
3166 }
3167
3168 // Removing a specific reference signal
3169 if (j>0 && j<=fRefs->GetSize())
3170 {
3171 TObject* obj=fRefs->RemoveAt(j-1);
3172 if (obj)
3173 {
3174 delete obj;
3175 nrem++;
3176 }
3177 }
3178
3179 // Compression of the storage array
3180 if (compress) fRefs->Compress();
3181
3182 return nrem;
3183}
3184
3185Int_t NcAstrolab::RemoveRefSignal(TString name,Int_t compress)
3186{
3206
3207 Int_t nrem=0;
3208
3209 Int_t j=GetSignalIndex(name);
3210 if (j>0) nrem=RemoveRefSignal(j,compress);
3211
3212 return nrem;
3213}
3214
3215Int_t NcAstrolab::RemoveSignal(Int_t j,Int_t type,Int_t compress)
3216{
3236
3237 Int_t nrem=0;
3238
3239 TObjArray* arr=fRefs;
3240 if (type) arr=fSigs;
3241
3242 if (!arr) return nrem;
3243
3244 // Clearing of the complete "type" storage
3245 if (!j)
3246 {
3247 nrem=arr->GetEntries();
3248 delete arr;
3249 if (type)
3250 {
3251 fSigs=0;
3252 fNen[1]=0;
3253 }
3254 else
3255 {
3256 fRefs=0;
3257 fNen[0]=0;
3258 }
3259 return nrem;
3260 }
3261
3262 // Removing the specified signal
3263 if (j>0 && j<=arr->GetSize())
3264 {
3265 TObject* obj=arr->RemoveAt(j-1);
3266 if (obj)
3267 {
3268 delete obj;
3269 nrem++;
3270 }
3271 }
3272
3273 // Compression of the storage array
3274 if (compress)
3275 {
3276 arr->Compress();
3277 Int_t n=arr->GetEntries();
3278 arr->Expand(n);
3279 }
3280
3281 return nrem;
3282}
3283
3284Int_t NcAstrolab::RemoveSignal(TString name,Int_t type,Int_t compress)
3285{
3308
3309 Int_t nrem=0;
3310
3311 if (name=="") return nrem;
3312
3313 if (name=="*")
3314 {
3315 nrem=RemoveSignal(0,type,compress);
3316 }
3317 else
3318 {
3319 Int_t j=GetSignalIndex(name,type);
3320 if (j>0) nrem=RemoveSignal(j,type,compress);
3321 }
3322
3323 return nrem;
3324}
3325
3326Int_t NcAstrolab::RemoveSignals(TString name,Int_t type,Int_t compress)
3327{
3350
3351 Int_t nrem=0;
3352
3353 if (name=="") return 0;
3354
3355 if (name=="*")
3356 {
3357 nrem=RemoveSignal(0,type,compress);
3358 }
3359 else
3360 {
3361 TObjArray* arr=fRefs;
3362 if (type) arr=fSigs;
3363
3364 if (!arr) return 0;
3365
3366 NcSignal* sx=0;
3367 TString namex="";
3368 Int_t nremx=0;
3369 for (Int_t j=1; j<=arr->GetSize(); j++)
3370 {
3371 sx=GetSignal(j,type);
3372 if (!sx) continue;
3373
3374 namex=sx->GetName();
3375 if (!namex.Contains(name)) continue;
3376
3377 nremx=RemoveSignal(j,type,0);
3378 if (nremx) nrem++;
3379 }
3380
3381 // Compression of the storage array
3382 if (compress)
3383 {
3384 arr->Compress();
3385 Int_t n=arr->GetEntries();
3386 arr->Expand(n);
3387 }
3388 }
3389
3390 return nrem;
3391}
3392
3393Int_t NcAstrolab::GetSignalIndex(TString name,Int_t type)
3394{
3407
3408 if (name=="") return -1;
3409
3410 Int_t index=-1;
3411
3412 TObjArray* arr=fRefs;
3413 if (type) arr=fSigs;
3414
3415 if (!arr) return -1;
3416
3417 for (Int_t i=0; i<arr->GetSize(); i++)
3418 {
3419 NcSignal* sx=(NcSignal*)arr->At(i);
3420 if (!sx) continue;
3421
3422 if (name==sx->GetName())
3423 {
3424 index=i+1;
3425 break;
3426 }
3427 }
3428
3429 return index;
3430}
3431
3433{
3444
3445 if (!s) return -1;
3446
3447 Int_t index=-1;
3448
3449 TObjArray* arr=fRefs;
3450 if (type) arr=fSigs;
3451
3452 if (!arr) return -1;
3453
3454 for (Int_t i=0; i<arr->GetSize(); i++)
3455 {
3456 NcSignal* sx=(NcSignal*)arr->At(i);
3457 if (!sx) continue;
3458
3459 if (sx==s)
3460 {
3461 index=i+1;
3462 break;
3463 }
3464 }
3465
3466 return index;
3467}
3468
3469void NcAstrolab::PrintSignal(TString frame,TString mode,NcTimestamp* ts,Int_t ndig,Int_t jref,TString emode,Int_t type,Bool_t align)
3470{
3549
3550 NcSignal* sx=GetSignal(jref,type);
3551
3552 if (!sx) return;
3553
3554 if (!ts) ts=sx->GetTimestamp();
3555
3556 Nc3Vector r;
3557 GetSignal(r,frame,mode,ts,jref,type);
3558
3559 // Local Hour Angle of the signal
3560 Double_t lha=GetHourAngle("A",ts,jref,type);
3561 TString slha="LAHA";
3562 if (mode=="M" || mode=="m")
3563 {
3564 lha=GetHourAngle("M",ts,jref,type);
3565 slha="LMHA";
3566 }
3567 else if ((mode=="B" || mode=="b" || mode=="J" || mode=="j") && emode=="M")
3568 {
3569 lha=GetHourAngle("M",ts,jref,type);
3570 slha="LMHA";
3571 }
3572
3573 if (frame=="equ")
3574 {
3575 Double_t a,d;
3576 d=90.-r.GetX(2,"sph","deg");
3577 a=r.GetX(3,"sph","rad");
3578 if (mode=="B" || mode=="b") mode="B1950";
3579 if (mode=="J" || mode=="j") mode="J2000";
3580 cout << "Equatorial (" << mode.Data() <<") | a :";
3581 if (!align) {cout << " ";} PrintAngle(a,"rad","hms",ndig,align);
3582 if (!align) {cout << " ";} PrintAngle(a,"rad","deg",ndig,align);
3583 cout << " | b :";
3584 if (!align) {cout << " ";} PrintAngle(d,"deg","dms",ndig,align);
3585 if (!align) {cout << " ";} PrintAngle(d,"deg","deg",ndig,align);
3586 cout << " | " << slha.Data() << " : ";
3587 PrintAngle(lha,"deg","hms",ndig,align);
3588 cout << " "; PrintAngle(lha,"deg","deg",ndig,align);
3589 }
3590
3591 if (frame=="gal")
3592 {
3593 Double_t l,b;
3594 b=90.-r.GetX(2,"sph","deg");
3595 l=r.GetX(3,"sph","deg");
3596 cout << "Galactic | l :";
3597 if (!align) {cout << " ";} PrintAngle(l,"deg","deg",ndig,align);
3598 if (!align) {cout << " ";} PrintAngle(l,"deg","dms",ndig,align);
3599 cout << " | b :";
3600 if (!align) {cout << " ";} PrintAngle(b,"deg","deg",ndig,align);
3601 if (!align) {cout << " ";} PrintAngle(b,"deg","dms",ndig,align);
3602 cout << " | " << slha.Data() << " : ";
3603 PrintAngle(lha,"deg","hms",ndig,align);
3604 cout << " "; PrintAngle(lha,"deg","deg",ndig,align);
3605 }
3606
3607 if (frame=="icr")
3608 {
3609 Double_t l,b;
3610 b=90.-r.GetX(2,"sph","deg");
3611 l=r.GetX(3,"sph","deg");
3612 cout << "ICRS | l :";
3613 if (!align) {cout << " ";} PrintAngle(l,"deg","deg",ndig,align);
3614 if (!align) {cout << " ";} PrintAngle(l,"deg","dms",ndig,align);
3615 cout << " | b :";
3616 if (!align) {cout << " ";} PrintAngle(b,"deg","deg",ndig,align);
3617 if (!align) {cout << " ";} PrintAngle(b,"deg","dms",ndig,align);
3618 cout << " | " << slha.Data() << " : ";
3619 PrintAngle(lha,"deg","hms",ndig,align);
3620 cout << " "; PrintAngle(lha,"deg","deg",ndig,align);
3621 }
3622
3623 if (frame=="ecl")
3624 {
3625 Double_t l,b;
3626 b=90.-r.GetX(2,"sph","deg");
3627 l=r.GetX(3,"sph","deg");
3628 cout << "Geocentric ecliptic | l :";
3629 if (!align) {cout << " ";} PrintAngle(l,"deg","deg",ndig,align);
3630 if (!align) {cout << " ";} PrintAngle(l,"deg","dms",ndig,align);
3631 cout << " | b :";
3632 if (!align) {cout << " ";} PrintAngle(b,"deg","deg",ndig,align);
3633 if (!align) {cout << " ";} PrintAngle(b,"deg","dms",ndig,align);
3634 cout << " | " << slha.Data() << " : ";
3635 PrintAngle(lha,"deg","hms",ndig,align);
3636 cout << " "; PrintAngle(lha,"deg","deg",ndig,align);
3637 }
3638
3639 if (frame=="hor")
3640 {
3641 Double_t alt=90.-r.GetX(2,"sph","deg");
3642 Double_t azi=180.-r.GetX(3,"sph","deg");
3643 while (azi>360)
3644 {
3645 azi-=360.;
3646 }
3647 while (azi<0)
3648 {
3649 azi+=360.;
3650 }
3651 cout << "Horizontal | azi :";
3652 if (!align) {cout << " ";} PrintAngle(azi,"deg","deg",ndig,align);
3653 if (!align) {cout << " ";} PrintAngle(azi,"deg","dms",ndig,align);
3654 cout << " | alt :";
3655 if (!align) {cout << " ";} PrintAngle(alt,"deg","deg",ndig,align);
3656 if (!align) {cout << " ";} PrintAngle(alt,"deg","dms",ndig,align);
3657 cout << " | " << slha.Data() << " : ";
3658 PrintAngle(lha,"deg","hms",ndig,align);
3659 cout << " "; PrintAngle(lha,"deg","deg",ndig,align);
3660 }
3661
3662 if (frame=="loc")
3663 {
3664 Double_t theta=r.GetX(2,"sph","deg");
3665 Double_t phi=r.GetX(3,"sph","deg");
3666 cout << "Local-frame | phi :";
3667 if (!align) {cout << " ";} PrintAngle(phi,"deg","deg",ndig,align);
3668 if (!align) {cout << " ";} PrintAngle(phi,"deg","dms",ndig,align);
3669 cout << " | theta :";
3670 if (!align) {cout << " ";} PrintAngle(theta,"deg","deg",ndig,align);
3671 if (!align) {cout << " ";} PrintAngle(theta,"deg","dms",ndig,align);
3672 cout << " | " << slha.Data() << " : ";
3673 PrintAngle(lha,"deg","hms",ndig,align);
3674 cout << " "; PrintAngle(lha,"deg","deg",ndig,align);
3675 }
3676
3677 cout << " |";
3678
3679 TString name=sx->GetName();
3680 if (name != "") cout << " " << name.Data();
3681}
3682
3683void NcAstrolab::PrintSignal(TString frame,TString mode,NcTimestamp* ts,Int_t ndig,TString name,TString emode,Int_t type,Bool_t align)
3684{
3760
3761 // Set c.q. update coordinates for Solar system objects
3762 SetSolarSystem(name,ts,type);
3763
3764 Int_t j=GetSignalIndex(name,type);
3765 if (j>=0) PrintSignal(frame,mode,ts,ndig,j,emode,type,align);
3766}
3767
3768void NcAstrolab::ListSignals(TString frame,TString mode,Int_t ndig,TString emode,Int_t nmax,Int_t j,Int_t type,NcTimestamp* ts,TString name)
3769{
3841
3842 Int_t iprint=0;
3843 Int_t width=0; // Width for printing of the index
3844 if (nmax>0) width=log10(nmax);
3845 if (nmax<0)
3846 {
3847 Int_t maxref=0;
3848 if (fRefs) maxref=fRefs->GetSize();
3849 Int_t maxsig=0;
3850 if (fSigs) maxsig=fSigs->GetSize();
3851 Int_t maxj=maxref;
3852 if (maxsig>maxj) maxj=maxsig;
3853 if (maxj>0) width=log10(maxj);
3854 }
3855 width++;
3856
3857 NcSignal* sx=0;
3858 NcTimestamp* tx=0;
3859
3860 Int_t dform=1;
3861 if (mode=="T" || mode=="t") dform=-1;
3862 if ((mode=="B" || mode=="b" || mode=="J" || mode=="j") && emode=="T") dform=-1;
3863
3864 if (j>0) sx=GetSignal(j,1);
3865 if (sx)
3866 {
3867 tx=sx->GetTimestamp();
3868 if (!tx) tx=ts;
3869 if (!tx) tx=(NcTimestamp*)this;
3870 printf(" *%-s::ListSignals* Name : %-s Title : %-s \n",ClassName(),GetName(),GetTitle());
3871 if (fTscmode!=2)
3872 {
3873 cout << " Timestamp of the measurement stored at index=" << j;
3874 }
3875 else
3876 {
3877 cout << " *Scrambled* timestamp of the measurement stored at index=" << j;
3878 }
3879 cout << " (Lab time offset w.r.t. UT : "; PrintTime(fToffset,12); cout << ")" << endl;
3880 tx->Date(dform,fToffset);
3881 tx->Date(4);
3882 cout << " Corresponding location of this measurement" << endl;
3883 cout << " "; PrintSignal(frame,mode,tx,ndig,j,emode,1); cout << endl;
3884 iprint=1;
3885 }
3886
3887 TObjArray* arr=0;
3888 Int_t nstored=0;
3889 Int_t jlist=0;
3890 Int_t test=type;
3891 while (test<2)
3892 {
3893 if (test==0)
3894 {
3895 type=0;
3896 arr=fRefs;
3897 test=999;
3898 }
3899 if (test==1)
3900 {
3901 type=1;
3902 arr=fSigs;
3903 test=999;
3904 }
3905 if (test<0)
3906 {
3907 type=0;
3908 arr=fRefs;
3909 test=1;
3910 }
3911
3912 if (!arr) continue;
3913
3914 nstored=arr->GetEntries();
3915 jlist=0;
3916 TString namex="";
3917 for (Int_t i=1; i<=arr->GetSize(); i++)
3918 {
3919 sx=GetSignal(i,type);
3920 if (!sx) continue;
3921
3922 jlist++;
3923 if (nmax>=0 && jlist>nmax) break;
3924
3925 // Check for the name pattern
3926 namex=sx->GetName();
3927 if (name!="*" && !namex.Contains(name)) continue;
3928
3929 if (!iprint)
3930 {
3931 printf(" *%-s::ListSignals* Name : %-s Title : %-s \n",ClassName(),GetName(),GetTitle());
3932 if (j==0) tx=ts;
3933 if (tx)
3934 {
3935 cout << " User provided timestamp (Lab time offset w.r.t. UT : "; PrintTime(fToffset,12); cout << ")";
3936 cout << endl;
3937 tx->Date(dform,fToffset);
3938 tx->Date(4);
3939 }
3940 else
3941 {
3942 tx=(NcTimestamp*)this;
3943 if (j>=0)
3944 {
3945 cout << " Current timestamp of the laboratory (Lab time offset w.r.t. UT : "; PrintTime(fToffset,12); cout << ")";
3946 cout << endl;
3947 tx->Date(dform,fToffset);
3948 tx->Date(4);
3949 }
3950 }
3951 iprint=1;
3952 }
3953 if (iprint==1)
3954 {
3955 if (nmax<0 || nmax>=nstored)
3956 {
3957 if (!type)
3958 {
3959 if (j>=0)
3960 {
3961 cout << " === All stored reference signals according to the above timestamp ===" << endl;
3962 }
3963 else
3964 {
3965 cout << " === All stored reference signals according to their actual recorded timestamp ===" << endl;
3966 }
3967 }
3968 else
3969 {
3970 if (fTscmode!=2)
3971 {
3972 cout << " === All stored measurements according to their actual observation timestamp ===" << endl;
3973 }
3974 else
3975 {
3976 cout << " === All stored measurements according to their *scrambled* observation timestamp ===" << endl;
3977 cout << " === Time scrambling was performed by adding dt from the interval [dtmin,dtmax] to their actual timestamp" << endl;
3978 cout << " === dtmin : " << fTscmin << " dtmax : " << fTscmax << " sec.";
3979 if (fTscfunc)
3980 {
3981 cout << " Randomising TF1 function " << fTscfunc->GetName() << " was used." << endl;
3982 }
3983 else
3984 {
3985 cout << " Uniform randomisation was used." << endl;
3986 }
3987 }
3988 }
3989 }
3990 else
3991 {
3992 if (!type)
3993 {
3994 if (j>=0)
3995 {
3996 cout << " === The first " << nmax << " stored reference signals according to the above timestamp ===" << endl;
3997 }
3998 else
3999 {
4000 cout << " === The first " << nmax << " stored reference signals according to their actual recorded timestamp ===" << endl;
4001 }
4002 }
4003 else
4004 {
4005 if (fTscmode!=2)
4006 {
4007 cout << " === The first " << nmax << " stored measurements according to their actual observation timestamp ===" << endl;
4008 }
4009 else
4010 {
4011 cout << " === The first " << nmax << " stored measurements according to their *scrambled* observation timestamp ===" << endl;
4012 cout << " === Time scrambling was performed by adding dt from the interval [dtmin,dtmax] to their actual timestamp" << endl;
4013 cout << " === dtmin : " << fTscmin << " dtmax : " << fTscmax << " sec.";
4014 if (fTscfunc)
4015 {
4016 cout << " Randomising TF1 function " << fTscfunc->GetName() << " was used." << endl;
4017 }
4018 else
4019 {
4020 cout << " Uniform randomisation was used." << endl;
4021 }
4022 }
4023 }
4024 }
4025 iprint=2;
4026 }
4027 if (type==1 || (!type && j<0)) tx=0;
4028 printf(" Index : %*d ",width,i); PrintSignal(frame,mode,tx,ndig,i,emode,type,kTRUE); printf("\n");
4029 }
4030 iprint=1;
4031 }
4032}
4033
4035{
4060
4061 // Convert back to J2000 values
4062 Nc3Vector r0;
4063 SetPmatrix(ts1);
4064 r0=r.GetUnprimed(&fP);
4065
4066 // Precess to the specified timestamp
4067 if (!ts2) ts2=(NcTimestamp*)this;
4068 SetPmatrix(ts2);
4069 r=r0.GetPrimed(&fP);
4070}
4071
4073{
4093
4094 // Nutation correction for the specified timestamp
4095 if (!ts) ts=(NcTimestamp*)this;
4096 SetNmatrix(ts);
4097 r=r.GetPrimed(&fN);
4098}
4099
4101{
4110
4111 Double_t pi=acos(-1.);
4112
4113 // Parameters in mas
4114 Double_t a=-14.6;
4115 Double_t x=-16.6170;
4116 Double_t e=-6.8192;
4117
4118 // Convert to radians
4119 a*=pi/(180.*3600.*1000.);
4120 x*=pi/(180.*3600.*1000.);
4121 e*=pi/(180.*3600.*1000.);
4122
4123 Double_t mat[9];
4124 mat[0]=1.-0.5*(a*a+x*x);
4125 mat[1]=a;
4126 mat[2]=-x;
4127 mat[3]=-a-e*x;
4128 mat[4]=1.-0.5*(a*a+e*e);
4129 mat[5]=-e;
4130 mat[6]=x-e*a;
4131 mat[7]=e+x*a;
4132 mat[8]=1.-0.5*(e*e+x*x);
4133
4134 fB.SetMatrix(mat);
4135 fBias=1;
4136}
4137
4139{
4149
4150 Double_t mat[9]={0,0,0,0,0,0,0,0,0};
4151 if (!ts)
4152 {
4153 fP.SetMatrix(mat);
4154 return;
4155 }
4156
4157 Double_t pi=acos(-1.);
4158
4159 Double_t t=(ts->GetJD()-2451545.0)/36525.; // Julian centuries since J2000.0
4160
4161 // Parameters for the precession matrix in arcseconds
4162 Double_t eps0=84381.406; // Mean ecliptic obliquity at J2000.0
4163 Double_t psi=5038.481507*t-1.0790069*pow(t,2)-0.00114045*pow(t,3)+0.000132851*pow(t,4)
4164 -0.0000000951*pow(t,4);
4165 Double_t om=eps0-0.025754*t+0.0512623*pow(t,2)-0.00772503*pow(t,3)-0.000000467*pow(t,4)
4166 +0.0000003337*pow(t,5);
4167 Double_t chi=10.556403*t-2.3814292*pow(t,2)-0.00121197*pow(t,3)+0.000170663*pow(t,4)
4168 -0.0000000560*pow(t,5);
4169
4170 // Convert to radians
4171 eps0*=pi/(180.*3600.);
4172 psi*=pi/(180.*3600.);
4173 om*=pi/(180.*3600.);
4174 chi*=pi/(180.*3600.);
4175
4176 Double_t s1=sin(eps0);
4177 Double_t s2=sin(-psi);
4178 Double_t s3=sin(-om);
4179 Double_t s4=sin(chi);
4180 Double_t c1=cos(eps0);
4181 Double_t c2=cos(-psi);
4182 Double_t c3=cos(-om);
4183 Double_t c4=cos(chi);
4184
4185 mat[0]=c4*c2-s2*s4*c3;
4186 mat[1]=c4*s2*c1+s4*c3*c2*c1-s1*s4*s3;
4187 mat[2]=c4*s2*s1+s4*c3*c2*s1+c1*s4*s3;
4188 mat[3]=-s4*c2-s2*c4*c3;
4189 mat[4]=-s4*s2*c1+c4*c3*c2*c1-s1*c4*s3;
4190 mat[5]=-s4*s2*s1+c4*c3*c2*s1+c1*c4*s3;
4191 mat[6]=s2*s3;
4192 mat[7]=-s3*c2*c1-s1*c3;
4193 mat[8]=-s3*c2*s1+c3*c1;
4194
4195 fP.SetMatrix(mat);
4196}
4197
4199{
4208
4209 Double_t mat[9]={0,0,0,0,0,0,0,0,0};
4210 if (!ts)
4211 {
4212 fN.SetMatrix(mat);
4213 return;
4214 }
4215
4216 Double_t pi=acos(-1.);
4217
4218 Double_t dpsi,deps,eps;
4219 ts->Almanac(&dpsi,&deps,&eps);
4220
4221 // Convert to radians
4222 dpsi*=pi/(180.*3600.);
4223 deps*=pi/(180.*3600.);
4224 eps*=pi/(180.*3600.);
4225
4226 Double_t s1=sin(eps);
4227 Double_t s2=sin(-dpsi);
4228 Double_t s3=sin(-(eps+deps));
4229 Double_t c1=cos(eps);
4230 Double_t c2=cos(-dpsi);
4231 Double_t c3=cos(-(eps+deps));
4232
4233 mat[0]=c2;
4234 mat[1]=s2*c1;
4235 mat[2]=s2*s1;
4236 mat[3]=-s2*c3;
4237 mat[4]=c3*c2*c1-s1*s3;
4238 mat[5]=c3*c2*s1+c1*s3;
4239 mat[6]=s2*s3;
4240 mat[7]=-s3*c2*c1-s1*c3;
4241 mat[8]=-s3*c2*s1+c3*c1;
4242
4243 fN.SetMatrix(mat);
4244}
4245
4246void NcAstrolab::SetGmatrix(TString mode)
4247{
4260
4261 Nc3Vector x; // The Galactic x-axis in the equatorial frame
4262 Nc3Vector y; // The Galactic y-axis in the equatorial frame
4263 Nc3Vector z; // The Galactic z-axis in the equatorial frame
4264
4265 Double_t a,d;
4266 Double_t vec[3]={1,0,0};
4267
4268 fGal=1; // Set flag to indicate B1950 matrix values
4269
4270 // B1950 equatorial coordinates of the North Galactic Pole (NGP)
4271 a=124900.;
4272 d=272400.;
4273 a=ConvertAngle(a,"hms","deg");
4274 d=ConvertAngle(d,"dms","deg");
4275 vec[1]=90.-d;
4276 vec[2]=a;
4277 z.SetVector(vec,"sph","deg");
4278
4279 // B1950 equatorial coordinates of the Galactic l=b=0 point
4280 a=174224.;
4281 d=-285500.;
4282 a=ConvertAngle(a,"hms","deg");
4283 d=ConvertAngle(d,"dms","deg");
4284 vec[1]=90.-d;
4285 vec[2]=a;
4286 x.SetVector(vec,"sph","deg");
4287
4288 // Precess to the corresponding J2000 values if requested
4289 if (mode=="J")
4290 {
4291 fGal=2; // Set flag to indicate J2000 matrix values
4292 NcTimestamp t1;
4293 t1.SetEpoch(1950,"B");
4294 NcTimestamp t2;
4295 t2.SetEpoch(2000,"J");
4296 Precess(z,&t1,&t2);
4297 Precess(x,&t1,&t2);
4298 }
4299
4300 // The Galactic y-axis is determined for the right handed frame
4301 y=z.Cross(x);
4302
4303 fG.SetAngles(x.GetX(2,"sph","deg"),x.GetX(3,"sph","deg"),
4304 y.GetX(2,"sph","deg"),y.GetX(3,"sph","deg"),
4305 z.GetX(2,"sph","deg"),z.GetX(3,"sph","deg"));
4306}
4307
4309{
4318
4319 Double_t dpsi,deps,eps;
4320 ts->Almanac(&dpsi,&deps,&eps);
4321
4322 // Convert to degrees
4323 eps/=3600.;
4324
4325 // Positions of the ecliptic axes w.r.t. the equatorial ones
4326 // at the moment of the specified timestamp
4327 Double_t theta1=90; // Ecliptic x-axis
4328 Double_t phi1=0;
4329 Double_t theta2=90.-eps; //Ecliptic y-axis
4330 Double_t phi2=90;
4331 Double_t theta3=eps; // Ecliptic z-axis
4332 Double_t phi3=270;
4333
4334 fE.SetAngles(theta1,phi1,theta2,phi2,theta3,phi3);
4335}
4336
4338{
4350
4351 Nc3Vector x; // The (South pointing) horizontal x-axis in the equatorial frame
4352 Nc3Vector y; // The (East pointing) horizontal y-axis in the equatorial frame
4353 Nc3Vector z; // The (Zenith pointing) horizontal z-axis in the equatorial frame
4354
4355 Double_t l,b;
4356 GetLabPosition(l,b,"deg");
4357
4358 Double_t a;
4359 Double_t vec[3]={1,0,0};
4360
4361 // Equatorial coordinates of the horizontal z-axis
4362 // at the moment of the specified timestamp
4363 a=ts->GetLAST(fToffset);
4364 a*=15.; // Convert fractional hours to degrees
4365 vec[1]=90.-b;
4366 vec[2]=a;
4367 z.SetVector(vec,"sph","deg");
4368
4369 // Equatorial coordinates of the horizontal x-axis
4370 // at the moment of the specified timestamp
4371 vec[1]=180.-b;
4372 vec[2]=a;
4373 x.SetVector(vec,"sph","deg");
4374
4375 // The horizontal y-axis is determined for the right handed frame
4376 y=z.Cross(x);
4377
4378 fH.SetAngles(x.GetX(2,"sph","deg"),x.GetX(3,"sph","deg"),
4379 y.GetX(2,"sph","deg"),y.GetX(3,"sph","deg"),
4380 z.GetX(2,"sph","deg"),z.GetX(3,"sph","deg"));
4381}
4382
4383void NcAstrolab::SetLocalFrame(Double_t t1,Double_t p1,Double_t t2,Double_t p2,Double_t t3,Double_t p3)
4384{
4413
4414 // Set the matrix for the conversion of our reference frame coordinates
4415 // into the local-frame ones.
4416
4417 fL.SetAngles(t1,p1,t2,p2,t3,p3);
4418
4419 // Store the local user frame axes orientations w.r.t. the standard local Horizon (zen,azi) frame
4420 fAxes[0]=t1;
4421 fAxes[1]=p1;
4422 fAxes[2]=t2;
4423 fAxes[3]=p2;
4424 fAxes[4]=t3;
4425 fAxes[5]=p3;
4426}
4427
4429{
4439
4440 arr[0]=fAxes[0];
4441 arr[1]=fAxes[1];
4442 arr[2]=fAxes[2];
4443 arr[3]=fAxes[3];
4444 arr[4]=fAxes[4];
4445 arr[5]=fAxes[5];
4446}
4447
4448Double_t NcAstrolab::ConvertAngle(Double_t a,TString in,TString out) const
4449{
4470
4471 if (in==out) return a;
4472
4473 // Convert input to its absolute value in (fractional) degrees.
4474 Double_t pi=acos(-1.);
4475 Double_t epsilon=1.e-12; // Accuracy in (arc)seconds
4476 Int_t word=0,ddd=0,hh=0,mm=0,ss=0;
4477 Double_t s=0;
4478
4479 Double_t b=fabs(a);
4480
4481 if (in=="rad") b*=180./pi;
4482
4483 if (in=="hrs") b*=15.;
4484
4485 if (in=="dms")
4486 {
4487 word=Int_t(b);
4488 ddd=word/10000;
4489 word=word%10000;
4490 mm=word/100;
4491 ss=word%100;
4492 s=b-Double_t(ddd*10000+mm*100+ss);
4493 b=Double_t(ddd)+Double_t(mm)/60.+(Double_t(ss)+s)/3600.;
4494 }
4495
4496 if (in=="hms")
4497 {
4498 word=Int_t(b);
4499 hh=word/10000;
4500 word=word%10000;
4501 mm=word/100;
4502 ss=word%100;
4503 s=b-Double_t(hh*10000+mm*100+ss);
4504 b=15.*(Double_t(hh)+Double_t(mm)/60.+(Double_t(ss)+s)/3600.);
4505 }
4506
4507 while (b>360)
4508 {
4509 b-=360.;
4510 }
4511
4512 if (out=="rad") b*=pi/180.;
4513
4514 if (out=="hrs") b/=15.;
4515
4516 if (out=="dms")
4517 {
4518 ddd=Int_t(b);
4519 b=b-Double_t(ddd);
4520 b*=60.;
4521 mm=Int_t(b);
4522 b=b-Double_t(mm);
4523 b*=60.;
4524 ss=Int_t(b);
4525 s=b-Double_t(ss);
4526 if (s>(1.-epsilon))
4527 {
4528 s=0.;
4529 ss++;
4530 }
4531 while (ss>=60)
4532 {
4533 ss-=60;
4534 mm++;
4535 }
4536 while (mm>=60)
4537 {
4538 mm-=60;
4539 ddd++;
4540 }
4541 while (ddd>=360)
4542 {
4543 ddd-=360;
4544 }
4545 b=Double_t(10000*ddd+100*mm+ss)+s;
4546 }
4547
4548 if (out=="hms")
4549 {
4550 b/=15.;
4551 hh=Int_t(b);
4552 b=b-Double_t(hh);
4553 b*=60.;
4554 mm=Int_t(b);
4555 b=b-Double_t(mm);
4556 b*=60.;
4557 ss=Int_t(b);
4558 s=b-Double_t(ss);
4559 if (s>(1.-epsilon))
4560 {
4561 s=0.;
4562 ss++;
4563 }
4564 while (ss>=60)
4565 {
4566 ss-=60;
4567 mm++;
4568 }
4569 while (mm>=60)
4570 {
4571 mm-=60;
4572 hh++;
4573 }
4574 while (hh>=24)
4575 {
4576 hh-=24;
4577 }
4578 b=Double_t(10000*hh+100*mm+ss)+s;
4579 }
4580
4581 if (a<0) b=-b;
4582
4583 return b;
4584}
4585
4586Double_t NcAstrolab::GetSolidAngle(Double_t thetamin,Double_t thetamax,TString tu,Double_t phimin,Double_t phimax,TString pu) const
4587{
4602
4603 Double_t omega=0;
4604
4605 Double_t th1=ConvertAngle(thetamin,tu,"rad");
4606 Double_t th2=ConvertAngle(thetamax,tu,"rad");
4607 Double_t ph1=ConvertAngle(phimin,pu,"rad");
4608 Double_t ph2=ConvertAngle(phimax,pu,"rad");
4609
4610 omega=(ph2-ph1)*(cos(th1)-cos(th2));
4611 if (omega<0) omega=-omega;
4612
4613 return omega;
4614}
4615
4616Double_t NcAstrolab::GetHourAngle(TString mode,NcTimestamp* ts,Int_t jref,Int_t type)
4617{
4651
4652 if (!ts) ts=(NcTimestamp*)this;
4653
4654 // Get corrected right ascension and declination for the specified timestamp.
4655 Double_t d,a,b;
4656 if (mode=="M" || mode=="m") GetSignal(d,a,"deg",b,"deg","equ",ts,jref,"M",type);
4657 if (mode=="A" || mode=="a") GetSignal(d,a,"deg",b,"deg","equ",ts,jref,"T",type);
4658
4659 a/=15.; // Convert a to fractional hours
4660 Double_t ha=0;
4661 if (mode=="M" || mode=="m") ha=ts->GetLMST(fToffset)-a;
4662 if (mode=="A" || mode=="a") ha=ts->GetLAST(fToffset)-a;
4663 ha*=15.; // Convert to (fractional) degrees
4664
4665 // Project to the interval [-180,180]
4666 while (ha<-180)
4667 {
4668 ha+=360.;
4669 }
4670 while (ha>180)
4671 {
4672 ha-=360.;
4673 }
4674
4675 return ha;
4676}
4677
4678void 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)
4679{
4701
4702 SetLT(fToffset,y,m,d,hh,mm,ss,ns,ps);
4703}
4704
4705void NcAstrolab::SetLT(Int_t y,Int_t m,Int_t d,Int_t hh,Int_t mm,Double_t s)
4706{
4727
4728 SetLT(fToffset,y,m,d,hh,mm,s);
4729}
4730
4731void NcAstrolab::SetLT(Int_t y,Int_t m,Int_t d,TString time)
4732{
4751
4752 SetLT(fToffset,y,m,d,time);
4753}
4754
4755void NcAstrolab::SetLT(TString date,TString time,Int_t mode)
4756{
4777
4778 SetLT(fToffset,date,time,mode);
4779}
4780
4781void NcAstrolab::SetLT(Int_t y,Int_t d,Int_t s,Int_t ns,Int_t ps)
4782{
4807
4808 SetLT(fToffset,y,d,s,ns,ps);
4809}
4810
4811Double_t NcAstrolab::GetDifference(Int_t j,TString au,Double_t& dt,TString tu,Int_t mode,Int_t* ia,Int_t* it)
4812{
4858
4859 Double_t da=999;
4860 dt=1.e30;
4861
4862 if (ia) *ia=0;
4863 if (it) *it=0;
4864
4865 if (j<0) return da;
4866
4867 NcDevice matches;
4868 Int_t nhits=0;
4869 NcSignal* sx=0;
4870 if (j) // Space and time difference w.r.t. a specific reference signal
4871 {
4872 MatchSignals(matches,da,au,dt,tu,mode,j,j,0,1,1,1);
4873 nhits=matches.GetNhits();
4874 if (nhits)
4875 {
4876 da=matches.GetSignal(1);
4877 dt=matches.GetSignal(2);
4878 if (ia) *ia=j;
4879 if (it) *it=j;
4880 }
4881 }
4882 else // Minimal space and time difference encountered over all reference signals
4883 {
4884 MatchSignals(matches,da,au,dt,tu,mode,1,0,0,1,1,1);
4885 nhits=matches.GetNhits();
4886 if (nhits)
4887 {
4888 da=matches.GetSignal(1);
4889 dt=matches.GetSignal(2);
4890 if (ia)
4891 {
4892 Int_t ipsi=matches.GetSignal("ipsi");
4893 sx=matches.GetHit(ipsi);
4894 if (sx) *ia=sx->GetSignal("index1");
4895 }
4896 if (it)
4897 {
4898 Int_t idt=matches.GetSignal("idt");
4899 sx=matches.GetHit(idt);
4900 if (sx) *it=sx->GetSignal("index1");
4901 }
4902 }
4903 }
4904 return da;
4905}
4906
4907Double_t NcAstrolab::GetSeparation(TString name1,TString name2,TString au,Double_t* dt,TString tu,Int_t mode,Double_t* diftheta,Double_t* difphi)
4908{
4955
4956 // Obtain the storage indices for the requested signals
4957 Int_t i=GetSignalIndex(name1,1); // Search for "name1" among the measurement signals
4958 Int_t j=GetSignalIndex(name2,1); // Search for "name2" among the measurement signals
4959
4960 if (i>0) // Set to negative value to indicate measurement entry
4961 {
4962 i=-i;
4963 }
4964 else // Search for "name1" among the reference signals
4965 {
4966 // In case a Solar system body was specified, store c.q. update it as a reference object.
4967 SetSolarSystem(name1,0,0);
4968 i=GetSignalIndex(name1,0);
4969 if (i<0) i=0;
4970 }
4971
4972 if (j>0) // Set to negative value to indicate measurement entry
4973 {
4974 j=-j;
4975 }
4976 else // Search for "name2" among the reference signals
4977 {
4978 // In case a Solar system body was specified, store c.q. update it as a reference object.
4979 SetSolarSystem(name2,0,0);
4980 j=GetSignalIndex(name2,0);
4981 if (j<0) j=0;
4982 }
4983
4984 // Retrieve the requested data via the internal GetSeparation() memberfunction
4985 Double_t dtx;
4986 Double_t da=GetSeparation(i,j,au,dtx,tu,mode,0,diftheta,difphi);
4987
4988Double_t dthetax,dphix;
4989da=GetSeparation(i,j,au,dtx,tu,mode,0,&dthetax,&dphix);
4990printf(" 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());
4991
4992 if (dt) *dt=dtx;
4993 return da;
4994}
4995
4996Double_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)
4997{
5045
5046 Double_t dang=-999;
5047 dt=1.e30;
5048 if (diftheta) *diftheta=-999;
5049 if (difphi) *difphi=-999;
5050
5051 if (!i || !j) return dang;
5052 if ((i>0 || j>0) && !fRefs) return dang;
5053 if ((i<0 || j<0) && !fSigs) return dang;
5054
5055 // If needed, initialise the randomiser with a "date/time driven" seed
5056 // using the timestamp of the moment of this invokation of the member function.
5057 // This will ensure different random sequences if the user repeats analyses
5058 // with identical measurements and reference signals without explicit initialisation
5059 // of the randomiser by the user at the start of the analysis.
5060 if (!fRan && (fRscmode>0 || fTscmode>0)) fRan=new NcRandom(-1);
5061
5062 Int_t itype=0;
5063 if (i<0)
5064 {
5065 itype=1;
5066 i=abs(i);
5067 }
5068
5069 Int_t jtype=0;
5070 if (j<0)
5071 {
5072 jtype=1;
5073 j=abs(j);
5074 }
5075
5076 Nc3Vector ri; // Position of the i-th signal
5077 Nc3Vector rj; // Position of the j-th signal
5078 NcSignal* si=0; // Link to the stored i-th signal
5079 NcSignal* sj=0; // Link to the stored j-th signal
5080 NcTimestamp* ti=0; // Link to the timestamp of the i-th signal
5081 NcTimestamp* tj=0; // Link to the timestamp of the j-th signal
5082
5083 si=GetSignal(i,itype);
5084 sj=GetSignal(j,jtype);
5085 if (!si || !sj) return dang;
5086
5087 ti=si->GetTimestamp();
5088 tj=sj->GetTimestamp();
5089 if (!ti || !tj) return dang;
5090
5091 Int_t reftype=0;
5092 Int_t evttype=0;
5093 Int_t idxref=0;
5094 Int_t idxevt=0;
5095 NcSignal* sxref=0; // Link to the stored reference signal
5096 NcTimestamp* txref=0; // Link to the timestamp of the reference signal
5097 NcTimestamp* txevt=0; // Link to the timestamp of the measurement signal
5098 Nc3Vector rxref; // Position of the reference signal
5099 Nc3Vector rxevt; // Position of the measurement signal
5100
5101 if (itype==jtype) // Self correlations
5102 {
5103 reftype=itype;
5104 idxref=i;
5105 sxref=si;
5106 txref=ti;
5107 evttype=jtype;
5108 idxevt=j;
5109 txevt=tj;
5110 }
5111 else // Correlations between sources and measurements
5112 {
5113 if (itype)
5114 {
5115 evttype=itype;
5116 idxevt=i;
5117 txevt=ti;
5118 reftype=jtype;
5119 idxref=j;
5120 sxref=sj;
5121 txref=tj;
5122 }
5123 else
5124 {
5125 reftype=itype;
5126 idxref=i;
5127 sxref=si;
5128 txref=ti;
5129 evttype=jtype;
5130 idxevt=j;
5131 txevt=tj;
5132 }
5133 }
5134
5135 // Update the location and timestamp in case of a Solar system reference object
5136 TString name=sxref->GetName();
5137 if (SetSolarSystem(name,txevt,reftype)) txref=sxref->GetTimestamp();
5138
5139 // Local variables to act on requested scrambling
5140 Int_t Tscmode=fTscmode;
5141 Int_t Rscmode=fRscmode;
5142
5143 // Create scrambled background patch data even when also the on-source data are scrambled
5144 if (bkgpatch)
5145 {
5146 Tscmode=-abs(fTscmode);
5147 Rscmode=-abs(fRscmode);
5148 }
5149
5150 // Apply time scrambling of the date/time of the observation if requested
5151 NcTimestamp txtmp(*txevt);
5152 Double_t trndm=0;
5153 if (Tscmode==1 || Tscmode==3 || (Tscmode<0 && bkgpatch))
5154 {
5155 if (!fTscfunc)
5156 {
5157 trndm=fRan->Uniform(fTscmin,fTscmax);
5158 }
5159 else
5160 {
5161 trndm=fTscfunc->GetRandom(fTscmin,fTscmax);
5162 }
5163 // Creating a fake scrambled timestamp
5164 if (Tscmode==3 || (abs(Tscmode)>1 && bkgpatch)) txtmp.AddSec(trndm);
5165 }
5166
5167 // Obtain the (scrambled) time difference
5168 if (Tscmode==1 || (Tscmode==-1 && bkgpatch)) // Only provide a random time difference
5169 {
5170 if (tu=="d")
5171 {
5172 trndm/=double(24*3600);
5173 }
5174 if (tu=="ns")
5175 {
5176 trndm*=1.e9;
5177 trndm*=1.e9;
5178 }
5179 if (tu=="ps")
5180 {
5181 trndm*=1.e12;
5182 trndm*=1.e12;
5183 }
5184 dt=trndm;
5185 }
5186 else // Determine the time difference w.r.t. the fake timestamp of the measurement
5187 {
5188 dt=txref->GetDifference(&txtmp,tu,mode);
5189 }
5190
5191 // Update the location of Solar system objects if needed
5192 name=sxref->GetName();
5193 SetSolarSystem(name,&txtmp,reftype);
5194
5195 // Get the original measurement position and (time modified) reference position in local coordinates
5196 GetSignal(rxevt,"loc","T",txevt,idxevt,evttype);
5197 GetSignal(rxref,"loc","T",&txtmp,idxref,reftype);
5198
5199 // Apply position scrambling of the measurement if requested
5200 Double_t pi=acos(-1.);
5201 Float_t cosmin=0;
5202 Float_t cosmax=0;
5203 Double_t cosang=0;
5204 Double_t vec[3];
5205 Double_t dd=0;
5206 Double_t dtheta=0;
5207 Double_t dphi=0;
5208
5209 if (Rscmode==1 || (Rscmode==-1 && bkgpatch)) // Only provide a random angular separation
5210 {
5211 if (!fDscfunc)
5212 {
5213 cosmin=cos(fDscmin*pi/180.);
5214 cosmax=cos(fDscmax*pi/180.);
5215 if (cosmin>cosmax)
5216 {
5217 Float_t temp=cosmin;
5218 cosmin=cosmax;
5219 cosmax=temp;
5220 }
5221 cosang=fRan->Uniform(cosmin,cosmax);
5222 dang=acos(cosang);
5223 if (au=="deg") dang*=180./pi;
5224 }
5225 else
5226 {
5227 dang=fDscfunc->GetRandom(fDscmin,fDscmax);
5228 if (au=="rad") dang*=pi/180.;
5229 }
5230 }
5231 else // Create a fake local position for the measurement
5232 {
5233 if (Rscmode==3 || (abs(Rscmode)>1 && bkgpatch))
5234 {
5235 rxevt.GetVector(vec,"sph","deg");
5236
5237 // Allow specific offset studies
5238 if (fDscmin==fDscmax) dd=fDscmin;
5239 if (fThetascmin==fThetascmax) dtheta=fThetascmin;
5240 if (fPhiscmin==fPhiscmax) dphi=fPhiscmin;
5241
5242 // Go for randomly scrambled values
5243 if (fDscfunc)
5244 {
5245 if (fDscmax>fDscmin)
5246 {
5247 dd=fDscfunc->GetRandom(fDscmin,fDscmax);
5248 }
5249 }
5250 else
5251 {
5252 if (fDscmax>fDscmin) dd=fRan->Uniform(fDscmin,fDscmax);
5253 }
5254
5255 if (fThetascfunc)
5256 {
5258 {
5259 dtheta=fThetascfunc->GetRandom(fThetascmin,fThetascmax);
5260 }
5261 }
5262 else if (fThetascmax>fThetascmin)
5263 {
5264 cosmin=cos(fThetascmin*pi/180.);
5265 cosmax=cos(fThetascmax*pi/180.);
5266 if (cosmin>cosmax)
5267 {
5268 Float_t temp=cosmin;
5269 cosmin=cosmax;
5270 cosmax=temp;
5271 }
5272 cosang=fRan->Uniform(cosmin,cosmax);
5273 dtheta=acos(cosang)*180./pi;
5274 }
5275
5276 if (fPhiscfunc)
5277 {
5278 if (fPhiscmax>fPhiscmin)
5279 {
5280 dphi=fPhiscfunc->GetRandom(fPhiscmin,fPhiscmax);
5281 }
5282 }
5283 else
5284 {
5285 if (fPhiscmax>fPhiscmin) dphi=fRan->Uniform(fPhiscmin,fPhiscmax);
5286 }
5287
5288 vec[0]+=dd;
5289 if (vec[0]<=0) vec[0]=1e-20; // Keep a physical situation
5290 vec[1]+=dtheta;
5291 vec[2]+=dphi;
5292 rxevt.SetVector(vec,"sph","deg");
5293 }
5294
5295 dang=rxref.GetOpeningAngle(rxevt,au);
5296 }
5297
5298 // Determine the difference in local theta and phi
5299 Double_t refvec[3];
5300 rxevt.GetVector(vec,"sph",au);
5301 rxref.GetVector(refvec,"sph",au);
5302 dtheta=vec[1]-refvec[1];
5303 dphi=vec[2]-refvec[2];
5304 if (diftheta) *diftheta=dtheta;
5305 if (difphi) *difphi=dphi;
5306
5307 return dang;
5308}
5309
5310Double_t NcAstrolab::GetDifference(TString name,TString au,Double_t& dt,TString tu,Int_t mode)
5311{
5346
5347 Double_t dang=999;
5348 dt=1.e30;
5349
5350 Int_t j=GetSignalIndex(name);
5351
5352 if (j==-1) // Set and store info for the requested Solar system object if not already stored
5353 {
5354 SetSolarSystem(name,0);
5355 j=GetSignalIndex(name);
5356 }
5357
5358 if (j>0) dang=GetDifference(j,au,dt,tu,mode);
5359 return dang;
5360}
5361
5362TArrayI* NcAstrolab::MatchRefSignal(Double_t da,TString au,Double_t dt,TString tu,Int_t mode)
5363{
5392
5393 if (!fSigs || !fRefs) return 0;
5394
5395 NcDevice matches;
5396 MatchSignals(matches,da,au,dt,tu,mode,1,0,0,1,1,1); // Perform the obsolete MatchRefSignal() action
5397
5398 Int_t nhits=matches.GetNhits();
5399 if (!nhits) return 0;
5400
5401 if (fIndices) delete fIndices;
5402 fIndices=new TArrayI(nhits);
5403
5404 Int_t index=0;
5405 NcSignal* sx=0;
5406 Int_t jfill=0;
5407 for (Int_t i=1; i<=nhits; i++)
5408 {
5409 sx=matches.GetHit(i);
5410
5411 if(!sx) continue;
5412
5413 index=sx->GetSignal("index1");
5414 fIndices->AddAt(index,jfill);
5415 jfill++;
5416 }
5417
5418 fIndices->Set(jfill);
5419
5420 if (!jfill) return 0; // No match found
5421
5422 return fIndices;
5423}
5424
5425void 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)
5426{
5538
5539 // Initialize the Device/Hit structure to contain the correlation info
5540 matches.Reset(1);
5541 matches.SetHitCopy(1);
5542
5543 TString name="Matches";
5544 TString title="Space and time matchings of NcAstrolab stored signals";
5545 matches.SetNameTitle(name.Data(),title.Data());
5546 TString tux=tu;
5547 if (tu=="d") tux="days";
5548 if (tu=="s") tux="sec";
5549 TString namedamin="psimin in ";
5550 namedamin+=au;
5551 TString namedtmin="dtmin in ";
5552 namedtmin+=tux;
5553 matches.AddNamedSlot(namedamin);
5554 matches.AddNamedSlot(namedtmin);
5555 matches.AddNamedSlot("ipsi");
5556 matches.AddNamedSlot("idt");
5557
5558 NcSignal data;
5559 TString nameda="psi in ";
5560 nameda+=au;
5561 TString namedt="t2-t1 in ";
5562 namedt+=tux;
5563 data.AddNamedSlot("type1");
5564 data.AddNamedSlot("index1");
5565 data.AddNamedSlot("type2");
5566 data.AddNamedSlot("index2");
5567 data.AddNamedSlot(nameda);
5568 data.AddNamedSlot(namedt);
5569
5570 if ((!itype || !jtype) && !fRefs)
5571 {
5572 printf(" *%-s::MatchSignals* Error: itype=%-i jtype=%-i but no reference signals are present. \n",ClassName(),itype,jtype);
5573 return;
5574 }
5575
5576 if ((itype || jtype) && !fSigs)
5577 {
5578 printf(" *%-s::MatchSignals* Error: itype=%-i jtype=%-i but no measurements are present. \n",ClassName(),itype,jtype);
5579 return;
5580 }
5581
5582 Int_t nrefs=0;
5583 if (fRefs) nrefs=fRefs->GetSize();
5584 Int_t nsigs=0;
5585 if (fSigs) nsigs=fSigs->GetSize();
5586
5587
5588 // Make input data consistent with conventions
5589 if (itype) itype=1;
5590 if (jtype) jtype=1;
5591 if (!itype)
5592 {
5593 if (i2<1 || i2>nrefs) i2=nrefs;
5594 }
5595 else
5596 {
5597 if (i2<1 || i2>nsigs) i2=nsigs;
5598 }
5599 if (!jtype)
5600 {
5601 if (j2<1 || j2>nrefs) j2=nrefs;
5602 }
5603 else
5604 {
5605 if (j2<1 || j2>nsigs) j2=nsigs;
5606 }
5607
5608 if (i1<1 || j1<1 || i1>i2 || j1>j2)
5609 {
5610 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);
5611 return;
5612 }
5613
5614 Double_t dang,dtime;
5615 Int_t ix=0;
5616 Int_t jx=0;
5617 NcSignal* sx=0;
5618 Int_t id=0;
5619 Double_t dangmin=0;
5620 Double_t dtmin=0;
5621 Int_t idamin=0;
5622 Int_t idtmin=0;
5623 Bool_t first=kTRUE;
5624 for (Int_t i=i1; i<=i2; i++)
5625 {
5626 ix=i;
5627 if (itype) ix=-i;
5628
5629 for (Int_t j=j1; j<=j2; j++)
5630 {
5631 // Skip matching a signal with itself
5632 if (itype==jtype && i==j) continue;
5633
5634 jx=j;
5635 if (jtype) jx=-j;
5636
5637 dang=GetSeparation(ix,jx,au,dtime,tu,mode,0);
5638
5639 if ((fabs(dang)<=da || da<0) && (fabs(dtime)<=dt || dt<0))
5640 {
5641 data.Reset();
5642 name="Object1=";
5643 sx=GetSignal(i,itype);
5644 if (!sx) continue;
5645 name+=sx->GetName();
5646 title="Object2=";
5647 sx=GetSignal(j,jtype);
5648 if (!sx) continue;
5649 title+=sx->GetName();
5650 id++;
5651 data.SetNameTitle(name.Data(),title.Data());
5652 data.SetUniqueID(id);
5653 data.SetSignal(itype,"type1");
5654 data.SetSignal(i,"index1");
5655 data.SetSignal(jtype,"type2");
5656 data.SetSignal(j,"index2");
5657 data.SetSignal(dtime,namedt);
5658 data.SetSignal(dang,nameda);
5659 matches.AddHit(data);
5660
5661 // Record the data for the minimal encountered opening angle
5662 if (first || fabs(dang)<dangmin)
5663 {
5664 dangmin=fabs(dang);
5665 idamin=id;
5666 }
5667
5668 // Record the data for the minimal encountered time difference
5669 if (first || fabs(dtime)<fabs(dtmin))
5670 {
5671 dtmin=dtime;
5672 idtmin=id;
5673 }
5674
5675 first=kFALSE;
5676 }
5677 }
5678 }
5679
5680 // Store the data for the minimal encountered opening angle and time difference
5681 matches.SetSignal(dangmin,namedamin);
5682 matches.SetSignal(dtmin,namedtmin);
5683 matches.SetSignal(idamin,"ipsi");
5684 matches.SetSignal(idtmin,"idt");
5685}
5686
5687void 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)
5688{
5798
5799 Int_t i=GetSignalIndex(name,itype);
5800
5801 if (i==-1) // Add the info for the requested Solar system object if not already stored
5802 {
5803 SetSolarSystem(name,0,itype);
5804 i=GetSignalIndex(name,itype);
5805 if (i>0) fSolUpdate=1;
5806 }
5807
5808 if (i<1)
5809 {
5810 printf(" *%-s::MatchSignals* Object %-s not found for itype=%-i. \n",ClassName(),name.Data(),itype);
5811 }
5812 else
5813 {
5814 MatchSignals(matches,da,au,dt,tu,mode,i,i,itype,j1,j2,jtype);
5815 }
5816
5817 fSolUpdate=0;
5818}
5819
5820void NcAstrolab::SetTimeScramble(Int_t mode,Double_t tmin,Double_t tmax,TF1* frndm)
5821{
5891
5892 fTscmode=mode;
5893 fTscmin=tmin;
5894 fTscmax=tmax;
5895 if (fTscfunc)
5896 {
5897 delete fTscfunc;
5898 fTscfunc=0;
5899 }
5900 if (frndm)
5901 {
5902 fTscfunc=new TF1(*frndm);
5903 if (tmax>tmin) fTscfunc->SetRange(tmin,tmax);
5904 }
5905}
5906
5907Int_t NcAstrolab::GetTimeScramble(Double_t* tmin,Double_t* tmax,TF1* frndm)
5908{
5938
5939 if (tmin) *tmin=fTscmin;
5940 if (tmax) *tmax=fTscmax;
5941 if (frndm) *frndm=*fTscfunc;
5942
5943 return fTscmode;
5944}
5945
5946void 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)
5947{
6025
6026 // Keep parameters within physical bounds for angular difference scrambling (mode=1)
6027 if (abs(mode)==1 && dmin<0) dmin=0;
6028 if (abs(mode)==1 && dmax>180) dmax=180;
6029
6030 // Check for specific requested offsets
6031 if (dmax<dmin) dmax=dmin;
6032 if (thmax<thmin) thmax=thmin;
6033 if (phimax<phimin) phimax=phimin;
6034
6035 fRscmode=mode;
6036 fDscmin=dmin;
6037 fDscmax=dmax;
6038 if (fDscfunc)
6039 {
6040 delete fDscfunc;
6041 fDscfunc=0;
6042 }
6043 if (df)
6044 {
6045 fDscfunc=new TF1(*df);
6046 if (dmax>dmin) fDscfunc->SetRange(dmin,dmax);
6047 }
6048 fThetascmin=thmin;
6049 fThetascmax=thmax;
6050 if (fThetascfunc)
6051 {
6052 delete fThetascfunc;
6053 fThetascfunc=0;
6054 }
6055 if (thf)
6056 {
6057 fThetascfunc=new TF1(*thf);
6058 if (thmax>thmin) fThetascfunc->SetRange(thmin,thmax);
6059 }
6060 fPhiscmin=phimin;
6061 fPhiscmax=phimax;
6062 if (fPhiscfunc)
6063 {
6064 delete fPhiscfunc;
6065 fPhiscfunc=0;
6066 }
6067 if (phif)
6068 {
6069 fPhiscfunc=new TF1(*phif);
6070 if (phimax>phimin) fPhiscfunc->SetRange(phimin,phimax);
6071 }
6072}
6073
6074Int_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)
6075{
6111
6112 if (dmin) *dmin=fDscmin;
6113 if (dmax) *dmax=fDscmax;
6114 if (df) *df=*fDscfunc;
6115 if (thmin) *thmin=fThetascmin;
6116 if (thmax) *thmax=fThetascmax;
6117 if (thf) *thf=*fThetascfunc;
6118 if (phimin) *phimin=fPhiscmin;
6119 if (phimax) *phimax=fPhiscmax;
6120 if (phif) *phif=*fPhiscfunc;
6121
6122 return fRscmode;
6123}
6124
6125void NcAstrolab::DisplaySignal(TString frame,TString mode,NcTimestamp* ts,Int_t j,TString proj,Int_t clr,TString name)
6126{
6225
6226 // Comply with the new (jref,type) convention for measurements and reference signals.
6227 Int_t jref=abs(j);
6228 Int_t type=0;
6229 if (j<=0) type=1;
6230 if (!j) jref=1;
6231
6232 NcSignal* sx=0;
6233
6234 if (!ts)
6235 {
6236 sx=GetSignal(jref,type);
6237 if (!sx) return;
6238 ts=sx->GetTimestamp();
6239 }
6240
6241 Nc3Vector r;
6242 sx=GetSignal(r,frame,mode,ts,jref,type);
6243
6244 if (!sx) return;
6245
6246 // Save name and timestamp to enable timestamp restoration for Solar system objects
6247 // after a Day View or Year View display
6248 TString namesave=sx->GetName();
6249 NcTimestamp tsave=(*ts);
6250
6251 // The generic input angles (in rad) for the projections
6252 Double_t theta=0;
6253 Double_t phi=0;
6254
6255 Double_t pi=acos(-1.);
6256
6257 if (frame=="equ" || frame=="gal" || frame=="icr" || frame=="ecl" || frame=="loc")
6258 {
6259 theta=(pi/2.)-r.GetX(2,"sph","rad");
6260 phi=r.GetX(3,"sph","rad");
6261 }
6262
6263 if (frame=="hor")
6264 {
6265 theta=(pi/2.)-r.GetX(2,"sph","rad");
6266 phi=pi-r.GetX(3,"sph","rad");
6267 }
6268
6269 // Automatic choice of central meridian if not selected by the user
6270 if (!fUsMeridian || abs(fUsMeridian)>1)
6271 {
6272 if (frame=="equ")
6273 {
6274 fMeridian=pi;
6275 fUsMeridian=-2;
6276 }
6277 if (frame=="gal" || frame=="icr" || frame=="ecl")
6278 {
6279 fMeridian=0;
6280 fUsMeridian=-2;
6281 }
6282 if (frame=="hor" || frame=="loc")
6283 {
6284 fMeridian=0;
6285 fUsMeridian=2;
6286 }
6287 }
6288
6289 // Obtain the projected (x,y) position
6290 Double_t x=0;
6291 Double_t y=0;
6292 Project(phi,theta,proj,x,y);
6293
6294 // X-axis inversion of the display
6295 if (fUsMeridian<0) x*=-1.;
6296
6297 Int_t hist=0;
6298 if (proj=="hamh" || proj=="aith" || proj=="merh" || proj=="cylh" || proj=="angh") hist=1;
6299 if (proj=="UTh" || proj=="LTh" || proj=="GSTh" || proj=="LSTh") hist=1;
6300 if (proj=="UYh" || proj=="LYh" || proj=="GSYh" || proj=="LSYh") hist=1;
6301
6302 // Update the display for this signal position
6303
6304 // Create a new canvas if needed
6305 if (!fCanvas || !(gROOT->GetListOfCanvases()->FindObject("NcAstrolab"))) fCanvas=new TCanvas("NcAstrolab","Skymap");
6306
6307 // Construct the various strings for this map
6308 TString titleup; // The upper title string
6309 TString titlelow; // The lower title string
6310 TString sleft; // The most left coordinate indicator
6311 TString sright; // The most right coordinate indicator
6312 TString sup; // The most upper coordinate indicator
6313 TString slow; // The most lower coordinate indicator
6314 sup="90#circ";
6315 slow="-90#circ";
6316 if (name!="")
6317 {
6318 titleup=name;
6319 titleup+=" ";
6320 }
6321 if (frame=="equ")
6322 {
6323 titleup+="Geocentric Equatorial (";
6324 titleup+=mode;
6325 if (mode=="J") titleup+="2000";
6326 if (mode=="B") titleup+="1950";
6327 titleup+=") ";
6328 }
6329 if (frame=="gal") titleup+="Heliocentric Galactic";
6330 if (frame=="ecl") titleup+=" Geocentric Ecliptic";
6331 if (frame=="hor") titleup+=" Standard Horizon";
6332 if (frame=="icr") titleup+="Static Barycentric ICRS";
6333 if (frame=="loc")
6334 {
6335 titleup+=" User defined Local";
6336 sup=" 0#circ";
6337 slow="180#circ";
6338 }
6339 titleup+=" Coordinates";
6340 titlelow="Projection : ";
6341 if (proj=="ham" || proj=="hamh") titlelow+="Hammer";
6342 if (proj=="cyl" || proj=="cylh") titlelow+="Cylindrical";
6343 if (proj=="ait" || proj=="aith") titlelow+="Aitoff";
6344 if (proj=="mer" || proj=="merh") titlelow+="Mercator";
6345 if (proj=="ang" || proj=="angh")
6346 {
6347 titlelow+="sin(b) vs. l";
6348 sup=" 1";
6349 slow=" -1";
6350 }
6351 titlelow+=" Central Meridian : ";
6352 Int_t ang,h,m,s,d;
6353 Int_t angmax,hmin,hmax,dmin,dmax;
6354 TString corr;
6355 TString scenter="";
6356 if (frame=="equ")
6357 {
6358 ang=int(ConvertAngle(fMeridian,"rad","hms"));
6359 angmax=ang+120000;
6360 h=ang/10000;
6361 ang=ang%10000;
6362 m=ang/100;
6363 s=ang%100;
6364 titlelow+=h;
6365 titlelow+="h ";
6366 titlelow+=m;
6367 titlelow+="m ";
6368 titlelow+=s;
6369 titlelow+="s";
6370 hmax=angmax/10000;
6371 corr="";
6372 while (hmax>24)
6373 {
6374 hmax-=24;
6375 corr="+";
6376 }
6377 hmin=hmax-24;
6378 while (hmin<-12)
6379 {
6380 hmin+=24;
6381 corr="+";
6382 }
6383 sright+=corr;
6384 if (fUsMeridian<0)
6385 {
6386 sright+=hmin;
6387 }
6388 else
6389 {
6390 sright+=hmax;
6391 }
6392 sright+="h";
6393 if (fUsMeridian<0)
6394 {
6395 sleft+=hmax;
6396 }
6397 else
6398 {
6399 sleft+=hmin;
6400 }
6401 sleft+="h";
6402 scenter+=h;
6403 scenter+="h";
6404 }
6405 else
6406 {
6407 ang=int(ConvertAngle(fMeridian,"rad","dms"));
6408 angmax=ang+1800000;
6409 d=ang/10000;
6410 ang=ang%10000;
6411 m=ang/100;
6412 s=ang%100;
6413 titlelow+=d;
6414 titlelow+="d ";
6415 titlelow+=m;
6416 titlelow+="' ";
6417 titlelow+=s;
6418 titlelow+="\"";
6419 dmax=angmax/10000;
6420 corr="";
6421 while (dmax>360)
6422 {
6423 dmax-=360;
6424 corr="+";
6425 }
6426 dmin=dmax-360;
6427 while (dmin<-180)
6428 {
6429 dmin+=360;
6430 corr="+";
6431 }
6432 sright+=corr;
6433 if (fUsMeridian<0)
6434 {
6435 sright+=dmin;
6436 }
6437 else
6438 {
6439 sright+=dmax;
6440 }
6441 sright+="#circ";
6442 if (fUsMeridian<0)
6443 {
6444 sleft+=dmax;
6445 }
6446 else
6447 {
6448 sleft+=dmin;
6449 }
6450 sleft+="#circ";
6451 scenter+=d;
6452 scenter+="#circ";
6453 }
6454
6455 if (!hist) // 2-D Marker display (i.e. not a histogram)
6456 {
6457 TMarker* marker=0;
6458 // Remove existing markers, grid and outline from display if needed
6459 if (clr==1 || proj!=fProj)
6460 {
6461 if (fMarkers)
6462 {
6463 delete fMarkers;
6464 fMarkers=0;
6465 }
6466 fCanvas->Clear();
6467 fProj=proj;
6468 }
6469
6470 // Create a new display if needed
6471 if (!fMarkers)
6472 {
6473 fMarkers=new TObjArray();
6474 fMarkers->SetOwner();
6475
6476 // Set canvas range, header and axes
6477 Float_t xup=2; // Maximal x coordinate of the projection
6478 Float_t yup=1; // maximal y coordinate of the projection
6479 Float_t xlow=-xup;
6480 Float_t ylow=-yup;
6481 Float_t xmargin=0.5; // X margin for canvas size
6482 Float_t ymargin=0.3; // Y margin for canvas size
6483 fCanvas->Range(xlow-xmargin,ylow-ymargin,xup+xmargin,yup+ymargin);
6484
6485 // The ellipse outline with the skymap c.q. projection grid
6486 if (proj=="ham" || proj=="ait")
6487 {
6488 // Draw ellips outline
6489 TEllipse* outline=new TEllipse(0,0,xup,yup);
6490 fMarkers->Add(outline);
6491 outline->Draw();
6492 }
6493
6495 // Draw the skymap c.q. projection grid //
6497
6498 // Drawing of the projected meridians every 30 degrees
6499 const Int_t nphi=13;
6500 Double_t gphiarr[nphi]={0,30,60,90,120,150,180,210,240,270,300,330,360};
6501 Double_t gphi=0;
6502 Double_t gtheta=0;
6503 Int_t ndots=100;
6504 Float_t gstep=180./float(ndots);
6505 Double_t xgrid=0;
6506 Double_t ygrid=0;
6507 for (Int_t iph=0; iph<nphi; iph++)
6508 {
6509 gphi=gphiarr[iph]*pi/180.;
6510 if (frame=="hor") gphi=pi-gphi;
6511 gtheta=pi/2.;
6512 for (Int_t ith=1; ith<ndots; ith++)
6513 {
6514 gtheta=gtheta-(gstep*pi/180.);
6515 Project(gphi,gtheta,proj,xgrid,ygrid);
6516 marker=new TMarker(xgrid,ygrid,fMarkerStyle[3]);
6517 marker->SetMarkerSize(fMarkerSize[3]);
6518 marker->SetMarkerColor(fMarkerColor[3]);
6519 fMarkers->Add(marker);
6520 marker->Draw();
6521 }
6522 }
6523
6524 // Drawing of the projected latitude circles every 15 degrees
6525 const Int_t nth=10;
6526 Double_t gtharr[nth]={15,30,45,60,75,105,120,135,150,165};
6527 gphi=0;
6528 gtheta=0;
6529 gstep=360./float(ndots);
6530 TString gs;
6531 Int_t igs=0;
6532 TLatex* lgs=0;
6533 Double_t xtext=0;
6534 Double_t ytext=0;
6535 for (Int_t ith=0; ith<nth; ith++)
6536 {
6537 gtheta=pi/2.-(gtharr[ith]*pi/180.);
6538 igs=int(90.-gtharr[ith]);
6539 if (frame=="loc") igs=int(gtharr[ith]);
6540 gs="";
6541 gs+=igs;
6542 gs+="#circ";
6543 xtext=0;
6544 for (Int_t iphi=1; iphi<ndots; iphi++)
6545 {
6546 gphi=gphi+gstep;
6547 Project(gphi,gtheta,proj,xgrid,ygrid);
6548 marker=new TMarker(xgrid,ygrid,fMarkerStyle[3]);
6549 marker->SetMarkerSize(fMarkerSize[3]);
6550 marker->SetMarkerColor(fMarkerColor[3]);
6551 if (xgrid<xtext)
6552 {
6553 xtext=xgrid;
6554 ytext=ygrid;
6555 }
6556 fMarkers->Add(marker);
6557 marker->Draw();
6558 }
6559 lgs=new TLatex;
6560 fMarkers->Add(lgs);
6561 if (ytext>0)
6562 {
6563 if (proj=="ham" || proj=="ait")
6564 {
6565 lgs->DrawLatex(xtext-0.25,ytext,gs.Data());
6566 }
6567 else
6568 {
6569 lgs->DrawLatex(xtext-0.4,ytext-0.02,gs.Data());
6570 }
6571 }
6572 else
6573 {
6574 if (proj=="ham" || proj=="ait")
6575 {
6576 lgs->DrawLatex(xtext-0.3,ytext-0.1,gs.Data());
6577 }
6578 else
6579 {
6580 lgs->DrawLatex(xtext-0.4,ytext-0.02,gs.Data());
6581 }
6582 }
6583 }
6584
6585 // The horizontal and vertical axes
6586 TLine* line=new TLine(xlow,0,xup,0);
6587 fMarkers->Add(line);
6588 line->Draw();
6589 line=new TLine(0,yup,0,ylow);
6590 fMarkers->Add(line);
6591 line->Draw();
6592
6593 // The header and footer text
6594 TLatex* header=new TLatex;
6595 fMarkers->Add(header);
6596 header->SetTextAlign(21); // Text will be horizontally centered
6597 header->DrawLatex(0,yup+0.2,titleup.Data());
6598 TLatex* footer=new TLatex;
6599 fMarkers->Add(footer);
6600 footer->SetTextAlign(21); // Text will be horizontally centered
6601 footer->DrawLatex(0,ylow-0.25,titlelow.Data());
6602
6603 // The left side angular value indicator
6604 TLatex* left=new TLatex;
6605 fMarkers->Add(left);
6606 if (proj=="ham" || proj=="ait")
6607 {
6608 left->DrawLatex(xlow-0.4,0,sleft.Data());
6609 }
6610 else
6611 {
6612 left->DrawLatex(xlow-0.15,yup+0.05,sleft.Data());
6613 }
6614 // The right side angular value indicator
6615 TLatex* right=new TLatex;
6616 fMarkers->Add(right);
6617 if (proj=="ham" || proj=="ait")
6618 {
6619 right->DrawLatex(xup+0.1,0,sright.Data());
6620 }
6621 else
6622 {
6623 right->DrawLatex(xup-0.1,yup+0.05,sright.Data());
6624 }
6625 // The upper angular value indicator
6626 TLatex* up=new TLatex;
6627 fMarkers->Add(up);
6628 if (proj=="ham" || proj=="ait")
6629 {
6630 up->DrawLatex(-0.1,yup+0.05,sup.Data());
6631 }
6632 else
6633 {
6634 up->DrawLatex(-0.1,yup+0.05,scenter.Data());
6635 if (proj!="ang")
6636 {
6637 up=new TLatex;
6638 fMarkers->Add(up);
6639 up->DrawLatex(xlow-0.4,yup-0.04,sup.Data());
6640 }
6641 }
6642 // The lower angular value indicator
6643 TLatex* low=new TLatex;
6644 fMarkers->Add(low);
6645 if (proj=="ham" || proj=="ait")
6646 {
6647 low->DrawLatex(-0.15,ylow-0.15,slow.Data());
6648 }
6649 else
6650 {
6651 if (proj!="ang") low->DrawLatex(xlow-0.4,ylow,slow.Data());
6652 }
6653
6655 // Indicate the Galactic Center //
6657
6658 // Add the Galactic Center temporarily as a reference signal for coordinate retrieval
6659 sx=SetSignal(1,0,"deg",0,"deg","gal",0,-1,"J","GC",0);
6660 Int_t idx=fRefs->IndexOf(sx);
6661 idx++;
6662 Nc3Vector rgc;
6663 sx=GetSignal(rgc,frame,mode,ts,idx,0);
6664 if (sx)
6665 {
6666 Double_t thetagc=0;
6667 Double_t phigc=0;
6668 if (frame=="equ" || frame=="gal" || frame=="icr" || frame=="ecl" || frame=="loc")
6669 {
6670 thetagc=(pi/2.)-rgc.GetX(2,"sph","rad");
6671 phigc=rgc.GetX(3,"sph","rad");
6672 }
6673 if (frame=="hor")
6674 {
6675 thetagc=(pi/2.)-rgc.GetX(2,"sph","rad");
6676 phigc=pi-rgc.GetX(3,"sph","rad");
6677 }
6678 // Obtain the projected (x,y) position
6679 Double_t xgc=0;
6680 Double_t ygc=0;
6681 Project(phigc,thetagc,proj,xgc,ygc);
6682 if (fUsMeridian<0) xgc*=-1.;
6683 marker=new TMarker(xgc,ygc,fMarkerStyle[2]);
6684 marker->SetMarkerSize(fMarkerSize[2]);
6685 marker->SetMarkerColor(fMarkerColor[2]);
6686 fMarkers->Add(marker);
6687 marker->Draw();
6688 // Remove the temporary Galactic Center object again
6689 RemoveSignal(idx,0,0);
6690 }
6691 }
6692
6693 // Indicate the measurement(s) or reference signal(s) on the display
6694 marker=new TMarker(x,y,fMarkerStyle[type]);
6695 marker->SetMarkerSize(fMarkerSize[type]);
6696 marker->SetMarkerColor(fMarkerColor[type]);
6697 fMarkers->Add(marker);
6698 marker->Draw();
6699 }
6700 else if (hist==1) // 2-D display via histogram
6701 {
6702 Float_t xfac=90;
6703 Float_t yfac=90;
6704 if (frame=="equ") xfac=6;
6705 if (proj=="angh") yfac=1;
6706 // Reset the histogram if needed
6707 if (clr==1 || proj!=fProj || !fHist[type])
6708 {
6709 if (clr==1 || proj!=fProj)
6710 {
6711 fCanvas->Clear();
6712 fCanvas->SetGrid();
6713 for (Int_t i=0; i<2; i++)
6714 {
6715 if (fHist[i])
6716 {
6717 fHist[i]->Delete();
6718 fHist[i]=0;
6719 }
6720 }
6721 }
6722 if (!fHist[type]) fHist[type]=new TH2F();
6723 fHist[type]->Reset();
6724 fHist[type]->SetMarkerStyle(fMarkerStyle[type]);
6725 fHist[type]->SetMarkerSize(fMarkerSize[type]);
6726 fHist[type]->SetMarkerColor(fMarkerColor[type]);
6727 TString title=titleup;
6728 title+=" ";
6729 title+=titlelow;
6730 fHist[type]->SetNameTitle("SkyMap",title.Data());
6731 fHist[type]->GetXaxis()->SetTitle("Degrees from central Meridian");
6732 if (proj=="angh")
6733 {
6734 fHist[type]->SetBins(1000,-181,181,100,-1.1,1.1);
6735 fHist[type]->GetYaxis()->SetTitle("sin(b)");
6736 }
6737 else
6738 {
6739 fHist[type]->SetBins(1000,-181,181,500,-91,91);
6740 fHist[type]->GetYaxis()->SetTitle("Projected Latitude in degrees");
6741 }
6742 if (frame=="equ")
6743 {
6744 fHist[type]->GetXaxis()->SetTitle("Hours from central Meridian");
6745 if (proj=="angh")
6746 {
6747 fHist[type]->SetBins(200,-12.1,12.1,100,-1.1,1.1);
6748 if (frame=="equ") fHist[type]->GetYaxis()->SetTitle("sin(#delta)");
6749 }
6750 else
6751 {
6752 fHist[type]->SetBins(200,-12.1,12.1,500,-91,91);
6753 if (frame=="equ") fHist[type]->GetYaxis()->SetTitle("Projected Declination in degrees");
6754 }
6755 }
6756 if (frame=="hor")
6757 {
6758 if (proj=="angh")
6759 {
6760 fHist[type]->GetYaxis()->SetTitle("sin(alt)=cos(zenith)");
6761 }
6762 else
6763 {
6764 fHist[type]->GetYaxis()->SetTitle("Projected Altitude in degrees");
6765 }
6766 }
6767 if (frame=="loc")
6768 {
6769 if (proj=="angh")
6770 {
6771 fHist[type]->GetYaxis()->SetTitle("cos(#theta)=sin(b)");
6772 }
6773 else
6774 {
6775 fHist[type]->GetYaxis()->SetTitle("Projected degrees from the equator");
6776 }
6777 }
6778 fProj=proj;
6779 }
6780
6781 if (proj=="merh")
6782 {
6783 fHist[type]->Fill(x*xfac,theta*180./pi);
6784 }
6785 else if (proj=="hamh" || proj=="aith" || proj=="cylh" || proj=="angh")
6786 {
6787 fHist[type]->Fill(x*xfac,y*yfac);
6788 }
6789 else if (proj=="UTh" || proj=="LTh" || proj=="GSTh" || proj=="LSTh") // The 24 hour day view
6790 {
6791 // Set histogram binning and axes attributes
6792 fHist[type]->SetBins(100,0,24,181,-90.5,90.5);
6793 if (!ts) ts=(NcTimestamp*)this;
6794 NcTimestamp tx=(*ts);
6795 Double_t toffset=GetLabTimeOffset();
6796 TString title="Day view";
6797 if (name!="")
6798 {
6799 title+=" of ";
6800 title+=name;
6801 }
6802 title+=" at ";
6803 title+=GetName();
6804 title+=" on ";
6805 TString date;
6806 ts->GetDayTimeString("UT",0,0,&date);
6807 title+=date;
6808 TString tmode="UT";
6809 if (proj=="LTh") tmode="LMT";
6810 if (proj=="GSTh")
6811 {
6812 tmode="GMST";
6813 if (mode=="T") tmode="GAST";
6814 }
6815 if (proj=="LSTh")
6816 {
6817 tmode="LMST";
6818 if (mode=="T") tmode="LAST";
6819 }
6820 if (proj=="UTh") title+=";Universal Time";
6821 if (proj=="LTh") title+=";Local Time";
6822 if (proj=="GSTh") title+=";Greenwich Sidereal Time";
6823 if (proj=="LSTh") title+=";Local Sidereal Time";
6824 if (proj!="UTh")
6825 {
6826 title+=" (";
6827 title+=tmode;
6828 title+=")";
6829 }
6830 title+=" in hours;";
6831 TString ytitle="Declination ";
6832 if (frame=="equ" && mode=="J") ytitle+="(J2000)";
6833 if (frame=="equ" && mode=="B") ytitle+="(B1950)";
6834 if (frame=="equ" && mode=="M") ytitle+="(Mean)";
6835 if (frame=="equ" && mode=="T") ytitle+="(True)";
6836 if (frame=="gal") ytitle="Galactic latitude";
6837 if (frame=="ecl") ytitle="Geocentric Ecliptic latitude";
6838 if (frame=="hor") ytitle="Horizon altitude";
6839 if (frame=="icr") ytitle="ICRS latitude";
6840 if (frame=="loc") ytitle="Angle w.r.t. local frame equator";
6841 ytitle+=" in degrees";
6842 title+=ytitle;
6843 fHist[type]->SetTitle(title);
6844 fHist[type]->SetStats(kFALSE);
6845
6846 // Fill the day view histogram
6847 Double_t hour=0;
6848 Double_t d,a,b;
6849 for (Int_t i=0; i<24; i++)
6850 {
6851 if (tmode=="UT") hour=tx.GetUT();
6852 if (tmode=="LMT") hour=tx.GetLT(toffset);
6853 if (tmode=="GMST") hour=tx.GetGMST();
6854 if (tmode=="GAST") hour=tx.GetGAST();
6855 if (tmode=="LMST") hour=tx.GetLMST(toffset);
6856 if (tmode=="LAST") hour=tx.GetLAST(toffset);
6857
6858 // Get coordinates at this time step
6859 GetSignal(d,a,"deg",b,"deg",frame,&tx,jref,mode,type);
6860
6861 if (frame=="hor") b=90.-b;
6862 if (frame=="loc") b=90.-a;
6863
6864 fHist[type]->Fill(hour,b);
6865
6866 tx.Add(1); // Add 1 hour for each time step
6867 }
6868
6869 // Restore the original timestamp for Solar system objects
6870 SetSolarSystem(namesave,&tsave,type);
6871 }
6872 else if (proj=="UYh" || proj=="LYh" || proj=="GSYh" || proj=="LSYh") // The day of the year view
6873 {
6874 // Set histogram binning and axes attributes
6875 fHist[type]->SetBins(1500,0,370,181,-90.5,90.5);
6876 if (!ts) ts=(NcTimestamp*)this;
6877 NcTimestamp tx=(*ts);
6878 Double_t toffset=GetLabTimeOffset();
6879 TString year="";
6880 year+=int(ts->GetEpoch("J"));
6881 TString tmode="UT";
6882 if (proj=="LYh") tmode="LMT";
6883 if (proj=="GSYh")
6884 {
6885 tmode="GMST";
6886 if (mode=="T") tmode="GAST";
6887 }
6888 if (proj=="LSYh")
6889 {
6890 tmode="LMST";
6891 if (mode=="T") tmode="LAST";
6892 }
6893 TString time;
6894 if (proj=="UYh" || proj=="GSYh") ts->GetDayTimeString(tmode,0,0,0,&time);
6895 if (proj=="LYh" || proj=="LSYh") ts->GetDayTimeString(tmode,0,toffset,0,&time);
6896
6897 TString title="Year view";
6898 if (name!="")
6899 {
6900 title+=" of ";
6901 title+=name;
6902 }
6903 title+=" at ";
6904 title+=GetName();
6905 title+=" in ";
6906 title+=year;
6907 title+=" at ";
6908 title+=time;
6909 title+=";Day of the year;";
6910 TString ytitle="Declination ";
6911 if (frame=="equ" && mode=="J") ytitle+="(J2000)";
6912 if (frame=="equ" && mode=="B") ytitle+="(B1950)";
6913 if (frame=="equ" && mode=="M") ytitle+="(Mean)";
6914 if (frame=="equ" && mode=="T") ytitle+="(True)";
6915 if (frame=="gal") ytitle="Galactic latitude";
6916 if (frame=="ecl") ytitle="Geocentric Ecliptic latitude";
6917 if (frame=="hor") ytitle="Horizon altitude";
6918 if (frame=="icr") ytitle="ICRS latitude";
6919 if (frame=="loc") ytitle="Angle w.r.t. local frame equator";
6920 ytitle+=" in degrees";
6921 title+=ytitle;
6922 fHist[type]->SetTitle(title);
6923 fHist[type]->SetStats(kFALSE);
6924
6925 // Fill the year view histogram
6926 // Start at 01-jan 00:00:00h for the corresponding year at the selected location
6927 // and then set the time according to the specified timestamp
6928 Double_t hour=0;
6929 if (proj=="UYh" || proj=="GSYh") // Location is Greenwich
6930 {
6931 tx.SetUT(year.Atoi(),1,1,"00:00:00");
6932 hour=ts->GetUT();
6933 }
6934 if (proj=="LYh" || proj=="LSYh") // The lab location
6935 {
6936 tx.SetLT(toffset,year.Atoi(),1,1,"00:00:00");
6937 hour=ts->GetLT(toffset);
6938 }
6939 tx.Add(hour); // Set the selected time
6940
6941 Double_t d,a,b;
6942 Int_t day=0;
6943 for (Int_t i=0; i<367; i++)
6944 {
6945
6946 // Get coordinates at this time step
6947 GetSignal(d,a,"deg",b,"deg",frame,&tx,jref,mode,type);
6948
6949 if (frame=="hor") b=90.-b;
6950 if (frame=="loc") b=90.-a;
6951
6952 if (proj=="UYh" || proj=="GSYh") day=tx.GetDayOfYear();
6953 if (proj=="LYh" || proj=="LSYh") day=tx.GetDayOfYear(kFALSE,toffset);
6954
6955 fHist[type]->Fill(day,b);
6956
6957 tx.Add(24); // Add 1 day (= 24 hours) for each time step
6958 }
6959
6960 // Restore the original timestamp for Solar system objects
6961 SetSolarSystem(namesave,&tsave,type);
6962 }
6963
6964 // Draw the selected histogram
6965 if ((!type && fHist[1]) || (type && fHist[0]))
6966 {
6967 fHist[type]->Draw("same");
6968 }
6969 else
6970 {
6971 fHist[type]->Draw();
6972
6973 // Draw a horizontal thick line to mark the horizon c.q. equator for the day and year views
6974 if (proj=="UTh" || proj=="LTh" || proj=="GSTh" || proj=="LSTh" ||
6975 proj=="UYh" || proj=="LYh" || proj=="GSYh" || proj=="LSYh")
6976 {
6977 if (!fMarkers)
6978 {
6979 fMarkers=new TObjArray();
6980 fMarkers->SetOwner();
6981 }
6982 TLine* line=0;
6983 if (proj=="UTh" || proj=="LTh" || proj=="GSTh" || proj=="LSTh") line=new TLine(0,0,24,0);
6984 if (proj=="UYh" || proj=="LYh" || proj=="GSYh" || proj=="LSYh") line=new TLine(0,0,370,0);
6985 if (line)
6986 {
6987 line->SetLineWidth(3);
6988 fMarkers->Add(line);
6989 line->Draw();
6990 }
6991 }
6992 }
6993 }
6994}
6995
6996void NcAstrolab::DisplaySignal(TString frame,TString mode,NcTimestamp* ts,TString name,TString proj,Int_t clr,Int_t type)
6997{
7087
7088 // Create a signal for a solar system object if needed
7089 Double_t d,a,b;
7090 GetSignal(d,a,"deg",b,"deg",frame,ts,name,mode,type);
7091
7092 Int_t j=GetSignalIndex(name,type);
7093 if (j>0)
7094 {
7095 if (type) j=-j;
7096 DisplaySignal(frame,mode,ts,j,proj,clr,name);
7097 }
7098
7099 // Update the canvas so that the Skymap GUI immediately shows the result
7100 if (fCanvas) fCanvas->Update();
7101}
7102
7103void NcAstrolab::DisplaySignals(TString frame,TString mode,NcTimestamp* ts,TString proj,Int_t clr,Int_t nmax,Int_t j,Int_t type,TString name)
7104{
7199
7200 NcSignal* sx=0;
7201 TString namex="";
7202 NcTimestamp* tx=0;
7203 Int_t jdisp=0;
7204
7205 // Display stored reference signals
7206 if (fRefs && type<=0)
7207 {
7208 // Use timestamp of j-th measurement if requested
7209 if (j>0)
7210 {
7211 sx=GetSignal(j,1);
7212 if (sx) tx=sx->GetTimestamp();
7213 }
7214
7215 // Use the provided timestamp
7216 if (!j || !tx) tx=ts;
7217
7218 // Use the current lab timestamp if no timestamp selected
7219 if (!tx) tx=(NcTimestamp*)this;
7220
7221 jdisp=0;
7222 for (Int_t i=1; i<=fRefs->GetSize(); i++)
7223 {
7224 sx=GetSignal(i,0);
7225 if (!sx) continue;
7226
7227 jdisp++;
7228 if (nmax>=0 && jdisp>nmax) break;
7229
7230 // Check for the name pattern
7231 namex=sx->GetName();
7232 if (name!="*" && !namex.Contains(name)) continue;
7233
7234 // Use the actual timestamp of the reference signal
7235 if (j<0)
7236 {
7237 tx=sx->GetTimestamp();
7238 if (!tx) tx=ts;
7239 if (!tx) tx=(NcTimestamp*)this;
7240 }
7241
7242 if (name=="*")
7243 {
7244 DisplaySignal(frame,mode,tx,i,proj,clr);
7245 }
7246 else
7247 {
7248 DisplaySignal(frame,mode,tx,i,proj,clr,name);
7249 }
7250 clr=0; // No display clear for subsequent signals
7251 }
7252 }
7253
7254 // Display all stored measurements
7255 if (fSigs && type)
7256 {
7257 jdisp=0;
7258 for (Int_t j=1; j<=fSigs->GetSize(); j++)
7259 {
7260 sx=GetSignal(j,1);
7261 if (!sx) continue;
7262
7263 jdisp++;
7264 if (nmax>=0 && jdisp>nmax) break;
7265
7266 // Check for the name pattern
7267 namex=sx->GetName();
7268 if (name!="*" && !namex.Contains(name)) continue;
7269
7270 tx=sx->GetTimestamp();
7271 if (!tx) tx=ts;
7272 if (!tx) tx=(NcTimestamp*)this;
7273 if (name=="*")
7274 {
7275 DisplaySignal(frame,mode,tx,-j,proj,clr);
7276 }
7277 else
7278 {
7279 DisplaySignal(frame,mode,tx,-j,proj,clr,name);
7280 }
7281 clr=0; // No display clear for subsequent signals
7282 }
7283 }
7284
7285 // Update the canvas so that the Skymap GUI immediately shows the result
7286 if (fCanvas) fCanvas->Update();
7287}
7288
7289void NcAstrolab::SetMarkerSize(Float_t size,Int_t type)
7290{
7302
7303 if (type<0 || type >3) return;
7304
7305 fMarkerSize[type]=size;
7306}
7307
7308void NcAstrolab::SetMarkerStyle(Int_t style,Int_t type)
7309{
7321
7322 if (type<0 || type >3) return;
7323
7324 fMarkerStyle[type]=style;
7325}
7326
7327void NcAstrolab::SetMarkerColor(Int_t color,Int_t type)
7328{
7340
7341 if (type<0 || type >3) return;
7342
7343 fMarkerColor[type]=color;
7344}
7345
7346void NcAstrolab::SetCentralMeridian(Int_t mode,Double_t phi,TString u)
7347{
7371
7372 fMeridian=ConvertAngle(phi,u,"rad");
7373 fUsMeridian=0;
7374 if (mode>0) fUsMeridian=1;
7375 if (mode<0) fUsMeridian=-1;
7376 Double_t pi=acos(-1.);
7377 Double_t twopi=2.*pi;
7378 // Set range to 0 <= meridian < 2pi
7379 while (fMeridian>=twopi)
7380 {
7381 fMeridian-=twopi;
7382 }
7383 while (fMeridian<0)
7384 {
7385 fMeridian+=twopi;
7386 }
7387 // Prevent accuracy problems
7388 if (fMeridian>0) fMeridian+=1.e-6;
7389}
7390
7391void NcAstrolab::Project(Double_t l,Double_t b,TString proj,Double_t& x,Double_t& y)
7392{
7423
7424 Double_t pi=acos(-1.);
7425
7426 // Subtract central meridian from longitude
7427 l-=fMeridian;
7428
7429 // Take l between -180 and 180 degrees
7430 while (l>pi)
7431 {
7432 l-=2.*pi;
7433 }
7434 while (l<-pi)
7435 {
7436 l+=2.*pi;
7437 }
7438
7439 x=0;
7440 y=0;
7441
7442 // Convert (l,b) to (x,y) with -2 < x <= 2
7443 if (proj=="cyl" || proj=="cylh") ProjectCylindrical(l,b,x,y);
7444 if (proj=="ham" || proj=="hamh") ProjectHammer(l,b,x,y);
7445 if (proj=="ait" || proj=="aith") ProjectAitoff(l,b,x,y);
7446 if (proj=="mer" || proj=="merh") ProjectMercator(l,b,x,y);
7447 if (proj=="ang" || proj=="angh")
7448 {
7449 x=2.*l/pi;
7450 y=sin(b);
7451 }
7452}
7453
7454void NcAstrolab::ProjectCylindrical(Double_t l,Double_t b,Double_t& x, Double_t& y)
7455{
7464
7465 Double_t pi=acos(-1.);
7466 x=2.*l/pi;
7467 y=2.*b/pi;
7468}
7469
7470void NcAstrolab::ProjectHammer(Double_t l,Double_t b,Double_t& x,Double_t& y)
7471{
7481
7482 Double_t k=1./sqrt(1.+cos(b)*cos(l/2.));
7483 x=2.*k*cos(b)*sin(l/2.);
7484 y=k*sin(b);
7485}
7486
7487void NcAstrolab::ProjectAitoff(Double_t l,Double_t b,Double_t& x,Double_t& y)
7488{
7497
7498 Double_t pi=acos(-1.);
7499 x=0;
7500 y=0;
7501 Double_t k=acos(cos(b)*cos(l/2.));
7502 if(sin(k)!=0)
7503 {
7504 x=4.*k*cos(b)*sin(l/2.)/(pi*sin(k));
7505 y=2.*k*sin(b)/(pi*sin(k));
7506 }
7507}
7508
7509void NcAstrolab::ProjectMercator(Double_t l,Double_t b,Double_t& x,Double_t& y)
7510{
7525
7526 Double_t pi=acos(-1.);
7527 Double_t bcut=85.051*pi/180.; // Latitude cut off value in radians
7528
7529 x=2.*l/pi;
7530 y=0;
7531 if (b > bcut) b=bcut;
7532 if (b < -bcut) b=-bcut;
7533 y=0.5*log((1.+sin(b))/(1.-sin(b)))/pi;
7534}
7535
7536void NcAstrolab::SetPhysicalParameter(TString name,Double_t value)
7537{
7575
7576 // Variable to correct conversion factors when a parameter is modified
7577 Double_t frac=1;
7578
7579 if (name=="SpeedC")
7580 {
7581 frac=value/fSpeedC;
7582 fSpeedC=value;
7583 fMe*=frac*frac;
7584 fMmu*=frac*frac;
7585 fMtau*=frac*frac;
7586 fAmu*=frac*frac;
7587 fMp*=frac*frac;
7588 fMn*=frac*frac;
7589 fMW*=frac*frac;
7590 fMZ*=frac*frac;
7591 fHbarc*=frac;
7592 fHbarc2*=pow(frac,2.);
7593 }
7594 if (name=="Qe")
7595 {
7596 frac=value/fQe;
7597 fQe=value;
7598 fMe/=frac;
7599 fMmu/=frac;
7600 fMtau/=frac;
7601 fAmu/=frac;
7602 fMp/=frac;
7603 fMn/=frac;
7604 fMW/=frac;
7605 fMZ/=frac;
7606 fHbar/=frac;
7607 fHbarc/=frac;
7608 fHbarc2/=pow(frac,2.);
7609 }
7610 if (name=="Me") fMe=value;
7611 if (name=="Mmu") fMmu=value;
7612 if (name=="Mtau") fMtau=value;
7613 if (name=="Amu")
7614 {
7615 frac=value/fAmu;
7616 fAmu=value;
7617 fMp*=frac;
7618 fMn*=frac;
7619 }
7620 if (name=="Mp") fMp=value;
7621 if (name=="Mn") fMn=value;
7622 if (name=="MW") fMW=value;
7623 if (name=="GammaW") fGammaW=value;
7624 if (name=="MZ") fMZ=value;
7625 if (name=="GammaZ") fGammaZ=value;
7626 if (name=="AlphaEM") fAlphaEM=value;
7627 if (name=="Fermi") fFermi=value;
7628 if (name=="Planck")
7629 {
7630 frac=value/fPlanck;
7631 fPlanck=value;
7632 fHbar*=frac;
7633 fHbarc*=frac;
7634 fFermi/=pow(frac,3.);
7635 }
7636 if (name=="Boltz") fBoltz=value;
7637 if (name=="Newton")
7638 {
7639 frac=value/fNewton;
7640 fNewton=value;
7641 fGn*=frac;
7642 }
7643 if (name=="Gn") fGn=value;
7644 if (name=="Au") fAu=value;
7645 if (name=="Pc") fPc=value;
7646 if (name=="Hubble") fHubble=value;
7647 if (name=="OmegaM") fOmegaM=value;
7648 if (name=="OmegaR") fOmegaR=value;
7649 if (name=="OmegaL") fOmegaL=value;
7650 if (name=="OmegaB") fOmegaB=value;
7651 if (name=="OmegaC") fOmegaC=value;
7652}
7653
7654Double_t NcAstrolab::GetPhysicalParameter(TString name) const
7655{
7677
7678 Double_t val=0;
7679
7680 // Standard parameters
7681 if (name=="SpeedC") return fSpeedC;
7682 if (name=="Qe") return fQe;
7683 if (name=="Me") return fMe;
7684 if (name=="Mmu") return fMmu;
7685 if (name=="Mtau") return fMtau;
7686 if (name=="Amu") return fAmu;
7687 if (name=="Mp") return fMp;
7688 if (name=="Mn") return fMn;
7689 if (name=="MW") return fMW;
7690 if (name=="GammaW") return fGammaW;
7691 if (name=="GammaZ") return fGammaZ;
7692 if (name=="AlphaEM") return fAlphaEM;
7693 if (name=="Fermi") return fFermi;
7694 if (name=="Planck") return fPlanck;
7695 if (name=="Boltz") return fBoltz;
7696 if (name=="Newton") return fNewton;
7697 if (name=="Gn") return fGn;
7698 if (name=="Au") return fAu;
7699 if (name=="Pc") return fPc;
7700 if (name=="Hubble") return fHubble;
7701 if (name=="OmegaM") return fOmegaM;
7702 if (name=="OmegaR") return fOmegaR;
7703 if (name=="OmegaL") return fOmegaL;
7704 if (name=="OmegaB") return fOmegaB;
7705 if (name=="OmegaC") return fOmegaC;
7706
7707 // Derived parameters
7708 if (name=="Hbar") return fHbar;
7709 if (name=="Hbarc") return fHbarc;
7710 if (name=="Hbarc2") return fHbarc2;
7711 if (name=="Mnucl")
7712 {
7713 val=(fMp+fMn)/2.;
7714 return val;
7715 }
7716 if (name=="Sin2w")
7717 {
7718 val=1.-pow(fMW/fMZ,2.);
7719 return val;
7720 }
7721 if (name=="Jy") return 1e-23;
7722 if (name=="Erg")
7723 {
7724 val=1e-7/(fQe*1e9);
7725 return val;
7726 }
7727
7728 // Unknown parameter
7729 return 0;
7730}
7731
7732Double_t NcAstrolab::GetPhysicalDistance(Double_t z,TString u,Int_t t) const
7733{
7767
7768 if (z<=0 || fHubble<=0) return 0;
7769
7770 Double_t c=fSpeedC/1000.; // Lightspeed in km/s
7771
7772 TF1 f("f","1./sqrt([0]*pow((1.+x),4)+[1]*pow((1.+x),3)+[2])");
7773
7774 f.SetParameter(0,fOmegaR);
7775 f.SetParameter(1,fOmegaM);
7776 f.SetParameter(2,fOmegaL);
7777 f.SetRange(0,z);
7778
7779 Double_t dist=f.Integral(0,z);
7780 dist*=c/fHubble; // The distance in Mpc
7781
7782 Double_t distm=dist*1e6*fPc; // corresponding distance in meter
7783
7784 Double_t val=0;
7785
7786 if (u=="Gpc") val=dist*1e-3;
7787 if (u=="Mpc") val=dist;
7788 if (u=="pc") val=dist*1e6;
7789 if (u=="ly") val=dist*3.26156e6;
7790 if (u=="m") val=distm;
7791 if (u=="km") val=distm*1e-3;
7792 if (u=="cm") val=distm*1e2;
7793
7794 if (!t) val=val/(z+1.);
7795
7796 return val;
7797}
7798
7799Double_t NcAstrolab::GetProperDistance(Double_t z,TString u,Int_t t) const
7800{
7834
7835 Double_t val=GetPhysicalDistance(z,u,t);
7836
7837 return val;
7838}
7839
7840Double_t NcAstrolab::GetComovingDistance(Double_t z,TString u) const
7841{
7872
7873 Double_t val=GetPhysicalDistance(z,u,1);
7874
7875 return val;
7876}
7877
7878Double_t NcAstrolab::GetLuminosityDistance(Double_t z,TString u) const
7879{
7913
7914 Double_t val=GetPhysicalDistance(z,u,1);
7915 val=val*(z+1.);
7916
7917 return val;
7918}
7919
7920Double_t NcAstrolab::GetLightTravelDistance(Double_t z,TString u) const
7921{
7955
7956 if (z<=0 || fHubble<=0) return 0;
7957
7958 Double_t c=fSpeedC/1000.; // Lightspeed in km/s
7959
7960 TF1 f("f","1./((1.+x)*sqrt([0]*pow((1.+x),4)+[1]*pow((1.+x),3)+[2]))");
7961
7962 f.SetParameter(0,fOmegaR);
7963 f.SetParameter(1,fOmegaM);
7964 f.SetParameter(2,fOmegaL);
7965 f.SetRange(0,z);
7966
7967 Double_t dist=f.Integral(0,z);
7968 dist*=c/fHubble; // The distance in Mpc
7969
7970 Double_t distm=dist*1e6*fPc; // corresponding distance in meter
7971
7972 Double_t val=0;
7973
7974 if (u=="Gpc") val=dist*1e-3;
7975 if (u=="Mpc") val=dist;
7976 if (u=="pc") val=dist*1e6;
7977 if (u=="ly") val=dist*3.26156e6;
7978 if (u=="m") val=distm;
7979 if (u=="km") val=distm*1e-3;
7980 if (u=="cm") val=distm*1e2;
7981
7982 return val;
7983}
7984
7985Double_t NcAstrolab::GetLightTravelTime(Double_t z) const
7986{
8004
8005 Double_t val=GetLightTravelDistance(z,"ly");
8006
8007 return val;
8008}
8009
8010Double_t NcAstrolab::GetHubbleParameter(Double_t z,TString u) const
8011{
8032
8033 if (z<0 || fHubble<=0) return 0;
8034
8035 TF1 f("f","sqrt([0]*pow((1.+x),4)+[1]*pow((1.+x),3)+[2])");
8036
8037 f.SetParameter(0,fOmegaR);
8038 f.SetParameter(1,fOmegaM);
8039 f.SetParameter(2,fOmegaL);
8040 f.SetRange(0,z);
8041
8042 Double_t H=f.Eval(z);
8043 H*=fHubble; // The current Hubble parameter (H0) in km/s per Mpc
8044
8045 Double_t Hm=H/(1e6*fPc); // corresponding H in km/s per meter
8046
8047 Double_t val=0;
8048
8049 if (u=="Gpc") val=H/1e-3;
8050 if (u=="Mpc") val=H;
8051 if (u=="pc") val=H/1e6;
8052 if (u=="ly") val=H/3.26156e6;
8053 if (u=="m") val=Hm;
8054 if (u=="km") val=Hm/1e-3;
8055 if (u=="cm") val=Hm/1e2;
8056
8057 return val;
8058}
8059
8060Double_t NcAstrolab::GetNuclearMass(Int_t Z,Int_t N,Int_t mode) const
8061{
8089
8090 if (Z<0 || N<0) return 0;
8091
8092 Double_t rz=Z;
8093 Double_t rn=N;
8094 Double_t ra=Z+N;
8095
8096 // Coefficients from a recent fit mentioned in Tipler's modern physics (4th ed.) textbook.
8097 // The values in the comment field are the ones of the slides mentioned above.
8098 Double_t a=15.67; //15.835;
8099 Double_t b=17.23; //18.33;
8100 Double_t s=23.2; //23.20;
8101 Double_t d=0.75; //0.714;
8102 Double_t delta=12; //11.2;
8103
8104 Double_t term1=a*ra; // Constant bulk binding energy like cohesion in a liquid
8105 Double_t term2=b*pow(ra,2./3.); // Surface energy of a sphere like surface tension of liquids
8106 Double_t term3=s*pow((rn-rz),2.)/ra; // Symmetry term
8107 Double_t term4=d*pow(rz,2.)/pow(ra,1./3.); // Coulomb term
8108 Double_t term5=0; // Phenomenological correction for light nuclei (pairing energy term)
8109
8110 Int_t oz=Z%2; // Flag (1) for odd Z nuclei
8111 Int_t on=N%2; // Flag (1) for odd N nuclei
8112
8113 if (oz && on) term5=delta/sqrt(ra);
8114 if (!oz && !on) term5=-delta/sqrt(ra);
8115
8116 // Binding energy in MeV
8117 Double_t bnz=term1-term2-term3-term4-term5;
8118
8119 // In case a single nucleon was specified
8120 if ((Z+N)<2)
8121 {
8122 bnz=0;
8123 ra=1;
8124 }
8125
8126 // Nuclear mass in MeV/c^2
8127 Double_t mass=rz*fMp+rn*fMn-bnz;
8128
8129 // Explicit literature values for very light elements
8130 if (Z==1 && N==1) // Deuteron
8131 {
8132 mass=2.013553212712*fAmu;
8133 bnz=rz*fMp+rn*fMn-mass;
8134 }
8135
8136 if (Z==1 && N==2) // Triton
8137 {
8138 mass=3.0155007134*fAmu;
8139 bnz=rz*fMp+rn*fMn-mass;
8140 }
8141
8142 if (Z==2 && N==1) // Helion
8143 {
8144 mass=3.0149322468*fAmu;
8145 bnz=rz*fMp+rn*fMn-mass;
8146 }
8147
8148 if (Z==2 && N==2) // Alpha
8149 {
8150 mass=4.001506179125*fAmu;
8151 bnz=rz*fMp+rn*fMn-mass;
8152 }
8153
8154 Double_t value=0;
8155
8156 switch(mode)
8157 {
8158 case 1 : // Nuclear mass in GeV/c^2
8159 value=mass/1000.;
8160 break;
8161
8162 case -1 : // Nuclear mass in amu
8163 value=mass/fAmu;
8164 break;
8165
8166 case 2 : // Total binding energy in MeV
8167 value=bnz;
8168 break;
8169
8170 case -2 : // Total binding energy in amu
8171 value=bnz/fAmu;
8172 break;
8173
8174 case 3 : // Binding energy per nucleon in MeV
8175 value=bnz/ra;
8176 break;
8177
8178 case -3 : // Binding energy per nucleon in amu
8179 value=bnz/(fAmu*ra);
8180 break;
8181 }
8182
8183 return value;
8184}
8185
8186Double_t NcAstrolab::GetRadiationLength(Double_t Z,Double_t A,Double_t rho) const
8187{
8216
8217 Double_t X0=-1;
8218
8219 if (Z<=0 || A<1 || A<Z) return -1;
8220
8221 X0=716.4*A/(Z*(Z+1.)*(log(287./sqrt(Z))));
8222
8223 Double_t mN=0.001*fGn*fQe/fAmu; // The nucleon mass in gram
8224 if (rho==0) X0=X0/mN;
8225 if (rho>0) X0=X0/rho;
8226
8227 return X0;
8228}
8229
8230Double_t NcAstrolab::GetMeanFreePath(Double_t sigma,Double_t rho,Int_t mode) const
8231{
8266
8267 Double_t lambda=-1;
8268
8269 if (sigma<=0 || rho<=0 || mode<0 || mode>4) return -1;
8270
8271 Double_t mN=0.001*fGn*fQe/fAmu; // The nucleon mass in gram
8272 Double_t n=fabs(rho)/mN; // The number of nucleons per cm^3
8273 if (mode<2) n=rho; // The number of scattering centers per cm^3
8274 sigma=sigma*1e-24; // Convert to cm^2
8275
8276 lambda=1./(sigma*n);
8277
8278 if (mode==1 || mode==4) lambda=lambda*n;
8279 if (mode==3) lambda=lambda*rho;
8280
8281 return lambda;
8282}
8283
8284Double_t NcAstrolab::GetInteractionProbability(Double_t x,Double_t lambda) const
8285{
8316
8317 Double_t prob=-1;
8318
8319 if (x<0 || lambda<=0) return -1;
8320
8321 prob=1.-exp(-x/lambda);
8322
8323 return prob;
8324}
8325
8326Double_t NcAstrolab::GetInteractionProbability(Double_t x,Double_t sigma,Double_t rho,Int_t mode) const
8327{
8359
8360 Double_t prob=-1;
8361
8362 Double_t lambda=GetMeanFreePath(sigma,rho,mode);
8363
8364 if (lambda>0) prob=GetInteractionProbability(x,lambda);
8365
8366 return prob;
8367}
8368
8369Double_t NcAstrolab::GetSurvivalProbability(Double_t x,Double_t lambda) const
8370{
8401
8402 Double_t prob=-1;
8403
8404 if (x<0 || lambda<=0) return -1;
8405
8406 prob=exp(-x/lambda);
8407
8408 return prob;
8409}
8410
8411Double_t NcAstrolab::GetSurvivalProbability(Double_t x,Double_t sigma,Double_t rho,Int_t mode) const
8412{
8444
8445 Double_t prob=-1;
8446
8447 Double_t lambda=GetMeanFreePath(sigma,rho,mode);
8448
8449 if (lambda>0) prob=GetSurvivalProbability(x,lambda);
8450
8451 return prob;
8452}
8453
8454Double_t NcAstrolab::GetShieldingThickness(Double_t prob,Double_t lambda) const
8455{
8483
8484 Double_t x=-1;
8485
8486 if (prob<=0 || prob>1 || lambda<=0) return -1;
8487
8488 x=-lambda*log(prob);
8489
8490 return x;
8491}
8492
8493Double_t NcAstrolab::GetShieldingThickness(Double_t prob,Double_t sigma,Double_t rho,Int_t mode) const
8494{
8523
8524 Double_t x=-1;
8525
8526 if (prob<=0 || prob>1) return -1;
8527
8528 Double_t lambda=GetMeanFreePath(sigma,rho,mode);
8529
8530 if (lambda>0) x=GetShieldingThickness(prob,lambda);
8531
8532 return x;
8533}
8534
8535Double_t NcAstrolab::GetTargetThickness(Double_t prob,Double_t lambda) const
8536{
8564
8565 if (prob<=0 || prob>1 || lambda<=0) return -1;
8566
8567 Double_t p=1.-prob;
8568 Double_t x=GetShieldingThickness(p,lambda);
8569
8570 return x;
8571}
8572
8573Double_t NcAstrolab::GetTargetThickness(Double_t prob,Double_t sigma,Double_t rho,Int_t mode) const
8574{
8603
8604 Double_t x=-1;
8605
8606 if (prob<=0 || prob>1) return -1;
8607
8608 Double_t lambda=GetMeanFreePath(sigma,rho,mode);
8609
8610 Double_t p=1.-prob;
8611 if (lambda>0) x=GetShieldingThickness(p,lambda);
8612
8613 return x;
8614}
8615
8616Double_t NcAstrolab::GetNeutrinoXsection(Int_t mode,Int_t type,Double_t egev,Double_t xscale,Double_t* eprimgev,Double_t* alpha) const
8617{
8664
8665 if (eprimgev) *eprimgev=0;
8666 if (alpha) *alpha=0;
8667 if (!mode || mode>3 || mode<-4 || !type || abs(type)>3) return 0;
8668
8669 const Double_t fnumuccn=6.77e-15; // Nu_mu+Nucleon CC sigma/E in barn/GeV
8670 const Double_t fanumuccn=3.34e-15; // Anti-Nu_mu+Nucleon CC sigma/E in barn/GeV
8671
8672 const Double_t sinw2=GetPhysicalParameter("Sin2w"); // sin^2 of the Weinberg angle
8673
8674 const Double_t fnuetote=0.25+sinw2+4.*pow(sinw2,2.)/3.; // Nu_e+e total sigma/sigma0
8675 const Double_t fanuetote=(1./12.)+(sinw2/3.)+4.*pow(sinw2,2.)/3.; // Anti-Nu_e+e total sigma/sigma0
8676 Double_t fnumucce=1.; // Nu_mu+e CC sigma/sigma0
8677 const Double_t fnumunce=0.25-sinw2+4.*pow(sinw2,2.)/3.; // Nu_mu+e NC sigma/sigma0
8678 const Double_t fanumunce=(1./12.)-(sinw2/3.)+4.*pow(sinw2,2.)/3.; // Anti-Nu_mu+e NC sigma/sigma0
8679 const Double_t f4=1./3.; // Anti-Nu_e+e-->Anti-Nu_mu+mu CC sigma/sigma0
8680
8681 // Parameters for the (anti)neutrino+Nucleon cross section parametrisations of Conolly et al.
8682 const Double_t c0nu=-1.826;
8683 const Double_t c1nu=-17.31;
8684 const Double_t c2nunc=-6.448;
8685 const Double_t c2nucc=-6.406;
8686 const Double_t c3nu=1.431;
8687 const Double_t c4nunc=-18.61;
8688 const Double_t c4nucc=-17.91;
8689 const Double_t c0anu=-1.033;
8690 const Double_t c1anu=-15.95;
8691 const Double_t c2anunc=-7.296;
8692 const Double_t c2anucc=-7.247;
8693 const Double_t c3anu=1.569;
8694 const Double_t c4anunc=-18.30;
8695 const Double_t c4anucc=-17.72;
8696
8697 Double_t rncnu=0.2261/0.7221; // sigma_nc/sigma_cc for Neutrino+Nucleon DIS at 100 GeV
8698 Double_t rncanu=0.1307/0.3747; // sigma_nc/sigma_cc for Anti-neutrino+Nucleon DIS at 100 GeV
8699
8700 // Average inelasticity (y) values from Gandhi et al.
8701 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};
8702 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};
8703 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};
8704 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};
8705
8706 Double_t loge=log10(egev);
8707 Double_t y=0;
8708 Int_t index=int(loge+0.5);
8709 if (index<1) index=1;
8710 if (index>12) index=12;
8711 if (eprimgev)
8712 {
8713 if (type>0) // Neutrinos
8714 {
8715 if (abs(mode)==1) y=ynucc[index-1];
8716 if (abs(mode)==2) y=ynunc[index-1];
8717 if (mode==3) y=(ynucc[index-1]+rncnu*ynunc[index-1])/(1.+rncnu);
8718 if (mode==-3) y=(ynucc[index-1]+fnumunce*ynunc[index-1])/(1.+fnumunce);
8719 }
8720 else // Anti-neutrinos
8721 {
8722 if (abs(mode)==1) y=yanucc[index-1];
8723 if (abs(mode)==2) y=yanunc[index-1];
8724 if (mode==3) y=(yanucc[index-1]+rncanu*yanunc[index-1])/(1.+rncanu);
8725 if (mode==-3) y=(yanucc[index-1]+fnumunce*yanunc[index-1])/(1.+fnumunce);
8726 }
8727 *eprimgev=egev*(1.-y);
8728 }
8729
8730 if (alpha)
8731 {
8732 Double_t mtarg=fMe;
8733 if (mode>0) mtarg=GetPhysicalParameter("Mnucl");
8734 *alpha=sqrt(2.e-3*mtarg/egev)*y*180./((1.-y)*acos(-1.));
8735 }
8736
8737 Double_t xsec=0;
8738 Double_t fact=0;
8739 Double_t c0=0,c1=0,c2=0,c3=0,c4=0;
8740
8741 if (mode>0) // DIS on Nucleon target
8742 {
8743 if (mode==3) // Total xsec
8744 {
8745 // Recursive invokation for NC+CC cross section
8746 xsec=GetNeutrinoXsection(1,type,egev,xscale);
8747 xsec+=GetNeutrinoXsection(2,type,egev,xscale);
8748 return xsec;
8749 }
8750 if (egev<1e4) // Energy below 10 TeV
8751 {
8752 if (mode==1) // CC xsec
8753 {
8754 fact=fnumuccn;
8755 if (type<0) fact=fanumuccn;
8756 }
8757 if (mode==2) // NC xsec
8758 {
8759 fact=fnumuccn*rncnu;
8760 if (type<0) fact=fanumuccn*rncanu;
8761 }
8762 xsec=fact*egev;
8763 }
8764 else // Energy of 10 TeV and above
8765 {
8766 if (mode==1) // CC xsec
8767 {
8768 if (type>0)
8769 {
8770 c0=c0nu;
8771 c1=c1nu;
8772 c2=c2nucc;
8773 c3=c3nu;
8774 c4=c4nucc;
8775 }
8776 else
8777 {
8778 c0=c0anu;
8779 c1=c1anu;
8780 c2=c2anucc;
8781 c3=c3anu;
8782 c4=c4anucc;
8783 }
8784 }
8785 if (mode==2) // NC xsec
8786 {
8787 if (type>0)
8788 {
8789 c0=c0nu;
8790 c1=c1nu;
8791 c2=c2nunc;
8792 c3=c3nu;
8793 c4=c4nunc;
8794 }
8795 else
8796 {
8797 c0=c0anu;
8798 c1=c1anu;
8799 c2=c2anunc;
8800 c3=c3anu;
8801 c4=c4anunc;
8802 }
8803 }
8804 Double_t lne=log(loge-c0);
8805 Double_t logsigma=c1+c2*lne+c3*pow(lne,2.)+c4/lne; // Log10(sigma) in cm^2
8806 logsigma+=24.;
8807 xsec=pow(10.,logsigma);
8808 }
8809 }
8810 else // Scattering on electron target
8811 {
8812 // Check whether we are in the Glashow resonance regime
8813 Double_t elow=pow((fMW-2.*fGammaW),2.)/(2.e-3*fMe);
8814 Double_t eup=pow((fMW+2.*fGammaW),2.)/(2.e-3*fMe);
8815 if (mode==-3 && type==-1 && egev>elow && egev<eup) // Total xsec at Glashow resonance
8816 {
8817 xsec=5.02e-7/xscale;
8818 if (eprimgev) *eprimgev=0;
8819 if (alpha) *alpha=0;
8820 return xsec;
8821 }
8822
8823 // Check if we are above the kinematical threshold energy for CC scattering
8824 Double_t mlepton=fMe;
8825 if (abs(type)==2) mlepton=fMmu;
8826 if (abs(type)==3) mlepton=fMtau;
8827 Double_t eth=1.e-3*(pow(mlepton,2.)-pow(fMe,2.))/(2.*fMe);
8828
8829 if (egev<eth) // Below CC kinematical threshold
8830 {
8831 fnumucce=0;
8832 if (mode==-1) // CC xsec was requested
8833 {
8834 if (eprimgev) *eprimgev=egev;
8835 if (alpha) *alpha=0;
8836 return 0;
8837 }
8838 }
8839
8840 // The Nu_mu+e CC cross section in barn well above threshold
8841 Double_t sigma0=pow(fFermi,2.)*fHbarc2*2.e-3*fMe*egev/acos(-1.);
8842
8843 if (mode==-1) // CC xsec
8844 {
8845 if (type>1) fact=fnumucce;
8846 }
8847 if (mode==-2) // NC xsec
8848 {
8849 if (type>1) fact=fnumunce;
8850 if (type<-1) fact=fanumunce;
8851 }
8852 if (mode==-3) // Total xsec
8853 {
8854 if (type==1) fact=fnuetote;
8855 if (type==-1) fact=fanuetote;
8856 if (type>1) fact=fnumucce+fnumunce;
8857 if (type<-1) fact=fanumunce;
8858 }
8859 if (mode==-4 && type==-1) fact=f4;
8860 xsec=fact*sigma0;
8861 }
8862
8863 xsec/=xscale;
8864
8865 return xsec;
8866}
8867
8868Double_t NcAstrolab::GetNeutrinoAngle(Double_t E,TString u,Int_t mode,TF1* f)
8869{
8905
8906 Double_t value=-1;
8907
8908 if (E<=0 || mode<0 || mode>2) return value;
8909
8910 // Convert to TeV
8911 E*=0.001;
8912
8913 // The parametrisation (in degrees) for a 1 TeV neutrino
8914 Double_t mean=1.38711583;
8915 Double_t median=0.86842105;
8916 Double_t mpv=0.560150;
8917 Double_t sigma=0.226679;
8918
8919 // Scaling the parameters to the provided neutrino energy
8920 Double_t p=log10(E);
8921 Double_t scale=1./(pow(1.5,p)*sqrt(E));
8922
8923 mean*=scale;
8924 median*=scale;
8925 mpv*=scale;
8926 sigma*=scale;
8927
8928 // Create a normalized Landau distribution template
8929 if (!fNuAngle)
8930 {
8931 fNuAngle=new TF1("NuAngle","TMath::Landau(x,[0],[1],1)",0,90);
8932 fNuAngle->SetTitle("Landau pdf;Neutrino-lepton opening angle in degrees;PDF");
8933 }
8934
8935 // Set the parameters for the Landau parametrization
8936 fNuAngle->SetParameter(0,mpv);
8937 fNuAngle->SetParameter(1,sigma);
8938
8939 // Obtain an opening angle value according to the pdf
8940 Double_t ang=fNuAngle->GetRandom();
8941
8942 if (u=="rad")
8943 {
8944 Double_t fact=acos(-1.)/180.; // Coversion factor degrees->radians
8945 mean*=fact;
8946 median*=fact;
8947 ang*=fact;
8948 }
8949
8950 // Provide the used pdf if requested
8951 if (f) fNuAngle->Copy(*f);
8952
8953 value=mean;
8954 if (mode==1) value=median;
8955 if (mode==2) value=ang;
8956
8957 return value;
8958}
8959
8960void NcAstrolab::RandomPosition(Nc3Vector& v,Double_t thetamin,Double_t thetamax,Double_t phimin,Double_t phimax)
8961{
8977
8978 // If needed, initialise the randomiser with a "date/time driven" seed
8979 // using the timestamp of the moment of this invokation of the member function.
8980 // This will ensure different random sequences if the user repeats analyses
8981 // with identical measurements and reference signals without explicit initialisation
8982 // of the randomiser by the user at the start of the analysis.
8983 if (!fRan) fRan=new NcRandom(-1);
8984
8985 // Generate random angles in the specified range
8986 Double_t pi=acos(-1.);
8987 Double_t cosmax=cos(thetamin*pi/180.);
8988 Double_t cosmin=cos(thetamax*pi/180.);
8989 Double_t cost=fRan->Uniform(cosmin,cosmax);
8990 Double_t theta=acos(cost)*180./pi;
8991 Double_t phi=fRan->Uniform(phimin,phimax);
8992
8993 Double_t norm=1;
8994 if (v.HasVector()) norm=v.GetNorm();
8995
8996 Double_t err[3]={0,0,0};
8997 Int_t ier=0;
8998 if (v.HasErrors())
8999 {
9000 ier=1;
9001 v.GetErrors(err,"car");
9002 }
9003
9004 v.SetVector(norm,theta,phi,"sph","deg");
9005 if (ier) v.SetErrors(err,"car");
9006}
9007
9009{
9028
9029 if (!v.HasVector()) return;
9030
9031 // If needed, initialise the randomiser with a "date/time driven" seed
9032 // using the timestamp of the moment of this invokation of the member function.
9033 // This will ensure different random sequences if the user repeats analyses
9034 // with identical measurements and reference signals without explicit initialisation
9035 // of the randomiser by the user at the start of the analysis.
9036 if (!fRan) fRan=new NcRandom(-1);
9037
9038 Double_t norm=v.GetX(1,"sph","deg");
9039 Double_t theta=v.GetX(2,"sph","deg");
9040 Double_t phi=v.GetX(3,"sph","deg");
9041 Double_t err[3]={0,0,0};
9042 Int_t ier=0;
9043 if (v.HasErrors())
9044 {
9045 ier=1;
9046 v.GetErrors(err,"car");
9047 }
9048 if (norm<=0)
9049 {
9050 norm=1;
9051 err[0]=0;
9052 }
9053 v.SetVector(norm,theta,phi,"sph","deg");
9054
9055 // The smeared position will be generated as if the actual vector "v" coincided with the positive Z-axis.
9056 // The actual smeared position will be obtained via a "backward rotation" to the real frame orientation.
9057
9058 // Determine the rotation matrix for the frame in which "v" coincides with the positive Z-axis.
9059 TRotMatrix m;
9060 m.SetAngles(90.+theta,phi,90,phi+90.,theta,phi);
9061
9062 // Generate smeared position w.r.t. the fictative Z-axis
9063 Double_t pi=acos(-1.);
9064 Double_t cosmax=1;
9065 Double_t cosmin=cos(fabs(sigma)*pi/180.);
9066 Double_t phimin=0;
9067 Double_t phimax=360;
9068 Double_t cost=0;
9069 if (sigma<0)
9070 {
9071 cost=fRan->Uniform(cosmin,cosmax);
9072 theta=acos(cost)*180./pi;
9073 }
9074 else
9075 {
9076 theta=fRan->Gauss(0.,sigma);
9077 }
9078 phi=fRan->Uniform(phimin,phimax);
9079
9080 // Enter the "fake" smeared position into vector "v".
9081 v.SetVector(norm,theta,phi,"sph","deg");
9082
9083 // Invoke the inverse rotation to obtain the actual smeared position.
9084 v=v.GetUnprimed(&m);
9085 if (ier) v.SetErrors(err,"car");
9086}
9087
9089{
9106
9107 if (!v.HasVector()) return;
9108
9109 // If needed, initialise the randomiser with a "date/time driven" seed
9110 // using the timestamp of the moment of this invokation of the member function.
9111 // This will ensure different random sequences if the user repeats analyses
9112 // under identical conditions without explicit initialisation of the randomiser
9113 // by the user at the start of the analysis.
9114 if (!fRan) fRan=new NcRandom(-1);
9115
9116 Double_t norm=v.GetX(1,"sph","deg");
9117 Double_t theta=v.GetX(2,"sph","deg");
9118 Double_t phi=v.GetX(3,"sph","deg");
9119 Double_t err[3]={0,0,0};
9120 Int_t ier=0;
9121 if (v.HasErrors())
9122 {
9123 ier=1;
9124 v.GetErrors(err,"car");
9125 }
9126 if (norm<=0)
9127 {
9128 norm=1;
9129 err[0]=0;
9130 }
9131 v.SetVector(norm,theta,phi,"sph","deg");
9132
9133 // The shifted position will be generated as if the actual vector "v" coincided with the positive Z-axis.
9134 // The actual shifted position will be obtained via a "backward rotation" to the real frame orientation.
9135
9136 // Determine the rotation matrix for the frame in which "v" coincides with the positive Z-axis.
9137 TRotMatrix m;
9138 m.SetAngles(90.+theta,phi,90,phi+90.,theta,phi);
9139
9140 // Generate the shifted position w.r.t. the fictative Z-axis
9141 Double_t phimin=0;
9142 Double_t phimax=360;
9143 theta=angle;
9144 phi=fRan->Uniform(phimin,phimax);
9145
9146 // Enter the "fake" shifted position into vector "v".
9147 v.SetVector(norm,theta,phi,"sph","deg");
9148
9149 // Invoke the inverse rotation to obtain the actual shifted position.
9150 v=v.GetUnprimed(&m);
9151 if (ier) v.SetErrors(err,"car");
9152}
9153
9154TH1F NcAstrolab::GetDxHistogram(TH1* hx,Int_t nc,Double_t dxbin,Double_t dxmin,Double_t dxmax,Int_t mode,Double_t fact)
9155{
9253
9254 TH1F hdx;
9255
9256 if (mode<0 || mode>3) return hdx;
9257
9258 if (!hx) return hdx;
9259
9260 if (nc<1) return hdx;
9261
9262 Int_t nenhx=hx->GetEntries();
9263 if (nenhx<=nc) return hdx;
9264
9265 Int_t idxbin=TMath::Nint(dxbin);
9266 if (idxbin<-2) return hdx;
9267
9268 // Create the output histogram if all parameters have been specified or determined automatically.
9269 // If not, this will be done at a recursive invokation (see below) once (some of) the
9270 // parameters have been determined automatically from the input histogram.
9271 if (dxmin>=0 && dxmax>=dxmin && dxbin>0)
9272 {
9273 Int_t nbins=1;
9274 Double_t range=dxmax-dxmin;
9275 if (range>dxbin) nbins=TMath::Nint(range/dxbin);
9276 hdx.SetBins(nbins,dxmin,dxmax);
9277
9278 // Add histogram and axes titles
9279 TString s;
9280 Double_t binwidth=hdx.GetXaxis()->GetBinWidth(1);
9281 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);
9282 hdx.SetNameTitle("DxHistogram",s);
9283 }
9284
9285 // If needed, initialise the randomiser with a "date/time driven" seed
9286 // using the timestamp of the moment of this invokation of the member function.
9287 // This will ensure different random sequences if the user repeats analyses
9288 // under identical conditions without explicit initialisation of the randomiser
9289 // by the user at the start of the analysis.
9290 if (!fRan) fRan=new NcRandom(-1);
9291
9292 // Determine the minimum and maximum encountered dx or fill the output histogram
9293 Double_t x1,x2,deltax;
9294 Int_t nx1,nx2;
9295 Double_t deltaxmin=0;
9296 Double_t deltaxmax=0;
9297 Bool_t found=kFALSE;
9298 Int_t ndxcount=0;
9299 Int_t jstart;
9300
9301 Int_t nbhx=hx->GetNbinsX();
9302 Double_t value=0;
9303 Double_t xlow=0;
9304 Double_t xup=0;
9305 Double_t bsize=0;
9306 for (Int_t i=1; i<=nbhx; i++)
9307 {
9308 deltax=-1;
9309 ndxcount=0;
9310 xlow=hx->GetBinLowEdge(i);
9311 bsize=hx->GetBinWidth(i);
9312 xup=xlow+bsize;
9313 x1=hx->GetBinCenter(i);
9314 if (mode==1 || mode==3) x1=fRan->Uniform(xlow,xup);
9315 value=hx->GetBinContent(i);
9316 nx1=0;
9317 if (value) nx1=1;
9318 if (mode<2) nx1=TMath::Nint(value);
9319
9320 while (nx1>0)
9321 {
9322 // Check for multiple counts (left) in this bin
9323 jstart=i+1;
9324 if (nx1>1) jstart=i;
9325
9326 for (Int_t j=jstart; j<=nbhx; j++)
9327 {
9328 xlow=hx->GetBinLowEdge(j);
9329 bsize=hx->GetBinWidth(j);
9330 xup=xlow+bsize;
9331 x2=hx->GetBinCenter(j);
9332 if (mode==1 || mode==3) x2=fRan->Uniform(xlow,xup);
9333 value=hx->GetBinContent(j);
9334 nx2=0;
9335 if (value) nx2=1;
9336 if (mode<2) nx2=TMath::Nint(value);
9337
9338 if (j==i) nx2=nx1-1; // Counting within the same bin
9339
9340 // Empty bin
9341 if (nx2<1) continue;
9342
9343 ndxcount+=nx2;
9344
9345 if (ndxcount>=nc)
9346 {
9347 deltax=fabs(x2-x1);
9348 if (dxmin>=0 && dxmax>=dxmin && dxbin>0) // Output histogram has been initialised
9349 {
9350 hdx.Fill(deltax);
9351 }
9352 else // Auto-determination of the output histogram range
9353 {
9354 if (!found || deltax<deltaxmin) deltaxmin=deltax;
9355 if (!found || deltax>deltaxmax) deltaxmax=deltax;
9356 }
9357 ndxcount=0;
9358 found=kTRUE;
9359 break;
9360 }
9361 }
9362 nx1--;
9363 }
9364 }
9365
9366 // Check if a suitable configuration of entries was encountered
9367 if (!found) return hdx;
9368
9369 // Check if a recursive call is needed to actually create and fill the output histogram
9370 Int_t nen=hdx.GetEntries();
9371 if (!nen)
9372 {
9373 // Set the bin size (if needed) for the output histogram
9374 if (!idxbin && dxbin<=0) dxbin=hx->GetBinWidth(1);
9375 if (idxbin==-1)
9376 {
9377 dxbin=(hx->GetBinWidth(1))*fact;
9378 if (deltaxmin>0 && deltaxmin>dxbin) dxbin=deltaxmin;
9379 if (dxbin<=0) dxbin=hx->GetBinWidth(1);
9380 }
9381 if (idxbin==-2)
9382 {
9383 dxbin=hx->GetBinWidth(1);
9384 dxbin=dxbin*float(nc);
9385 }
9386
9387 // Set the auto-determined range of the output histogram
9388 if (dxmin<0)
9389 {
9390 dxmin=deltaxmin;
9391 // Compensate for randomized x-values within the input histogram bins
9392 if (mode==1 || mode==3)
9393 {
9394 bsize=hx->GetBinWidth(1);
9395 dxmin=dxmin-2.*bsize;
9396 if (dxmin<0) dxmin=0;
9397 }
9398 }
9399 if (dxmax<0)
9400 {
9401 dxmax=deltaxmax+dxbin;
9402 // Compensate for randomized x-values within the input histogram bins
9403 if (mode==1 || mode==3)
9404 {
9405 bsize=hx->GetBinWidth(1);
9406 dxmax=dxmax+2.*bsize;
9407 }
9408 }
9409
9410 // Invoke the recursive call to create and fill the output histogram
9411 hdx=GetDxHistogram(hx,nc,dxbin,dxmin,dxmax,mode,fact);
9412 }
9413
9414 return hdx;
9415}
9416
9417TH1F NcAstrolab::GetDifHistogram(TH1* hin,Int_t mode,TString s,TF1* f) const
9418{
9453
9454 TH1F hout;
9455
9456 if (!hin) return hout;
9457
9458 Int_t nbins=hin->GetNbinsX();
9459 if (!nbins) return hout;
9460
9461 // Set the X-axis parameters identical to the input histogram
9462 const TArrayD* xarr=hin->GetXaxis()->GetXbins();
9463 Int_t xsize=xarr->GetSize();
9464 if (!xsize)
9465 {
9466 Double_t xmin=hin->GetXaxis()->GetXmin();
9467 Double_t xmax=hin->GetXaxis()->GetXmax();
9468 hout.SetBins(nbins,xmin,xmax);
9469 }
9470 else
9471 {
9472 const Double_t* xbins=xarr->GetArray();
9473 hout.SetBins(nbins,xbins);
9474 }
9475
9476 // Set histogram title
9477 hout.SetNameTitle("DifHistogram",hin->GetTitle());
9478
9479 // Set axes titles
9480 TString sxin=hin->GetXaxis()->GetTitle();
9481 TString syin=hin->GetYaxis()->GetTitle();
9482
9483 TString sxout=sxin;
9484
9485 TString syout=s;
9486 if (syout=="")
9487 {
9488 if (f)
9489 {
9490 syout=f->GetExpFormula("p");
9491 syout+="*";
9492 }
9493 syout+="d(";
9494 syout+=syin;
9495 syout+=")/d(";
9496
9497 // Remove Log indication from the "hin" X-axis title
9498 // to get a proper dy/dx label for the "hout" Y-axis
9499 if (mode)
9500 {
9501 sxin.ReplaceAll("^{10}log","");
9502 sxin.ReplaceAll("^{10}Log","");
9503 sxin.ReplaceAll("log10","");
9504 sxin.ReplaceAll("Log10","");
9505 sxin.ReplaceAll("log","");
9506 sxin.ReplaceAll("Log","");
9507 sxin.ReplaceAll("ln","");
9508 sxin.ReplaceAll("Ln","");
9509 }
9510
9511 syout+=sxin;
9512 syout+=")";
9513 syout.ReplaceAll("((","(");
9514 syout.ReplaceAll("))",")");
9515 }
9516
9517 hout.GetXaxis()->SetTitle(sxout.Data());
9518 hout.GetYaxis()->SetTitle(syout.Data());
9519
9520 // Determine the new Y-values and fill the output histogram
9521 Double_t x=0;
9522 Double_t y=0;
9523 Double_t err=0;
9524 Double_t width=0;
9525 Double_t binlow=0;
9526 Double_t binup=0;
9527 Double_t scale=0;
9528 for (Int_t i=1; i<=nbins; i++)
9529 {
9530 x=hin->GetBinCenter(i);
9531 y=hin->GetBinContent(i);
9532 err=fabs(hin->GetBinError(i));
9533 width=hin->GetBinWidth(i);
9534 binlow=hin->GetBinLowEdge(i);
9535 binup=binlow+width;
9536
9537 // Check if the binwidth is physical
9538 if (width<=0) continue;
9539
9540 // Correct for log-scale annotation on X-axis
9541 if (mode==1)
9542 {
9543 x=pow(10.,x);
9544 width=pow(10.,binup)-pow(10.,binlow);
9545 }
9546 if (mode==2)
9547 {
9548 x=exp(x);
9549 width=exp(binup)-exp(binlow);
9550 }
9551
9552 y=y/width;
9553 err=err/width;
9554
9555 // Rescale via the function "f" if provided
9556 if (f)
9557 {
9558 scale=f->Eval(x);
9559 y=y*scale;
9560 err=err*scale;
9561 }
9562
9563 hout.SetBinContent(i,y);
9564 hout.SetBinError(i,err);
9565 }
9566
9567 return hout;
9568}
9569
9570TH1F NcAstrolab::GetCountsHistogram(TF1& spec,Int_t nbins,Double_t xmin,Double_t xmax,Int_t mode,TString s) const
9571{
9597
9598 // Setting up the output histogram
9599 TH1F hout;
9600 hout.SetName("CountsHistogram");
9601
9602 // Set histogram title and axes labels
9603 if (s=="")
9604 {
9605 s="CountsHistogram;";
9606 if (mode==1)
9607 {
9608 s+="^{10}Log(";
9609 }
9610 else if (mode==2)
9611 {
9612 s+="Ln(";
9613 }
9614 s+=spec.GetXaxis()->GetTitle();
9615 if (mode) s+=")";
9616 s+=";Counts";
9617 }
9618 hout.SetTitle(s.Data());
9619
9620 // Setting histogram binning
9621 Double_t step=(xmax-xmin)/double(nbins);
9622 Double_t* xbins=new Double_t[nbins+1];
9623 Double_t x=xmin;
9624 for (Int_t ibin=0; ibin<=nbins; ibin++)
9625 {
9626 xbins[ibin]=x;
9627 x=x+step;
9628 }
9629
9630 hout.SetBins(nbins,xbins);
9631
9632 // Filling the output histogram
9633 Double_t xval=0;
9634 Double_t dx=0;
9635 Double_t N=0;
9636 x=xmin;
9637 for (Int_t ibin=1; ibin<=nbins; ibin++)
9638 {
9639 if (!mode)
9640 {
9641 xval=x;
9642 dx=xbins[ibin]-xbins[ibin-1];
9643 N=spec.Eval(x)*dx;
9644 }
9645 else if (mode==1)
9646 {
9647 xval=pow(10.,x);
9648 dx=pow(10.,xbins[ibin])-pow(10.,xbins[ibin-1]);
9649 N=spec.Eval(xval)*dx;
9650 }
9651 else if (mode==2)
9652 {
9653 xval=exp(x);
9654 dx=exp(xbins[ibin])-exp(xbins[ibin-1]);
9655 N=spec.Eval(xval)*dx;
9656 }
9657 hout.Fill(x,N);
9658 x=x+step;
9659 }
9660
9661 delete [] xbins;
9662
9663 return hout;
9664}
9665
9666TH1F NcAstrolab::GetCountsHistogram(TH1& hin,Int_t mode,TString s,TF1* fscale) const
9667{
9696
9697 // Setting up the output histogram
9698 TH1F hout;
9699 hout.SetName("CountsHistogram");
9700 Int_t nbins=hin.GetNbinsX();
9701
9702 if (nbins<1) return hout;
9703
9704 TAxis* ax=hin.GetXaxis();
9705 Double_t xmin=ax->GetXmin();
9706 Double_t xmax=ax->GetXmax();
9707 hout.SetBins(nbins,xmin,xmax);
9708
9709 // Set histogram title and axes labels
9710 if (s=="")
9711 {
9712 s=hin.GetTitle();
9713 s+=";";
9714 TString tx=ax->GetTitle();
9715 if (tx!="")
9716 {
9717 s+=tx;
9718 }
9719 else
9720 {
9721 if (mode==0) s+="x";
9722 if (mode==1) s+="^{10}Log(x)";
9723 if (mode==2) s+="Ln(x)";
9724 }
9725 s+=";Counts";
9726 }
9727 hout.SetTitle(s);
9728
9729 // Filling the output histogram
9730 Double_t x=0;
9731 Double_t xlow=0;
9732 Double_t xup=0;
9733 Double_t dx=0;
9734 Double_t xval=0;
9735 Double_t N=0;
9736 Double_t fval=0;
9737 for (Int_t ibin=1; ibin<=nbins; ibin++)
9738 {
9739 x=hin.GetBinCenter(ibin);
9740 xlow=hin.GetBinLowEdge(ibin);
9741 xup=xlow+hin.GetBinWidth(ibin);
9742 N=hin.GetBinContent(ibin);
9743 if (!mode)
9744 {
9745 xval=x;
9746 dx=xup-xlow;
9747 N=N*dx;
9748 }
9749 else if (mode==1)
9750 {
9751 xval=pow(10.,x);
9752 dx=pow(10.,xup)-pow(10.,xlow);
9753 N=N*dx;
9754 }
9755 else if (mode==2)
9756 {
9757 xval=exp(x);
9758 dx=exp(xup)-exp(xlow);
9759 N=N*dx;
9760 }
9761
9762 // Compensate for the Y-axis scaling if needed
9763 if (fscale)
9764 {
9765 fval=fscale->Eval(xval);
9766 if (fval) N=N/fval;
9767 }
9768
9769 hout.Fill(x,N);
9770 }
9771
9772 return hout;
9773}
9774
9775TH1F NcAstrolab::GetLogHistogram(TH1* hin,Int_t mode,TString s) const
9776{
9796
9797 TH1F hout;
9798
9799 if (!hin || mode<1 || mode>2) return hout;
9800
9801 Int_t nbins=hin->GetNbinsX();
9802 if (!nbins) return hout;
9803
9804 // Set the X-axis parameters identical to the input histogram
9805 const TArrayD* xarr=hin->GetXaxis()->GetXbins();
9806 Int_t xsize=xarr->GetSize();
9807 if (!xsize)
9808 {
9809 Double_t xmin=hin->GetXaxis()->GetXmin();
9810 Double_t xmax=hin->GetXaxis()->GetXmax();
9811 hout.SetBins(nbins,xmin,xmax);
9812 }
9813 else
9814 {
9815 const Double_t* xbins=xarr->GetArray();
9816 hout.SetBins(nbins,xbins);
9817 }
9818
9819 // Set histogram and axes titles
9820 hout.SetNameTitle("LogHistogram",hin->GetTitle());
9821
9822 if (s=="")
9823 {
9824 s="^{10}Log(";
9825 if (mode==2) s="Ln(";
9826 s+=hin->GetYaxis()->GetTitle();
9827 s+=")";
9828 }
9829
9830 hout.GetXaxis()->SetTitle(hin->GetXaxis()->GetTitle());
9831 hout.GetYaxis()->SetTitle(s.Data());
9832
9833 // Determine the new Y-values and fill the output histogram
9834 Double_t y=0;
9835 Double_t err=0;
9836 Double_t yplus=0;
9837 for (Int_t i=1; i<=nbins; i++)
9838 {
9839 y=hin->GetBinContent(i);
9840 err=fabs(hin->GetBinError(i));
9841 yplus=y+err;
9842
9843 // Check if Log10(y) or Ln(y) is defined
9844 if (y<=0) continue;
9845
9846 if (mode==1)
9847 {
9848 y=log10(y);
9849 yplus=log10(yplus);
9850 }
9851 else
9852 {
9853 y=log(y);
9854 yplus=log(yplus);
9855 }
9856
9857 hout.SetBinContent(i,y);
9858 err=fabs(yplus-y);
9859 hout.SetBinError(i,err);
9860 }
9861
9862 return hout;
9863}
9864
9865Double_t NcAstrolab::GetBackgroundRateProb(Double_t* vars,Double_t* pars)
9866{
9898
9899 Double_t b=vars[0];
9900 Int_t Noff=int(pars[0]);
9901 Double_t Toff=pars[1];
9902 Double_t bmax=pars[2];
9903 Double_t prec=pars[3];
9904
9905 if (b<=0 || Noff<0 || Toff<=0) return 0;
9906
9907 Double_t rNoff=Noff;
9908 if (bmax<0) bmax=100.*rNoff/Toff;
9909
9910 NcMath math;
9911
9912 Double_t lnU=0;
9913 Double_t lnD=0;
9914 Double_t lnprob=0;
9915 Double_t prob=0;
9916
9917 // The ln of the numerator of Eq.(15) of the publication mentioned above
9918 lnU=log(Toff)+rNoff*log(b*Toff)-b*Toff;
9919
9920 // The ln of the denominator of eq.(15) of the publication mentioned above
9921 lnD=math.LnGamma(Noff+1,bmax*Toff,1);
9922
9923 lnprob=lnU-lnD;
9924
9925 if (lnprob < -fabs(prec)) return 0;
9926
9927 if (lnprob > fabs(prec)) lnprob=fabs(prec);
9928 prob=exp(lnprob);
9929
9930 return prob;
9931}
9932
9933Double_t NcAstrolab::GetSignalRateProb(Double_t* vars,Double_t* pars)
9934{
9977
9978 Double_t s=vars[0];
9979 Int_t Non=TMath::Nint(pars[0]);
9980 Double_t Ton=pars[1];
9981 Int_t Noff=TMath::Nint(pars[2]);
9982 Double_t Toff=pars[3];
9983 Double_t smax=pars[4];
9984 Double_t bmax=pars[5];
9985 Double_t prec=pars[6];
9986
9987 if (s<0 || Non<0 || Ton<=0 || Noff<0 || Toff<=0) return 0;
9988
9989 Double_t rNon=Non;
9990 if (smax<0) smax=100.*rNon/Ton;
9991
9992 Double_t rNoff=Noff;
9993 if (bmax<0) bmax=100.*rNoff/Toff;
9994
9995 NcMath math;
9996
9997 //Store factorials in an array to decrease the processing time
9998 Int_t ndim=Non+Noff+1;
9999 TArrayD lnfacN(ndim);
10000
10001 lnfacN[0]=0;
10002 Double_t x=0;
10003 for (Int_t i=1; i<ndim; i++)
10004 {
10005 x+=log(double(i));
10006 lnfacN[i]=x;
10007 }
10008
10009 Double_t lnU=0;
10010 Double_t lnD=0;
10011 Double_t sumU=0;
10012 Double_t sumD=0;
10013 Double_t prob=0;
10014 Double_t gammaP1=0;
10015 Double_t gammaP2=0;
10016 Double_t ri=0;
10017
10018 for(Int_t i=0; i<=Non; i++)
10019 {
10020 ri=i;
10021
10022 // The incomplete gamma functions P(a,x)
10023 gammaP1=math.Gamma(Non+Noff+1-i,bmax*(Ton+Toff),0);
10024 gammaP2=math.Gamma(i+1,smax*Ton,0);
10025
10026 // The ln of the numerator of Eq.(21) of the publication mentioned above normalized by Non!/(Non+Noff)!
10027 lnU=-s*Ton+ri*log(s)+ri*log(Ton+Toff)-lnfacN[i]-lnfacN[Non-i]+lnfacN[Non+Noff-i]-lnfacN[Non+Noff]+lnfacN[Non];
10028
10029 if ((lnU > -fabs(prec)) && (lnU < fabs(prec))) sumU+=exp(lnU)*gammaP1;
10030
10031 //The ln of the denominator of Eq.(21) of the publication mentioned above normalized by Non!/(Non+Noff)!
10032 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];
10033
10034 if ((lnD > -fabs(prec)) && (lnD < fabs(prec))) sumD+=exp(lnD)*gammaP1*gammaP2;
10035 }
10036
10037 if (sumD) prob=sumU/sumD;
10038
10039 return prob;
10040}
10041
10042TF1 NcAstrolab::GetBackgroundRatePDF(Double_t Noff,Double_t Toff,Double_t bmax,Double_t prec)
10043{
10073
10074 if (bmax<0) bmax=100.*Noff/Toff;
10075
10076 Int_t npar=4;
10077 TF1 pdf("BkgRatePDF",this,&NcAstrolab::GetBackgroundRateProb,0,bmax,npar,"NcAstrolab","GetBackgroundRateProb");
10078
10079 pdf.SetParName(0,"Noff");
10080 pdf.SetParName(1,"Toff");
10081 pdf.SetParName(2,"bmax");
10082 pdf.SetParName(3,"prec");
10083
10084 pdf.SetParameter("Noff",Noff);
10085 pdf.SetParameter("Toff",Toff);
10086 pdf.SetParameter("bmax",bmax);
10087 pdf.SetParameter("prec",prec);
10088
10089 pdf.SetTitle("Bayesian posterior background rate PDF;Background rate B in Hz;p(B|Noff,Toff,I)");
10090 pdf.SetRange(0,bmax);
10091
10092 return pdf;
10093}
10094
10095TF1 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)
10096{
10134
10135 if (smax<0) smax=100.*Non/Ton;
10136
10137 // Correct the off source observation for different coverage and detection efficiency
10138 // with respect to the actual on source measurement
10139 Noff=Noff*Ra*Re;
10140
10141 if (bmax<0) bmax=100.*Noff/Toff;
10142
10143 Int_t npar=7;
10144 TF1 pdf("SignalRatePDF",this,&NcAstrolab::GetSignalRateProb,0,smax,npar,"NcAstrolab","GetSignalRateProb");
10145
10146 pdf.SetParName(0,"Non");
10147 pdf.SetParName(1,"Ton");
10148 pdf.SetParName(2,"Noff");
10149 pdf.SetParName(3,"Toff");
10150 pdf.SetParName(4,"smax");
10151 pdf.SetParName(5,"bmax");
10152 pdf.SetParName(6,"prec");
10153
10154 pdf.SetParameter("Non",Non);
10155 pdf.SetParameter("Ton",Ton);
10156 pdf.SetParameter("Noff",Noff);
10157 pdf.SetParameter("Toff",Toff);
10158 pdf.SetParameter("smax",smax);
10159 pdf.SetParameter("bmax",bmax);
10160 pdf.SetParameter("prec",prec);
10161
10162 pdf.SetTitle("Bayesian posterior signal rate PDF;Signal rate S in Hz;p(S|Non,Ton,Noff,Toff,I)");
10163 pdf.SetRange(0,smax);
10164
10165 return pdf;
10166}
10167
10168Double_t NcAstrolab::GetUpperLimit(TF1 pdf,Double_t p)
10169{
10186
10187 if (p<=0 || p>100) return 0;
10188
10189 Double_t ua[2];
10190 Double_t xa[2];
10191 Int_t nu=0;
10192 Double_t ul=0;
10193
10194 xa[0]=p/100.;
10195 nu=pdf.GetQuantiles(1,ua,xa);
10196
10197 if (nu) ul=ua[0];
10198
10199 return ul;
10200}
10201
10202Double_t NcAstrolab::GetUpperLimit(TH1* his,Double_t p)
10203{
10213
10214 if (p<=0 || p>100 || !his) return 0;
10215
10216 Double_t ua[2];
10217 Double_t xa[2];
10218 Int_t nu=0;
10219 Double_t ul=0;
10220
10221 // Ensure correct results als for histograms filled via SetBinContent().
10222 his->ComputeIntegral();
10223
10224 xa[0]=p/100.;
10225 nu=his->GetQuantiles(1,ua,xa);
10226
10227 if (nu) ul=ua[0];
10228
10229 return ul;
10230}
10231
10232Double_t NcAstrolab::GetCredibleInterval(TF1 pdf,Double_t p,Double_t& xlow,Double_t& xup,Int_t n)
10233{
10265
10266 xlow=0;
10267 xup=0;
10268
10269 if (p<=0 || p>100 || n<2) return 0;
10270
10271 // Set the precision
10272 Double_t prec=1./double(n);
10273
10274 // Obtain the n quantiles of the PDF
10275 Double_t* q=new Double_t[n];
10276 Double_t* sumq=new Double_t[n];
10277 Double_t sum=0;
10278 for (Int_t i=0; i<n; i++)
10279 {
10280 sumq[i]=sum;
10281 sum+=prec;
10282 }
10283 Int_t ncalc=pdf.GetQuantiles(n,q,sumq);
10284
10285 // More than 1 quantile is needed
10286 if (ncalc<2)
10287 {
10288 delete [] q;
10289 delete [] sumq;
10290 return 0;
10291 }
10292
10293 // Determine the index in the quantiles array q[] corresponding to
10294 // the X coordinate of the mode of the PDF
10295 Double_t xmode=pdf.GetMaximumX();
10296 Int_t imode=0;
10297 Double_t diff,diffmin;
10298 diffmin=fabs(q[ncalc-1]-q[0]);
10299 for (Int_t i=0; i<ncalc; i++)
10300 {
10301 diff=fabs(xmode-q[i]);
10302 if (diff<diffmin)
10303 {
10304 diffmin=diff;
10305 imode=i;
10306 }
10307 }
10308
10309 // Get the total integral over the quantiles range of the PDF
10310 Double_t xmin=q[0];
10311 Double_t xmax=q[ncalc-1];
10312 Double_t totint=pdf.Integral(xmin,xmax);
10313
10314 // The PDF should have a total integral >0
10315 if (totint<=0)
10316 {
10317 delete [] q;
10318 delete [] sumq;
10319 return 0;
10320 }
10321
10322 // Determine the requested credible interval around the mode
10323 Int_t ilow=imode;
10324 Int_t iup=imode;
10325 xlow=q[ilow];
10326 xup=q[iup];
10327 Double_t ylow=pdf.Eval(q[ilow]);
10328 Double_t yup=pdf.Eval(q[iup]);
10329 Double_t frac=p/100.;
10330 if (frac>1) frac=1;
10331 Double_t credint=-1;
10332 while (credint<frac*totint)
10333 {
10334 if (yup>ylow && iup<(ncalc-1)) // Shift the upper bound up
10335 {
10336 iup++;
10337 xup=q[iup];
10338 yup=pdf.Eval(xup);
10339 }
10340 else if (ylow>yup && ilow>0) // Shift the lower bound down
10341 {
10342 ilow--;
10343 xlow=q[ilow];
10344 ylow=pdf.Eval(xlow);
10345 }
10346 else if (iup<(ncalc-1)) // Shift the upper bound up in case yup=ylow
10347 {
10348 iup++;
10349 xup=q[iup];
10350 yup=pdf.Eval(xup);
10351 }
10352 else if (ilow>0) // Shift the lower bound down in case yup=ylow
10353 {
10354 ilow--;
10355 xlow=q[ilow];
10356 ylow=pdf.Eval(xlow);
10357 }
10358 else // No shift in any bound -> stop
10359 {
10360 break;
10361 }
10362 credint=pdf.Integral(xlow,xup);
10363 }
10364
10365 // Normalisation for non-normalised PDF
10366 Double_t intfrac=credint/totint;
10367
10368 delete [] q;
10369 delete [] sumq;
10370
10371 return intfrac;
10372}
10373
10374Double_t NcAstrolab::GetCredibleInterval(TF1 pdf,Double_t p,Float_t& xlow,Float_t& xup,Int_t n)
10375{
10407
10408 Double_t xxl=0;
10409 Double_t xxu=0;
10410 Double_t val=0;
10411
10412 val=GetCredibleInterval(pdf,p,xxl,xxu,n);
10413
10414 xlow=xxl;
10415 xup=xxu;
10416 return val;
10417}
10418
10419Double_t NcAstrolab::GetCredibleInterval(TH1* his,Double_t p,Double_t& xlow,Double_t& xup)
10420{
10442
10443 xlow=0;
10444 xup=0;
10445
10446 if (p<=0 || p>100 || !his) return 0;
10447
10448 Int_t nbins=his->GetNbinsX();
10449
10450 // More than 2 bins are always needed
10451 if (nbins<2) return 0;
10452
10453 // Ensure correct results also for histograms filled via SetBinContent()
10454 his->ComputeIntegral();
10455
10456 // Obtain the quantiles at the end of each bin of the histogram and at the start of the 1st bin
10457 Int_t n=nbins+1;
10458 Double_t* q=new Double_t[n];
10459 Int_t ncalc=his->GetQuantiles(n,q);
10460
10461 // More than 1 quantile is needed
10462 if (ncalc<2)
10463 {
10464 delete [] q;
10465 return 0;
10466 }
10467
10468 // Determine the index in the quantiles array q[] corresponding to
10469 // the X coordinate of the mode of the histogram
10470 Int_t imode=his->GetMaximumBin();
10471
10472 // Get the total integral of the histogram over the quantiles range
10473 Double_t totint=his->Integral(1,ncalc,"width");
10474
10475 // The histogram should have a total integral >0
10476 if (totint<=0)
10477 {
10478 delete [] q;
10479 return 0;
10480 }
10481
10482 // Determine the requested credible interval around the mode
10483 Int_t ilow=imode;
10484 Int_t iup=imode;
10485 xlow=q[ilow];
10486 xup=q[iup];
10487 Double_t ylow=his->GetBinContent(ilow);
10488 Double_t yup=his->GetBinContent(iup);
10489 Double_t frac=p/100.;
10490 if (frac>1) frac=1;
10491 Double_t credint=-1;
10492 while (credint<frac*totint)
10493 {
10494 if (yup>ylow && iup<(ncalc-1)) // Shift the upper bound up
10495 {
10496 iup++;
10497 xup=q[iup];
10498 yup=his->GetBinContent(iup);
10499 }
10500 else if (ylow>yup && ilow>0) // Shift the lower bound down
10501 {
10502 ilow--;
10503 xlow=q[ilow];
10504 ylow=his->GetBinContent(ilow);
10505 }
10506 else if (iup<(ncalc-1)) // Shift the upper bound up in case yup=ylow
10507 {
10508 iup++;
10509 xup=q[iup];
10510 yup=his->GetBinContent(iup);
10511 }
10512 else if (ilow>0) // Shift the lower bound down in case yup=ylow
10513 {
10514 ilow--;
10515 xlow=q[ilow];
10516 ylow=his->GetBinContent(ilow);
10517 }
10518 else // No shift in any bound -> stop
10519 {
10520 break;
10521 }
10522 credint=his->Integral(ilow,iup,"width");
10523 }
10524
10525 // Normalisation for non-normalised PDF
10526 Double_t intfrac=credint/totint;
10527
10528 delete [] q;
10529
10530 return intfrac;
10531}
10532
10533Double_t NcAstrolab::GetCredibleInterval(TH1* his,Double_t p,Float_t& xlow,Float_t& xup)
10534{
10556
10557 Double_t xxl=0;
10558 Double_t xxu=0;
10559 Double_t val=0;
10560
10561 val=GetCredibleInterval(his,p,xxl,xxu);
10562
10563 xlow=xxl;
10564 xup=xxu;
10565 return val;
10566}
10567
10568Double_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)
10569{
10662
10663 Double_t value=-1;
10664
10665 if (!mode.Contains("M") && !mode.Contains("K") && !mode.Contains("P")) return -1;
10666 if (mode.Contains("M") && (mode.Contains("K") || mode.Contains("P"))) return -1;
10667 if (mode.Contains("K") && (mode.Contains("M") || mode.Contains("P"))) return -1;
10668 if (mode.Contains("P") && (mode.Contains("M") || mode.Contains("K"))) return -1;
10669
10670 if (!h1) return -1;
10671 if (!h2 && !pdf) return -1;
10672 if (h2 && pdf) return -1;
10673
10674 ULong64_t nrep=ULong64_t(nr);
10675 ULong64_t jrep;
10676 if (!nrep)
10677 {
10678 if (ncut)
10679 {
10680 nrep=ULong64_t(1.e19);
10681 }
10682 else
10683 {
10684 return -1;
10685 }
10686 }
10687
10688 TAxis* xaxis=h1->GetXaxis();
10689 Double_t xmin1=xaxis->GetXmin();
10690 Double_t xmax1=xaxis->GetXmax();
10691 Double_t range1=xmax1-xmin1;
10692 Int_t nbins1=h1->GetNbinsX();
10693 Double_t nen1=h1->GetSumOfWeights();
10694 Double_t underflow1=h1->GetBinContent(0);
10695 Double_t overflow1=h1->GetBinContent(nbins1+1);
10696 if (mode.Contains("U")) nen1=nen1+underflow1;
10697 if (mode.Contains("O")) nen1=nen1+overflow1;
10698
10699 if (nbins1<=0 || nen1<=0 || range1<=0)
10700 {
10701 cout << " *" << ClassName() << "::KolmogorovTest* Histogram h1 is empty or has inconsistent data." << endl;
10702 cout << " h1 : nentries=" << nen1 << " nbins=" << nbins1 << " xmin=" << xmin1 << " xmax=" << xmax1 << endl;
10703 return -1;
10704 }
10705
10706 if (h2)
10707 {
10708 xaxis=h2->GetXaxis();
10709 Double_t xmin2=xaxis->GetXmin();
10710 Double_t xmax2=xaxis->GetXmax();
10711 Double_t range2=xmax2-xmin2;
10712 Int_t nbins2=h2->GetNbinsX();
10713 Double_t nen2=h2->GetSumOfWeights();
10714
10715 if (nen2<=0 || range2<=0)
10716 {
10717 cout << " *" << ClassName() << "::KolmogorovTest* Histogram h2 is empty or has inconsistent data." << endl;
10718 cout << " h2 : nentries=" << nen2 << " nbins=" << nbins2 << " xmin=" << xmin2 << " xmax=" << xmax2 << endl;
10719 return -1;
10720 }
10721
10722 Double_t prec=1e-6;
10723 if (nbins2!=nbins1 || fabs(xmin2-xmin1)>prec || fabs(xmax2-xmax1)>prec)
10724 {
10725 cout << " *" << ClassName() << "::KolmogorovTest* Histograms h1 and h2 do not have the same binning." << endl;
10726 cout << " h1 : nbins=" << nbins1 << " xmin=" << xmin1 << " xmax=" << xmax1 << endl;
10727 cout << " h2 : nbins=" << nbins2 << " xmin=" << xmin2 << " xmax=" << xmax2 << endl;
10728 return -1;
10729 }
10730 }
10731
10732 // Create the "h2" histogram from the "pdf" function to perform the KS test
10733 if (pdf)
10734 {
10735 pdf->SetRange(xmin1,xmax1);
10736 pdf->SetNpx(nbins1);
10737 h2=(TH1*)pdf->GetHistogram()->Clone();
10738 h2->SetName("hpdf");
10739 // Set all bin errors (incl. underflow and overflow bins) to zero
10740 for (Int_t i=0; i<=nbins1+1; i++)
10741 {
10742 h2->SetBinError(i,0);
10743 }
10744 }
10745
10746 // Convert "mode" into the corresponding character string for TH1::KolmogorovTest
10747 TString s="";
10748 if (mode.Contains("U")) s+="U";
10749 if (mode.Contains("O")) s+="O";
10750 if (mode.Contains("N") && !pdf) s+="N";
10751
10752 // Obtain the maximum KS distance (d0) for the input histogram "h1"
10753 TString s2=s;
10754 s2+="M";
10755 Double_t d0=h2->KolmogorovTest(h1,s2.Data());
10756
10757 // Complete "mode" conversion
10758 if (mode.Contains("M")) s+="M";
10759 if (mode.Contains("I")) s+="D";
10760
10761 // Perform the requested KS test
10762 if (mode.Contains("I"))
10763 {
10764 if (pdf)
10765 {
10766 cout << " *" << ClassName() << "::KolmogorovTest* Single sample KS-test results for execution mode "<< mode.Data() << endl;
10767 if (mode.Contains("N")) cout << " === For a single sample KS-test the mode=N is suppressed ===" << endl;
10768 }
10769 else
10770 {
10771 cout << " *" << ClassName() << "::KolmogorovTest* Two sample KS-test results for execution mode "<< mode.Data() << endl;
10772 }
10773 }
10774 value=h1->KolmogorovTest(h2,s.Data());
10775
10776 // Perform the pseudo experiments, if requested
10777 if (ksh) ksh->SetBins(101,0,1.01);
10778 Double_t xval=0;
10779 Double_t dist=0;
10780 Double_t sumrep=0;
10781 Int_t sumd=0;
10782 TH1* htemp=0;
10783 if (mode.Contains("P"))
10784 {
10785 htemp=(TH1*)h1->Clone();
10786 for (jrep=0; jrep<nrep; jrep++) // Loop of pseudo experiments
10787 {
10788 htemp->Reset();
10789 for (Int_t ien=0; ien<nen1; ien++) // Take the random entries from the reference distribution
10790 {
10791 xval=h2->GetRandom();
10792 htemp->Fill(xval);
10793 }
10794 dist=htemp->KolmogorovTest(h2,s2.Data());
10795 if (ksh) ksh->Fill(dist);
10796 sumrep+=1;
10797 if (dist>=d0) sumd++;
10798
10799 // Stop the pseudo experiments if the required precision is reached
10800 if (ncut && sumd>=ncut) break;
10801
10802 } // end loop over pseudo experiments
10803 value=double(sumd)/sumrep;
10804 if (nrx) *nrx=sumrep;
10805 if (mode.Contains("I"))
10806 {
10807 cout << " P-value = " << value << " after " << sumrep << " pseudo experiments." << endl;
10808 }
10809 }
10810
10811 if (mode.Contains("I")) cout << " Returned value = " << value << endl;
10812
10813 // Complete the attributes for the "ksh" histogram
10814 if (ksh)
10815 {
10816 TString xlabel="Dmax";
10817 TString ylabel="Counts after ";
10818 ylabel+=sumrep;
10819 ylabel+=" pseudo experiments";
10820
10821 ksh->SetTitle("KS-test Dmax distribution from pseudo experiments");
10822 ksh->SetXTitle(xlabel.Data());
10823 ksh->SetYTitle(ylabel.Data());
10824
10825 // Mark the actually observed D0 value by a vertical line in the "ksh" histogram
10826 // Also the corresponding P-value is mentioned in the legend
10827 if (mark)
10828 {
10829 Float_t x=d0;
10830 Float_t ymin=0;
10831 Float_t ymax=ksh->GetMaximum();
10832
10833 TLine* vline=new TLine(x,ymin,x,ymax);
10834 vline->SetLineStyle(2); // Dashed line
10835 vline->SetLineWidth(2);
10836 vline->SetLineColor(4); // Blue color
10837
10838 TString title="P-value : %-10.3g";
10839 TString sh=title.Format(title.Data(),value);
10840
10841 TLegend* leg=new TLegend(0.6,0.8,0.8,0.9);
10842 leg->SetFillColor(0);
10843 leg->SetHeader(sh.Data());
10844 leg->AddEntry(vline,"Observed Dmax","L");
10845
10846 TList* hlist=ksh->GetListOfFunctions();
10847 hlist->Add(vline);
10848 hlist->Add(leg);
10849 }
10850 }
10851
10852 // Delete temporary histograms, if any
10853 if (pdf && h2)
10854 {
10855 delete h2;
10856 h2=0;
10857 }
10858
10859 if (htemp) delete htemp;
10860
10861 return value;
10862}
10863
10864TH1F NcAstrolab::GetCumulHistogram(TH1* h,TString name,TString mode) const
10865{
10892
10893 TH1F hcd;
10894 TString title="Cumulative Distribution of histogram ";
10895 hcd.SetNameTitle(name.Data(),title.Data());
10896
10897 if (!h) return hcd;
10898
10899 TAxis* xaxis=h->GetXaxis();
10900 TAxis* yaxis=h->GetYaxis();
10901 Double_t xmin=xaxis->GetXmin();
10902 Double_t xmax=xaxis->GetXmax();
10903 Double_t range=xmax-xmin;
10904 Int_t nbins=h->GetNbinsX();
10905 Double_t nen=h->GetSumOfWeights();
10906 TString nameh=h->GetName();
10907 TString xtitle=xaxis->GetTitle();
10908 TString ytitle=yaxis->GetTitle();
10909 title+=nameh;
10910 hcd.SetNameTitle(name.Data(),title.Data());
10911 hcd.SetXTitle(xtitle.Data());
10912 hcd.SetYTitle(ytitle.Data());
10913
10914 if (nbins<=0 || nen<=0 || range<=0) return hcd;
10915
10916 if(!(mode.Contains("F") || mode.Contains("B")) || (mode.Contains("F") && mode.Contains("B"))) return hcd;
10917
10918 hcd.SetBins(nbins,xmin,xmax);
10919 title="";
10920 if (mode.Contains("N")) title="Normalized ";
10921 if (mode.Contains("F")) title+="Forward ";
10922 if (mode.Contains("B")) title+="Backward ";
10923 title+="Cumulative Distribution of histogram ";
10924 title+=nameh;
10925 hcd.SetNameTitle(name.Data(),title.Data());
10926 hcd.SetXTitle(xtitle.Data());
10927 hcd.SetYTitle(ytitle.Data());
10928
10929 Double_t norm=1;
10930 if (mode.Contains("N")) norm=nen;
10931 Double_t y=0;
10932 Double_t sum=0;
10933
10934 if (mode.Contains("F")) // Forward cumulation
10935 {
10936 for (Int_t ibin=1; ibin<=nbins; ibin++)
10937 {
10938 y=h->GetBinContent(ibin);
10939 sum+=y/norm;
10940 hcd.SetBinContent(ibin,sum);
10941 }
10942 }
10943 else // Backward cumulation
10944 {
10945 for (Int_t ibin=nbins; ibin>=1; ibin--)
10946 {
10947 y=h->GetBinContent(ibin);
10948 sum+=y/norm;
10949 hcd.SetBinContent(ibin,sum);
10950 }
10951 }
10952 return hcd;
10953}
10954
10955TH1F NcAstrolab::GetCumulHistogram(TF1* f,TString name,Int_t nbins,Double_t xmin,Double_t xmax,TString mode) const
10956{
10984
10985 TH1F hcd;
10986 TString title="Cumulative Distribution Histogram of function ";
10987 hcd.SetNameTitle(name.Data(),title.Data());
10988
10989 if (!f) return hcd;
10990
10991 // The original range of the function "f"
10992 Double_t xminold=f->GetXmin();
10993 Double_t xmaxold=f->GetXmax();
10994
10995 f->SetRange(xmin,xmax);
10996 f->SetNpx(nbins);
10997 TH1* hf=(TH1*)f->GetHistogram();
10998
10999 hcd=GetCumulHistogram(hf,name,mode);
11000
11001 if (hcd.GetEntries()>0) // Histogram has been filled
11002 {
11003 title="";
11004 if (mode.Contains("N")) title="Normalized ";
11005 if (mode.Contains("F")) title+="Forward ";
11006 if (mode.Contains("B")) title+="Backward ";
11007 title+="Cumulative Distribution Histogram of function ";
11008 }
11009
11010 TString namef=f->GetName();
11011 title+=namef;
11012
11013 hcd.SetTitle(title.Data());
11014
11015 // Restore the original range for the function "f"
11016 f->SetRange(xminold,xmaxold);
11017
11018 return hcd;
11019}
11020
11021void NcAstrolab::InitDataNames(Int_t dir,TString frame,TString mode)
11022{
11049
11050 if (!dir || (frame!="equ" && frame!="gal" && frame!="ecl" && frame!="hor" && frame!="icr" && frame!="loc") ||
11051 (mode!="M" && mode!="T" && mode!="B" && mode!="J"))
11052 {
11053 cout << endl;
11054 cout << " *" << ClassName() << "::InitDataNames* Invalid input encountered." << endl;
11055 cout << " dir=" << dir << " frame=" << frame << " mode=" << mode << endl;
11056 return;
11057 }
11058
11059 fDataDir=dir;
11060 fDataFrame=frame;
11061 fDataMode=mode;
11062
11063 // Reset the correspondence table
11064 fDataNames.Reset();
11065
11066 TString sdir="arrival";
11067 if (dir<0) sdir="moving";
11068
11069 if (frame=="equ")
11070 {
11071 if (mode=="M") frame="mean";
11072 if (mode=="T") frame="true";
11073 if (mode=="B") frame="B1950";
11074 if (mode=="J") frame="J2000";
11075 frame+=" equatorial";
11076 }
11077 if (frame=="gal") frame="galactic";
11078 if (frame=="ecl") frame="ecliptic";
11079 if (frame=="hor") frame="horizontal";
11080 if (frame=="icr") frame="ICRS";
11081 if (frame=="loc") frame="local";
11082
11083 cout << endl;
11084 cout << " *" << ClassName() << "::InitDataNames* Prepared for input of " << sdir << " directions in " << frame << " coordinates." << endl;
11085 cout << endl;
11086}
11087
11088void NcAstrolab::SetDataNames(TString obsname,TString varname,TString units,TString func)
11089{
11176
11177 Bool_t error=kFALSE;
11178
11179 if (obsname!="Name" && obsname!="Run" && obsname!="Event" && obsname!="Eventb" && obsname!="VetoLevel"
11180 && obsname!="DetId" && obsname!="Date" && obsname!="Tobs" && obsname!="Tstart" && obsname!="Tend"
11181 && obsname!="d" && obsname!="a" && obsname!="b" && obsname!="z"
11182 && obsname!="E" && obsname!="L" && obsname!="S" && obsname!="F" && obsname!="I" && obsname!="J"
11183 && obsname!="T90" && obsname!="T100"
11184 && obsname!="dsigma" && obsname!="csigma" && obsname!="zsigma"
11185 && obsname!="Esigma" && obsname!="Lsigma" && obsname!="Ssigma" && obsname!="Fsigma" && obsname!="Isigma"
11186 && obsname!="T90sigma" && obsname!="T100sigma") error=kTRUE;
11187 if (obsname=="Date" && (units!="ddmmyyyy" && units!="yyyymmdd" && units!="mmddyyyy" && units!="yyyyddmm")) error=kTRUE;
11188 if ((obsname=="Tobs" || obsname=="Tstart" || obsname=="Tend")
11189 && (units!="JD" && units!="MJD" && units!="TJD" && units!="hms" && units!="hrs")) error=kTRUE;
11190 if ((obsname=="a" || obsname=="b" || obsname=="csigma")
11191 && (units!="rad" && units!="deg" && units!="dms" && units!="hms" && units!="hrs")) error=kTRUE;
11192 if (func!="none" && func!="Log" && func!="Ln") error=kTRUE;
11193
11194 if (error)
11195 {
11196 cout << " *" << ClassName() << "::SetDataNames* Invalid input encountered." << endl;
11197 cout << " obsname=" << obsname << " units=" << units << " func=" << func << endl;
11198 return;
11199 }
11200
11201 Int_t n=fDataNames.GetMaxRow();
11202 TObjString* obs=new TObjString(obsname);
11203 TObjString* var=new TObjString(varname);
11204 TObjString* u=new TObjString(units);
11205 TObjString* f=new TObjString(func);
11206 TObjString* val=new TObjString(""); // Value will be filled in LoadInputData()
11207
11208 fDataNames.EnterObject(n+1,1,obs);
11209 fDataNames.EnterObject(n+1,2,var);
11210 fDataNames.EnterObject(n+1,3,u);
11211 fDataNames.EnterObject(n+1,4,f);
11212 fDataNames.EnterObject(n+1,5,val);
11213}
11214
11216{
11223
11224 TString sdir="undefined";
11225 if (fDataDir>0) sdir="arrival";
11226 if (fDataDir<0) sdir="moving";
11227
11228 TString frame="undefined";
11229 if (fDataFrame=="equ")
11230 {
11231 if (fDataMode=="M") frame="mean";
11232 if (fDataMode=="T") frame="true";
11233 if (fDataMode=="B") frame="B1950";
11234 if (fDataMode=="J") frame="J2000";
11235 frame+=" equatorial";
11236 }
11237 if (fDataFrame=="gal") frame="galactic";
11238 if (fDataFrame=="ecl") frame="ecliptic";
11239 if (fDataFrame=="hor") frame="horizontal";
11240 if (fDataFrame=="icr") frame="ICRS";
11241 if (fDataFrame=="loc") frame="local";
11242
11243 cout << endl;
11244 cout << " *" << ClassName() << "::ListDataNames* Settings for input of " << sdir << " directions in " << frame << " coordinates." << endl;
11245
11246 Int_t n=fDataNames.GetMaxRow();
11247
11248 if (n<1)
11249 {
11250 cout << " *** No settings were specified ***" << endl;
11251 }
11252 else
11253 {
11254 cout << " *** The following " << n << " settings were specified ***" << endl;
11255 }
11256
11257 TObjString* obs=0;
11258 TObjString* var=0;
11259 TObjString* u=0;
11260 TObjString* f=0;
11261 for (Int_t i=1; i<=n; i++)
11262 {
11263 obs=(TObjString*)fDataNames.GetObject(i,1);
11264 var=(TObjString*)fDataNames.GetObject(i,2);
11265 u=(TObjString*)fDataNames.GetObject(i,3);
11266 f=(TObjString*)fDataNames.GetObject(i,4);
11267 cout << " obsname=" << obs->GetString() << " varname=" << var->GetString() << " units=" << u->GetString() << " func=" << f->GetString() << endl;
11268 }
11269 cout << endl;
11270}
11271
11272void NcAstrolab::SetBurstParameter(TString name,Double_t value)
11273{
11389
11390 if (!fBurstParameters)
11391 {
11393 fBurstParameters->SetNameTitle("BurstParameters","Parameter settings for transient burst investigations");
11394 }
11395
11396 if (name!="*")
11397 {
11398 fBurstParameters->AddNamedSlot(name);
11399 fBurstParameters->SetSignal(value,name);
11400 }
11401 else
11402 {
11403 Double_t pi=acos(-1.);
11404 name="Nmaxsrc";
11405 fBurstParameters->AddNamedSlot(name);
11406 fBurstParameters->SetSignal(-1,name);
11407 name="Nmaxevt";
11408 fBurstParameters->AddNamedSlot(name);
11409 fBurstParameters->SetSignal(-1,name);
11410 name="RAmin";
11411 fBurstParameters->AddNamedSlot(name);
11412 fBurstParameters->SetSignal(0,name);
11413 name="RAmax";
11414 fBurstParameters->AddNamedSlot(name);
11415 fBurstParameters->SetSignal(360,name);
11416 name="Declmin";
11417 fBurstParameters->AddNamedSlot(name);
11418 fBurstParameters->SetSignal(-90,name);
11419 name="Declmax";
11420 fBurstParameters->AddNamedSlot(name);
11421 fBurstParameters->SetSignal(90,name);
11422 name="T90min";
11423 fBurstParameters->AddNamedSlot(name);
11424 fBurstParameters->SetSignal(1e-5,name);
11425 name="T90max";
11426 fBurstParameters->AddNamedSlot(name);
11427 fBurstParameters->SetSignal(1e5,name);
11428 name="Zmin";
11429 fBurstParameters->AddNamedSlot(name);
11430 fBurstParameters->SetSignal(-1e-6,name);
11431 name="Zmax";
11432 fBurstParameters->AddNamedSlot(name);
11433 fBurstParameters->SetSignal(20,name);
11434 name="Sigmamin";
11435 fBurstParameters->AddNamedSlot(name);
11436 fBurstParameters->SetSignal(0,name);
11437 name="Sigmamax";
11438 fBurstParameters->AddNamedSlot(name);
11439 fBurstParameters->SetSignal(2,name);
11440 name="Grbnu";
11441 fBurstParameters->AddNamedSlot(name);
11442 fBurstParameters->SetSignal(0,name);
11443 name="Avgrbz";
11444 fBurstParameters->AddNamedSlot(name);
11445 fBurstParameters->SetSignal(-1,name);
11446 name="Avgrbt90";
11447 fBurstParameters->AddNamedSlot(name);
11448 fBurstParameters->SetSignal(-1,name);
11449 name="Inburst";
11450 fBurstParameters->AddNamedSlot(name);
11451 fBurstParameters->SetSignal(0,name);
11452 name="Dtnu";
11453 fBurstParameters->AddNamedSlot(name);
11454 fBurstParameters->SetSignal(0,name);
11455 name="Dtnus";
11456 fBurstParameters->AddNamedSlot(name);
11457 fBurstParameters->SetSignal(-0.5,name);
11458 name="ESigmin";
11459 fBurstParameters->AddNamedSlot(name);
11460 fBurstParameters->SetSignal(1e3,name);
11461 name="ESigmax";
11462 fBurstParameters->AddNamedSlot(name);
11463 fBurstParameters->SetSignal(1e10,name);
11464 name="Ezcor";
11465 fBurstParameters->AddNamedSlot(name);
11466 fBurstParameters->SetSignal(1,name);
11467 name="Emin";
11468 fBurstParameters->AddNamedSlot(name);
11469 fBurstParameters->SetSignal(200,name);
11470 name="Emax";
11471 fBurstParameters->AddNamedSlot(name);
11472 fBurstParameters->SetSignal(1e7,name);
11473 name="Alphasig";
11474 fBurstParameters->AddNamedSlot(name);
11475 fBurstParameters->SetSignal(2,name);
11476 name="Alphabkg";
11477 fBurstParameters->AddNamedSlot(name);
11478 fBurstParameters->SetSignal(3.5,name);
11479 name="Kinangle";
11480 fBurstParameters->AddNamedSlot(name);
11481 fBurstParameters->SetSignal(3,name);
11482 name="Angresmin";
11483 fBurstParameters->AddNamedSlot(name);
11484 fBurstParameters->SetSignal(0,name);
11485 name="Angresmax";
11486 fBurstParameters->AddNamedSlot(name);
11487 fBurstParameters->SetSignal(2,name);
11488 name="Angresfix";
11489 fBurstParameters->AddNamedSlot(name);
11490 fBurstParameters->SetSignal(1,name);
11491 name="Recoangle";
11492 fBurstParameters->AddNamedSlot(name);
11493 fBurstParameters->SetSignal(3,name);
11494 name="Sumsigmas";
11495 fBurstParameters->AddNamedSlot(name);
11496 fBurstParameters->SetSignal(2,name);
11497 name="Timres";
11498 fBurstParameters->AddNamedSlot(name);
11499 fBurstParameters->SetSignal(1e-5,name);
11500 name="Sensarea";
11501 fBurstParameters->AddNamedSlot(name);
11502 fBurstParameters->SetSignal(1e6,name);
11503 name="Bkgrate";
11504 fBurstParameters->AddNamedSlot(name);
11505 fBurstParameters->SetSignal(-0.003/(2.*pi),name);
11506 name="Nbkg";
11507 fBurstParameters->AddNamedSlot(name);
11508 fBurstParameters->SetSignal(1,name);
11509 name="Tunits";
11510 fBurstParameters->AddNamedSlot(name);
11511 fBurstParameters->SetSignal(2,name);
11512 name="Tmin";
11513 fBurstParameters->AddNamedSlot(name);
11514 fBurstParameters->SetSignal(-3600,name);
11515 name="Tmax";
11516 fBurstParameters->AddNamedSlot(name);
11517 fBurstParameters->SetSignal(3600,name);
11518 name="Dawin";
11519 fBurstParameters->AddNamedSlot(name);
11520 fBurstParameters->SetSignal(5,name);
11521 name="Datype";
11522 fBurstParameters->AddNamedSlot(name);
11523 fBurstParameters->SetSignal(0,name);
11524 name="Tbint90";
11525 fBurstParameters->AddNamedSlot(name);
11526 fBurstParameters->SetSignal(1,name);
11527 name="Tbin";
11528 fBurstParameters->AddNamedSlot(name);
11529 fBurstParameters->SetSignal(1,name);
11530 name="VarTbin";
11531 fBurstParameters->AddNamedSlot(name);
11532 fBurstParameters->SetSignal(10,name);
11533 name="Abin";
11534 fBurstParameters->AddNamedSlot(name);
11535 fBurstParameters->SetSignal(1,name);
11536
11537 // Remove all histograms related to burst investigations
11538 fBurstHistos.Clear();
11539 fBurstHistos.SetOwner();
11540 }
11541
11543 // Store some derived parameters //
11545
11546 // The correction factor to get from Tunits to seconds
11547 Int_t fTunits=TMath::Nint(fBurstParameters->GetSignal("Tunits"));
11548 Double_t Tfact=1;
11549 if (fTunits==0) Tfact=86400;
11550 if (fTunits==1) Tfact=3600;
11551 if (fTunits==3) Tfact=1e-9;
11552 if (fTunits==4) Tfact=1e-12;
11553 name="Tfact";
11554 fBurstParameters->AddNamedSlot(name);
11555 fBurstParameters->SetSignal(Tfact,name);
11556
11557 // Combined burst position and event reconstruction angular uncertainty interval (sigma in degrees)
11558 Int_t fSumsigmas=TMath::Nint(fBurstParameters->GetSignal("Sumsigmas"));
11559 Int_t fRecoangle=TMath::Nint(fBurstParameters->GetSignal("Recoangle"));
11560 Float_t fSigmamin=fabs(fBurstParameters->GetSignal("Sigmamin"));
11561 Float_t fAngresmin=fBurstParameters->GetSignal("Angresmin");
11562 Float_t fAngresfix=fBurstParameters->GetSignal("Angresfix");
11563 if (!fRecoangle) fAngresmin=fAngresfix;
11564 Float_t Minsigmatot=-1;
11565 if (fSumsigmas==-1) Minsigmatot=fAngresmin;
11566 if (fSumsigmas==0) Minsigmatot=fSigmamin;
11567 if (fSumsigmas==1) Minsigmatot=fSigmamin+fAngresmin;
11568 if (fSumsigmas==2) Minsigmatot= sqrt(fSigmamin*fSigmamin+fAngresmin*fAngresmin);
11569 name="Minsigmatot";
11570 fBurstParameters->AddNamedSlot(name);
11571 fBurstParameters->SetSignal(Minsigmatot,name);
11572 Float_t fSigmamax=fBurstParameters->GetSignal("Sigmamax");
11573 Float_t fAngresmax=fBurstParameters->GetSignal("Angresmax");
11574 if (!fRecoangle) fAngresmax=fAngresfix;
11575 Float_t Maxsigmatot=-1;
11576 if (fSumsigmas==-1) Maxsigmatot=fAngresmax;
11577 if (fSumsigmas==0) Maxsigmatot=fSigmamax;
11578 if (fSumsigmas==1) Maxsigmatot=fSigmamax+fAngresmax;
11579 if (fSumsigmas==2) Maxsigmatot= sqrt(fSigmamax*fSigmamax+fAngresmax*fAngresmax);
11580 name="Maxsigmatot";
11581 fBurstParameters->AddNamedSlot(name);
11582 fBurstParameters->SetSignal(Maxsigmatot,name);
11583
11584 // The total search time window in seconds
11585 Float_t fTmin=fBurstParameters->GetSignal("Tmin");
11586 Float_t fTmax=fBurstParameters->GetSignal("Tmax");
11587 Float_t Dtwin=fTmax-fTmin;
11588 name="Dtwin";
11589 fBurstParameters->AddNamedSlot(name);
11590 fBurstParameters->SetSignal(Dtwin,name);
11591
11592 Float_t fTbin=fBurstParameters->GetSignal("Tbin");
11593 if (!fTbin) // Center the time window around the burst trigger for variable time bins
11594 {
11595 fTmin=-Dtwin/2.;
11596 fTmax=Dtwin/2.;
11597 name="Tmin";
11598 fBurstParameters->AddNamedSlot(name);
11599 fBurstParameters->SetSignal(fTmin,name);
11600 name="Tmax";
11601 fBurstParameters->AddNamedSlot(name);
11602 fBurstParameters->SetSignal(fTmax,name);
11603 }
11604
11605 // The solid angle corresponding to the selected declination band
11606 Float_t fRAmin=fBurstParameters->GetSignal("RAmin");
11607 Float_t fRAmax=fBurstParameters->GetSignal("RAmax");
11608 Float_t fDeclmin=fBurstParameters->GetSignal("Declmin");
11609 Float_t fDeclmax=fBurstParameters->GetSignal("Declmax");
11610 Float_t phimin=fRAmin;
11611 Float_t phimax=fRAmax;
11612 Float_t thmin=90.-fDeclmax;
11613 Float_t thmax=90.-fDeclmin;
11614 Float_t OmegaDecl=GetSolidAngle(thmin,thmax,"deg",phimin,phimax,"deg");
11615 name="OmegaDecl";
11616 fBurstParameters->AddNamedSlot(name);
11617 fBurstParameters->SetSignal(OmegaDecl,name);
11618
11619 // Background event rate from the selected declination band
11620 Float_t fBkgrate=fBurstParameters->GetSignal("Bkgrate");
11621 Float_t RbkgDecl=fBkgrate;
11622 if (fBkgrate<0)
11623 {
11624 RbkgDecl=fabs(fBkgrate)*OmegaDecl;
11625 }
11626 name="RbkgDecl";
11627 fBurstParameters->AddNamedSlot(name);
11628 fBurstParameters->SetSignal(RbkgDecl,name);
11629
11630 // Mean number of background events per hour from the selected declination band
11631 Float_t NbkgHour=RbkgDecl*3600.;
11632 name="NbkgHour";
11633 fBurstParameters->AddNamedSlot(name);
11634 fBurstParameters->SetSignal(NbkgHour,name);
11635
11636 // Mean number of background events in the search time window from the selected declination band
11637 Float_t fDtwin=fBurstParameters->GetSignal("Dtwin");
11638 Float_t NbkgWin=RbkgDecl*fDtwin*Tfact;
11639 name="NbkgWin";
11640 fBurstParameters->AddNamedSlot(name);
11641 fBurstParameters->SetSignal(NbkgWin,name);
11642}
11643
11645{
11655
11656 return fBurstParameters;
11657}
11658
11660{
11670
11671 // User provided settings
11672 Int_t fNmaxsrc=TMath::Nint(fBurstParameters->GetSignal("Nmaxsrc"));
11673 Int_t fNmaxevt=TMath::Nint(fBurstParameters->GetSignal("Nmaxevt"));
11674 Float_t fRAmin=fBurstParameters->GetSignal("RAmin");
11675 Float_t fRAmax=fBurstParameters->GetSignal("RAmax");
11676 Float_t fDeclmin=fBurstParameters->GetSignal("Declmin");
11677 Float_t fDeclmax=fBurstParameters->GetSignal("Declmax");
11678 Float_t fT90min=fBurstParameters->GetSignal("T90min");
11679 Float_t fT90max=fBurstParameters->GetSignal("T90max");
11680 Float_t fZmin=fBurstParameters->GetSignal("Zmin");
11681 Float_t fZmax=fBurstParameters->GetSignal("Zmax");
11682 Float_t fSigmamin=fBurstParameters->GetSignal("Sigmamin");
11683 Float_t fSigmamax=fBurstParameters->GetSignal("Sigmamax");
11684 Float_t fGrbnu=fBurstParameters->GetSignal("Grbnu");
11685 Float_t fAvgrbz=fBurstParameters->GetSignal("Avgrbz");
11686 Float_t fAvgrbt90=fBurstParameters->GetSignal("Avgrbt90");
11687 Float_t fAvgrbsigma=fBurstParameters->GetSignal("Avgrbsigma");
11688 Int_t fInburst=TMath::Nint(fBurstParameters->GetSignal("Inburst"));
11689 Float_t fDtnu=fBurstParameters->GetSignal("Dtnu");
11690 Float_t fDtnus=fBurstParameters->GetSignal("Dtnus");
11691 Float_t fESigmin=fBurstParameters->GetSignal("ESigmin");
11692 Float_t fESigmax=fBurstParameters->GetSignal("ESigmax");
11693 Int_t fEzcor=TMath::Nint(fBurstParameters->GetSignal("Ezcor"));
11694 Float_t fEmin=fBurstParameters->GetSignal("Emin");
11695 Float_t fEmax=fBurstParameters->GetSignal("Emax");
11696 Float_t fAlphasig=fBurstParameters->GetSignal("Alphasig");
11697 Float_t fAlphabkg=fBurstParameters->GetSignal("Alphabkg");
11698 Int_t fKinangle=TMath::Nint(fBurstParameters->GetSignal("Kinangle"));
11699 Float_t fAngresmin=fBurstParameters->GetSignal("Angresmin");
11700 Float_t fAngresmax=fBurstParameters->GetSignal("Angresmax");
11701 Float_t fAngresfix=fBurstParameters->GetSignal("Angresfix");
11702 Int_t fRecoangle=TMath::Nint(fBurstParameters->GetSignal("Recoangle"));
11703 Int_t fSumsigmas=TMath::Nint(fBurstParameters->GetSignal("Sumsigmas"));
11704 Float_t fTimres=fBurstParameters->GetSignal("Timres");
11705 Float_t fSensarea=fBurstParameters->GetSignal("Sensarea");
11706 Float_t fBkgrate=fBurstParameters->GetSignal("Bkgrate");
11707 Int_t fNbkg=TMath::Nint(fBurstParameters->GetSignal("Nbkg"));
11708 Float_t fTmin=fBurstParameters->GetSignal("Tmin");
11709 Float_t fTmax=fBurstParameters->GetSignal("Tmax");
11710 Int_t fTunits=TMath::Nint(fBurstParameters->GetSignal("Tunits"));
11711 Float_t fDawin=fBurstParameters->GetSignal("Dawin");
11712 Int_t fDatype=TMath::Nint(fBurstParameters->GetSignal("Datype"));
11713 Int_t fTbint90=TMath::Nint(fBurstParameters->GetSignal("Tbint90"));
11714 Float_t fTbin=fBurstParameters->GetSignal("Tbin");
11715 Float_t fVarTbin=fBurstParameters->GetSignal("VarTbin");
11716 Float_t fAbin=fBurstParameters->GetSignal("Abin");
11717
11718 // Derived parameters
11719 Float_t fMaxsigmatot=fBurstParameters->GetSignal("Maxsigmatot");
11720 Float_t fMinsigmatot=fBurstParameters->GetSignal("Minsigmatot");
11721 Float_t fOmegaDecl=fBurstParameters->GetSignal("OmegaDecl");
11722 Float_t fRbkgDecl=fBurstParameters->GetSignal("RbkgDecl");
11723 Float_t fNbkgHour=fBurstParameters->GetSignal("NbkgHour");
11724 Float_t fNbkgWin=fBurstParameters->GetSignal("NbkgWin");
11725
11726 // Internal statistics
11727 Int_t fNgrbs=TMath::Nint(fBurstParameters->GetSignal("Ngrbs"));
11728 Int_t fNevts=TMath::Nint(fBurstParameters->GetSignal("Nevts"));
11729
11730 TString tu="days";
11731 if (fTunits==1) tu="hours";
11732 if (fTunits==2) tu="sec";
11733 if (fTunits==3) tu="ns";
11734 if (fTunits==4) tu="ps";
11735
11736 cout << " ========================= User provided source c.q. burst settings ===============================" << endl;
11737 if (fNmaxsrc<0)
11738 {
11739 printf(" No limitation has been put on the number of sources to be accepted for analysis. \n");
11740 }
11741 else
11742 {
11743 printf(" Maximal number of sources to be accepted for analysis : %-i \n",fNmaxsrc);
11744 }
11745 if (fNmaxevt<0)
11746 {
11747 printf(" No limitation has been put on the number of observed events to be accepted for analysis. \n");
11748 }
11749 else
11750 {
11751 printf(" Maximal number of observed events to be accepted for analysis : %-i \n",fNmaxevt);
11752 }
11753 printf(" Right ascension interval (J2000 in degrees) for source c.q. event position acceptance : [%-g,%-g] \n",fRAmin,fRAmax);
11754 printf(" Declination interval (J2000 in degrees) for source c.q. event position acceptance : [%-g,%-g] \n",fDeclmin,fDeclmax);
11755 printf(" Redshift interval for source acceptance : [%-g,%-g] \n",fabs(fZmin),fZmax);
11756 if (fZmin<0) printf(" Random redshift values taken from z-distribution in case of unknown redshift \n");
11757 if (fAvgrbz>=0) printf(" User defined average source redshift : %-g \n",fAvgrbz);
11758 printf(" Event energy interval (in GeV) for event acceptance : [%-g,%-g] \n",fEmin,fEmax);
11759 printf(" Position uncertainty interval (sigma in degrees) for source acceptance : [%-g,%-g] \n",fabs(fSigmamin),fSigmamax);
11760 if (fSigmamin<0) printf(" Random sigma values taken from sigma-distribution when missing in loaded data \n");
11761 printf(" Event angular resolution interval (sigma in degrees) for event acceptance : [%-g,%-g] \n",fAngresmin,fAngresmax);
11762 if (fDatype>0) printf(" Sigma (combination) selection (-1=event sigma only 0=source sigma only 1=linear summation 2=quadratic summation) : %-i \n",fSumsigmas);
11763 if (fDawin>=0)
11764 {
11765 if (fDatype<0) printf(" Unrestricted angular search area. \n");
11766 if (!fDatype) printf(" Fixed angular search circle around the source position : %-g degrees \n",fDawin);
11767 if (fDatype==1) printf(" Fixed angular search circle (in combined max. source/event sigma) around the source position : %-g \n",fDawin);
11768 if (fDatype==2) printf(" Variable angular search circle (in combined actual source/event sigma) around the source position : %-g \n",fDawin);
11769 }
11770 else
11771 {
11772 if (fDatype<0) printf(" Unrestricted angular search area. \n");
11773 if (!fDatype) printf(" Fixed angular local zenith band above/below the source position : %-g degrees \n",fabs(fDawin));
11774 if (fDatype==1) printf(" Fixed angular local zenith band (in combined max. source/event sigma) above/below the source position : %-g \n",fabs(fDawin));
11775 if (fDatype==2) printf(" Variable angular local zenith band (in combined actual source/event sigma) above/below the source position : %-g \n",fabs(fDawin));
11776 }
11777 printf(" Number of requested background patches per source : %-i \n",fNbkg);
11778 if (fT90max>0)
11779 {
11780 printf(" Duration interval (t90 in sec) for burst acceptance : [%-g,%-g] \n",fabs(fT90min),fT90max);
11781 if (fT90min<0) printf(" Random values taken from T90-distribution in case T90 and T100 were missing \n");
11782 if (fAvgrbt90>0) printf(" User defined average burst T90 duration : %-g sec. \n",fAvgrbt90);
11783 if (fTmax>fTmin) printf(" Total search time window (in %-s) with the burst trigger at t=0 : [%-g,%-g] \n",tu.Data(),fTmin,fTmax);
11784 }
11785 if (fTmax<=fTmin) printf(" Search will be performed with no restrictions on the time window \n");
11786 if (fTbin<0) printf(" Automatic time histogram binning with as mean number of bkg counts/bin : %-g \n",fabs(fTbin));
11787 if (!fTbin) printf(" Variable time histogram binning with as size (in %-s) for the first time : %-g \n",tu.Data(),fVarTbin);
11788 if (fTbin>0)
11789 {
11790 if (fTbint90)
11791 {
11792 printf(" Time histogram bin size in average T90 units : %-g",fTbin);
11793 if (fAvgrbt90>0 || fNgrbs>0) printf(" (=%-g sec)",fTbin*fabs(fAvgrbt90));
11794 printf("\n");
11795 }
11796 else
11797 {
11798 printf( " Time histogram bin size : %-g %-s \n",fTbin,tu.Data());
11799 }
11800 }
11801 if (fAbin<0)
11802 {
11803 printf(" Automatic angular histogram binning with as mean number of bkg counts per bin : %-g \n",fabs(fAbin));
11804 }
11805 else
11806 {
11807 printf(" Angular histogram bin size : %-g degrees \n",fAbin);
11808 }
11809
11810 // Parameters for burst signal and background generation
11811 if (fGrbnu)
11812 {
11813 if (fGrbnu<0)
11814 {
11815 printf(" Number of generated neutrinos per burst : %-g without statistical fluctuations \n",fabs(fGrbnu));
11816 }
11817 else
11818 {
11819 printf(" Maximum number of generated neutrinos per burst : %-g \n",fGrbnu);
11820 printf(" The actual number of neutrinos may be less due to statistical fluctuations \n");
11821 }
11822 printf(" Energy interval (in GeV) for signal event generation at the source : [%-g,%-g] \n",fESigmin,fESigmax);
11823 if (fEzcor)
11824 {
11825 printf(" The signal neutrino energy at Earth will be corrected for redshift \n");
11826 }
11827 else
11828 {
11829 printf(" No redshift correction will be applied on the generated signal neutrino energy \n");
11830 }
11831 if (!fInburst)
11832 {
11833 printf(" Neutrino production is assumed to be NOT coupled to the observed burst duration \n");
11834 printf(" Mean decoupled time difference between burst gammas/GW and neutrinos : %-g sec. \n",fDtnu);
11835 }
11836 else
11837 {
11838 printf(" Neutrino production is assumed to be coupled to the observed burst duration \n");
11839 printf(" Mean coupled time difference (in units of T90 w.r.t. trigger) between burst gammas/GW and neutrinos : %-g",fDtnu);
11840 }
11841 if (fDtnus>=0)
11842 {
11843 printf(" Sigma of mean time difference between burst gammas/GW and neutrinos : %-g sec. \n",fDtnus);
11844 }
11845 else
11846 {
11847 printf(" Sigma of mean time difference (in units of T90) between burst gammas/GW and neutrinos : %-g \n",fabs(fDtnus));
11848 }
11849 printf(" Default spectral index for a dN/dE=E^-alpha source induced signal energy spectrum within [%-g,%-g] GeV : %-g \n",fEmin,fEmax,fAlphasig);
11850 printf(" --- The user may have changed the spectrum by invokation of the memberfunction MakeBurstEnergydist(). \n");
11851 printf(" Default spectral index for a dN/dE=E^-alpha background energy spectrum within [%-g,%-g] GeV : %-g \n",fEmin,fEmax,fAlphabkg);
11852 printf(" --- The user may have changed the spectrum by invokation of the memberfunction MakeBurstEnergydist(). \n");
11853 printf(" Fixed event reco angular resolution (sigma in degrees), also used when no distribution (value) is available : %-g \n",fAngresfix);
11854 printf(" Event reconstruction angular uncertainty selection (0=use fixed value 1=mean 2=median 3=draw from distribution) : %-i \n",fRecoangle);
11855 printf(" Neutrino-lepton kinematic opening angle selection for CC interactions (0=none 1=mean 2=median 3=draw from pdf) : %-i \n",fKinangle);
11856 }
11857
11858 printf("\n");
11859 printf(" Time resolution of the neutrino detector : %-g sec. \n",fTimres);
11860 printf(" Area covered c.q. overlooked by the neutrino detector : %-g m^2 \n",fSensarea);
11861 if (fBkgrate) printf(" User defined mean rate of background events for the specified declination interval (<0 : rate per steradian) : %-g Hz \n",fBkgrate);
11862
11863 printf("\n");
11864 printf(" ============================== Derived parameters ==================================== \n");
11865 printf(" Combined source position and event reco angular uncertainty interval (sigma in degrees) : [%-g,%-g] \n",fMinsigmatot,fMaxsigmatot);
11866 printf(" Solid angle coverage corresponding to the selected declination band : %-g steradian \n",fOmegaDecl);
11867 if (fBkgrate)
11868 {
11869 printf(" Background event rate (from user setting) for the selected declination band : %-g Hz \n",fRbkgDecl);
11870 printf(" Mean number of background events (from user setting) per hour from the selected declination band : %-g \n",fNbkgHour);
11871 printf(" Mean number of background events (from user setting) in the time window from the selected declination band : %-g \n",fNbkgWin);
11872 }
11873 if (fNgrbs>0)
11874 {
11875 printf(" Number of bursts accepted for analysis : %-i \n",fNgrbs);
11876 printf(" Median source redshift from the data sample : %-g \n",fabs(fAvgrbz));
11877 if (fAvgrbt90) printf(" Median burst T90 duration from the data sample : %-g sec. \n",fabs(fAvgrbt90));
11878 printf(" Median souce position uncertainty (sigma in degrees) from the data sample : %-g \n",fAvgrbsigma);
11879 }
11880 if (fNevts>0) printf(" Number of observed events accepted for analysis : %-i \n",fNevts);
11881 printf(" ====================================================================================== \n");
11882 printf("\n");
11883}
11884
11885void NcAstrolab::LoadInputData(Bool_t src,TString file,TString tree,Int_t date1,Int_t date2,Int_t nmax,TString type)
11886{
11943
11944 // Set the default type identifier
11945 if (type=="-" && src) type="GRB";
11946 if (type=="-" && !src) type="EVT";
11947
11948 Int_t nvars=fDataNames.GetMaxRow();
11949
11950 if (nvars<1)
11951 {
11952 cout << " *" << ClassName() << "::LoadInputData* No variables were specified for " << type << " data."<< endl;
11953 return;
11954 }
11955
11956 // Set the data mode : observed events or source data
11957 Int_t iobs=1;
11958 if (src) iobs=0;
11959
11960 // Retreive the needed parameters
11961 Int_t fNmaxsrc=TMath::Nint(fBurstParameters->GetSignal("Nmaxsrc"));
11962 Int_t fNmaxevt=TMath::Nint(fBurstParameters->GetSignal("Nmaxevt"));
11963 Float_t fRAmin=fBurstParameters->GetSignal("RAmin");
11964 Float_t fRAmax=fBurstParameters->GetSignal("RAmax");
11965 Float_t fDeclmin=fBurstParameters->GetSignal("Declmin");
11966 Float_t fDeclmax=fBurstParameters->GetSignal("Declmax");
11967 Float_t fT90min=fBurstParameters->GetSignal("T90min");
11968 Float_t fT90max=fBurstParameters->GetSignal("T90max");
11969 Float_t fZmin=fBurstParameters->GetSignal("Zmin");
11970 Float_t fZmax=fBurstParameters->GetSignal("Zmax");
11971 Float_t fSigmamin=fBurstParameters->GetSignal("Sigmamin");
11972 Float_t fSigmamax=fBurstParameters->GetSignal("Sigmamax");
11973 Float_t fEmin=fBurstParameters->GetSignal("Emin");
11974 Float_t fEmax=fBurstParameters->GetSignal("Emax");
11975 Float_t fAngresmin=fBurstParameters->GetSignal("Angresmin");
11976 Float_t fAngresmax=fBurstParameters->GetSignal("Angresmax");
11977
11978 // Internal statistics
11979 Int_t fNgrbs=GetNsignals(0);
11980 Int_t fNevts=GetNsignals(1);
11981
11982 // Get access to a redshift distribution to draw randomly source redshifts if needed
11983 TH1* zdist=0;
11984 if (src && fZmin<0) zdist=GetBurstZdist("LoadInputData()",type);
11985
11986 // Get access to a T90 distribution to draw randomly source c.q. burst T90 values if needed
11987 TH1* t90dist=0;
11988 if (src && fT90min<0) t90dist=GetBurstT90dist("LoadInputData()",type);
11989
11990 // Get access to a 1-sigma position uncertainty distribution to draw randomly source position uncertaintes
11991 TH1* sigmaposdist=0;
11992 if (src && fSigmamin<0) sigmaposdist=GetBurstSigmaPosdist("LoadInputData()",type);
11993
11994 // The TTree containing the source (c.q. burst) or observed event data
11995 TChain data(tree.Data());
11996 data.Add(file.Data());
11997
11998 // The pre-defined (physical) observables
11999 TString obsname;
12000 TString varname;
12001 TString units;
12002 TString func;
12003
12004 // The (physical) observable value in string format
12005 TObjString* pval=0;
12006 TString val;
12007
12008 // The retrieved numerical (physical) observable value from the ROOT Tree
12009 Double_t value=0;
12010
12011 // The conversion factor depending on the units specification
12012 Double_t fact=0;
12013
12014 // Some of the pre-defined observable values that are used for selections
12015 // or that need special treatment
12016 TString Name,Date,Tobs,Tstart,Tend;
12017 Double_t d,a,b;
12018 Float_t z,csigma,T90,T100,E;
12019
12020 UInt_t yyyy,mm,dd; // The date format
12021 Int_t h,m; // The integer hour and minute time format
12022 Double_t s; // The (fractional) seconds time format
12023 Int_t dmode=0;
12024 Int_t idate=0;
12025 Int_t jdate=0;
12026 TString grbname;
12027 NcTimestamp tobs;
12028 NcTimestamp tstart;
12029 NcTimestamp tend;
12030 NcSignal* sx=0;
12031 Int_t nnew=0;
12032 TLeaf* lx=0;
12033 TLeafC* lxc=0;
12034 Int_t jlast=0;
12035
12036 // Create or increase the corresponding storage array to hold the new data
12037 Int_t nent=data.GetEntries();
12038 Int_t size=0;
12039 if (src) // Input represents reference objects
12040 {
12041 if (!fRefs)
12042 {
12043 fRefs=new TObjArray(nent);
12044 fRefs->SetOwner();
12045 }
12046 else
12047 {
12048 size=fRefs->GetSize();
12049 fRefs->Expand(size+nent);
12050 }
12051 }
12052 else // Input represents measured signals
12053 {
12054 if (!fSigs)
12055 {
12056 fSigs=new TObjArray(nent);
12057 fSigs->SetOwner();
12058 }
12059 else
12060 {
12061 size=fSigs->GetSize();
12062 fSigs->Expand(size+nent);
12063 }
12064 }
12065
12066 // Loop over the data entries in the input Tree
12067 for (Int_t ient=0; ient<nent; ient++)
12068 {
12069 if (nmax>=0 && nnew>=nmax) break;
12070 if (src && fNmaxsrc>=0 && (fNgrbs+nnew)>=fNmaxsrc) break;
12071 if (!src && fNmaxevt>=0 && (fNevts+nnew)>=fNmaxevt) break;
12072
12073 data.GetEntry(ient);
12074
12075 // Initialisation of the values that are used for selections
12076 // or that need special treatment
12077 Name="none";
12078 Date="none";
12079 Tobs="none";
12080 Tstart="none";
12081 Tend="none";
12082 d=-999;
12083 a=-999;
12084 b=-999;
12085 z=-999;
12086 csigma=-999;
12087 T90=-999;
12088 T100=-999;
12089 E=-999;
12090
12091 // Loop over the selected input variables and retrieve the corresponding input value
12092 for (Int_t ivar=1; ivar<=nvars; ivar++)
12093 {
12094 obsname=((TObjString*)fDataNames.GetObject(ivar,1))->GetString();
12095 varname=((TObjString*)fDataNames.GetObject(ivar,2))->GetString();
12096 units=((TObjString*)fDataNames.GetObject(ivar,3))->GetString();
12097 func=((TObjString*)fDataNames.GetObject(ivar,4))->GetString();
12098
12099 pval=(TObjString*)fDataNames.GetObject(ivar,5);
12100
12101 if (!pval) continue;
12102
12103 lx=data.GetLeaf(varname);
12104
12105 // Record -999 for missing data
12106 if (!lx)
12107 {
12108 pval->SetString("-999");
12109 continue;
12110 }
12111
12112 if (obsname=="Name") // Character string data from the input Tree
12113 {
12114 value=0;
12115 lxc=(TLeafC*)lx;
12116 Name=lxc->GetValueString();
12117 }
12118 else // Numerical data from the input Tree
12119 {
12120 value=lx->GetValue();
12121 }
12122
12123 if (func=="Log") value=pow(10,value);
12124 if (func=="Ln") value=exp(value);
12125
12126 // Convert all angular values to degrees
12127 if (obsname=="a" || obsname=="b" || obsname=="csigma") value=ConvertAngle(value,units,"deg");
12128
12129 // Convert numerical values to the standard units
12130 if (units.IsFloat())
12131 {
12132 fact=units.Atof();
12133 value*=fact;
12134 }
12135
12136 // Store the obtained value in string format
12137 val="";
12138 val+=value;
12139 pval->SetString(val);
12140
12141 // Special values needed for later selections
12142 if (obsname=="Date")
12143 {
12144 Date="";
12145 Date+=int(value);
12146 if (units=="ddmmyyyy") dmode=0;
12147 if (units=="yyyymmdd") dmode=1;
12148 if (units=="mmddyyyy") dmode=2;
12149 if (units=="yyyyddmm") dmode=3;
12150 }
12151 if (obsname=="Tobs")
12152 {
12153 Tobs="set"; // Indicate that Tobs is encountered
12154 if (units=="JD") tobs.SetJD(value);
12155 if (units=="MJD") tobs.SetMJD(value);
12156 if (units=="TJD") tobs.SetTJD(value);
12157 if (units=="hms")
12158 {
12159 Tobs="";
12160 Tobs+=value;
12161 }
12162 if (units=="hrs") // Convert "hrs" to "hms" time format
12163 {
12164 Tobs="";
12165 Convert(value,h,m,s);
12166 value=s+double(100*m+10000*h);
12167 Tobs+=value;
12168 }
12169 }
12170 if (obsname=="Tstart")
12171 {
12172 Tstart="set"; // Indicate that Tstart is encountered
12173 if (units=="JD") tstart.SetJD(value);
12174 if (units=="MJD") tstart.SetMJD(value);
12175 if (units=="TJD") tstart.SetTJD(value);
12176 if (units=="hms")
12177 {
12178 Tstart="";
12179 Tstart+=value;
12180 }
12181 if (units=="hrs") // Convert "hrs" to "hms" time format
12182 {
12183 Tstart="";
12184 Convert(value,h,m,s);
12185 value=s+double(100*m+10000*h);
12186 Tstart+=value;
12187 }
12188 }
12189 if (obsname=="Tend")
12190 {
12191 Tend="set"; // Indicate that Tend is encountered
12192 if (units=="JD") tend.SetJD(value);
12193 if (units=="MJD") tend.SetMJD(value);
12194 if (units=="TJD") tend.SetTJD(value);
12195 if (units=="hms")
12196 {
12197 Tend="";
12198 Tend+=value;
12199 }
12200 if (units=="hrs") // Convert "hrs" to "hms" time format
12201 {
12202 Tend="";
12203 Convert(value,h,m,s);
12204 value=s+double(100*m+10000*h);
12205 Tend+=value;
12206 }
12207 }
12208
12209 if (obsname=="d") d=value;
12210 if (obsname=="a") a=value;
12211 if (obsname=="b") b=value;
12212 if (obsname=="z") z=value;
12213 if (obsname=="csigma") csigma=value;
12214 if (obsname=="T90") T90=value;
12215 if (obsname=="T100") T100=value;
12216 if (obsname=="E") E=value;
12217 } // End of the loop over the selected input variables
12218
12219 // For angular coordinates the distance may be irrelevant
12220 if (d<=0) d=1;
12221
12222 // Check for the presence of valid location data
12223 if (a<-900 || b<-900) continue;
12224
12225 // Check on (RA,DEC) acceptance in case of J2000 equatorial coordinates
12226 if (fDataFrame=="equ" && fDataMode=="J" && (a<fRAmin || a>fRAmax || b<fDeclmin || b>fDeclmax)) continue;
12227
12228 // Construct the various timestamps from the (date,time) specification if needed
12229 if (Tobs!="none" && Tobs!="set" && Date!="none") tobs.SetUT(Date,Tobs,dmode);
12230 if (Tstart!="none" && Tstart!="set" && Date!="none") tstart.SetUT(Date,Tstart,dmode);
12231 if (Tend!="none" && Tend!="set" && Date!="none") tend.SetUT(Date,Tend,dmode);
12232
12233 // Check for the presence of a valid observation c.q. trigger timestamp
12234 if (Tobs=="none" || (Tobs!="set" && Date=="none")) continue;
12235
12236 // Obtain the date in yyyymmdd format
12237 tobs.GetDate(kTRUE,0,&yyyy,&mm,&dd);
12238 idate=dd+100*mm+10000*yyyy;
12239
12240 if (Name!="none") // Set the name of the object or observation
12241 {
12242 grbname=Name;
12243 }
12244 else // Compose the name of the source c.q. burst with the common yymmdd suffix
12245 {
12246 jdate=idate%1000000;
12247 grbname=type;
12248 if (jdate<100000) grbname+="0"; // Add leading zero for the year if needed
12249 grbname+=jdate;
12250 }
12251
12252 if (date1 && idate<date1) continue;
12253 if (date2 && idate>date2) continue;
12254
12255 if (src) // Source c.q. burst specific selections
12256 {
12257 if (T90<=0) T90=T100;
12258 if (fT90min<0 && T90<0 && t90dist) T90=t90dist->GetRandom();
12259
12260 if (T90<fabs(fT90min) || T90>fT90max) continue;
12261
12262 if (fZmin<0 && z<0 && zdist) z=zdist->GetRandom();
12263
12264 if (z<fabs(fZmin) || z>fZmax) continue;
12265
12266 if (fSigmamin<0 && csigma<0 && sigmaposdist) csigma=sigmaposdist->GetRandom();
12267
12268 if (csigma<fabs(fSigmamin) || csigma>fSigmamax) continue;
12269 }
12270 else // Observed event specific selections
12271 {
12272 if (E<fEmin || E>fEmax) continue;
12273 if (csigma<fAngresmin || csigma>fAngresmax) continue;
12274 }
12275
12276 // Store the location c.q. arrival direction data
12277 sx=SetSignal(d,a,"deg",b,"deg",fDataFrame,&tobs,-1,fDataMode,grbname,iobs);
12278
12279 // Obtain the RA and DEC coordinates for acceptance selection if input was not in J2000
12280 if (fDataFrame!="equ" || fDataMode!="J")
12281 {
12282 jlast=GetSignalIndex(sx,iobs);
12283 GetSignal(d,a,"deg",b,"deg","equ",&tobs,jlast,"J",iobs);
12284
12285 // Remove the signal again when it falls outside the acceptance
12286 if (a<fRAmin || a>fRAmax || b<fDeclmin || b>fDeclmax)
12287 {
12288 RemoveSignal(jlast,iobs,0);
12289 sx=0;
12290 continue;
12291 }
12292 }
12293
12294 if (!sx) continue;
12295
12296 nnew++;
12297
12298 // Storing the requested data in NcSignal slots
12299 for (Int_t ivar=1; ivar<=nvars; ivar++)
12300 {
12301 obsname=((TObjString*)fDataNames.GetObject(ivar,1))->GetString();
12302 val=((TObjString*)fDataNames.GetObject(ivar,5))->GetString();
12303
12304 // The observable Name is not stored in the NcSignal slots
12305 if (obsname=="Name") continue;
12306
12307 value=val.Atof();
12308
12309 // The values of the observables a and b depend on the reference frame
12310 // They should be retrieved via the GetSignal() facility
12311 if (obsname=="a" || obsname=="b") continue;
12312
12313 // The Date and timestamps in specific format
12314 if (obsname=="Date") value=idate;
12315 if (obsname=="Tobs") value=tobs.GetMJD();
12316 if (obsname=="Tstart") value=tstart.GetMJD();
12317 if (obsname=="TEnd") value=tend.GetMJD();
12318
12319 // Values that may have got random values
12320 if (obsname=="z") value=z;
12321 if (obsname=="csigma") value=csigma;
12322 if (obsname=="T90") value=T90;
12323
12324 sx->AddNamedSlot(obsname);
12325 sx->SetSignal(value,obsname);
12326 }
12327 } // End of loop over the entries of the input Tree
12328
12329 // Compress the storage array size to the number of actually stored elements
12330 RemoveSignal(-1,iobs,1);
12331
12332 Int_t nstored=GetNsignals(iobs);
12333
12334 cout << endl;
12335 if (src)
12336 {
12337 // Update internal statistics
12338 fBurstParameters->AddNamedSlot("Ngrbs");
12339 fBurstParameters->SetSignal(nstored,"Ngrbs");
12340 cout << " *" << ClassName() << "::LoadInputData* " << nnew << " new source(s) of type " << type
12341 << " stored from Tree:" << tree << " of file(s):" << file << endl;
12342 cout << " Total number of stored sources c.q. bursts : " << nstored << endl;
12343 }
12344 else
12345 {
12346 // Update internal statistics
12347 fBurstParameters->AddNamedSlot("Nevts");
12348 fBurstParameters->SetSignal(nstored,"Nevts");
12349 cout << " *" << ClassName() << "::LoadInputData* " << nnew
12350 << " new observed event(s) were stored from Tree:" << tree << " of file(s):" << file << endl;
12351 cout << " Total number of stored events : " << nstored << endl;
12352 }
12353}
12354
12355void NcAstrolab::GenBurstGCNdata(Int_t n,TString name,Bool_t scale)
12356{
12377
12378 // Retreive the needed parameters
12379 Int_t fNmaxsrc=TMath::Nint(fBurstParameters->GetSignal("Nmaxsrc"));
12380 Float_t fRAmin=fBurstParameters->GetSignal("RAmin");
12381 Float_t fRAmax=fBurstParameters->GetSignal("RAmax");
12382 Float_t fDeclmin=fBurstParameters->GetSignal("Declmin");
12383 Float_t fDeclmax=fBurstParameters->GetSignal("Declmax");
12384 Float_t fT90min=fBurstParameters->GetSignal("T90min");
12385 Float_t fT90max=fBurstParameters->GetSignal("T90max");
12386 Float_t fZmin=fBurstParameters->GetSignal("Zmin");
12387 Float_t fZmax=fBurstParameters->GetSignal("Zmax");
12388 Float_t fSigmamin=fBurstParameters->GetSignal("Sigmamin");
12389 Float_t fSigmamax=fBurstParameters->GetSignal("Sigmamax");
12390 Float_t fOmegaDecl=fBurstParameters->GetSignal("OmegaDecl");
12391
12392 if (scale)
12393 {
12394 Double_t pi=acos(-1.);
12395 n=TMath::Nint(double(n)*fOmegaDecl/(4.*pi));
12396 }
12397
12398 // Internal statistics
12399 Int_t fNgrbs=GetNsignals(0);
12400
12401 // Get access to a redshift distribution to draw randomly redshifts
12402 TH1* zdist=GetBurstZdist("GenBurstGCNdata()",name);
12403
12404 // Get access to a T90 distribution to draw randomly T90 values
12405 TH1* t90dist=GetBurstT90dist("GenBurstGCNdata()",name);
12406
12407 // Get access to a 1-sigma position uncertainty distribution to draw randomly position uncertaintes
12408 TH1* sigmaposdist=GetBurstSigmaPosdist("GenBurstGCNdata()",name);
12409
12410 if (!zdist || !t90dist || !sigmaposdist)
12411 {
12412 cout << endl;
12413 cout << " *" << ClassName() << "::GenBurstGCNdata* A distribution for random values is missing." << endl;
12414 cout << endl;
12415 return;
12416 }
12417
12418 Float_t thlow=90.-fDeclmax; // Lower theta angle in overall Earth spherical coordinates (North Pole is theta=0)
12419 Float_t thup=90.-fDeclmin; // Upper theta angle in overall Earth spherical coordinates (North Pole is theta=0)
12420 Float_t phimin=fRAmin; // Minimal phi angle in overall Earth spherical coordinates
12421 Float_t phimax=fRAmax; // Maximal phi angle in overall Earth spherical coordinates
12422 if (thlow<0) thlow=0;
12423 if (thup>180) thup=180;
12424
12425 NcSignal* sx=0;
12426 NcPosition rgrb;
12427 Float_t t90grb=0;
12428 Float_t zgrb=0;
12429 Float_t sigmagrb=0;
12430 TString grbname;
12431 Double_t thetagrb,phigrb,ragrb,decgrb;
12432 Int_t ngen=0;
12433
12434 for (Int_t igrb=1; igrb<=n; igrb++)
12435 {
12436 if (fNmaxsrc>=0 && (fNgrbs+ngen)>=fNmaxsrc) break;
12437
12438 zgrb=-1;
12439 if (fabs(fZmin)==fZmax) zgrb=fZmax;
12440 while (zgrb<fabs(fZmin) || zgrb>fZmax)
12441 {
12442 zgrb=zdist->GetRandom();
12443 }
12444
12445 t90grb=-1;
12446 if (fabs(fT90min)==fT90max) t90grb=fT90max;
12447 while (t90grb<fabs(fT90min) || t90grb>fT90max)
12448 {
12449 t90grb=t90dist->GetRandom();
12450 t90grb=pow(float(10),t90grb);
12451 }
12452
12453 sigmagrb=-1;
12454 if (fabs(fSigmamin)==fSigmamax) sigmagrb=fSigmamax;
12455 while (sigmagrb<fabs(fSigmamin) || sigmagrb>fSigmamax)
12456 {
12457 sigmagrb=sigmaposdist->GetRandom();
12458 }
12459
12460 rgrb.SetPosition(1,0,0,"sph","deg");
12461 RandomPosition(rgrb,thlow,thup,phimin,phimax);
12462 thetagrb=rgrb.GetX(2,"sph","deg");
12463 phigrb=rgrb.GetX(3,"sph","deg");
12464
12465 grbname="Random-";
12466 grbname+=name;
12467 grbname+=igrb;
12468 grbname+="#";
12469 ragrb=phigrb;
12470 decgrb=90.-thetagrb;
12471 sx=SetSignal(1,ragrb,"deg",decgrb,"deg","equ",0,-1,"J",grbname);
12472
12473 if (!sx) continue;
12474
12475 ngen++;
12476
12477 sx->AddNamedSlot("T90");
12478 sx->SetSignal(t90grb,"T90");
12479 sx->AddNamedSlot("csigma");
12480 sx->SetSignal(sigmagrb,"csigma");
12481 sx->AddNamedSlot("z");
12482 sx->SetSignal(zgrb,"z");
12483
12484 }
12485
12486 // Update internal statistics
12487 fNgrbs=GetNsignals(0);
12488 fBurstParameters->AddNamedSlot("Ngrbs");
12489 fBurstParameters->SetSignal(fNgrbs,"Ngrbs");
12490
12491 cout << endl;
12492 cout << " *" << ClassName() << "::GenBurstGCNdata* " << ngen << " new generated bursts with name " << name << " were stored." << endl;
12493 cout << " Total number of stored bursts : " << fNgrbs << endl;
12494}
12495
12496void NcAstrolab::MakeBurstZdist(TString file,TString tree,TString name,Int_t nb,Float_t zmin,Float_t zmax)
12497{
12529
12530 // The Tree containing the archival data
12531 TChain data(tree.Data());
12532 data.Add(file.Data());
12533
12534 Int_t nen=data.GetEntries();
12535 TLeaf* lx=data.FindLeaf(name.Data());
12536
12537 if (!nen || !lx)
12538 {
12539 cout << " *" << ClassName() << "::MakeBurstZdist* Missing information for tree variable:" << name << endl;
12540 cout << " of Tree:" << tree << " with " << nen << " entries in file:" << file << endl;
12541 return;
12542 }
12543
12544 // Create new distributions in case a redshift distribution is not yet present
12545 TH1* zdist=(TH1*)fBurstHistos.FindObject("hz");
12546 if (!zdist)
12547 {
12548 // Creation of the archival burst redshift histogram
12549 TH1F* hz=new TH1F("hz","Archival data of observed burst redshifts",nb,zmin,zmax);
12550 fBurstHistos.Add(hz);
12551 hz->GetXaxis()->SetTitle("Burst redshift");
12552 hz->GetYaxis()->SetTitle("Counts");
12553
12554 // Creation of the corresponding physical distance histo
12555 Float_t dmin=GetPhysicalDistance(zmin);
12556 Float_t dmax=GetPhysicalDistance(zmax);
12557 TH1F* hd=new TH1F("hd","Burst distances derived from the archival redshift data",nb,dmin,dmax);
12558 fBurstHistos.Add(hd);
12559 hd->GetXaxis()->SetTitle("Burst physical distance in Mpc");
12560 hd->GetYaxis()->SetTitle("Counts");
12561 }
12562
12563 // Get pointers to the relevant histograms
12564 TH1* hz=(TH1*)fBurstHistos.FindObject("hz");
12565 TH1* hd=(TH1*)fBurstHistos.FindObject("hd");
12566
12567 Int_t nz=0;
12568 Double_t z=0;
12569 Double_t d=0;
12570 for (Int_t ien=0; ien<nen; ien++)
12571 {
12572 data.GetEntry(ien);
12573
12574 lx=data.GetLeaf(name.Data());
12575 if (!lx) continue;
12576
12577 z=lx->GetValue();
12578 if (z<zmin || z>zmax) continue;
12579
12580 hz->Fill(z);
12581 nz++;
12582
12584 hd->Fill(d);
12585 }
12586
12587 cout << " *" << ClassName() << "::MakeBurstZdist* " << nz << " archival z-values have been obtained from tree variable:" << name
12588 << " of Tree:" << tree << " in file(s):" << file << endl;
12589}
12590
12591TH1* NcAstrolab::GetBurstZdist(TString name,TString type)
12592{
12601
12602 TH1* zdist=(TH1*)fBurstHistos.FindObject("hz");
12603 if (!zdist)
12604 {
12605 if (type.Contains("GRB"))
12606 {
12607 cout << endl;
12608 cout << " *" << ClassName() << "::GetBurstZdist* Called from " << name << endl;
12609 cout << " *** Archival observed redshift distribution not found. ***" << endl;
12610 cout << " A Landau fit from Swift GRB redshift data will be used to provide missing c.q. random z values." << endl;
12611
12612 zdist=(TH1*)fBurstHistos.FindObject("hZpdf");
12613 if (!zdist)
12614 {
12615 TF1 fz("fz","59.54*TMath::Landau(x,1.092,0.5203)");
12616 fz.SetRange(0,10);
12617 fz.SetNpx(10000);
12618 TH1* hfz=fz.GetHistogram();
12619 zdist=(TH1*)hfz->Clone();
12620 zdist->SetNameTitle("hZpdf","Landau fit for Swift GRB z data");
12621 zdist->GetXaxis()->SetTitle("GRB redshift");
12622 zdist->GetYaxis()->SetTitle("Counts");
12623 fBurstHistos.Add(zdist);
12624 }
12625 }
12626 else // Source class for which no fit is available
12627 {
12628 cout << endl;
12629 cout << " *" << ClassName() << "::GetBurstZdist* Called from " << name << endl;
12630 cout << " *** No redshift fit is available for source class " << type << " ***" << endl;
12631 }
12632 }
12633
12634 return zdist;
12635}
12636
12637void NcAstrolab::MakeBurstT90dist(TString file,TString tree,TString name,Int_t nb,Float_t xmin,Float_t xmax)
12638{
12668
12669 // The Tree containing the burst data
12670 TChain data(tree.Data());
12671 data.Add(file.Data());
12672
12673 Int_t nen=data.GetEntries();
12674 TLeaf* lx=data.FindLeaf(name.Data());
12675
12676 if (!nen || !lx)
12677 {
12678 cout << " *" << ClassName() << "::MakeBurstT90dist* Missing information for tree variable:" << name << endl;
12679 cout << " of Tree:" << tree << " with " << nen << " entries in file:" << file << endl;
12680 return;
12681 }
12682
12683 // Create a new distribution in case a T90 distribution is not yet present
12684 TH1* t90dist=(TH1*)fBurstHistos.FindObject("ht90");
12685 if (!t90dist)
12686 {
12687 // Creation of observed burst t90 duration histo
12688 TH1F* ht90=new TH1F("ht90","Archival data of observed burst durations",nb,xmin,xmax);
12689 fBurstHistos.Add(ht90);
12690 ht90->GetXaxis()->SetTitle("Burst duration ^{10}log(T90) in sec.");
12691 ht90->GetYaxis()->SetTitle("Counts");
12692 }
12693
12694 // Get pointer to the relevant histogram
12695 TH1* ht90=(TH1*)fBurstHistos.FindObject("ht90");
12696
12697 Int_t nt90=0;
12698 Double_t t90=0;
12699 for (Int_t ien=0; ien<nen; ien++)
12700 {
12701 data.GetEntry(ien);
12702
12703 lx=data.GetLeaf(name.Data());
12704 if (!lx) continue;
12705
12706 t90=lx->GetValue();
12707 if (t90>0)
12708 {
12709 ht90->Fill(log10(t90));
12710 nt90++;
12711 }
12712 }
12713
12714 cout << " *" << ClassName() << "::MakeBurstT90dist* " << nt90 << " archival T90 values have been obtained from variable:" << name
12715 << " of Tree:" << tree << " in file(s):" << file << endl;
12716}
12717
12718TH1* NcAstrolab::GetBurstT90dist(TString name,TString type)
12719{
12728
12729 TH1* t90dist=(TH1*)fBurstHistos.FindObject("ht90");
12730 if (!t90dist)
12731 {
12732 if (type.Contains("GRB"))
12733 {
12734 cout << endl;
12735 cout << " *" << ClassName() << "::GetBurstT90dist* Called from " << name << endl;
12736 cout << " *** Observational T90 distribution not found. ***" << endl;
12737 cout << " A double Gaussian fit from Fermi GRB T90 data will be used to provide missing c.q. random T90 values." << endl;
12738
12739 t90dist=(TH1*)fBurstHistos.FindObject("hT90pdf");
12740 if (!t90dist)
12741 {
12742 TF1 ft("ft","44.39*TMath::Gaus(x,-0.131,0.481)+193.8*TMath::Gaus(x,1.447,0.4752)");
12743 ft.SetRange(-5,5);
12744 ft.SetNpx(10000);
12745 TH1* hft=ft.GetHistogram();
12746 t90dist=(TH1*)hft->Clone();
12747 t90dist->SetNameTitle("hT90pdf","Double Gauss fit for Fermi t90 data");
12748 t90dist->GetXaxis()->SetTitle("GRB duration ^{10}log(T90) in sec.");
12749 t90dist->GetYaxis()->SetTitle("Counts");
12750 fBurstHistos.Add(t90dist);
12751 }
12752 }
12753 else // Source class for which no fit is available
12754 {
12755 cout << endl;
12756 cout << " *" << ClassName() << "::GetBurstT90dist* Called from " << name << endl;
12757 cout << " *** No T90 fit is available for source class " << type << " ***" << endl;
12758 }
12759 }
12760
12761 return t90dist;
12762}
12763
12764void NcAstrolab::MakeBurstSigmaPosdist(TString file,TString tree,TString name,TString u,Int_t nb,Float_t xmin,Float_t xmax)
12765{
12804
12805 // The Tree containing the burst data
12806 TChain data(tree.Data());
12807 data.Add(file.Data());
12808
12809 Int_t nen=data.GetEntries();
12810 TLeaf* lx=data.FindLeaf(name.Data());
12811
12812 if (!nen || !lx)
12813 {
12814 cout << " *" << ClassName() << "::MakeBurstSigmaPosdist* Missing information for tree variable:" << name << endl;
12815 cout << " of Tree:" << tree << " with " << nen << " entries in file:" << file << endl;
12816 return;
12817 }
12818
12819 // Create a new distribution in case a burst position uncertainty distribution is not yet present
12820 TH1* sigmaposdist=(TH1*)fBurstHistos.FindObject("hsigmapos");
12821 if (!sigmaposdist)
12822 {
12823 // Creation of observed 1-sigma burst position uncertainty histo
12824 TH1F* hsigmapos=new TH1F("hsigmapos","Archival data of observed 1-sigma burst position uncertainties",nb,xmin,xmax);
12825 fBurstHistos.Add(hsigmapos);
12826 hsigmapos->GetXaxis()->SetTitle("Burst position uncertainty (sigma in degrees)");
12827 hsigmapos->GetYaxis()->SetTitle("Counts");
12828 }
12829
12830 // Get pointer to the relevant histogram
12831 TH1* hsigmapos=(TH1*)fBurstHistos.FindObject("hsigmapos");
12832
12833 Int_t nsigmapos=0;
12834 Double_t sigmapos=0;
12835 for (Int_t ien=0; ien<nen; ien++)
12836 {
12837 data.GetEntry(ien);
12838
12839 lx=data.GetLeaf(name.Data());
12840 if (!lx) continue;
12841
12842 sigmapos=lx->GetValue();
12843
12844 // Convert declination to degrees if needed
12845 sigmapos=ConvertAngle(sigmapos,u,"deg");
12846
12847 if (sigmapos<xmin || sigmapos>xmax) continue;
12848
12849 hsigmapos->Fill(sigmapos);
12850 nsigmapos++;
12851 }
12852
12853 cout << " *" << ClassName() << "::MakeBurstSigmaPosdist* " << nsigmapos << " archival sigmapos values have been obtained from variable:" << name
12854 << " of Tree:" << tree << " in file(s):" << file << endl;
12855}
12856
12857TH1* NcAstrolab::GetBurstSigmaPosdist(TString name,TString type)
12858{
12867
12868 TH1* sigmaposdist=(TH1*)fBurstHistos.FindObject("hsigmapos");
12869 if (!sigmaposdist)
12870 {
12871 if (type.Contains("GRB"))
12872 {
12873 cout << endl;
12874 cout << " *" << ClassName() << "::GetBurstSigmaPosdist* Called from " << name << endl;
12875 cout << " *** Archival observed GRB position uncertainty distribution not found. ***" << endl;
12876 cout << " A Landau fit from observed GRB data will be used to provide missing c.q. random 1-sigma uncertainty values." << endl;
12877
12878 sigmaposdist=(TH1*)fBurstHistos.FindObject("hSigmaSourcePDF");
12879 if (!sigmaposdist)
12880 {
12881 TF1 fsigmapos("fsigmapos","245.2*TMath::Landau(x,-2.209,0.6721,1)");
12882 fsigmapos.SetRange(0,90);
12883 fsigmapos.SetNpx(10000);
12884 TH1* hfsigmapos=fsigmapos.GetHistogram();
12885 sigmaposdist=(TH1*)hfsigmapos->Clone();
12886 sigmaposdist->SetNameTitle("hSigmaSourcePDF","Landau fit for burst 1-sigma position uncertainty data");
12887 sigmaposdist->GetXaxis()->SetTitle("Burst position uncertainty (sigma in degrees)");
12888 sigmaposdist->GetYaxis()->SetTitle("Counts");
12889 fBurstHistos.Add(sigmaposdist);
12890 }
12891 }
12892 else // Source class for which no fit is available
12893 {
12894 cout << endl;
12895 cout << " *" << ClassName() << "::GetBurstSigmaPosdist* Called from " << name << endl;
12896 cout << " *** No position uncertainty fit is available for source class " << type << " ***" << endl;
12897 }
12898 }
12899
12900 return sigmaposdist;
12901}
12902
12903void NcAstrolab::MakeBurstEnergydist(Int_t mode,TF1& spec,Double_t Emin,Double_t Emax,Int_t nbins)
12904{
12930
12931 if (Emin<=0) Emin=1e-10;
12932
12933 if ((mode!=1 && mode!=2) || Emax<=Emin)
12934 {
12935 cout << " *" << ClassName() << "::MakeBurstEnergydist* Inconsistent data: mode=" << mode << " Emin=" << Emin << " Emax=" << Emax << endl;
12936 return;
12937 }
12938
12939 // Convert the energy boundaries to the log10 scale of the X-axis
12940 Double_t xmin=log10(Emin);
12941 Double_t xmax=log10(Emax);
12942
12943 TString sf="dN/dE=";
12944 sf+=spec.GetExpFormula("p");
12945 if (mode==1) sf+=" background";
12946 if (mode==2) sf+=" signal";
12947 sf+=" distribution";
12948 sf.ReplaceAll("x","E");
12949 TString sh="";
12950 if (mode==1) sh="Background energy distribution;^{10}Log(E) in GeV;";
12951 if (mode==2) sh="Source induced signal energy distribution;^{10}Log(E) in GeV;";
12952 sh+=sf;
12953 TH1F his=GetCountsHistogram(spec,nbins,xmin,xmax,1,sh);
12954
12955 // Remove the corresponding old distribution (if any) from the storage
12956 TH1* dist=0;
12957 if (mode==1) dist=(TH1*)fBurstHistos.FindObject("hBkgEpdf");
12958 if (mode==2) dist=(TH1*)fBurstHistos.FindObject("hSigEpdf");
12959 if (dist)
12960 {
12961 fBurstHistos.Remove(dist);
12962 fBurstHistos.Compress();
12963 delete dist;
12964 dist=0;
12965 }
12966
12967 // Store the newly created distribution
12968 // and set a flag to indicate a parametrized distribution
12969 if (mode==1)
12970 {
12971 TH1F* hBkgEpdf=(TH1F*)his.Clone();
12972 hBkgEpdf->SetName("hBkgEpdf");
12973 fBurstHistos.Add(hBkgEpdf);
12974 fBurstParameters->AddNamedSlot("PDFbkgE");
12975 fBurstParameters->SetSignal(1,"PDFbkgE");
12976 }
12977 if (mode==2)
12978 {
12979 TH1F* hSigEpdf=(TH1F*)his.Clone();
12980 hSigEpdf->SetName("hSigEpdf");
12981 fBurstHistos.Add(hSigEpdf);
12982 fBurstParameters->AddNamedSlot("PDFsigE");
12983 fBurstParameters->SetSignal(1,"PDFsigE");
12984 }
12985
12986 cout << " *" << ClassName() << "::MakeBurstEnergydist* Created a " << sf
12987 << " on [Emin,Emax]=[" << Emin << "," << Emax << "] GeV" << endl;
12988}
12989
12990void NcAstrolab::MakeBurstEnergydist(Int_t mode,Double_t alpha,Double_t Emin,Double_t Emax,Int_t nbins)
12991{
13018
13019 TF1 spec("spec","pow(x,[0])");
13020 spec.SetParameter(0,-alpha);
13021 MakeBurstEnergydist(mode,spec,Emin,Emax,nbins);
13022}
13023
13024void NcAstrolab::MakeBurstEnergydist(Int_t mode,TString file,TString tree,TString name1,TString name2,TString u,Double_t Emin,Double_t Emax,Int_t nb)
13025{
13080
13081 Float_t fDeclmin=fBurstParameters->GetSignal("Declmin");
13082 Float_t fDeclmax=fBurstParameters->GetSignal("Declmax");
13083
13084 if (Emin<=0) Emin=1e-10;
13085
13086 if ((abs(mode)!=1 && abs(mode)!=2) || Emax<=Emin)
13087 {
13088 cout << " *" << ClassName() << "::MakeBurstEnergydist* Inconsistent data: mode=" << mode << " Emin=" << Emin << " Emax=" << Emax << endl;
13089 return;
13090 }
13091
13092 // Convert the energy boundaries to the log10 scale of the X-axis
13093 Double_t xmin=log10(Emin);
13094 Double_t xmax=log10(Emax);
13095
13096 // The Tree containing the burst data
13097 TChain data(tree.Data());
13098 data.Add(file.Data());
13099
13100 Int_t nen=data.GetEntries();
13101
13102 if (!nen || !data.FindLeaf(name1.Data()) || !data.FindLeaf(name2.Data()))
13103 {
13104 cout << " *" << ClassName() << "::MakeBurstEnergydist* Missing information for tree variable:" << name1
13105 << " and/or tree variable:" << name2 << endl;
13106 cout << " of Tree:" << tree << " with " << nen << " entries in file:" << file << endl;
13107 return;
13108 }
13109
13110 // A corresponding parametrized distribution will always be removed
13111 Int_t flag=0;
13112 if (abs(mode)==1) flag=TMath::Nint(fBurstParameters->GetSignal("PDFbkgE"));
13113 if (abs(mode)==2) flag=TMath::Nint(fBurstParameters->GetSignal("PDFsigE"));
13114
13115 if (flag) mode=abs(mode);
13116
13117 // Remove the corresponding old distribution (if requested) from the storage
13118 TH1* Edist=0;
13119 if (abs(mode)==1) Edist=(TH1*)fBurstHistos.FindObject("hBkgEpdf");
13120 if (abs(mode)==2) Edist=(TH1*)fBurstHistos.FindObject("hSigEpdf");
13121
13122 if (mode>0 && Edist)
13123 {
13124 fBurstHistos.Remove(Edist);
13125 fBurstHistos.Compress();
13126 delete Edist;
13127 Edist=0;
13128 }
13129
13130 // Create a new distribution if needed
13131 if (!Edist)
13132 {
13133 mode=abs(mode);
13134 if (mode==1)
13135 {
13136 // Creation of the observed background energy histo
13137 TH1F* hBkgEpdf=new TH1F("hBkgEpdf","Archival data of observed background energies",nb,xmin,xmax);
13138 fBurstHistos.Add(hBkgEpdf);
13139 hBkgEpdf->GetXaxis()->SetTitle("^{10}log(Energy) in GeV");
13140 hBkgEpdf->GetYaxis()->SetTitle("Counts");
13141 fBurstParameters->AddNamedSlot("PDFbkgE");
13142 fBurstParameters->SetSignal(0,"PDFbkgE");
13143 }
13144 if (mode==2)
13145 {
13146 // Creation of the observed signal energy histo
13147 TH1F* hSigEpdf=new TH1F("hSigEpdf","Archival data of observed signal energies",nb,xmin,xmax);
13148 fBurstHistos.Add(hSigEpdf);
13149 hSigEpdf->GetXaxis()->SetTitle("^{10}log(Energy) in GeV");
13150 hSigEpdf->GetYaxis()->SetTitle("Counts");
13151 fBurstParameters->AddNamedSlot("PDFsigE");
13152 fBurstParameters->SetSignal(0,"PDFsigE");
13153 fBurstParameters->SetSignal(0,"Ezcor");
13154 }
13155 }
13156
13157 // Get pointer to the relevant histogram
13158 if (abs(mode)==1) Edist=(TH1*)fBurstHistos.FindObject("hBkgEpdf");
13159 if (abs(mode)==2) Edist=(TH1*)fBurstHistos.FindObject("hSigEpdf");
13160
13161 Int_t nE=0;
13162 Double_t logE=0;
13163 Double_t dec=0;
13164 TLeaf* lx=0;
13165 for (Int_t ien=0; ien<nen; ien++)
13166 {
13167 data.GetEntry(ien);
13168
13169 lx=data.GetLeaf(name1.Data());
13170 if (!lx) continue;
13171
13172 logE=lx->GetValue();
13173
13174 lx=data.GetLeaf(name2.Data());
13175 if (!lx) continue;
13176
13177 dec=lx->GetValue();
13178
13179 // Convert declination to degrees if needed
13180 dec=ConvertAngle(dec,u,"deg");
13181
13182 if (dec>=fDeclmin && dec<=fDeclmax)
13183 {
13184 Edist->Fill(logE);
13185 nE++;
13186 }
13187 }
13188
13189 TString smode="";
13190 if (abs(mode)==1) smode="archival background";
13191 if (abs(mode)==2) smode="archival signal";
13192
13193 if (mode>0)
13194 {
13195 cout << " *" << ClassName() << "::MakeBurstEnergydist* A new " << smode
13196 << " energy distribution has been created." << endl;
13197 }
13198 else
13199 {
13200 cout << " *" << ClassName() << "::MakeBurstEnergydist* Statistics of the existing " << smode
13201 << " energy distribution have been increased." << endl;
13202 }
13203
13204 cout << " " << nE << " energy values have been obtained from variable:" << name1
13205 << " of Tree:" << tree << " in file(s):" << file << endl;
13206}
13207
13208void 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)
13209{
13257
13258 Float_t fDeclmin=fBurstParameters->GetSignal("Declmin");
13259 Float_t fDeclmax=fBurstParameters->GetSignal("Declmax");
13260
13261 if (Emin<=0) Emin=1e-10;
13262
13263 if (Emax<=Emin)
13264 {
13265 cout << " *" << ClassName() << "::MakeBurstRecoAngresdist* Inconsistent data: Emin=" << Emin << " Emax=" << Emax << endl;
13266 return;
13267 }
13268
13269 // Convert the energy boundaries to the log10 scale of the X-axis
13270 Double_t xmin=log10(Emin);
13271 Double_t xmax=log10(Emax);
13272
13273 // The Tree containing the burst data
13274 TChain data(tree.Data());
13275 data.Add(file.Data());
13276
13277 Int_t nen=data.GetEntries();
13278
13279 if (!nen || !data.FindLeaf(name1.Data()) || !data.FindLeaf(name2.Data()) || !data.FindLeaf(name3.Data()))
13280 {
13281 cout << " *" << ClassName() << "::MakeBurstRecoAngresdist* Missing information for tree variable:" << name1
13282 << " and/or tree variable:" << name2 << " and/or tree variable:" << name3 << endl;
13283 cout << " of Tree:" << tree << " with " << nen << " entries in file:" << file << endl;
13284 return;
13285 }
13286
13287 // Create a new distribution in case a reconstruction angle resolution vs. energy distribution is not yet present
13288 TH2* Angresdist=(TH2*)fBurstHistos.FindObject("hAngresE");
13289 if (!Angresdist)
13290 {
13291 // Creation of the observed reconstruction angle resolution vs. energy histo
13292 TH2F* hAngresE=new TH2F("hAngresE","Archival data of observed reconstruction angle resolution vs. energy",
13293 nbe,xmin,xmax,nba,0,180.1);
13294 fBurstHistos.Add(hAngresE);
13295 hAngresE->GetXaxis()->SetTitle("^{10}log(Energy) in GeV");
13296 hAngresE->GetYaxis()->SetTitle("Angular resolution in degrees");
13297 }
13298
13299 // Get pointer to the relevant histogram
13300 TH2* hAngresE=(TH2*)fBurstHistos.FindObject("hAngresE");
13301
13302 Int_t nE=0;
13303 Double_t logE=0;
13304 Double_t dec=0;
13305 Double_t dang=0;
13306 TLeaf* lx=0;
13307 for (Int_t ien=0; ien<nen; ien++)
13308 {
13309 data.GetEntry(ien);
13310
13311 lx=data.GetLeaf(name1.Data());
13312 if (!lx) continue;
13313
13314 logE=lx->GetValue();
13315
13316 lx=data.GetLeaf(name2.Data());
13317 if (!lx) continue;
13318
13319 dang=lx->GetValue();
13320
13321 // Convert declination to degrees if needed
13322 dang=ConvertAngle(dang,ua,"deg");
13323
13324 lx=data.GetLeaf(name3.Data());
13325 if (!lx) continue;
13326
13327 dec=lx->GetValue();
13328
13329 // Convert declination to degrees if needed
13330 dec=ConvertAngle(dec,ud,"deg");
13331
13332 if (dec>=fDeclmin && dec<=fDeclmax)
13333 {
13334 hAngresE->Fill(logE,dang);
13335 nE++;
13336 }
13337 }
13338
13339 cout << " *" << ClassName() << "::MakeBurstRecoAngresdist* " << nE << " archival entries have been obtained for variables:" << name2
13340 << " vs. " << name1 << " of Tree:" << tree << " in file(s):" << file << endl;
13341}
13342
13343Double_t NcAstrolab::GetBurstSignalEnergy(Double_t Emin,Double_t Emax) const
13344{
13362
13363 Double_t E=-1;
13364
13365 // Get pointer to the relevant histogram
13366 TH1* hSigEpdf=(TH1*)fBurstHistos.FindObject("hSigEpdf");
13367
13368 if (!hSigEpdf) return E;
13369
13370 Int_t nbins=hSigEpdf->GetNbinsX();
13371 Int_t nentries=hSigEpdf->GetEntries();
13372
13373 if (nbins<=0 || nentries<=0) return E;
13374
13375 TAxis* xaxis=hSigEpdf->GetXaxis();
13376
13377 if (!xaxis) return E;
13378
13379 Double_t xlow=xaxis->GetBinLowEdge(1);
13380 Double_t xup=xaxis->GetBinUpEdge(nbins);
13381
13382 Double_t logEmin=0;
13383 if (Emin<=0)
13384 {
13385 logEmin=xlow;
13386 }
13387 else
13388 {
13389 logEmin=log10(Emin);
13390 }
13391
13392 Double_t logEmax=0;
13393 if (Emax<=0)
13394 {
13395 logEmax=xup;
13396 }
13397 else
13398 {
13399 logEmax=log10(Emax);
13400 }
13401
13402 if (logEmax<=logEmin || logEmin>=xup || logEmax<=xlow) return E;
13403
13404 while (E<logEmin || E>logEmax)
13405 {
13406 E=hSigEpdf->GetRandom();
13407 }
13408
13409 E=pow(float(10),E);
13410
13411 return E;
13412}
13413
13414Double_t NcAstrolab::GetBurstBackgroundEnergy(Double_t Emin,Double_t Emax) const
13415{
13433
13434 Double_t E=-1;
13435
13436 // Get pointer to the relevant histogram
13437 TH1* hBkgEpdf=(TH1*)fBurstHistos.FindObject("hBkgEpdf");
13438
13439 if (!hBkgEpdf) return E;
13440
13441 Int_t nbins=hBkgEpdf->GetNbinsX();
13442 Int_t nentries=hBkgEpdf->GetEntries();
13443
13444 if (nbins<=0 || nentries<=0) return E;
13445
13446 TAxis* xaxis=hBkgEpdf->GetXaxis();
13447
13448 if (!xaxis) return E;
13449
13450 Double_t xlow=xaxis->GetBinLowEdge(1);
13451 Double_t xup=xaxis->GetBinUpEdge(nbins);
13452
13453 Double_t logEmin=0;
13454 if (Emin<=0)
13455 {
13456 logEmin=xlow;
13457 }
13458 else
13459 {
13460 logEmin=log10(Emin);
13461 }
13462
13463 Double_t logEmax=0;
13464 if (Emax<=0)
13465 {
13466 logEmax=xup;
13467 }
13468 else
13469 {
13470 logEmax=log10(Emax);
13471 }
13472
13473 if (logEmax<=logEmin || logEmin>=xup || logEmax<=xlow) return E;
13474
13475 while (E<logEmin || E>logEmax)
13476 {
13477 E=hBkgEpdf->GetRandom();
13478 }
13479
13480 E=pow(float(10),E);
13481
13482 return E;
13483}
13484
13485Double_t NcAstrolab::GetBurstRecoAngres(Double_t Emin,Double_t Emax,Double_t Amin,Double_t Amax) const
13486{
13510
13511 Double_t dang=-1;
13512
13513 if (Amin<0) Amin=0;
13514
13515 Int_t fRecoangle=TMath::Nint(fBurstParameters->GetSignal("Recoangle"));
13516 Float_t fAngresfix=fBurstParameters->GetSignal("Angresfix");
13517
13518 // The user requested a fixed angular resolution value "Angresfix"
13519 if (!fRecoangle)
13520 {
13521 dang=fAngresfix;
13522 return dang;
13523 }
13524
13525 // The user requested an angular resolution based on a distribution
13526
13527 // Get pointer to the reco angle resolution vs. energy distribution histogram
13528 TH2* hAngresE=(TH2*)fBurstHistos.FindObject("hAngresE");
13529
13530 // No distribution available -> Return the user provided "Angresfix" value
13531 if (!hAngresE)
13532 {
13533 dang=fAngresfix;
13534 return dang;
13535 }
13536
13537 // Obtain the projected reco angle resolution distribution within the [Emin,Emax] interval
13538
13539 Int_t nbins=hAngresE->GetNbinsX();
13540 Int_t nentries=hAngresE->GetEntries();
13541
13542 if (nbins<=0 || nentries<=0) return dang;
13543
13544 TAxis* xaxis=hAngresE->GetXaxis();
13545
13546 if (!xaxis) return dang;
13547
13548 Double_t xlow=xaxis->GetBinLowEdge(1);
13549 Double_t xup=xaxis->GetBinUpEdge(nbins);
13550
13551 Double_t logEmin=0;
13552 if (Emin<=0)
13553 {
13554 logEmin=xlow;
13555 }
13556 else
13557 {
13558 logEmin=log10(Emin);
13559 }
13560
13561 Double_t logEmax=0;
13562 if (Emax<=0)
13563 {
13564 logEmax=xup;
13565 }
13566 else
13567 {
13568 logEmax=log10(Emax);
13569 }
13570
13571 if (logEmax<logEmin || logEmin>=xup || logEmax<=xlow) return dang;
13572
13573 Int_t ilow=xaxis->FindBin(logEmin);
13574 Int_t iup=xaxis->FindBin(logEmax);
13575
13576 TH1D* hproj=hAngresE->ProjectionY("hproj",ilow,iup);
13577
13578 if (!hproj) return dang;
13579
13580 nbins=hproj->GetNbinsX();
13581 nentries=hproj->GetEntries();
13582
13583 if (nbins<=0 || nentries<=0) return dang;
13584
13585 if (fRecoangle==1) dang=hproj->GetMean();
13586
13587 if (fRecoangle==2)
13588 {
13589 NcSample q;
13590 dang=q.GetMedian(hproj);
13591 }
13592
13593 if (fRecoangle==3)
13594 {
13595 xaxis=hproj->GetXaxis();
13596
13597 if (!xaxis) return dang;
13598
13599 xlow=xaxis->GetBinLowEdge(1);
13600 xup=xaxis->GetBinUpEdge(nbins);
13601
13602 if (Amax<=Amin || Amin>=xup || Amax<=xlow) return dang;
13603
13604 dang=Amin-1.;
13605 while (dang<Amin || dang>Amax)
13606 {
13607 dang=hproj->GetRandom();
13608 }
13609 }
13610
13611 if (hproj) delete hproj;
13612
13613 return dang;
13614}
13615
13617{
13636
13637 // Signal and background generation can only be performed for a user defined fixed time window size
13638 Float_t fTmin=fBurstParameters->GetSignal("Tmin");
13639 Float_t fTmax=fBurstParameters->GetSignal("Tmax");
13640 if (fTmax<=fTmin)
13641 {
13642 printf("\n *%-s::GenBurstSignals* Error : [Tmin,Tmax]=[%-g,%-g] whereas Tmin<Tmax is required. \n",ClassName(),fTmin,fTmax);
13643 return;
13644 }
13645
13646 // If needed, initialise the randomiser with a "date/time driven" seed
13647 // using the timestamp of the moment of this invokation of the member function.
13648 // This will ensure different random sequences if the user repeats analyses
13649 // with identical measurements and reference signals without explicit initialisation
13650 // of the randomiser by the user at the start of the analysis.
13651 if (!fRan) fRan=new NcRandom(-1);
13652
13654 // Initialise the final sample histograms //
13656
13658
13659 // Retrieve the needed parameters
13660 Float_t fRAmin=fBurstParameters->GetSignal("RAmin");
13661 Float_t fRAmax=fBurstParameters->GetSignal("RAmax");
13662 Float_t fDeclmin=fBurstParameters->GetSignal("Declmin");
13663 Float_t fDeclmax=fBurstParameters->GetSignal("Declmax");
13664 Float_t fTimres=fBurstParameters->GetSignal("Timres");
13665 Int_t fEzcor=TMath::Nint(fBurstParameters->GetSignal("Ezcor"));
13666 Int_t fPDFsigE=TMath::Nint(fBurstParameters->GetSignal("PDFsigE"));
13667 Float_t fEmin=fBurstParameters->GetSignal("Emin");
13668 Float_t fEmax=fBurstParameters->GetSignal("Emax");
13669 Int_t fKinangle=TMath::Nint(fBurstParameters->GetSignal("Kinangle"));
13670 Float_t fAngresmin=fBurstParameters->GetSignal("Angresmin");
13671 Float_t fAngresmax=fBurstParameters->GetSignal("Angresmax");
13672 Float_t fAngresfix=fBurstParameters->GetSignal("Angresfix");
13673 Int_t fRecoangle=TMath::Nint(fBurstParameters->GetSignal("Recoangle"));
13674 Int_t fSumsigmas=TMath::Nint(fBurstParameters->GetSignal("Sumsigmas"));
13675 Float_t fTfact=fBurstParameters->GetSignal("Tfact");
13676 Float_t fDawin=fBurstParameters->GetSignal("Dawin");
13677 Int_t fDatype=TMath::Nint(fBurstParameters->GetSignal("Datype"));
13678 Float_t fGrbnu=fBurstParameters->GetSignal("Grbnu");
13679 Int_t fInburst=TMath::Nint(fBurstParameters->GetSignal("Inburst"));
13680 Float_t fDtnu=fBurstParameters->GetSignal("Dtnu");
13681 Float_t fDtnus=fBurstParameters->GetSignal("Dtnus");
13682 Int_t fNbkg=TMath::Nint(fBurstParameters->GetSignal("Nbkg"));
13683
13684 // Deactivate redshift correction for source signal events from archival observed data
13685 if (!fPDFsigE)
13686 {
13687 fEzcor=0;
13688 fBurstParameters->SetSignal(0,"Ezcor");
13689 }
13690
13691 // Derived parameters
13692 Float_t fMaxsigmatot=fBurstParameters->GetSignal("Maxsigmatot");
13693 Float_t fNbkgWin=fBurstParameters->GetSignal("NbkgWin");
13694
13696 // Some Burst statistics from the loaded data //
13698
13699 Int_t fNgrbs=GetNsignals(0);
13700
13701 TH1* hSigmaReco=(TH1*)fBurstHistos.FindObject("hSigmaReco");
13702 TH1* hSigE=(TH1*)fBurstHistos.FindObject("hSigE");
13703 TH1* hSigEzcor=(TH1*)fBurstHistos.FindObject("hSigEzcor");
13704
13706 // Generation of the signal and background observations //
13707 // based on the provided user settings //
13709
13710 NcSignal* sx=0;
13711 Float_t zgrb=0;
13712 Double_t dgrb=0;
13713 Float_t t90grb=0;
13714 Float_t sigmagrb=0;
13715 NcPosition rgrb;
13716 Int_t nmu;
13717 Double_t thetagrb,phigrb;
13718 Double_t dmu,thetamu,phimu;
13719 Float_t dt=0;
13720 NcPosition rgrb2; // Unknown actual GRB position from which the neutrinos/muons arrive
13721 NcPosition rmu;
13722 Float_t dang;
13723 Float_t dangmax=0;
13724 Float_t dangmaxon=0;
13725 Float_t dangmaxoff=0;
13726 Float_t thlow,thup;
13727 Float_t ranlow,ranup;
13728 Int_t nmugrb=0;
13729 NcTimestamp* tx=0;
13730 NcTimestamp tmu;
13731 Float_t solidangle=0;
13732 Float_t ramu,decmu; // Temporary RA and DEC of muon for background creation
13733 Double_t E=0;
13734 Double_t ang=0;
13735 Double_t sigmareco=0;
13736 Float_t sigmatot=0;
13737 TString name;
13738 Int_t fixedwinset=0; // Flag to indicate whether a fixed angular search window is set (1) or not (0) for this burst
13739
13740 // Storage for total on-source and off-source observed and signal injected energies
13741 fBurstParameters->AddNamedSlot("EnergyOn");
13742 fBurstParameters->AddNamedSlot("EnergyOff");
13743 fBurstParameters->AddNamedSlot("EnergySig");
13744
13745 // Loop over the (fictative) GRB space-time positions in the declination acceptance
13746 for (Int_t igrb=0; igrb<fNgrbs; igrb++)
13747 {
13748 sx=GetSignal(igrb+1);
13749
13750 if (!sx) continue;
13751
13752 tx=sx->GetTimestamp();
13753 zgrb=sx->GetSignal("z");
13754 t90grb=sx->GetSignal("T90");
13755 sigmagrb=sx->GetSignal("csigma");
13756 GetSignal(dgrb,thetagrb,"deg",phigrb,"deg","loc",tx,igrb+1);
13757 rgrb.SetPosition(1,thetagrb,phigrb,"sph","deg");
13758
13759 dangmax=-1;
13760 if (!fDatype) dangmax=fabs(fDawin);
13761 if (fDatype==1)
13762 {
13763 dangmax=0;
13764 if (fMaxsigmatot>0) dangmax=fabs(fDawin*fMaxsigmatot);
13765 }
13766
13767 if (fDatype==2)
13768 {
13769 if (!fSumsigmas) dangmax=fabs(fDawin*sigmagrb);
13770 if (!fRecoangle)
13771 {
13772 sigmatot=-1;
13773 if (fSumsigmas==-1) sigmatot=fAngresfix;
13774 if (fSumsigmas==1) sigmatot=sigmagrb+fAngresfix;
13775 if (fSumsigmas==2) sigmatot=sqrt(sigmagrb*sigmagrb+fAngresfix*fAngresfix);
13776 if (sigmatot>=0) dangmax=fabs(fDawin*sigmatot);
13777 }
13778 }
13779
13780 fixedwinset=1;
13781 if (dangmax<0) fixedwinset=0;
13782
13783 // Indicate incompatible input for sigma summation
13784 if (fDatype==1 && fMaxsigmatot<0) dangmax=-1;
13785
13786 // New signal slots for storage of maximum angular differences and corresponding solid angles
13787 name="fixedwinset";
13788 sx->AddNamedSlot(name);
13789 sx->SetSignal(fixedwinset,name);
13790 name="dangmaxOn";
13791 sx->AddNamedSlot(name);
13792 sx->SetSignal(-1,name);
13793 name="dangmaxOff";
13794 sx->AddNamedSlot(name);
13795 sx->SetSignal(-1,name);
13796 name="OmegaOn";
13797 sx->AddNamedSlot(name);
13798 sx->SetSignal(0,name);
13799 name="OmegaOff";
13800 sx->AddNamedSlot(name);
13801 sx->SetSignal(0,name);
13802
13803 // Store the On-source and Off-source maximum (solid) angles for this burst
13804 if (fixedwinset && dangmax>=0)
13805 {
13806 if (fDawin<0) // Local zenith band
13807 {
13808 thlow=thetagrb-0.5*dangmax;
13809 thup=thetagrb+0.5*dangmax;
13810 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
13811 }
13812 else // Circle around GRB position
13813 {
13814 thlow=0;
13815 thup=dangmax;
13816 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
13817 }
13818 sx->SetSignal(dangmax,"dangmaxOn");
13819 sx->SetSignal(solidangle,"OmegaOn");
13820 sx->SetSignal(dangmax,"dangmaxOff");
13821 sx->SetSignal(solidangle*float(fNbkg),"OmegaOff");
13822 }
13823 else // Initialize the encountered dynamic On-source and Off-source maximum angles for this burst
13824 {
13825 dangmaxon=0;
13826 if (fSumsigmas==0 || fSumsigmas==1 || fSumsigmas==2) dangmaxon=fabs(fDawin*sigmagrb);
13827 dangmaxoff=dangmaxon;
13828 }
13829
13830 // Generate the background events in the search time window
13831 // for both this GRB angular cone and the corresponding background bkg patch(es)
13832 for (Int_t bkgpatch=0; bkgpatch<=fNbkg; bkgpatch++)
13833 {
13834 nmu=int(fRan->Poisson(fNbkgWin));
13835 for (Int_t imu=0; imu<nmu; imu++)
13836 {
13837 // Obtain a random event time within the search time window
13838 ranlow=fTmin;
13839 ranup=fTmax;
13840 dt=fRan->Uniform(ranlow,ranup);
13841
13842 // Create a random background event within the user selected burst RA and Dec interval
13843 // and convert to local detector coordinates to allow a local zenith band selection.
13844 // For the conversion, a single, re-usable temp. reference signal will be created, since measurements may get scrambled when stored.
13845 thlow=90.-fDeclmax; // Lower theta angle in overall Earth spherical coordinates (North Pole is theta=0)
13846 thup=90.-fDeclmin; // Upper theta angle in overall Earth spherical coordinates (North Pole is theta=0)
13847 RandomPosition(rmu,thlow,thup,fRAmin,fRAmax);
13848 decmu=90.-rmu.GetX(2,"sph","deg");
13849 ramu=rmu.GetX(3,"sph","deg");
13850 tmu=*tx;
13851 tmu.AddSec(dt*fTfact);
13852 SetSignal(1,ramu,"deg",decmu,"deg","equ",&tmu,fNgrbs+1,"J","bkgtemp",0);
13853 GetSignal(dmu,thetamu,"deg",phimu,"deg","loc",&tmu,fNgrbs+1);
13854 rmu.SetPosition(1,thetamu,phimu,"sph","deg");
13855
13856 if (fDawin<0) // Local zenith band
13857 {
13858 dang=fabs(thetagrb-thetamu);
13859 }
13860 else // Circle around GRB position
13861 {
13862 dang=rgrb.GetOpeningAngle(rmu,"deg");
13863 }
13864
13865 // Check if event lies outside the allowed angular area
13866 if (fDatype>=0 && fixedwinset && dang>dangmax) continue;
13867
13868 // The energy of the background signal
13870
13871 if (E<0 || E<fEmin || E>fEmax) continue;
13872
13873 // The reconstruction angular resolution of the background signal
13874 sigmareco=GetBurstRecoAngres(E,E);
13875 if (sigmareco<0) sigmareco=fAngresfix;
13876
13877 if (sigmareco<fAngresmin || sigmareco>fAngresmax) continue;
13878
13879 if (hSigmaReco) hSigmaReco->Fill(sigmareco);
13880
13881 sigmatot=-1;
13882 if (fSumsigmas==-1) sigmatot=sigmareco;
13883 if (fSumsigmas==0) sigmatot=sigmagrb;
13884 if (fSumsigmas==1) sigmatot=sigmagrb+sigmareco;
13885 if (fSumsigmas==2) sigmatot=sqrt(sigmagrb*sigmagrb+sigmareco*sigmareco);
13886
13887 // Determine the dynamic angular window including the track reco uncertainty
13888 if (!fixedwinset)
13889 {
13890 dangmax=-1;
13891 if (sigmatot>=0) dangmax=fabs(fDawin*sigmatot);
13892 }
13893
13894 if (fDatype>=0 && dang>dangmax) continue;
13895
13896 if (!bkgpatch)
13897 {
13898 if (dangmax>dangmaxon) dangmaxon=dangmax;
13899 fBurstOnReco.Enter(zgrb,sigmagrb,sigmareco,sigmatot);
13900 fBurstOnMatch.Enter(E,dt,dang,dt/(zgrb+1.));
13901 fBurstParameters->AddSignal(E,"EnergyOn");
13902 }
13903 else
13904 {
13905 if (dangmax>dangmaxoff) dangmaxoff=dangmax;
13906 fBurstOffReco.Enter(zgrb,sigmagrb,sigmareco,sigmatot);
13907 fBurstOffMatch.Enter(E,dt,dang,dt/(zgrb+1.));
13908 fBurstParameters->AddSignal(E,"EnergyOff");
13909 }
13910 } // End of loop over the background tracks of this patch
13911 } // End of loop over the patches
13912
13913 // Generate the GRB related signal event(s) in the search window.
13914 // The GRB position gets Gaussian smeared to reflect the actual position.
13915 // The time difference between the gammas and the neutrinos gets corrected
13916 // for the GRB redshift and smeared by the detector time resolution.
13917 // The muon direction gets modified to account for the kinematical opening angle
13918 // w.r.t. the neutrino direction and Gaussian smeared by the detector angular resolution.
13919
13920 // Prevent statistical overfluctuation in number of GRB signal events if requested by fGrbnu<0
13921 if (fGrbnu>=0 || nmugrb<int(fabs(fGrbnu)*float(fNgrbs)))
13922 {
13923 // Obtain actual GRB position
13924 rgrb2.Load(rgrb);
13925 SmearPosition(rgrb2,sigmagrb);
13926
13927 nmu=int(fabs(fGrbnu));
13928 if (!nmu && fRan->Uniform()<fabs(fGrbnu)) nmu=1;
13929 for (Int_t imu=0; imu<nmu; imu++)
13930 {
13931 nmugrb++;
13932 if (!fInburst) // Neutrino and gamma production decoupled
13933 {
13934 if (fDtnus<0) // Sigma in units of T90
13935 {
13936 dt=fRan->Gauss(fDtnu,fabs(fDtnus)*t90grb);
13937 }
13938 else // Sigma in seconds
13939 {
13940 dt=fRan->Gauss(fDtnu,fDtnus);
13941 }
13942 dt=dt*(zgrb+1.);
13943 }
13944 else // Coupled neutrino and gamma production
13945 {
13946 if (fDtnus<0) // Sigma in units of T90
13947 {
13948 dt=fRan->Gauss(fDtnu*t90grb,fabs(fDtnus)*t90grb);
13949 }
13950 else // Sigma in seconds
13951 {
13952 dt=fRan->Gauss(fDtnu*t90grb,fDtnus);
13953 }
13954 }
13955 if (fTimres>0) dt=fRan->Gauss(dt,fTimres);
13956
13957 // Convert dt from seconds to the selected Tunit
13958 dt=dt/fTfact;
13959
13960 // The direction of the GRB signal
13961 rmu.Load(rgrb2);
13962
13963 // The energy of the GRB signal
13965
13966 if (hSigE) hSigE->Fill(E);
13967
13968 // Reduce the energy due to the cosmological redshift effect
13969 if (fEzcor) E=E/(zgrb+1.);
13970
13971 if (hSigEzcor) hSigEzcor->Fill(E);
13972
13973 if (E<0 || E<fEmin || E>fEmax) continue;
13974
13975 // Modification to account for the neutrino-lepton kinematic opening angle
13976 if (fKinangle>0)
13977 {
13978 Int_t mode=fKinangle-1;
13979 ang=GetNeutrinoAngle(E,"deg",mode);
13980 if (ang>0) ShiftPosition(rmu,ang);
13981 }
13982
13983 // Smearing according to the reconstruction angular resolution
13984 sigmareco=GetBurstRecoAngres(E,E);
13985 if (sigmareco<0) sigmareco=fAngresfix;
13986
13987 if (sigmareco<fAngresmin || sigmareco>fAngresmax) continue;
13988
13989 if (hSigmaReco) hSigmaReco->Fill(sigmareco);
13990
13991 SmearPosition(rmu,sigmareco);
13992
13993 // Determine angular difference w.r.t. the presumed GRB position
13994 dang=rgrb.GetOpeningAngle(rmu,"deg");
13995
13996 sigmatot=-1;
13997 if (fSumsigmas==-1) sigmatot=sigmareco;
13998 if (fSumsigmas==0) sigmatot=sigmagrb;
13999 if (fSumsigmas==1) sigmatot=sigmagrb+sigmareco;
14000 if (fSumsigmas==2) sigmatot=sqrt(sigmagrb*sigmagrb+sigmareco*sigmareco);
14001
14002 // Determine the dynamic angular window including the track reco uncertainty
14003 if (!fixedwinset)
14004 {
14005 dangmax=-1;
14006 if (sigmatot>=0) dangmax=fabs(fDawin*sigmatot);
14007 }
14008
14009 if (fDatype>=0 && dang>dangmax) continue;
14010
14011 if (dangmax>dangmaxon) dangmaxon=dangmax;
14012 fBurstOnReco.Enter(zgrb,sigmagrb,sigmareco,sigmatot);
14013 fBurstOnMatch.Enter(E,dt,dang,dt/(zgrb+1.));
14014 fBurstSigReco.Enter(zgrb,sigmagrb,sigmareco,sigmatot);
14015 fBurstSignal.Enter(E,dt,dang,dt/(zgrb+1.));
14016 fBurstParameters->AddSignal(E,"EnergyOn");
14017 fBurstParameters->AddSignal(E,"EnergySig");
14018 }
14019 } // End of loop over the signal events of this burst
14020
14021 if (fixedwinset) continue;
14022
14023 // Store the dynamic On-source and Off-source maximum (solid) angles that are encountered for this burst
14024 if (fDawin<0) // Local zenith band
14025 {
14026 thlow=thetagrb-0.5*dangmaxon;
14027 thup=thetagrb+0.5*dangmaxon;
14028 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
14029 sx->SetSignal(dangmaxon,"dangmaxOn");
14030 sx->SetSignal(solidangle,"OmegaOn");
14031 thlow=thetagrb-0.5*dangmaxoff;
14032 thup=thetagrb+0.5*dangmaxoff;
14033 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
14034 sx->SetSignal(dangmaxoff,"dangmaxOff");
14035 sx->SetSignal(solidangle*float(fNbkg),"OmegaOff");
14036 }
14037 else // Circle around GRB position
14038 {
14039 thlow=0;
14040 thup=dangmaxon;
14041 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
14042 sx->SetSignal(solidangle,"OmegaOn");
14043 sx->SetSignal(dangmaxon,"dangmaxOn");
14044 thup=dangmaxoff;
14045 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
14046 sx->SetSignal(dangmaxoff,"dangmaxOff");
14047 sx->SetSignal(solidangle*float(fNbkg),"OmegaOff");
14048 }
14049 } // End of loop over the individual GRBs
14050
14051 // Remove the temporary storage of the background event
14052 if (fNgrbs>0) RemoveSignal(fNgrbs+1,0,0);
14053
14054 // Compensate statistical underfluctuation in number of GRB signal events if requested by fGrbnu<0
14055 if (fGrbnu<0) BurstCompensate(nmugrb);
14056
14057 // Determine the On-source and Off-source total stacked solid angles that have been encountered
14058 name="SolidangleOn";
14059 fBurstParameters->AddNamedSlot(name);
14060 fBurstParameters->SetSignal(0,name);
14061 name="SolidangleOff";
14062 fBurstParameters->AddNamedSlot(name);
14063 fBurstParameters->SetSignal(0,name);
14064 for (Int_t igrb=1; igrb<=fNgrbs; igrb++)
14065 {
14066 sx=GetSignal(igrb);
14067
14068 if (!sx) continue;
14069
14070 solidangle=sx->GetSignal("OmegaOn");
14071 fBurstParameters->AddSignal(solidangle,"SolidangleOn");
14072 solidangle=sx->GetSignal("OmegaOff");
14073 fBurstParameters->AddSignal(solidangle,"SolidangleOff");
14074 }
14075
14076 // Determine and list the burst statistics
14077 MakeBurstDataStats(0,nmugrb);
14078}
14079
14080void NcAstrolab::MakeBurstDataStats(Int_t mode,Int_t nmugrb)
14081{
14096
14097 Double_t pi=acos(-1.);
14098
14099 // Retrieve the needed parameters
14100 Int_t fNgrbs=TMath::Nint(fBurstParameters->GetSignal("Ngrbs"));
14101 Int_t fNbkg=TMath::Nint(fBurstParameters->GetSignal("Nbkg"));
14102 Int_t fTunits=TMath::Nint(fBurstParameters->GetSignal("Tunits"));
14103 Float_t fTfact=fBurstParameters->GetSignal("Tfact");
14104 Float_t fTmin=fBurstParameters->GetSignal("Tmin");
14105 Float_t fTmax=fBurstParameters->GetSignal("Tmax");
14106 Int_t fTbint90=TMath::Nint(fBurstParameters->GetSignal("Tbint90"));
14107 Float_t fTbin=fBurstParameters->GetSignal("Tbin");
14108 Float_t fVarTbin=fBurstParameters->GetSignal("VarTbin");
14109 Float_t fAbin=fBurstParameters->GetSignal("Abin");
14110 Float_t fAvgrbz=fBurstParameters->GetSignal("Avgrbz");
14111 Float_t fAvgrbt90=fBurstParameters->GetSignal("Avgrbt90");
14112 Float_t fRbkgDecl=fBurstParameters->GetSignal("RbkgDecl");
14113 Float_t fSolidangleOn=fBurstParameters->GetSignal("SolidangleOn");
14114 Float_t fSolidangleOff=fBurstParameters->GetSignal("SolidangleOff");
14115 Float_t fEnergyOn=fBurstParameters->GetSignal("EnergyOn");
14116 Float_t fEnergyOff=fBurstParameters->GetSignal("EnergyOff");
14117 Float_t fEnergySig=fBurstParameters->GetSignal("EnergySig");
14118 Float_t fEnergyBkg=fEnergyOn-fEnergySig;
14119 Float_t fSensarea=fBurstParameters->GetSignal("Sensarea");
14120
14121 TString tu="days";
14122 if (fTunits==1) tu="hours";
14123 if (fTunits==2) tu="sec";
14124 if (fTunits==3) tu="ns";
14125 if (fTunits==4) tu="ps";
14126
14127 Int_t non=fBurstOnMatch.GetN();
14128 Int_t noff=fBurstOffMatch.GetN();
14129 Int_t nsig=fBurstSignal.GetN();
14130 Double_t TminOn=fTmin;
14131 Double_t TmaxOn=fTmax;
14132 Double_t TminOff=fTmin;
14133 Double_t TmaxOff=fTmax;
14134
14135 if (fTmax<=fTmin)
14136 {
14137 TminOn=fBurstOnMatch.GetMinimum("dtime");
14138 TmaxOn=fBurstOnMatch.GetMaximum("dtime");
14139 TminOff=fBurstOffMatch.GetMinimum("dtime");
14140 TmaxOff=fBurstOffMatch.GetMaximum("dtime");
14141 }
14142
14143 Double_t AminOn=fBurstOnMatch.GetMinimum("dang");
14144 Double_t AmaxOn=fBurstOnMatch.GetMaximum("dang");
14145 Double_t AminOff=fBurstOffMatch.GetMinimum("dang");
14146 Double_t AmaxOff=fBurstOffMatch.GetMaximum("dang");
14147
14148 // Update the time window sizes and the average number of background events in them
14149 Float_t DtwinOn=TmaxOn-TminOn;
14150 Float_t DtwinOff=TmaxOff-TminOff;
14151 Float_t NbkgWinOn=fRbkgDecl*DtwinOn*fTfact;
14152 Float_t NbkgWinOff=fRbkgDecl*DtwinOff*fTfact;
14153
14154 TString title;
14155 TString name;
14156 TString s;
14157 Float_t xmin=0;
14158 Float_t xmax=0;
14159 TAxis* axis=0;
14160 Int_t nbins=0;
14161 Double_t binsize=0;
14162 Double_t binsizecos=0;
14163 Int_t nabinsOn=0;
14164 Double_t abinsizeOn=0;
14165 Int_t nabinsOff=0;
14166 Double_t abinsizeOff=0;
14167
14168 // The source redshift, position and reconstruction uncertainty histograms
14169 TH1F* hOnSourceZ=0;
14170 TH1F* hOffSourceZ=0;
14171 TH1F* hOnSigSourceZ=0;
14172 TH1F* hOnSigmaSource=0;
14173 TH1F* hOffSigmaSource=0;
14174 TH1F* hOnSigSigmaSource=0;
14175 TH1F* hOnSigmaReco=0;
14176 TH1F* hOffSigmaReco=0;
14177 TH1F* hOnSigSigmaReco=0;
14178 TH1F* hOnSigmaComb=0;
14179 TH1F* hOffSigmaComb=0;
14180 TH1F* hOnSigSigmaComb=0;
14181 nbins=100;
14182 if (fBurstOnReco.GetN())
14183 {
14184 title.Form("On-Source object redshifts with matching event(s);Redshift;Counts");
14185 hOnSourceZ=new TH1F("hOnSourceZ",title,nbins,1,0);
14186 hOnSourceZ->SetBuffer(non);
14187
14188 title.Form("On-Source object position uncertainties with matching event(s);Object position angular uncertainty (sigma in degrees);Counts");
14189 hOnSigmaSource=new TH1F("hOnSigmaSource",title,nbins,1,0);
14190 hOnSigmaSource->SetBuffer(non);
14191
14192 title.Form("On-source event reconstruction uncertainties in the final sample;Event angular reconstruction uncertainty (sigma in degrees);Counts");
14193 hOnSigmaReco=new TH1F("hOnSigmaReco",title,nbins,1,0);
14194 hOnSigmaReco->SetBuffer(non);
14195
14196 title.Form("On-source combined object position and event reconstruction uncertainty;Combined object position and event reco angular uncertainty (sigma in degrees);Counts");
14197 hOnSigmaComb=new TH1F("hOnSigmaComb",title,nbins,1,0);
14198 hOnSigmaComb->SetBuffer(non);
14199 }
14200
14201 if (fBurstOffReco.GetN())
14202 {
14203 title.Form("Off-Source object redshifts with matching event(s);Redshift;Counts");
14204 hOffSourceZ=new TH1F("hOffSourceZ",title,nbins,1,0);
14205 hOffSourceZ->SetBuffer(noff);
14206
14207 title.Form("Off-Source object position uncertainties with matching event(s);Object position angular uncertainty (sigma in degrees);Counts");
14208 hOffSigmaSource=new TH1F("hOffSigmaSource",title,nbins,1,0);
14209 hOffSigmaSource->SetBuffer(noff);
14210
14211 title.Form("Off-source event reconstruction uncertainties in the final sample;Event angular reconstruction uncertainty (sigma in degrees);Counts");
14212 hOffSigmaReco=new TH1F("hOffSigmaReco",title,nbins,1,0);
14213 hOffSigmaReco->SetBuffer(noff);
14214
14215 title.Form("Off-source combined object position and event reconstruction uncertainty;Combined object position and event reco angular uncertainty (sigma in degrees);Counts");
14216 hOffSigmaComb=new TH1F("hOffSigmaComb",title,nbins,1,0);
14217 hOffSigmaComb->SetBuffer(noff);
14218 }
14219
14220 if (fBurstSigReco.GetN())
14221 {
14222 title.Form("On-Source object redshifts with matching simulated signal event(s);Redshift;Counts");
14223 hOnSigSourceZ=new TH1F("hOnSigSourceZ",title,nbins,1,0);
14224 hOnSigSourceZ->SetBuffer(nsig);
14225
14226 title.Form("On-Source object position uncertainties with matching simulated signal event(s);Object position angular uncertainty (sigma in degrees);Counts");
14227 hOnSigSigmaSource=new TH1F("hOnSigSigmaSource",title,nbins,1,0);
14228 hOnSigSigmaSource->SetBuffer(nsig);
14229
14230 title.Form("On-source simulated signal event reconstruction uncertainties in the final sample;Event angular reconstruction uncertainty (sigma in degrees);Counts");
14231 hOnSigSigmaReco=new TH1F("hOnSigSigmaReco",title,nbins,1,0);
14232 hOnSigSigmaReco->SetBuffer(nsig);
14233
14234 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");
14235 hOnSigSigmaComb=new TH1F("hOnSigSigmaComb",title,nbins,1,0);
14236 hOnSigSigmaComb->SetBuffer(nsig);
14237 }
14238
14239 // The energy histograms
14240 TH1F* hOnE=0;
14241 TH1F* hOffE=0;
14242 TH1F* hOnSigE=0;
14243 nbins=1000;
14244 if (non)
14245 {
14246 title.Form("On-source reconstructed event energy in the final sample;Event energy in GeV;Counts");
14247 if (!mode) title.ReplaceAll("reconstructed","simulated");
14248 hOnE=new TH1F("hOnE",title,nbins,1,0);
14249 }
14250 if (noff)
14251 {
14252 title.Form("Off-source reconstructed event energy in the final sample;Event energy in GeV;Counts");
14253 if (!mode) title.ReplaceAll("reconstructed","simulated");
14254 hOffE=new TH1F("hOffE",title,nbins,1,0);
14255 }
14256 if (nsig)
14257 {
14258 title.Form("On-source simulated signal event energy in the final sample;Event energy in GeV;Counts");
14259 hOnSigE=new TH1F("hOnSigE",title,nbins,1,0);
14260 }
14261
14262 // Additional text for histo titles to indicate scrambling of the corresponding data
14263 TString scrt=""; // Time scrambling
14264 TString scrp=""; // Position scrambling
14265 if (fTscmode>0) scrt="(scrambled)";
14266 if (fRscmode>0 || fTscmode==3) scrp="(scrambled)";
14267
14268 // Create the angular separation histograms
14269 TH1F* hOna=0;
14270 TH1F* hOffa=0;
14271 TH1F* hOnSiga=0;
14272 TH1F* hOnCosa=0;
14273 TH1F* hOffCosa=0;
14274 TH1F* hOnSigcosa=0;
14275 if (non && fAbin)
14276 {
14277 if (fAbin>0)
14278 {
14279 binsize=fAbin;
14280 nbins=int((AmaxOn-AminOn)/binsize);
14281 }
14282 else
14283 {
14284 nbins=int(((AmaxOn-AminOn)/180.)*NbkgWinOn*float(fNgrbs)/fabs(fAbin));
14285 if (nbins) binsize=(AmaxOn-AminOn)/float(nbins);
14286 }
14287 if (nbins)
14288 {
14289 title.Form("Reconstructed %-s opening angle of on-source events in time window;Opening angle (degrees);Counts per %-.3g degrees",scrp.Data(),binsize);
14290 hOna=new TH1F("hOna",title,nbins+1,AminOn,AmaxOn+binsize);
14291 }
14292 else
14293 {
14294 nbins=100;
14295 binsize=AmaxOn/float(nbins);
14296 title.Form("Reconstructed %-s opening angle of on-source events in time window;Opening angle (degrees);Counts per %-.3g degrees",scrp.Data(),binsize);
14297 hOna=new TH1F("hOna",title,nbins+2,AminOn-binsize,AmaxOn+binsize);
14298 }
14299 nabinsOn=nbins;
14300 abinsizeOn=binsize;
14301 if (nbins) binsizecos=(cos(AminOn*pi/180.)-cos(AmaxOn*pi/180.))/float(nbins);
14302 if (binsizecos>0)
14303 {
14304 title.Form("Reconstructed %-s cos(opening angle) of on-source events in time window;cos(opening angle);Counts per %-.3g",scrp.Data(),binsizecos);
14305 hOnCosa=new TH1F("hOnCosa",title,nbins+1,cos(AmaxOn*pi/180.),cos(AminOn*pi/180.)+binsizecos);
14306 }
14307 else
14308 {
14309 nbins=100;
14310 binsizecos=fabs(cos(AmaxOn*pi/180.))/float(nbins);
14311 title.Form("Reconstructed %-s cos(opening angle) of on-source events in time window;cos(opening angle);Counts per %-.3g",scrp.Data(),binsizecos);
14312 hOnCosa=new TH1F("hOnCosa",title,nbins+2,cos(AmaxOn*pi/180.)-binsizecos,cos(AminOn*pi/180.)+binsizecos);
14313 }
14314 }
14315 if (nsig && nbins)
14316 {
14317 title.Form("Reconstructed opening angle of on-source simulated signal events in time window;Opening angle (degrees);Counts per %-.3g degrees",binsize);
14318 hOnSiga=new TH1F("hOnSiga",title,nbins+2,AminOn-binsize,AmaxOn+binsize);
14319 title.Form("Reconstructed cos(opening angle) of on-source simulated signal events in time window;cos(opening angle);Counts per %-.3g",binsizecos);
14320 hOnSigcosa=new TH1F("hOnSigcosa",title,nbins+2,cos(AmaxOn*pi/180.)-binsizecos,cos(AminOn*pi/180.)+binsizecos);
14321 }
14322 nbins=0;
14323 binsize=0;
14324 binsizecos=0;
14325 if (noff && fAbin)
14326 {
14327 if (fAbin>0)
14328 {
14329 binsize=fAbin;
14330 nbins=int((AmaxOff-AminOff)/binsize);
14331 }
14332 else
14333 {
14334 nbins=int(((AmaxOff-AminOff)/180.)*NbkgWinOff*float(fNgrbs)*float(fNbkg)/fabs(fAbin));
14335 if (nbins) binsize=(AmaxOff-AminOff)/float(nbins);
14336 }
14337 if (nbins)
14338 {
14339 title.Form("Reconstructed opening angle of off-source events in time window;Opening angle (degrees);Counts per %-.3g degrees",binsize);
14340 hOffa=new TH1F("hOffa",title,nbins+1,AminOff,AmaxOff+binsize);
14341 }
14342 else
14343 {
14344 nbins=100;
14345 binsize=AmaxOff/float(nbins);
14346 title.Form("Reconstructed opening angle of off-source events in time window;Opening angle (degrees);Counts per %-.3g degrees",binsize);
14347 hOffa=new TH1F("hOffa",title,nbins+2,AminOff-binsize,AmaxOff+binsize);
14348 }
14349 nabinsOff=nbins;
14350 abinsizeOff=binsize;
14351 if (nbins) binsizecos=(cos(AminOff*pi/180.)-cos(AmaxOff*pi/180.))/float(nbins);
14352 if (binsizecos>0)
14353 {
14354 title.Form("Reconstructed cos(opening angle) of off-source events in time window;cos(opening angle);Counts per %-.3g",binsizecos);
14355 hOffCosa=new TH1F("hOffCosa",title,nbins+1,cos(AmaxOff*pi/180.),cos(AminOff*pi/180.)+binsizecos);
14356 }
14357 else
14358 {
14359 nbins=100;
14360 binsizecos=fabs(cos(AmaxOff*pi/180.))/float(nbins);
14361 title.Form("Reconstructed cos(opening angle) of off-source events in time window;cos(opening angle);Counts per %-.3g",binsizecos);
14362 hOffCosa=new TH1F("hOffCosa",title,nbins+2,cos(AmaxOff*pi/180.)-binsizecos,cos(AminOff*pi/180.)+binsizecos);
14363 }
14364 }
14365
14366 // Create the arrival time histograms
14367 TH1F* hOnt=0;
14368 TH1F* hOfft=0;
14369 TH1F* hOnSigt=0;
14370 TH2F* hOnta=0;
14371 TH2F* hOffta=0;
14372 TH2F* hOnSigta=0;
14373 TH2F* hOnZta=0;
14374 TH2F* hOffZta=0;
14375 TH2F* hOnSigZta=0;
14376
14377 // The redshift corrected arrival time histograms
14378 TH1F* hOnZt=0;
14379 TH1F* hOffZt=0;
14380 TH1F* hOnSigZt=0;
14381
14382 nbins=0;
14383 binsize=0;
14384 TString addtitle;
14385 addtitle.Form(" (=%-g*<T90>)",fTbin);
14386 if (fTbin<0) addtitle.Form(" (~%-g counts/bin)",fabs(fTbin));
14387 if (fabs(fTbin)>0) // Fixed time bins
14388 {
14389 // Automatic time binning to get the specified maximal bkg counts per bin
14390 nbins=int(NbkgWinOn*float(fNgrbs)/fabs(fTbin));
14391 Int_t temp=int(NbkgWinOff*float(fNgrbs)*float(fNbkg)/fabs(fTbin));
14392 if (temp>nbins) nbins=temp;
14393 if (nbins) binsize=DtwinOn/float(nbins);
14394
14395 if (fTbin>0) // User defined time bin size
14396 {
14397 binsize=fTbin;
14398 if (fTbint90) binsize=fTbin*fabs(fAvgrbt90)/fTfact;
14399 nbins=DtwinOn/binsize;
14400 }
14401 if (nbins && non)
14402 {
14403 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());
14404 if (fTbint90 || fTbin<0) title+=addtitle;
14405 hOnt=new TH1F("hOnt",title,nbins+2,TminOn-binsize,TmaxOn+binsize);
14406 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());
14407 hOnta=new TH2F("hOnta",title,nabinsOn+2,AminOn-abinsizeOn,AmaxOn+abinsizeOn,nbins+2,TminOn-binsize,TmaxOn+binsize);
14408 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());
14409 if (fTbint90 || fTbin<0) title+=addtitle;
14410 hOnZt=new TH1F("hOnZt",title,nbins+2,TminOn-binsize,TmaxOn+binsize);
14411 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());
14412 hOnZta=new TH2F("hOnZta",title,nabinsOn+2,AminOn-abinsizeOn,AmaxOn+abinsizeOn,nbins+2,TminOn-binsize,TmaxOn+binsize);
14413 }
14414 if (nbins && nsig)
14415 {
14416 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());
14417 if (fTbint90 || fTbin<0) title+=addtitle;
14418 hOnSigt=new TH1F("hOnSigt",title,nbins+2,TminOn-binsize,TmaxOn+binsize);
14419 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());
14420 hOnSigta=new TH2F("hOnSigta",title,nabinsOn+2,AminOn-abinsizeOn,AmaxOn+abinsizeOn,nbins+2,TminOn-binsize,TmaxOn+binsize);
14421 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());
14422 if (fTbint90 || fTbin<0) title+=addtitle;
14423 hOnSigZt=new TH1F("hOnSigZt",title,nbins+2,TminOn-binsize,TmaxOn+binsize);
14424 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());
14425 hOnSigZta=new TH2F("hOnSigZta",title,nabinsOn+2,AminOn-abinsizeOn,AmaxOn+abinsizeOn,nbins+2,TminOn-binsize,TmaxOn+binsize);
14426 }
14427
14428 if (fTbin>0) // User defined time bin size
14429 {
14430 binsize=fTbin;
14431 if (fTbint90) binsize=fTbin*fabs(fAvgrbt90)/fTfact;
14432 nbins=DtwinOff/binsize;
14433 }
14434 if (nbins && noff)
14435 {
14436 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());
14437 if (fTbint90 || fTbin<0) title+=addtitle;
14438 hOfft=new TH1F("hOfft",title,nbins+2,TminOff-binsize,TmaxOff+binsize);
14439 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());
14440 hOffta=new TH2F("hOffta",title,nabinsOff+2,AminOff-abinsizeOff,AmaxOff+abinsizeOff,nbins+2,TminOff-binsize,TmaxOff+binsize);
14441 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());
14442 if (fTbint90 || fTbin<0) title+=addtitle;
14443 hOffZt=new TH1F("hOffZt",title,nbins+2,TminOff-binsize,TmaxOff+binsize);
14444 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());
14445 hOffZta=new TH2F("hOffZta",title,nabinsOff+2,AminOff-abinsizeOff,AmaxOff+abinsizeOff,nbins+2,TminOff-binsize,TmaxOff+binsize);
14446 }
14447 }
14448 else // Variable time bins
14449 {
14450 Double_t* binarr=0;
14451 Int_t nbx=int(DtwinOn/fVarTbin);
14452 Float_t gamma=fabs(fAvgrbz)+1.;
14453 Float_t* bins=new Float_t[nbx];
14454 nbins=0;
14455 Float_t xlow=0,xup=0,size=fVarTbin;
14456 for (Int_t i=0; i<nbx-1; i++)
14457 {
14458 xup=xlow+size;
14459 if (xup>DtwinOn/2.) // Store the last lowerbound
14460 {
14461 bins[i]=xlow;
14462 nbins++;
14463 break;
14464 }
14465 bins[i]=xlow;
14466 nbins++;
14467 xlow=xup;
14468 size=xlow*gamma;
14469 }
14470 binarr=new Double_t[2*nbins-1];
14471 for (Int_t j=nbins; j>0; j--)
14472 {
14473 binarr[nbins-j]=-bins[j-1];
14474 binarr[nbins+j-2]=bins[j-1];
14475 }
14476 nbins=2*nbins-2;
14477 if (nbins && non)
14478 {
14479 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());
14480 hOnt=new TH1F("hOnt",title,nbins,binarr);
14481 if (nabinsOn)
14482 {
14483 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());
14484 hOnta=new TH2F("hOnta",title,nabinsOn,AminOn,AmaxOn,nbins,binarr);
14485 }
14486 }
14487 if (nbins && noff)
14488 {
14489 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());
14490 hOfft=new TH1F("hOfft",title,nbins,binarr);
14491 if (nabinsOff)
14492 {
14493 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());
14494 hOffta=new TH2F("hOffta",title,nabinsOff,AminOff,AmaxOff,nbins,binarr);
14495 }
14496 }
14497 if (nbins && nsig)
14498 {
14499 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());
14500 hOnSigt=new TH1F("hOnSigt",title,nbins,binarr);
14501 if (nabinsOn)
14502 {
14503 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());
14504 hOnSigta=new TH2F("hOnSigta",title,nabinsOn,AminOn,AmaxOn,nbins,binarr);
14505 }
14506 }
14507
14508 delete[] binarr;
14509 }
14510
14511 // Fill the histograms
14512 Double_t value1=0;
14513 Double_t value2=0;
14514 Double_t value3=0;
14515 Double_t value4=0;
14516
14517 // The on-source data
14518 for (Int_t i=1; i<=fBurstOnReco.GetN(); i++)
14519 {
14520 value1=fBurstOnReco.GetEntry(i,"zburst");
14521 value2=fBurstOnReco.GetEntry(i,"sigmaburst");
14522 value3=fBurstOnReco.GetEntry(i,"sigmareco");
14523 value4=fBurstOnReco.GetEntry(i,"sigmacomb");
14524 if (hOnSourceZ) hOnSourceZ->Fill(value1);
14525 if (hOnSigmaSource) hOnSigmaSource->Fill(value2);
14526 if (hOnSigmaReco) hOnSigmaReco->Fill(value3);
14527 if (hOnSigmaComb) hOnSigmaComb->Fill(value4);
14528 }
14529
14530 for (Int_t i=1; i<=fBurstOnMatch.GetN(); i++)
14531 {
14532 value1=fBurstOnMatch.GetEntry(i,"E");
14533 value2=fBurstOnMatch.GetEntry(i,"dang");
14534 value3=fBurstOnMatch.GetEntry(i,"dtime");
14535 value4=fBurstOnMatch.GetEntry(i,"dtimez");
14536 if (hOnE) hOnE->Fill(value1);
14537 if (hOna) hOna->Fill(value2);
14538 if (hOnCosa) hOnCosa->Fill(cos(value2*pi/180.));
14539 if (hOnt) hOnt->Fill(value3);
14540 if (hOnta) hOnta->Fill(value2,value3);
14541 if (hOnZt) hOnZt->Fill(value4);
14542 if (hOnZta) hOnZta->Fill(value2,value4);
14543 }
14544
14545 // The off-source data
14546 for (Int_t i=1; i<=fBurstOffReco.GetN(); i++)
14547 {
14548 value1=fBurstOffReco.GetEntry(i,"zburst");
14549 value2=fBurstOffReco.GetEntry(i,"sigmaburst");
14550 value3=fBurstOffReco.GetEntry(i,"sigmareco");
14551 value4=fBurstOffReco.GetEntry(i,"sigmacomb");
14552 if (hOffSourceZ) hOffSourceZ->Fill(value1);
14553 if (hOffSigmaSource) hOffSigmaSource->Fill(value2);
14554 if (hOffSigmaReco) hOffSigmaReco->Fill(value3);
14555 if (hOffSigmaComb) hOffSigmaComb->Fill(value4);
14556 }
14557
14558 for (Int_t i=1; i<=fBurstOffMatch.GetN(); i++)
14559 {
14560 value1=fBurstOffMatch.GetEntry(i,"E");
14561 value2=fBurstOffMatch.GetEntry(i,"dang");
14562 value3=fBurstOffMatch.GetEntry(i,"dtime");
14563 value4=fBurstOffMatch.GetEntry(i,"dtimez");
14564 if (hOffE) hOffE->Fill(value1);
14565 if (hOffa) hOffa->Fill(value2);
14566 if (hOffCosa) hOffCosa->Fill(cos(value2*pi/180.));
14567 if (hOfft) hOfft->Fill(value3);
14568 if (hOffta) hOffta->Fill(value2,value3);
14569 if (hOffZt) hOffZt->Fill(value4);
14570 if (hOffZta) hOffZta->Fill(value2,value4);
14571 }
14572
14573 // The simulated signal data
14574 for (Int_t i=1; i<=fBurstSigReco.GetN(); i++)
14575 {
14576 value1=fBurstSigReco.GetEntry(i,"zburst");
14577 value2=fBurstSigReco.GetEntry(i,"sigmaburst");
14578 value3=fBurstSigReco.GetEntry(i,"sigmareco");
14579 value4=fBurstSigReco.GetEntry(i,"sigmacomb");
14580 if (hOnSigSourceZ) hOnSigSourceZ->Fill(value1);
14581 if (hOnSigSigmaSource) hOnSigSigmaSource->Fill(value2);
14582 if (hOnSigSigmaReco) hOnSigSigmaReco->Fill(value3);
14583 if (hOnSigSigmaComb) hOnSigSigmaComb->Fill(value4);
14584 }
14585
14586 for (Int_t i=1; i<=fBurstSignal.GetN(); i++)
14587 {
14588 value1=fBurstSignal.GetEntry(i,"E");
14589 value2=fBurstSignal.GetEntry(i,"dang");
14590 value3=fBurstSignal.GetEntry(i,"dtime");
14591 value4=fBurstSignal.GetEntry(i,"dtimez");
14592 if (hOnSigE) hOnSigE->Fill(value1);
14593 if (hOnSiga) hOnSiga->Fill(value2);
14594 if (hOnSigcosa) hOnSigcosa->Fill(cos(value2*pi/180.));
14595 if (hOnSigt) hOnSigt->Fill(value3);
14596 if (hOnSigta) hOnSigta->Fill(value2,value3);
14597 if (hOnSigZt) hOnSigZt->Fill(value4);
14598 if (hOnSigZta) hOnSigZta->Fill(value2,value4);
14599 }
14600
14601 // Bayesian block analysis of the arrival times
14602 NcBlocks BB;
14603 TH1F hOnBBt;
14604 TH1F hOnBBzt;
14605 if (fBurstOnMatch.GetN())
14606 {
14607 BB.GetBlocks(fBurstOnMatch,"dtime",0.05,&hOnBBt);
14608 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);
14609 title.ReplaceAll("days^","day^");
14610 title.ReplaceAll("hours^","hour^");
14611 hOnBBt.SetNameTitle("hOnBBt",title);
14612 BB.GetBlocks(fBurstOnMatch,"dtimez",0.05,&hOnBBzt);
14613 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);
14614 title.ReplaceAll("days^","day^");
14615 title.ReplaceAll("hours^","hour^");
14616 hOnBBzt.SetNameTitle("hOnBBzt",title);
14617 }
14618 TH1F hOffBBt;
14619 TH1F hOffBBzt;
14620 if (fBurstOffMatch.GetN())
14621 {
14622 BB.GetBlocks(fBurstOffMatch,"dtime",0.05,&hOffBBt);
14623 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);
14624 title.ReplaceAll("days^","day^");
14625 title.ReplaceAll("hours^","hour^");
14626 hOffBBt.SetNameTitle("hOffBBt",title);
14627 BB.GetBlocks(fBurstOffMatch,"dtimez",0.05,&hOffBBzt);
14628 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);
14629 title.ReplaceAll("days^","day^");
14630 title.ReplaceAll("hours^","hour^");
14631 hOffBBzt.SetNameTitle("hOffBBzt",title);
14632 }
14633
14634 // Ratio On/Off for the Bayesian Block histograms
14635 Float_t temp=0;
14636 Int_t nb1=0;
14637 Int_t nb2=0;
14638
14639 axis=hOnBBt.GetXaxis();
14640 xmin=axis->GetXmin();
14641 xmax=axis->GetXmax();
14642 axis=hOffBBt.GetXaxis();
14643 temp=axis->GetXmin();
14644 if (temp<xmin) xmin=temp;
14645 temp=axis->GetXmax();
14646 if (temp>xmax) xmax=temp;
14647
14648 TH1F hOnUBBt;
14649 TH1F hOffUBBt;
14650 TH1F hRatUBBt;
14651 title.Form("Event rate (%-s^{-1}) scaled per time window",tu.Data());
14652 title.ReplaceAll("days^","day^");
14653 title.ReplaceAll("hours^","hour^");
14654 nb1=BB.Rebin(&hOnBBt,&hOnUBBt,kFALSE,0,xmin,xmax);
14655 nb2=BB.Rebin(&hOffBBt,&hOffUBBt,kFALSE,0,xmin,xmax);
14656 if (nb2>nb1) BB.Rebin(&hOnBBt,&hOnUBBt,kFALSE,nb2,xmin,xmax);
14657 hOnUBBt.SetName("hOnUBBt");
14658 hOffUBBt.SetName("hOffUBBt");
14659 if (fNgrbs>1) hOnUBBt.Scale(1./float(fNgrbs));
14660 if (fNgrbs*fNbkg>1) hOffUBBt.Scale(1./float(fNgrbs*fNbkg));
14661 hOnUBBt.SetYTitle(title);
14662 hOffUBBt.SetYTitle(title);
14663 BB.Divide(&hOnUBBt,&hOffUBBt,&hRatUBBt,kFALSE,1);
14664 hRatUBBt.SetName("hRatUBBt");
14665 hRatUBBt.SetYTitle("Ratio");
14666
14667 nbins=hOnBBzt.GetNbinsX();
14668 if (hOffBBzt.GetNbinsX()>nbins) nbins=hOffBBzt.GetNbinsX();
14669 axis=hOnBBzt.GetXaxis();
14670 xmin=axis->GetXmin();
14671 xmax=axis->GetXmax();
14672 axis=hOffBBzt.GetXaxis();
14673 temp=axis->GetXmin();
14674 if (temp<xmin) xmin=temp;
14675 temp=axis->GetXmax();
14676 if (temp>xmax) xmax=temp;
14677
14678 TH1F hOnUBBzt;
14679 TH1F hOffUBBzt;
14680 TH1F hRatUBBzt;
14681 nb1=BB.Rebin(&hOnBBzt,&hOnUBBzt,kFALSE,0,xmin,xmax);
14682 nb2=BB.Rebin(&hOffBBzt,&hOffUBBzt,kFALSE,0,xmin,xmax);
14683 if (nb2>nb1) BB.Rebin(&hOnBBzt,&hOnUBBzt,kFALSE,nb2,xmin,xmax);
14684 hOnUBBzt.SetName("hOnUBBzt");
14685 hOffUBBzt.SetName("hOffUBBzt");
14686 if (fNgrbs>1) hOnUBBzt.Scale(1./float(fNgrbs));
14687 if (fNgrbs*fNbkg>1) hOffUBBzt.Scale(1./float(fNgrbs*fNbkg));
14688 hOnUBBzt.SetYTitle(title);
14689 hOffUBBzt.SetYTitle(title);
14690 BB.Divide(&hOnUBBzt,&hOffUBBzt,&hRatUBBzt,kFALSE,1);
14691 hRatUBBzt.SetName("hRatUBBzt");
14692 hRatUBBzt.SetYTitle("Ratio");
14693
14694 // Store the produced histograms
14695 if (hOnSourceZ) fBurstHistos.Add(hOnSourceZ);
14696 if (hOffSourceZ) fBurstHistos.Add(hOffSourceZ);
14697 if (hOnSigSourceZ) fBurstHistos.Add(hOnSigSourceZ);
14698 if (hOnSigmaSource) fBurstHistos.Add(hOnSigmaSource);
14699 if (hOffSigmaSource) fBurstHistos.Add(hOffSigmaSource);
14700 if (hOnSigSigmaSource) fBurstHistos.Add(hOnSigSigmaSource);
14701 if (hOnSigmaReco) fBurstHistos.Add(hOnSigmaReco);
14702 if (hOffSigmaReco) fBurstHistos.Add(hOffSigmaReco);
14703 if (hOnSigSigmaReco) fBurstHistos.Add(hOnSigSigmaReco);
14704 if (hOnSigmaComb) fBurstHistos.Add(hOnSigmaComb);
14705 if (hOffSigmaComb) fBurstHistos.Add(hOffSigmaComb);
14706 if (hOnSigSigmaComb) fBurstHistos.Add(hOnSigSigmaComb);
14707 if (hOnE) fBurstHistos.Add(hOnE);
14708 if (hOffE) fBurstHistos.Add(hOffE);
14709 if (hOnSigE) fBurstHistos.Add(hOnSigE);
14710 if (hOna) fBurstHistos.Add(hOna);
14711 if (hOffa) fBurstHistos.Add(hOffa);
14712 if (hOnSiga) fBurstHistos.Add(hOnSiga);
14713 if (hOnCosa) fBurstHistos.Add(hOnCosa);
14714 if (hOffCosa) fBurstHistos.Add(hOffCosa);
14715 if (hOnSigcosa) fBurstHistos.Add(hOnSigcosa);
14716 if (hOnt) fBurstHistos.Add(hOnt);
14717 if (hOfft) fBurstHistos.Add(hOfft);
14718 if (hOnSigt) fBurstHistos.Add(hOnSigt);
14719 if (hOnta) fBurstHistos.Add(hOnta);
14720 if (hOffta) fBurstHistos.Add(hOffta);
14721 if (hOnSigta)fBurstHistos.Add(hOnSigta);
14722 if (hOnt && hOnBBt.GetEntries()) fBurstHistos.Add(hOnBBt.Clone());
14723 if (hOfft && hOffBBt.GetEntries()) fBurstHistos.Add(hOffBBt.Clone());
14724 if (hOnt && hOnUBBt.GetEntries()) fBurstHistos.Add(hOnUBBt.Clone());
14725 if (hOfft && hOffUBBt.GetEntries()) fBurstHistos.Add(hOffUBBt.Clone());
14726 if (hOnt && hOfft && hRatUBBt.GetEntries()) fBurstHistos.Add(hRatUBBt.Clone());
14727 if (hOnZt) fBurstHistos.Add(hOnZt);
14728 if (hOffZt) fBurstHistos.Add(hOffZt);
14729 if (hOnSigZt) fBurstHistos.Add(hOnSigZt);
14730 if (hOnZta) fBurstHistos.Add(hOnZta);
14731 if (hOffZta) fBurstHistos.Add(hOffZta);
14732 if (hOnSigZta) fBurstHistos.Add(hOnSigZta);
14733 if (hOnZt && hOnBBzt.GetEntries()) fBurstHistos.Add(hOnBBzt.Clone());
14734 if (hOffZt && hOffBBzt.GetEntries()) fBurstHistos.Add(hOffBBzt.Clone());
14735 if (hOnZt && hOnUBBzt.GetEntries()) fBurstHistos.Add(hOnUBBzt.Clone());
14736 if (hOffZt && hOffUBBzt.GetEntries()) fBurstHistos.Add(hOffUBBzt.Clone());
14737 if (hOnZt && hOffZt && hRatUBBzt.GetEntries()) fBurstHistos.Add(hRatUBBzt.Clone());
14738
14739 // Make sure that also the auto-binned histograms have their axes ranges set
14740 Int_t nh=fBurstHistos.GetEntries();
14741 for (Int_t ih=0; ih<nh; ih++)
14742 {
14743 TH1* hx=(TH1*)fBurstHistos.At(ih);
14744 if (!hx) continue;
14745 hx->BufferEmpty(1);
14746
14747 name=hx->GetName();
14748
14749 if (name=="hTdiff")
14750 {
14751 binsize=hx->GetBinWidth(1);
14752 s.Form("Counts per %-.3g %-s",binsize,tu.Data());
14753 axis=hx->GetYaxis();
14754 if (axis) axis->SetTitle(s);
14755 }
14756
14757 if (name=="hAdiff" || name.Contains("Sigma"))
14758 {
14759 binsize=hx->GetBinWidth(1);
14760 s.Form("Counts per %-.3g degrees",binsize);
14761 axis=hx->GetYaxis();
14762 if (axis) axis->SetTitle(s);
14763 }
14764
14765 if (name=="hOnE" || name=="hOffE" || name=="hOnSigE")
14766 {
14767 binsize=hx->GetBinWidth(1);
14768 s.Form("Counts per %-.3g GeV",binsize);
14769 axis=hx->GetYaxis();
14770 if (axis) axis->SetTitle(s);
14771 }
14772 }
14773
14774 // Determination of the on-source and off-source event rates
14775 Float_t nOn=non;
14776 Float_t nOff=noff;
14777 Float_t nsigOn=nsig;
14778 Float_t nbkgOn=nOn-nsigOn;
14779 Float_t Ton=DtwinOn*fTfact*float(fNgrbs); // Total on-source exposure time in seconds
14780 Float_t Toff=DtwinOff*fTfact*float(fNgrbs)*float(fNbkg); // Total off-source exposure time in seconds
14781 Float_t rateOn=nOn/(DtwinOn*fTfact);
14782 Float_t rateOff=nOff/(DtwinOff*fTfact);
14783
14784 // (Average) values per patch
14785 Float_t TwinOn=DtwinOn*fTfact;
14786 Float_t TwinOff=DtwinOff*fTfact;
14787 Float_t AvSolidangleOn=0;
14788 Float_t AvSolidangleOff=0;
14789 Float_t AvNon=0;
14790 Float_t AvNoff=0;
14791 Float_t AvRon=0;
14792 Float_t AvRoff=0;
14793 Float_t AvEon=0;
14794 Float_t AvEoff=0;
14795 Float_t AvNsigOn=0;
14796 Float_t AvNbkgOn=0;
14797 Float_t AvRsigOn=0;
14798 Float_t AvRbkgOn=0;
14799 Float_t AvEsigOn=0;
14800 Float_t AvEbkgOn=0;
14801 Float_t scale=fNgrbs;
14802 if (scale)
14803 {
14804 AvSolidangleOn=fSolidangleOn/scale;
14805 AvNon=nOn/scale;
14806 AvRon=nOn/Ton;
14807 AvEon=fEnergyOn/scale;
14808 AvNsigOn=nsigOn/scale;
14809 AvNbkgOn=nbkgOn/scale;
14810 AvRsigOn=nsigOn/Ton;
14811 AvRbkgOn=nbkgOn/Ton;
14812 AvEsigOn=fEnergySig/scale;
14813 AvEbkgOn=fEnergyBkg/scale;
14814 }
14815 scale=fNgrbs*fNbkg;
14816 if (scale)
14817 {
14818 AvSolidangleOff=fSolidangleOff/scale;
14819 AvNoff=nOff/scale;
14820 AvRoff=nOff/Toff;
14821 AvEoff=fEnergyOff/scale;
14822 }
14823
14824 // Statistics of the stacked event samples
14825 printf("\n *%-s::MakeBurstDataStats* Statistics of the stacked observed event samples. \n",ClassName());
14826 printf(" Integrated on-source exposure time of the %-i stacked time windows : %-g %-s \n",fNgrbs,Ton/fTfact,tu.Data());
14827 printf(" Integrated off-source exposure time of the %-i*%-i stacked time windows : %-g %-s \n",fNgrbs,fNbkg,Toff/fTfact,tu.Data());
14828 printf(" Total accumulated on-source solid angle : %-g sr in %-i stacked patches --> Average per patch : %-g sr \n",fSolidangleOn,fNgrbs,AvSolidangleOn);
14829 printf(" Total accumulated off-source solid angle : %-g sr in %-i*%-i stacked patches --> Average per patch : %-g sr \n",fSolidangleOff,fNgrbs,fNbkg,AvSolidangleOff);
14830 if (fSensarea>0) printf(" Area covered c.q. overlooked by the detector sensors : %-g m^2. \n",fSensarea);
14831 fSensarea*=1e4; // Convert to cm^2
14832
14833 printf(" *On source* Total number of recorded on-source events : %-g --> Average per patch : %-g events. \n",nOn,AvNon);
14834 printf(" --- Average values per on-source patch --- \n");
14835 printf(" Steady event rate during the time window : %-g Hz",AvRon);
14836 if (AvSolidangleOn) printf(" --> %-g Hz sr^-1",AvRon/AvSolidangleOn);
14837 printf("\n");
14838 if (fSensarea>0)
14839 {
14840 printf(" Particle fluence : %-g cm^-2",AvNon/fSensarea);
14841 if (AvSolidangleOn) printf(" --> %-g cm^-2 sr^-1",AvNon/(fSensarea*AvSolidangleOn));
14842 printf("\n");
14843 printf(" Particle flux : %-g cm^-2 s^-1",AvRon/fSensarea);
14844 if (AvSolidangleOn) printf(" --> Intensity : %-g cm^-2 s^-1 sr^-1",AvRon/(fSensarea*AvSolidangleOn));
14845 printf("\n");
14846 }
14847 printf(" Cumulated energy : %-g GeV",AvEon);
14848 if (AvSolidangleOn) printf(" --> %-g GeV sr^-1",AvEon/AvSolidangleOn);
14849 printf("\n");
14850 printf(" Power : %-g GeV/s",AvEon/TwinOn);
14851 if (AvSolidangleOn) printf(" --> %-g GeV s^-1 sr^-1",AvEon/(TwinOn*AvSolidangleOn));
14852 printf("\n");
14853 if (fSensarea>0)
14854 {
14855 printf(" Energy fluence : %-g GeV cm^-2",AvEon/fSensarea);
14856 if (AvSolidangleOn) printf(" --> %-g GeV cm^-2 sr^-1",AvEon/(fSensarea*AvSolidangleOn));
14857 printf("\n");
14858 printf(" Energy flux : %-g GeV cm^-2 s^-1",AvEon/(fSensarea*TwinOn));
14859 if (AvSolidangleOn) printf(" --> Intensity : %-g GeV cm^-2 s^-1 sr^-1",AvEon/(fSensarea*TwinOn*AvSolidangleOn));
14860 printf("\n");
14861 }
14862
14863 if (fNbkg)
14864 {
14865 printf(" *Off source* Total number of recorded off-source (background) events : %-g --> Average per patch : %-g events. \n",nOff,AvNoff);
14866 printf(" --- Average values per off-source patch --- \n");
14867 printf(" Steady event rate during the time window : %-g Hz",AvRoff);
14868 if (AvSolidangleOff) printf(" --> %-g Hz sr^-1",AvRoff/AvSolidangleOff);
14869 printf("\n");
14870 if (fSensarea>0)
14871 {
14872 printf(" Particle fluence : %-g cm^-2",AvNoff/fSensarea);
14873 if (AvSolidangleOff) printf(" --> %-g cm^-2 sr^-1",AvNoff/(fSensarea*AvSolidangleOff));
14874 printf("\n");
14875 printf(" Particle flux : %-g cm^-2 s^-1",AvRoff/fSensarea);
14876 if (AvSolidangleOff) printf(" --> Intensity : %-g cm^-2 s^-1 sr^-1",AvRoff/(fSensarea*AvSolidangleOff));
14877 printf("\n");
14878 }
14879 printf(" Cumulated energy : %-g GeV",AvEoff);
14880 if (AvSolidangleOff) printf(" --> %-g GeV sr^-1",AvEoff/AvSolidangleOff);
14881 printf("\n");
14882 printf(" Power : %-g GeV/s",AvEoff/TwinOff);
14883 if (AvSolidangleOff) printf(" --> %-g GeV s^-1 sr^-1",AvEoff/(TwinOn*AvSolidangleOff));
14884 printf("\n");
14885 if (fSensarea>0)
14886 {
14887 printf(" Energy fluence : %-g GeV cm^-2",AvEoff/fSensarea);
14888 if (AvSolidangleOff) printf(" --> %-g GeV cm^-2 sr^-1",AvEoff/(fSensarea*AvSolidangleOff));
14889 printf("\n");
14890 printf(" Energy flux : %-g GeV cm^-2 s^-1",AvEoff/(fSensarea*TwinOff));
14891 if (AvSolidangleOff) printf(" --> Intensity : %-g GeV cm^-2 s^-1 sr^-1",AvEoff/(fSensarea*TwinOff*AvSolidangleOff));
14892 printf("\n");
14893 }
14894 }
14895
14896 // On-source signal and background info is only available for simulated data
14897 if (!mode)
14898 {
14899 printf(" -(Unknown)- Total number of injected on-source signal events : %-i \n",nmugrb);
14900 printf(" Total number of recorded on-source signal events : %-g",nsigOn);
14901 if (fNgrbs) printf(" --> Average per patch : %-g events.",nsigOn/float(fNgrbs));
14902 printf("\n");
14903 printf(" Total number of recorded on-source bkg events : %-g",nbkgOn);
14904 if (fNgrbs) printf(" --> Average per patch : %-g events.",nbkgOn/float(fNgrbs));
14905 printf("\n");
14906
14907 printf(" --- Average signal values per on-source patch --- \n");
14908 printf(" Steady event rate during the time window : %-g Hz",AvRsigOn);
14909 if (AvSolidangleOn) printf(" --> %-g Hz sr^-1",AvRsigOn/AvSolidangleOn);
14910 printf("\n");
14911 if (fSensarea>0)
14912 {
14913 printf(" Particle fluence : %-g cm^-2",AvNsigOn/fSensarea);
14914 if (AvSolidangleOn) printf(" --> %-g cm^-2 sr^-1",AvNsigOn/(fSensarea*AvSolidangleOn));
14915 printf("\n");
14916 printf(" Particle flux : %-g cm^-2 s^-1",AvRsigOn/fSensarea);
14917 if (AvSolidangleOn) printf(" --> Intensity : %-g cm^-2 s^-1 sr^-1",AvRsigOn/(fSensarea*AvSolidangleOn));
14918 printf("\n");
14919 }
14920 printf(" Cumulated energy : %-g GeV",AvEsigOn);
14921 if (AvSolidangleOn) printf(" --> %-g GeV sr^-1",AvEsigOn/AvSolidangleOn);
14922 printf("\n");
14923 printf(" Power : %-g GeV/s",AvEsigOn/TwinOn);
14924 if (AvSolidangleOn) printf(" --> %-g GeV s^-1 sr^-1",AvEsigOn/(TwinOn*AvSolidangleOn));
14925 printf("\n");
14926 if (fSensarea>0)
14927 {
14928 printf(" Energy fluence : %-g GeV cm^-2",AvEsigOn/fSensarea);
14929 if (AvSolidangleOn) printf(" --> %-g GeV cm^-2 sr^-1",AvEsigOn/(fSensarea*AvSolidangleOn));
14930 printf("\n");
14931 printf(" Energy flux : %-g GeV cm^-2 s^-1",AvEsigOn/(fSensarea*TwinOn));
14932 if (AvSolidangleOn) printf(" --> Intensity : %-g GeV cm^-2 s^-1 sr^-1",AvEsigOn/(fSensarea*TwinOn*AvSolidangleOn));
14933 printf("\n");
14934 }
14935 printf(" --- Average background values per on-source patch --- \n");
14936 printf(" Steady event rate during the time window : %-g Hz",AvRbkgOn);
14937 if (AvSolidangleOn) printf(" --> %-g Hz sr^-1",AvRbkgOn/AvSolidangleOn);
14938 printf("\n");
14939 if (fSensarea>0)
14940 {
14941 printf(" Particle fluence : %-g cm^-2",AvNbkgOn/fSensarea);
14942 if (AvSolidangleOn) printf(" --> %-g cm^-2 sr^-1",AvNbkgOn/(fSensarea*AvSolidangleOn));
14943 printf("\n");
14944 printf(" Particle flux : %-g cm^-2 s^-1",AvRbkgOn/fSensarea);
14945 if (AvSolidangleOn) printf(" --> Intensity : %-g cm^-2 s^-1 sr^-1",AvRbkgOn/(fSensarea*AvSolidangleOn));
14946 printf("\n");
14947 }
14948 printf(" Cumulated energy : %-g GeV",AvEbkgOn);
14949 if (AvSolidangleOn) printf(" --> %-g GeV sr^-1",AvEbkgOn/AvSolidangleOn);
14950 printf("\n");
14951 printf(" Power : %-g GeV/s",AvEbkgOn/TwinOn);
14952 if (AvSolidangleOn) printf(" --> %-g GeV s^-1 sr^-1",AvEbkgOn/(TwinOn*AvSolidangleOn));
14953 printf("\n");
14954 if (fSensarea>0)
14955 {
14956 printf(" Energy fluence : %-g GeV cm^-2",AvEbkgOn/fSensarea);
14957 if (AvSolidangleOn) printf(" --> %-g GeV cm^-2 sr^-1",AvEbkgOn/(fSensarea*AvSolidangleOn));
14958 printf("\n");
14959 printf(" Energy flux : %-g GeV cm^-2 s^-1",AvEbkgOn/(fSensarea*TwinOn));
14960 if (AvSolidangleOn) printf(" --> Intensity : %-g GeV cm^-2 s^-1 sr^-1",AvEbkgOn/(fSensarea*TwinOn*AvSolidangleOn));
14961 printf("\n");
14962 }
14963 }
14964 printf("\n");
14965
14966 // Update internal statistics
14967 fBurstParameters->AddNamedSlot("TminOn");
14968 fBurstParameters->SetSignal(TminOn,"TminOn");
14969 fBurstParameters->AddNamedSlot("TmaxOn");
14970 fBurstParameters->SetSignal(TmaxOn,"TmaxOn");
14971 fBurstParameters->AddNamedSlot("TminOff");
14972 fBurstParameters->SetSignal(TminOff,"TminOff");
14973 fBurstParameters->AddNamedSlot("TmaxOff");
14974 fBurstParameters->SetSignal(TmaxOff,"TmaxOff");
14975 fBurstParameters->AddNamedSlot("DtwinOn");
14976 fBurstParameters->SetSignal(DtwinOn,"DtwinOn");
14977 fBurstParameters->AddNamedSlot("DtwinOff");
14978 fBurstParameters->SetSignal(DtwinOff,"DtwinOff");
14979 fBurstParameters->AddNamedSlot("NbkgWinOn");
14980 fBurstParameters->SetSignal(NbkgWinOn,"NbkgWinOn");
14981 fBurstParameters->AddNamedSlot("NbkgWinOff");
14982 fBurstParameters->SetSignal(NbkgWinOff,"NbkgWinOff");
14983 fBurstParameters->AddNamedSlot("TtotOn"); // The on-source total exposure time in sec.
14984 fBurstParameters->SetSignal(Ton,"TtotOn");
14985 fBurstParameters->AddNamedSlot("TtotOff"); // The off-source total exposure time ins sec.
14986 fBurstParameters->SetSignal(Toff,"TtotOff");
14987 fBurstParameters->AddNamedSlot("AvSolidangleOn"); // The average on-source solid angle
14988 fBurstParameters->SetSignal(AvSolidangleOn,"AvSolidangleOn");
14989 fBurstParameters->AddNamedSlot("AvSolidangleOff"); // The average off-source solid angle
14990 fBurstParameters->SetSignal(AvSolidangleOff,"AvSolidangleOff");
14991
14992 fBurstParameters->AddNamedSlot("rateOn");
14993 fBurstParameters->SetSignal(rateOn,"rateOn");
14994 fBurstParameters->AddNamedSlot("rateOff");
14995 fBurstParameters->SetSignal(rateOff,"rateOff");
14996
14997 // Update old parameters
14998 fBurstParameters->SetSignal(TminOn,"Tmin");
14999 fBurstParameters->SetSignal(TmaxOn,"Tmax");
15000 fBurstParameters->SetSignal(DtwinOn,"Dtwin");
15001 fBurstParameters->SetSignal(NbkgWinOn,"NbkgWin");
15002}
15003
15004void NcAstrolab::MatchBurstData(NcDevice& matches,Int_t i1,Int_t i2,Int_t itype,Int_t j1,Int_t j2,Int_t jtype)
15005{
15100
15101 Float_t fAngresfix=fBurstParameters->GetSignal("Angresfix");
15102 Int_t fRecoangle=TMath::Nint(fBurstParameters->GetSignal("Recoangle"));
15103 Int_t fSumsigmas=TMath::Nint(fBurstParameters->GetSignal("Sumsigmas"));
15104 Int_t fTunits=TMath::Nint(fBurstParameters->GetSignal("Tunits"));
15105 Float_t fTmin=fBurstParameters->GetSignal("Tmin");
15106 Float_t fTmax=fBurstParameters->GetSignal("Tmax");
15107 Float_t fDawin=fBurstParameters->GetSignal("Dawin");
15108 Int_t fDatype=TMath::Nint(fBurstParameters->GetSignal("Datype"));
15109 Float_t fMaxsigmatot=fBurstParameters->GetSignal("Maxsigmatot");
15110 Int_t fNbkg=TMath::Nint(fBurstParameters->GetSignal("Nbkg"));
15111
15112 // Update internal statistics to account for objects introduced by hand
15113 Int_t fNgrbs=GetNsignals(0);
15114 Int_t fNevts=GetNsignals(1);
15115 fBurstParameters->AddNamedSlot("Ngrbs");
15116 fBurstParameters->AddNamedSlot("Nevts");
15117 fBurstParameters->SetSignal(fNgrbs,"Ngrbs");
15118 fBurstParameters->SetSignal(fNevts,"Nevts");
15119
15120 // Initialize generic histograms for analysis
15122
15123 TString tu="d";
15124 if (fTunits==1) tu="hrs";
15125 if (fTunits==2) tu="s";
15126 if (fTunits==3) tu="ns";
15127 if (fTunits==4) tu="ps";
15128
15129 // Initialize the Device/Hit structure to contain the correlation info
15130 matches.Reset(1);
15131 matches.SetHitCopy(1);
15132
15133 TString name="Matches";
15134 TString title="Space and time matchings of NcAstrolab stored signals";
15135 matches.SetNameTitle(name,title);
15136 TString tux=tu;
15137 if (tu=="d") tux="days";
15138 if (tu=="hrs") tux="hours";
15139 if (tu=="s") tux="sec";
15140 TString namedamin="psimin in deg";
15141 TString namedtmin="dtmin in ";
15142 namedtmin+=tux;
15143 matches.AddNamedSlot(namedamin);
15144 matches.AddNamedSlot(namedtmin);
15145 matches.AddNamedSlot("ipsi");
15146 matches.AddNamedSlot("idt");
15147
15148 NcSignal data;
15149 TString nameda="psi in deg";
15150 TString namedt="t2-t1 in ";
15151 namedt+=tux;
15152 data.AddNamedSlot("type1");
15153 data.AddNamedSlot("index1");
15154 data.AddNamedSlot("type2");
15155 data.AddNamedSlot("index2");
15156 data.AddNamedSlot(nameda);
15157 data.AddNamedSlot(namedt);
15158
15159 if ((!itype || !jtype) && !fRefs)
15160 {
15161 printf(" *%-s::MatchBurstData* Error: itype=%-i jtype=%-i but no reference signals are present. \n",ClassName(),itype,jtype);
15162 return;
15163 }
15164
15165 if ((itype || jtype) && !fSigs)
15166 {
15167 printf(" *%-s::MatchBurstData* Error: itype=%-i jtype=%-i but no measurements are present. \n",ClassName(),itype,jtype);
15168 return;
15169 }
15170
15171 Int_t nrefs=0;
15172 if (fRefs) nrefs=fRefs->GetSize();
15173 Int_t nsigs=0;
15174 if (fSigs) nsigs=fSigs->GetSize();
15175
15176 // Make input data consistent with conventions
15177 if (itype) itype=1;
15178 if (jtype) jtype=1;
15179 if (!itype)
15180 {
15181 if (i2<1 || i2>nrefs) i2=nrefs;
15182 }
15183 else
15184 {
15185 if (i2<1 || i2>nsigs) i2=nsigs;
15186 }
15187 if (!jtype)
15188 {
15189 if (j2<1 || j2>nrefs) j2=nrefs;
15190 }
15191 else
15192 {
15193 if (j2<1 || j2>nsigs) j2=nsigs;
15194 }
15195
15196 if (i1<1 || j1<1 || i1>i2 || j1>j2)
15197 {
15198 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);
15199 return;
15200 }
15201
15202 if (fDatype==1 && fMaxsigmatot<0)
15203 {
15204 printf(" *%-s::MatchBurstData* Incompatible parameter settings Datype=%-i Maxsigmatot=%-g \n",ClassName(),fDatype,fMaxsigmatot);
15205 printf(" === No matching analysis will be performed === \n");
15206 }
15207
15208 // The number of actually stored items
15209 Int_t ni=GetNsignals(itype);
15210 Int_t nj=GetNsignals(jtype);
15211
15212 // Additional text for histo titles to indicate scrambling of the corresponding data
15213 TString scrt=""; // Time scrambling
15214 TString scrp=""; // Position scrambling
15215 if (fTscmode>0) scrt="(scrambled)";
15216 if (fRscmode>0 || fTscmode==3) scrp="(scrambled)";
15217
15218 // The auto binned event-burst time difference histo for the full selected sample
15219 Int_t nbins=10000;
15220 title.Form("Time difference %-s between events and bursts for the full selected dataset;Tevent-Tburst in %-s;Counts",scrt.Data(),tux.Data());
15221 TH1F* hTdiff=new TH1F("hTdiff",title,nbins,1,0);
15222 if (ni && nj) hTdiff->SetBuffer(ni*nj);
15223
15224 // The auto binned event-burst angular difference histo for the full selected sample
15225 nbins=100;
15226 title.Form("Angular separation %-s between events and bursts for the full selected dataset;Opening angle in degrees;Counts",scrp.Data());
15227 TH1F* hAdiff=new TH1F("hAdiff",title,nbins,1,0);
15228 if (ni && nj) hAdiff->SetBuffer(ni*nj);
15229
15230 // Recording of the cumulated on-source reconstructed event energy
15231 fBurstParameters->AddNamedSlot("EnergyOn");
15232 fBurstParameters->AddNamedSlot("EnergyOff");
15233
15234 Double_t dang,dtime,diftheta;
15235 Int_t ix=0;
15236 Int_t jx=0;
15237 NcSignal* sxi=0;
15238 NcSignal* sxj=0;
15239 NcSignal* sxgrb=0;
15240 NcSignal* sxevt=0;
15241 Float_t sigmai=0;
15242 Float_t sigmaj=0;
15243 Float_t sigmagrb=0;
15244 Float_t sigmareco=0;
15245 Float_t sigmatot=0;
15246 Int_t id=0;
15247 Double_t dangmin=0;
15248 Double_t dtmin=0;
15249 Int_t idamin=0;
15250 Int_t idtmin=0;
15251 Bool_t first=kTRUE;
15252 Double_t dangmax=-1;
15253 Float_t Ereco=0;
15254 Float_t thlow=0;
15255 Float_t thup=0;
15256 Float_t thetagrb=0;
15257 Float_t solidangle=0;
15258 Int_t grbtype=0;
15259 Int_t k1=0;
15260 Int_t k2=0;
15261 Float_t zgrb=0;
15262 for (Int_t bkgpatch=0; bkgpatch<=fNbkg; bkgpatch++) // On-source and Off-source patches
15263 {
15264 if (bkgpatch && !fTscmode && !fRscmode) break; // No background data without time and/or position scrambling
15265
15266 for (Int_t i=i1; i<=i2; i++)
15267 {
15268 sxi=GetSignal(i,itype);
15269 if (!sxi) continue;
15270
15271 sigmai=sxi->GetSignal("csigma");
15272
15273 if (itype && !fRecoangle) sigmai=fAngresfix;
15274
15275 for (Int_t j=j1; j<=j2; j++)
15276 {
15277 // Skip matching a signal with itself
15278 if (itype==jtype && i==j) continue;
15279
15280 sxj=GetSignal(j,jtype);
15281 if (!sxj) continue;
15282
15283 sigmaj=sxj->GetSignal("csigma");
15284
15285 if (jtype && !fRecoangle) sigmaj=fAngresfix;
15286
15287 if (itype==jtype) // Self correlations
15288 {
15289 sigmagrb=sigmai;
15290 sxgrb=sxi;
15291 sigmareco=sigmaj;
15292 sxevt=sxj;
15293 }
15294 else // Correlations between sources and measurements
15295 {
15296 if (itype)
15297 {
15298 sigmareco=sigmai;
15299 sxevt=sxi;
15300 sigmagrb=sigmaj;
15301 sxgrb=sxj;
15302 }
15303 else
15304 {
15305 sigmagrb=sigmai;
15306 sxgrb=sxi;
15307 sigmareco=sigmaj;
15308 sxevt=sxj;
15309 }
15310 }
15311
15312 sigmatot=-1;
15313 if (fSumsigmas==-1) sigmatot=sigmareco;
15314 if (fSumsigmas==0) sigmatot=sigmagrb;
15315 if (fSumsigmas==1) sigmatot=sigmagrb+sigmareco;
15316 if (fSumsigmas==2) sigmatot=sqrt(sigmagrb*sigmagrb+sigmareco*sigmareco);
15317
15318 dangmax=-1;
15319 if (!fDatype) dangmax=fabs(fDawin);
15320 if (fDatype==1)
15321 {
15322 dangmax=0;
15323 if (fMaxsigmatot>0) dangmax=fabs(fDawin*fMaxsigmatot);
15324 }
15325 if (fDatype==2)
15326 {
15327 if (sigmatot>=0) dangmax=fabs(fDawin*sigmatot);
15328 }
15329
15330 // Flag incompatible input for sigma summation
15331 if (fDatype==1 && fMaxsigmatot<0) dangmax=-1;
15332
15333 ix=i;
15334 if (itype) ix=-i;
15335 jx=j;
15336 if (jtype) jx=-j;
15337
15338 if (tu!="hrs")
15339 {
15340 dang=GetSeparation(ix,jx,"deg",dtime,tu,1,bkgpatch,&diftheta);
15341 }
15342 else
15343 {
15344 dang=GetSeparation(ix,jx,"deg",dtime,"s",1,bkgpatch,&diftheta);
15345 dtime=dtime/3600.;
15346 }
15347
15348 if (!bkgpatch) // On-source data
15349 {
15350 // Fill the time difference histogram for full selected dataset
15351 if (hTdiff) hTdiff->Fill(dtime);
15352
15353 // Fill the angular difference histogram for full selected dataset
15354 if (hAdiff) hAdiff->Fill(dang);
15355
15356 // Initialize the On-source total solid angle for this source
15357 if (dangmax>=0 && !(sxgrb->GetSlotIndex("OmegaOn")))
15358 {
15359 sxgrb->AddNamedSlot("OmegaOn");
15360 if (fDawin<0) // Local zenith band
15361 {
15362 thlow=thetagrb-0.5*dangmax;
15363 thup=thetagrb+0.5*dangmax;
15364 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
15365 }
15366 else // Circle around GRB position
15367 {
15368 thlow=0;
15369 thup=dangmax;
15370 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
15371 }
15372 sxgrb->SetSignal(solidangle,"OmegaOn");
15373 }
15374 }
15375 else // Off-source c.q. background data
15376 {
15377 // Initialize the Off-source total solid angle for this source
15378 if (dangmax>=0 && !(sxgrb->GetSlotIndex("OmegaOff")))
15379 {
15380 sxgrb->AddNamedSlot("OmegaOff");
15381 if (fDawin<0) // Local zenith band
15382 {
15383 thlow=thetagrb-0.5*dangmax;
15384 thup=thetagrb+0.5*dangmax;
15385 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
15386 }
15387 else // Circle around GRB position
15388 {
15389 thlow=0;
15390 thup=dangmax;
15391 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
15392 }
15393 sxgrb->SetSignal(solidangle,"OmegaOff");
15394 }
15395 }
15396
15397 if (fDatype>=0)
15398 {
15399 if (fDawin<0) // Declination band
15400 {
15401 if (diftheta<thlow || diftheta>thup) continue;
15402 }
15403 else // Circle around the GRB
15404 {
15405 if (fabs(dang)>dangmax) continue;
15406 }
15407 }
15408
15409 if (fTmax>fTmin && (dtime<fTmin || dtime>fTmax)) continue;
15410
15411 if (!bkgpatch) // On-source data
15412 {
15413 // Tag this source of having an on-source matching event
15414 if (!(sxgrb->GetSlotIndex("HasMatchOn")))
15415 {
15416 sxgrb->AddNamedSlot("HasMatchOn");
15417 sxgrb->SetSignal(1,"HasMatchOn");
15418 }
15419
15420 data.Reset();
15421 name="Object1=";
15422 name+=sxi->GetName();
15423 title="Object2=";
15424 title+=sxj->GetName();
15425 id++;
15426 data.SetNameTitle(name,title);
15427 data.SetUniqueID(id);
15428 data.SetSignal(itype,"type1");
15429 data.SetSignal(i,"index1");
15430 data.SetSignal(jtype,"type2");
15431 data.SetSignal(j,"index2");
15432 data.SetSignal(dtime,namedt);
15433 data.SetSignal(dang,nameda);
15434 matches.AddHit(data);
15435
15436 // Update the maximum encountered dynamic On-source solid angle for this source
15437 if (fDatype==2)
15438 {
15439 if (fDawin<0) // Local zenith band
15440 {
15441 thlow=thetagrb-0.5*dangmax;
15442 thup=thetagrb+0.5*dangmax;
15443 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
15444 }
15445 else // Circle around GRB position
15446 {
15447 thlow=0;
15448 thup=dangmax;
15449 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
15450 }
15451 if (solidangle>sxgrb->GetSignal("OmegaOn")) sxgrb->SetSignal(solidangle,"OmegaOn");
15452 }
15453 }
15454 else // Off-source c.q. background data
15455 {
15456 // Tag this source of having an off-source matching event
15457 if (!(sxgrb->GetSlotIndex("HasMatchOff")))
15458 {
15459 sxgrb->AddNamedSlot("HasMatchOff");
15460 sxgrb->SetSignal(1,"HasMatchOff");
15461 }
15462
15463 // Update the maximum encountered dynamic Off-source solid angle for this source
15464 if (fDatype==2)
15465 {
15466 if (fDawin<0) // Local zenith band
15467 {
15468 thlow=thetagrb-0.5*dangmax;
15469 thup=thetagrb+0.5*dangmax;
15470 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
15471 }
15472 else // Circle around GRB position
15473 {
15474 thlow=0;
15475 thup=dangmax;
15476 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
15477 }
15478 if (solidangle>sxgrb->GetSignal("OmegaOff")) sxgrb->SetSignal(solidangle,"OmegaOff");
15479 }
15480 }
15481
15482 // Fill the histograms for the matching data
15483 if (!bkgpatch) // On-source data
15484 {
15485 Ereco=sxevt->GetSignal("E");
15486 zgrb=sxgrb->GetSignal("z");
15487 fBurstOnReco.Enter(zgrb,sigmagrb,sigmareco,sigmatot);
15488 fBurstOnMatch.Enter(Ereco,dtime,dang,dtime/(zgrb+1.));
15489 fBurstParameters->AddSignal(Ereco,"EnergyOn");
15490
15491 // Record the data for the minimal encountered opening angle
15492 if (first || fabs(dang)<dangmin)
15493 {
15494 dangmin=fabs(dang);
15495 idamin=id;
15496 }
15497
15498 // Record the data for the minimal encountered time difference
15499 if (first || fabs(dtime)<fabs(dtmin))
15500 {
15501 dtmin=dtime;
15502 idtmin=id;
15503 }
15504
15505 first=kFALSE;
15506 }
15507 else // Off-source c.q. backgound data
15508 {
15509 Ereco=sxevt->GetSignal("E");
15510 zgrb=sxgrb->GetSignal("z");
15511 fBurstOffReco.Enter(zgrb,sigmagrb,sigmareco,sigmatot);
15512 fBurstOffMatch.Enter(Ereco,dtime,dang,dtime/(zgrb+1.));
15513 fBurstParameters->AddSignal(Ereco,"EnergyOff");
15514 }
15515 } // End of the j-loop
15516 } // End of the i-loop
15517 } // End of loop over the patches
15518
15519 // Store the filled histograms in the storage container
15520 if (hTdiff->GetEntries()) fBurstHistos.Add(hTdiff);
15521 if (hAdiff->GetEntries()) fBurstHistos.Add(hAdiff);
15522
15523 // Recording of the On-source and Off-source total stacked solid angles
15524 name="SolidangleOn";
15525 fBurstParameters->AddNamedSlot(name);
15526 fBurstParameters->SetSignal(0,name);
15527 name="SolidangleOff";
15528 fBurstParameters->AddNamedSlot(name);
15529 fBurstParameters->SetSignal(0,name);
15530 if (itype==jtype) // Self correlations
15531 {
15532 grbtype=itype;
15533 k1=i1;
15534 k2=i2;
15535 }
15536 else // Correlations between sources and measurements
15537 {
15538 if (itype)
15539 {
15540 grbtype=jtype;
15541 k1=j1;
15542 k2=j2;
15543 }
15544 else
15545 {
15546 grbtype=itype;
15547 k1=i1;
15548 k2=i2;
15549 }
15550 }
15551 // Loop over all grbs in the selection
15552 for (Int_t k=k1; k<=k2; k++)
15553 {
15554 sxgrb=GetSignal(k,grbtype);
15555 if (!sxgrb) continue;
15556
15557 solidangle=sxgrb->GetSignal("OmegaOn");
15558 fBurstParameters->AddSignal(solidangle,"SolidangleOn");
15559
15560 solidangle=sxgrb->GetSignal("OmegaOff");
15561 fBurstParameters->AddSignal(solidangle*float(fNbkg),"SolidangleOff");
15562 }
15563
15564 // Store the data for the minimal encountered opening angle and time difference
15565 matches.SetSignal(dangmin,namedamin);
15566 matches.SetSignal(dtmin,namedtmin);
15567 matches.SetSignal(idamin,"ipsi");
15568 matches.SetSignal(idtmin,"idt");
15569
15570 // Determine and list the burst statistics
15572}
15573
15574void NcAstrolab::MatchBurstData(NcDevice& matches,TString name,Int_t itype,Int_t j1,Int_t j2,Int_t jtype)
15575{
15674
15675 Int_t i=GetSignalIndex(name,itype);
15676
15677 if (i==-1) // Add the info for the requested Solar system object if not already stored
15678 {
15679 SetSolarSystem(name,0,itype);
15680 i=GetSignalIndex(name,itype);
15681 if (i>0) fSolUpdate=1;
15682 }
15683
15684 if (i<1)
15685 {
15686 printf(" *%-s::MatchBurstData* Object %-s not found for itype=%-i. \n",ClassName(),name.Data(),itype);
15687 }
15688 else
15689 {
15690 MatchBurstData(matches,i,i,itype,j1,j2,jtype);
15691 }
15692
15693 fSolUpdate=0;
15694}
15695
15697{
15710
15711 // Retreive the needed parameters
15712 Float_t fT90min=fBurstParameters->GetSignal("T90min");
15713 Float_t fT90max=fBurstParameters->GetSignal("T90max");
15714 Float_t fESigmin=fBurstParameters->GetSignal("ESigmin");
15715 Float_t fESigmax=fBurstParameters->GetSignal("ESigmax");
15716 Float_t fEmin=fBurstParameters->GetSignal("Emin");
15717 Float_t fEmax=fBurstParameters->GetSignal("Emax");
15718 Float_t fAlphasig=fBurstParameters->GetSignal("Alphasig");
15719 Float_t fAlphabkg=fBurstParameters->GetSignal("Alphabkg");
15720 Float_t fAvgrbz=fBurstParameters->GetSignal("Avgrbz");
15721 Float_t fAvgrbt90=fBurstParameters->GetSignal("Avgrbt90");
15722 Int_t fTunits=TMath::Nint(fBurstParameters->GetSignal("Tunits"));
15723
15724 TString tu="days";
15725 if (fTunits==1) tu="hours";
15726 if (fTunits==2) tu="sec";
15727 if (fTunits==3) tu="ns";
15728 if (fTunits==4) tu="ps";
15729
15730 TString title;
15731 TString s;
15732
15733 // Initialize the On-source and Off-source data samples
15734 fBurstOnReco.Reset();
15735 fBurstOnMatch.Reset();
15736 fBurstSigReco.Reset();
15737 fBurstSignal.Reset();
15738 fBurstOffReco.Reset();
15739 fBurstOffMatch.Reset();
15740 fBurstOnReco.SetNameTitle("BurstOnReco","On-source reco data");
15741 fBurstOnReco.SetStoreMode();
15742 fBurstOnReco.SetNames("zburst","sigmaburst","sigmareco","sigmacomb");
15743 fBurstOnMatch.SetNameTitle("BurstOnMatch","On-source matching data");
15744 fBurstOnMatch.SetStoreMode();
15745 fBurstOnMatch.SetNames("E","dtime","dang","dtimez");
15746 fBurstSigReco.SetNameTitle("BurstSigReco","Simulated signal reco data");
15747 fBurstSigReco.SetStoreMode();
15748 fBurstSigReco.SetNames("zburst","sigmaburst","sigmareco","sigmacomb");
15749 fBurstSignal.SetNameTitle("BurstSignal","Simulated signal events");
15750 fBurstSignal.SetStoreMode();
15751 fBurstSignal.SetNames("E","dtime","dang","dtimez");
15752 fBurstOffReco.SetNameTitle("BurstOffReco","Off-source reco data");
15753 fBurstOffReco.SetStoreMode();
15754 fBurstOffReco.SetNames("zburst","sigmaburst","sigmareco","sigmacomb");
15755 fBurstOffMatch.SetNameTitle("BurstOffMatch","Off-source matching data");
15756 fBurstOffMatch.SetStoreMode();
15757 fBurstOffMatch.SetNames("E","dtime","dang","dtimez");
15758
15759 // Set default simulation signal and background energy spectra if needed
15760 if (!mode)
15761 {
15762 TH1* edist=0;
15763 edist=(TH1*)fBurstHistos.FindObject("hSigEpdf");
15764 if (!edist) MakeBurstEnergydist(2,fAlphasig,fESigmin,fESigmax,10000);
15765 edist=(TH1*)fBurstHistos.FindObject("hBkgEpdf");
15766 if (!edist) MakeBurstEnergydist(1,fAlphabkg,fEmin,fEmax,10000);
15767 }
15768
15770 // Some statistics from the loaded data //
15772
15773 Int_t fNgrbs=GetNsignals(0);
15774 Int_t fNevts=GetNsignals(1);
15775
15776 Float_t xmin=0;
15777 Float_t xmax=0;
15778 Float_t range=0;
15779 Int_t nbins=100;
15780 Float_t binsize=0;
15781 Int_t srcbufsize=10000;
15782 if (fNgrbs && fNgrbs<srcbufsize) srcbufsize=fNgrbs;
15783 Int_t evtbufsize=10000;
15784 if (fNevts && fNevts<evtbufsize) evtbufsize=fNevts;
15785
15786 // Creation of the burst redshift histo
15787 title.Form("Redshifts for the selected source sample;Redshift;Counts");
15788 TH1F* hSourceZ=new TH1F("hSourceZ",title,nbins,1,0);
15789 hSourceZ->SetBuffer(srcbufsize);
15790
15791 // Creation of the corresponding physical distance histo
15792 nbins=100;
15793 title.Form("Distances for the selected source sample derived from the redshifts;Physical distance in Mpc;Counts");
15794 TH1F* hSourceD=new TH1F("hSourceD",title,nbins,xmin,xmax);
15795 hSourceD->SetBuffer(srcbufsize);
15796
15797 // Creation of the burst t90 duration histo
15798 xmin=-5;
15799 if (fabs(fT90min)>0) xmin=log10(fabs(fT90min));
15800 xmax=5;
15801 if (fT90max>0) xmax=log10(fT90max);
15802 range=xmax-xmin;
15803 binsize=0.2; // Bins of 0.2
15804 nbins=TMath::Nint(range/binsize);
15805 if (nbins<1)
15806 {
15807 xmin=xmin-1.;
15808 xmax=xmax+1.;
15809 nbins=10;
15810 }
15811 title.Form("Burst durations for the selected source sample;Burst duration ^{10}log(T90) in sec.;Counts");
15812 TH1F* hBurstT90=new TH1F("hBurstT90",title,nbins,xmin,xmax);
15813
15814 // Creation of the full selected sample burst position uncertainty histo with automatic binning
15815 nbins=100;
15816 title.Form("Position uncertainties for the selected source sample;Position angular uncertainty (sigma in degrees);Counts");
15817 TH1F* hSigmaSource=new TH1F("hSigmaSource",title,nbins,1,0);
15818 hSigmaSource->SetBuffer(srcbufsize);
15819
15820 // Creation of the real event reconstructed energy histo with automatic binning
15821 TH1F* hEreco=0;
15822 nbins=1000;
15823 if (mode==1)
15824 {
15825 title.Form("Reconstructed energy for the full selected real event sample;Reconstructed event energy in GeV;Counts");
15826 hEreco=new TH1F("hEreco",title,nbins,1,0);
15827 hEreco->SetBuffer(evtbufsize);
15828 }
15829
15830 // Creation of the injected source signal event energy histo with automatic binning
15831 TH1F* hSigE=0;
15832 TH1F* hSigEzcor=0;
15833 nbins=1000;
15834 if (mode==0)
15835 {
15836 title.Form("Injected signal energy at the source;Event energy in GeV;Counts");
15837 hSigE=new TH1F("hSigE",title,nbins,1,0);
15838 fBurstHistos.Add(hSigE);
15839 title.Form("(Redshift corrected) injected signal energy arriving at Earth;Event energy in GeV;Counts");
15840 hSigEzcor=new TH1F("hSigEzcor",title,nbins,1,0);
15841 fBurstHistos.Add(hSigEzcor);
15842 }
15843
15844 // Creation of the full selected sample event reconstruction uncertainty histo with automatic binning
15845 TH1F* hSigmaReco=0;
15846 nbins=100;
15847 title.Form("Event reconstruction uncertainties for the full selected sample;Event angular reconstruction uncertainty (sigma in degrees);Counts");
15848 hSigmaReco=new TH1F("hSigmaReco",title,nbins,1,0);
15849 hSigmaReco->SetBuffer(evtbufsize);
15850
15851 // Fill the generic source c.q. burst histograms
15852 NcSignal* sx=0;
15853 Float_t zgrb=0;
15854 Double_t dgrb=0;
15855 Float_t t90grb=0;
15856 Float_t sigmagrb=0;
15857 NcSample zsample;
15858 zsample.SetStoreMode();
15859 NcSample t90sample;
15860 t90sample.SetStoreMode();
15861 NcSample sigmasample;
15862 sigmasample.SetStoreMode();
15863 Int_t nsig=GetNsignals(0,1);
15864 for (Int_t i=1; i<=nsig; i++)
15865 {
15866 sx=GetSignal(i,0);
15867
15868 if (!sx) continue;
15869
15870 zgrb=sx->GetSignal("z");
15871 dgrb=GetPhysicalDistance(zgrb);
15872 t90grb=sx->GetSignal("T90");
15873 sigmagrb=sx->GetSignal("csigma");
15874
15875 hSourceZ->Fill(zgrb);
15876 hSourceD->Fill(dgrb);
15877 if (t90grb>0) hBurstT90->Fill(log10(t90grb));
15878 hSigmaSource->Fill(sigmagrb);
15879
15880 if (fAvgrbz<0) zsample.Enter(zgrb);
15881 if (fAvgrbt90<0) t90sample.Enter(t90grb);
15882 sigmasample.Enter(sigmagrb);
15883 }
15884
15885 // Add the filled histograms to the storage container
15886 if (hSourceZ->GetEntries()) fBurstHistos.Add(hSourceZ);
15887 if (hSourceD->GetEntries()) fBurstHistos.Add(hSourceD);
15888 if (hBurstT90->GetEntries()) fBurstHistos.Add(hBurstT90);
15889 if (hSigmaSource->GetEntries()) fBurstHistos.Add(hSigmaSource);
15890
15891 // Determine median redshift if requested
15892 if (fAvgrbz<0)
15893 {
15894 fAvgrbz=zsample.GetMedian(1);
15895 fAvgrbz*=-1.;
15896 }
15897
15898 // Determine median T90 duration if requested
15899 if (fAvgrbt90<0)
15900 {
15901 fAvgrbt90=t90sample.GetMedian(1);
15902 fAvgrbt90*=-1.;
15903 }
15904
15905 Float_t fAvgrbsigma=sigmasample.GetMedian(1);
15906
15907 // Fill the generic event histograms
15908 Float_t sigmareco=0;
15909 Float_t Ereco=0;
15910 nsig=GetNsignals(1,1);
15911 for (Int_t i=1; i<=nsig; i++)
15912 {
15913 sx=GetSignal(i,1);
15914
15915 if (!sx) continue;
15916
15917 sigmareco=sx->GetSignal("csigma");
15918 Ereco=sx->GetSignal("E");
15919
15920 if (hSigmaReco) hSigmaReco->Fill(sigmareco);
15921 if (hEreco) hEreco->Fill(Ereco);
15922 }
15923
15924 // Add the filled histograms to the storage container
15925 if (hSigmaReco->GetEntries()) fBurstHistos.Add(hSigmaReco);
15926 if (hEreco)
15927 {
15928 if (hEreco->GetEntries()) fBurstHistos.Add(hEreco);
15929 }
15930
15931 // Update internal statistics
15932 fBurstParameters->SetSignal(fAvgrbz,"Avgrbz");
15933 fBurstParameters->SetSignal(fAvgrbt90,"Avgrbt90");
15934 fBurstParameters->AddNamedSlot("Avgrbsigma");
15935 fBurstParameters->SetSignal(fAvgrbsigma,"Avgrbsigma");
15936}
15937
15939{
15945
15946 // Retreive the needed parameters
15947 Float_t fGrbnu=fBurstParameters->GetSignal("Grbnu");
15948 Int_t fNgrbs=TMath::Nint(fBurstParameters->GetSignal("Ngrbs"));
15949 Int_t fInburst=TMath::Nint(fBurstParameters->GetSignal("Inburst"));
15950 Float_t fDtnu=fBurstParameters->GetSignal("Dtnu");
15951 Float_t fDtnus=fBurstParameters->GetSignal("Dtnus");
15952 Float_t fTimres=fBurstParameters->GetSignal("Timres");
15953 Int_t fDatype=TMath::Nint(fBurstParameters->GetSignal("Datype"));
15954 Float_t fDawin=fBurstParameters->GetSignal("Dawin");
15955 Float_t fTfact=fBurstParameters->GetSignal("Tfact");
15956 Int_t fEzcor=TMath::Nint(fBurstParameters->GetSignal("Ezcor"));
15957 Int_t fPDFsigE=TMath::Nint(fBurstParameters->GetSignal("PDFsigE"));
15958 Float_t fEmin=fBurstParameters->GetSignal("Emin");
15959 Float_t fEmax=fBurstParameters->GetSignal("Emax");
15960 Int_t fKinangle=TMath::Nint(fBurstParameters->GetSignal("Kinangle"));
15961 Float_t fAngresmin=fBurstParameters->GetSignal("Angresmin");
15962 Float_t fAngresmax=fBurstParameters->GetSignal("Angresmax");
15963 Float_t fAngresfix=fBurstParameters->GetSignal("Angresfix");
15964 Int_t fSumsigmas=TMath::Nint(fBurstParameters->GetSignal("Sumsigmas"));
15965
15966 // Deactivate redshift correction for source signal events from archival observed data
15967 if (!fPDFsigE)
15968 {
15969 fEzcor=0;
15970 fBurstParameters->SetSignal(0,"Ezcor");
15971 }
15972
15973 Int_t nmu=int(fabs(fGrbnu)*float(fNgrbs));
15974 Int_t jgrb=0;
15975 NcSignal* sx=0;
15976 NcTimestamp* tx=0;
15977 Float_t t90grb=0;
15978 Float_t zgrb=0;
15979 Float_t sigmagrb=0;
15980 NcPosition rgrb;
15981 NcPosition rgrb2;
15982 Float_t dt=0;
15983 Double_t dgrb=0;
15984 Double_t thetagrb=0;
15985 Double_t phigrb=0;
15986 Float_t dang=0;
15987 Float_t dangmax=0;
15988 Float_t dangmaxOn=0;
15989 NcPosition rmu;
15990 Double_t E=0;
15991 Double_t sigmareco=0;
15992 Float_t sigmatot=0;
15993 Float_t OmegaOn=0; // The current on-source solid angle probed for a certain GRB
15994 Float_t thlow=0;
15995 Float_t thup=0;
15996 Float_t solidangle=0;
15997 Int_t fixedwinset=0; // Flag to indicate whether a fixed angular search window was set (1) or not (0) for this burst
15998
15999 TH1* hSigE=(TH1*)fBurstHistos.FindObject("hSigE");
16000 TH1* hSigEzcor=(TH1*)fBurstHistos.FindObject("hSigEzcor");
16001
16002 while (nmugrb<nmu)
16003 {
16004 // Pick randomly one of the stored GRBs
16005 jgrb=int(fRan->Uniform(0.,float(fNgrbs)));
16006 if (jgrb==0) jgrb=1;
16007 sx=GetSignal(jgrb);
16008
16009 if (!sx) continue;
16010
16011 tx=sx->GetTimestamp();
16012 GetSignal(dgrb,thetagrb,"deg",phigrb,"deg","loc",tx,jgrb);
16013 rgrb.SetPosition(1,thetagrb,phigrb,"sph","deg");
16014 zgrb=sx->GetSignal("z");
16015 t90grb=sx->GetSignal("T90");
16016 sigmagrb=sx->GetSignal("csigma");
16017 fixedwinset=TMath::Nint(sx->GetSignal("fixedwinset"));
16018 dangmaxOn=sx->GetSignal("dangmaxOn");
16019 OmegaOn=sx->GetSignal("OmegaOn");
16020
16021 dangmax=dangmaxOn;
16022
16023 // Obtain actual GRB position
16024 rgrb2.Load(rgrb);
16025 SmearPosition(rgrb2,sigmagrb);
16026
16027 nmugrb++;
16028
16029 if (!fInburst) // Neutrino and gamma production decoupled
16030 {
16031 if (fDtnus<0) // Sigma in units of T90
16032 {
16033 dt=fRan->Gauss(fDtnu,fabs(fDtnus)*t90grb);
16034 }
16035 else // Sigma in seconds
16036 {
16037 dt=fRan->Gauss(fDtnu,fDtnus);
16038 }
16039 dt=dt*(zgrb+1.);
16040 }
16041 else // Coupled neutrino and gamma production
16042 {
16043 if (fDtnus<0) // Sigma in units of T90
16044 {
16045 dt=fRan->Gauss(fDtnu*t90grb,fabs(fDtnus)*t90grb);
16046 }
16047 else // Sigma in seconds
16048 {
16049 dt=fRan->Gauss(fDtnu*t90grb,fDtnus);
16050 }
16051 }
16052 if (fTimres>0) dt=fRan->Gauss(dt,fTimres);
16053
16054 // Convert dt from seconds to the selected Tunits
16055 dt=dt/fTfact;
16056
16057 // The direction of the GRB signal
16058 rmu.Load(rgrb2);
16059
16060 // The energy of the GRB signal
16062
16063 if (hSigE) hSigE->Fill(E);
16064
16065 // Reduce the energy due to the cosmological redshift effect
16066 if (fEzcor) E=E/(zgrb+1.);
16067
16068 if (hSigEzcor) hSigEzcor->Fill(E);
16069
16070 if (E<0 || E<fEmin || E>fEmax) continue;
16071
16072 // Modification to account for the neutrino-lepton kinematic opening angle
16073 if (fKinangle>0)
16074 {
16075 Int_t mode=fKinangle-1;
16076 Double_t ang=GetNeutrinoAngle(E,"deg",mode);
16077 if (ang>0) ShiftPosition(rmu,ang);
16078 }
16079
16080 // Smearing according to the reconstruction angular resolution
16081 sigmareco=GetBurstRecoAngres(E,E);
16082 if (sigmareco<0) sigmareco=fAngresfix;
16083
16084 if (sigmareco<fAngresmin || sigmareco>fAngresmax) continue;
16085
16086 SmearPosition(rmu,sigmareco);
16087
16088 // Determine angular difference w.r.t. the presumed GRB position
16089 dang=rgrb.GetOpeningAngle(rmu,"deg");
16090
16091 sigmatot=-1;
16092 if (fSumsigmas==-1) sigmatot=sigmareco;
16093 if (fSumsigmas==0) sigmatot=sigmagrb;
16094 if (fSumsigmas==1) sigmatot=sigmagrb+sigmareco;
16095 if (fSumsigmas==2) sigmatot=sqrt(sigmagrb*sigmagrb+sigmareco*sigmareco);
16096
16097 // Determine the dynamic angular window including the track reco uncertainty
16098 if (!fixedwinset)
16099 {
16100 dangmax=-1;
16101 if (sigmatot>=0) dangmax=fabs(fDawin*sigmatot);
16102 }
16103
16104 if (fDatype>=0 && dang>dangmax) continue;
16105
16106 fBurstOnReco.Enter(zgrb,sigmagrb,sigmareco,sigmatot);
16107 fBurstOnMatch.Enter(E,dt,dang,dt/(zgrb+1.));
16108 fBurstSigReco.Enter(zgrb,sigmagrb,sigmareco,sigmatot);
16109 fBurstSignal.Enter(E,dt,dang,dt/(zgrb+1.));
16110 fBurstParameters->AddSignal(E,"EnergyOn");
16111 fBurstParameters->AddSignal(E,"EnergySig");
16112
16113 if (fixedwinset) continue;
16114
16115 // Update the dynamic On-source maximum (solid) angle that is encountered for this burst
16116 if (fDawin<0) // Local zenith band
16117 {
16118 thlow=thetagrb-0.5*dangmax;
16119 thup=thetagrb+0.5*dangmax;
16120 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
16121 }
16122 else // Circle around GRB position
16123 {
16124 thlow=0;
16125 thup=dangmax;
16126 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
16127 }
16128 if (dangmax>dangmaxOn) sx->SetSignal(dangmax,"dangmaxOn");
16129 if (solidangle>OmegaOn) sx->SetSignal(solidangle,"OmegaOn");
16130 }
16131}
16132
16133TH1* NcAstrolab::GetBurstBayesianSignalRate(Double_t p,Double_t& rlow,Double_t& rup,Int_t n)
16134{
16160
16161 rlow=0;
16162 rup=0;
16163
16164 // The number of on-source and off-source patches
16165 Int_t fNgrbs=GetNsignals(0);
16166 Int_t fNbkg=TMath::Nint(fBurstParameters->GetSignal("Nbkg"));
16167
16168 // The recorded (stacked) on-source and off-source number of events
16169 Double_t Non=fBurstOnMatch.GetN();
16170 Double_t Noff=fBurstOffMatch.GetN();
16171
16172 if (fNgrbs<=0 || fNbkg<=0 || Non<=0 || Noff<=0)
16173 {
16174 printf(" \n *%-s::GetBurstBayesianSignalRate* \n",ClassName());
16175 if (fNgrbs<=0 || Non<=0) printf(" === No on-source data available === \n");
16176 if (fNbkg<=0 || Noff<=0) printf(" === No off-source data available === \n");
16177 return 0;
16178 }
16179
16180 Int_t fTunits=TMath::Nint(fBurstParameters->GetSignal("Tunits"));
16181 Float_t fTfact=fBurstParameters->GetSignal("Tfact");
16182
16183 TString tu="days";
16184 if (fTunits==1) tu="hours";
16185 if (fTunits==2) tu="sec";
16186 if (fTunits==3) tu="ns";
16187 if (fTunits==4) tu="ps";
16188
16189 // The (stacked) on-source and off-source solid angles that were probed
16190 Double_t fSolidangleOn=fBurstParameters->GetSignal("SolidangleOn");
16191 Double_t fSolidangleOff=fBurstParameters->GetSignal("SolidangleOff");
16192 Double_t fAvSolidangleOn=fBurstParameters->GetSignal("AvSolidangleOn");
16193 Double_t fAvSolidangleOff=fBurstParameters->GetSignal("AvSolidangleOff");
16194 Double_t Ra=-1;
16195 if (fAvSolidangleOff) Ra=fAvSolidangleOn/fAvSolidangleOff;
16196
16197 // The integrated on-source and off-source exposure times in seconds
16198 Double_t Ton=fBurstParameters->GetSignal("TtotOn");
16199 Double_t Toff=fBurstParameters->GetSignal("TtotOff");
16200
16201 // The Bayesian posterior background and signal rate PDFs
16202 TF1 fbkgrpdf=GetBackgroundRatePDF(Noff,Toff);
16203 TF1 fsigrpdf=GetSignalRatePDF(Non,Ton,Noff,Toff,Ra);
16204
16205 Double_t rmode=fsigrpdf.GetMaximumX();
16206 Double_t bkgrmode=fbkgrpdf.GetMaximumX();
16207
16208 // Determine the "p%" credible interval for the signal rate
16209 Float_t frac=0;
16210 frac=GetCredibleInterval(fsigrpdf,p,rlow,rup,n);
16211
16212 // Provide the signal and background rate PDFs as histograms in the output file
16213 fbkgrpdf.SetRange(0,3.*Noff/Toff);
16214 fbkgrpdf.SetNpx(n);
16215 TH1* hBkgRatePDF=(TH1*)fbkgrpdf.GetHistogram()->Clone();
16216 hBkgRatePDF->SetName("hBkgRatePDF");
16217 fBurstHistos.Add(hBkgRatePDF);
16218 fsigrpdf.SetRange(0,3.*Non/Ton);
16219 fsigrpdf.SetNpx(n);
16220 TH1* hSigRatePDF=(TH1*)fsigrpdf.GetHistogram()->Clone();
16221 hSigRatePDF->SetName("hSigRatePDF");
16222 fBurstHistos.Add(hSigRatePDF);
16223
16224 printf("\n *%-s::GetBurstBayesianSignalRate* Credible interval [rlow,rup] for p=%-g%% with a precision of 1/%-i \n",ClassName(),p,n);
16225
16226 // Issue a warning in case variable angular cones based on actual track reco sigmas were used.
16227 // This can induce large variations in the on-source and off-source event counts
16228 Int_t fDatype=TMath::Nint(fBurstParameters->GetSignal("Datype"));
16229 Int_t fRecoangle=TMath::Nint(fBurstParameters->GetSignal("Recoangle"));
16230 Int_t fSumsigmas=TMath::Nint(fBurstParameters->GetSignal("Sumsigmas"));
16231
16232 if (fRecoangle && fSumsigmas && fDatype==2)
16233 {
16234 printf(" === Warning: Variable angular cones based on actual track reconstruction sigmas were used. \n");
16235 printf(" Large variations between the on-source and off-source background counts may be present. \n");
16236 }
16237
16238 printf(" The %-g%% credible interval from the Bayesian posterior signal pdf : [%-g,%-g] Hz \n",100.*frac,rlow,rup);
16239 printf(" Modes of the on-source posterior PDFs : Signal=%-g Hz Background=%-g Hz",rmode,bkgrmode);
16240 if (bkgrmode) printf(" Signal/Background=%-g",rmode/bkgrmode);
16241 printf("\n");
16242 cout << " The following signal and background rate PDF histograms have been generated :" << endl;
16243 cout << " ... " << hSigRatePDF->GetName() << " : " << hSigRatePDF->GetTitle() << endl;
16244 cout << " ... " << hBkgRatePDF->GetName() << " : " << hBkgRatePDF->GetTitle() << endl;
16245
16246 // Provide statistics for the lower and upper signal rate boundaries and for the mode of the signal PDF as well
16247 Float_t fSensarea=fBurstParameters->GetSignal("Sensarea");
16248 Float_t TwinOn=Ton/float(fNgrbs); // The average time window in seconds
16249
16250 printf(" Integrated on-source exposure time of the %-i stacked time windows : %-g %-s \n",fNgrbs,Ton/fTfact,tu.Data());
16251 printf(" Integrated off-source exposure time of the %-i*%-i stacked time windows : %-g %-s \n",fNgrbs,fNbkg,Toff/fTfact,tu.Data());
16252 printf(" Total accumulated on-source solid angle : %-g sr in %-i stacked patches --> Average per patch : %-g sr \n",fSolidangleOn,fNgrbs,fAvSolidangleOn);
16253 printf(" Total accumulated off-source solid angle : %-g sr in %-i*%-i stacked patches --> Average per patch : %-g sr \n",fSolidangleOff,fNgrbs,fNbkg,fAvSolidangleOff);
16254 if (fSensarea>0) printf(" Area covered c.q. overlooked by the detector sensors : %-g m^2. \n",fSensarea);
16255 fSensarea*=1e4; // Convert to cm^2
16256
16257 printf(" Total number of recorded on-source events : %-g --> Average per patch : %-g events. \n",Non,Non/float(fNgrbs));
16258 printf(" Total number of recorded off-source events : %-g --> Average per patch : %-g events. \n",Noff,Noff/float(fNgrbs*fNbkg));
16259
16260 printf(" --- Average values per on-source patch based on the posterior PDFs --- \n");
16261
16262 printf(" *Lower bound* Steady signal event rate during the time window : %-g Hz",rlow);
16263 if (fAvSolidangleOn) printf(" --> %-g Hz sr^-1",rlow/fAvSolidangleOn);
16264 printf("\n");
16265 printf(" Expected number of signal events : %-g",rlow*TwinOn);
16266 if (fAvSolidangleOn) printf(" --> %-g events/sr",rlow*TwinOn/fAvSolidangleOn);
16267 printf("\n");
16268 if (fSensarea>0)
16269 {
16270 printf(" Expected signal particle fluence : %-g cm^-2",rlow*TwinOn/fSensarea);
16271 if (fAvSolidangleOn) printf(" --> : %-g cm^-2 sr^-1",rlow*TwinOn/(fSensarea*fAvSolidangleOn));
16272 printf("\n");
16273 printf(" Expected signal particle flux : %-g cm^-2 s^-1",rlow/fSensarea);
16274 if (fAvSolidangleOn) printf(" --> Intensity : %-g cm^-2 s^-1 sr^-1",rlow/(fSensarea*fAvSolidangleOn));
16275 printf("\n");
16276 }
16277
16278 printf(" *Mode* Steady signal event rate during the time window : %-g Hz",rmode);
16279 if (fAvSolidangleOn) printf(" --> %-g Hz sr^-1",rmode/fAvSolidangleOn);
16280 printf("\n");
16281 printf(" Expected number of signal events : %-g",rmode*TwinOn);
16282 if (fAvSolidangleOn) printf(" --> %-g events/sr",rmode*TwinOn/fAvSolidangleOn);
16283 printf("\n");
16284 if (fSensarea>0)
16285 {
16286 printf(" Expected signal particle fluence : %-g cm^-2",rmode*TwinOn/fSensarea);
16287 if (fAvSolidangleOn) printf(" --> : %-g cm^-2 sr^-1",rmode*TwinOn/(fSensarea*fAvSolidangleOn));
16288 printf("\n");
16289 printf(" Expected signal particle flux : %-g cm^-2 s^-1",rmode/fSensarea);
16290 if (fAvSolidangleOn) printf(" --> Intensity : %-g cm^-2 s^-1 sr^-1",rmode/(fSensarea*fAvSolidangleOn));
16291 printf("\n");
16292 }
16293
16294 printf(" *Upper bound* Steady signal event rate during the time window : %-g Hz",rup);
16295 if (fAvSolidangleOn) printf(" --> %-g Hz sr^-1",rup/fAvSolidangleOn);
16296 printf("\n");
16297 printf(" Expected number of signal events : %-g",rup*TwinOn);
16298 if (fAvSolidangleOn) printf(" --> %-g events/sr",rup*TwinOn/fAvSolidangleOn);
16299 printf("\n");
16300 if (fSensarea>0)
16301 {
16302 printf(" Expected signal particle fluence : %-g cm^-2",rup*TwinOn/fSensarea);
16303 if (fAvSolidangleOn) printf(" --> : %-g cm^-2 sr^-1",rup*TwinOn/(fSensarea*fAvSolidangleOn));
16304 printf("\n");
16305 printf(" Expected signal particle flux : %-g cm^-2 s^-1",rup/fSensarea);
16306 if (fAvSolidangleOn) printf(" --> Intensity : %-g cm^-2 s^-1 sr^-1",rup/(fSensarea*fAvSolidangleOn));
16307 printf("\n");
16308 }
16309
16310 printf(" *Background* Steady background event rate during the time window : %-g Hz",bkgrmode);
16311 if (fAvSolidangleOn) printf(" --> %-g Hz sr^-1",bkgrmode/fAvSolidangleOn);
16312 printf("\n");
16313 printf(" Expected number of background events : %-g",bkgrmode*TwinOn);
16314 if (fAvSolidangleOn) printf(" --> %-g events/sr",bkgrmode*TwinOn/fAvSolidangleOn);
16315 printf("\n");
16316 if (fSensarea>0)
16317 {
16318 printf(" Expected background particle fluence : %-g cm^-2",bkgrmode*TwinOn/fSensarea);
16319 if (fAvSolidangleOn) printf(" --> : %-g cm^-2 sr^-1",bkgrmode*TwinOn/(fSensarea*fAvSolidangleOn));
16320 printf("\n");
16321 printf(" Expected background particle flux : %-g cm^-2 s^-1",bkgrmode/fSensarea);
16322 if (fAvSolidangleOn) printf(" --> Intensity : %-g cm^-2 s^-1 sr^-1",bkgrmode/(fSensarea*fAvSolidangleOn));
16323 printf("\n");
16324 }
16325
16326 return hSigRatePDF;
16327}
16328
16330{
16343
16344 Double_t sigma=0;
16345
16346 // The recorded (stacked) "on source" and "off source" number of events
16347 Double_t Non=fBurstOnMatch.GetN();
16348 Double_t Noff=fBurstOffMatch.GetN();
16349
16350 if (Non<=0 || Noff<=0)
16351 {
16352 printf(" \n *%-s::GetBurstLiMaSignificance* \n",ClassName());
16353 if (Non<=0) printf(" === No on source data available === \n");
16354 if (Noff<=0) printf(" === No off source data available === \n");
16355 return 0;
16356 }
16357
16358 // The (stacked) "on source" and "off source" solid angles that were probed
16359 Double_t fAvSolidangleOn=fBurstParameters->GetSignal("AvSolidangleOn");
16360 Double_t fAvSolidangleOff=fBurstParameters->GetSignal("AvSolidangleOff");
16361 Double_t Ra=-1;
16362 if (fAvSolidangleOff) Ra=fAvSolidangleOn/fAvSolidangleOff;
16363
16364 // The (stacked) "on source" and "off source" exposure times
16365 Double_t Ton=fBurstParameters->GetSignal("TtotOn");
16366 Double_t Toff=fBurstParameters->GetSignal("TtotOff");
16367
16368 NcMath m;
16369 sigma=m.LiMaSignificance(Non,Ton,Noff,Toff,Ra);
16370
16371 printf("\n *%-s::GetBurstLiMaSignificance* The Li-Ma signal significance is : %-g \n",ClassName(),sigma);
16372
16373 // Issue a warning in case variable angular cones based on actual track reco sigmas were used.
16374 // This can induce large variations in the on-source and off-source event counts
16375 Int_t fDatype=TMath::Nint(fBurstParameters->GetSignal("Datype"));
16376 Int_t fRecoangle=TMath::Nint(fBurstParameters->GetSignal("Recoangle"));
16377 Int_t fSumsigmas=TMath::Nint(fBurstParameters->GetSignal("Sumsigmas"));
16378
16379 if (fRecoangle && fSumsigmas && fDatype==2)
16380 {
16381 printf(" === Warning: Variable angular cones based on actual track reconstruction sigmas were used. \n");
16382 printf(" Large variations between the on-source and off-source background counts may be present. \n");
16383 }
16384
16385 return sigma;
16386}
16387
16388void NcAstrolab::GetBurstBayesianPsiStatistics(TString type,Double_t nr,Int_t ncut,Int_t ndt,Bool_t zcor,Int_t freq)
16389{
16459
16460 NcMath math;
16461
16462 TString text="none";
16463 if (type=="time") text="arrival time";
16464 if (type=="BBtime") text="Bayesian Block event rate";
16465 if (type=="BBrat") text="normalized On-source/Off-source Bayesian Block event rate ratio";
16466 if (type=="angle") text="opening angle";
16467 if (type=="cosa") text="cos(opening angle)";
16468 if (type=="dt") text="arrival time interval";
16469
16470 if (zcor)
16471 {
16472 text.ReplaceAll("arrival time","redshift corrected arrival time");
16473 text.ReplaceAll("event rate","redshift corrected event rate");
16474 }
16475
16476 cout << endl;
16477 if (text=="none")
16478 {
16479 cout << " *" << ClassName() << "::GetBurstBayesianPsiStatistics* Unknown statistics type : " << type << endl;
16480 return;
16481 }
16482 else
16483 {
16484 cout << " *" << ClassName() << "::GetBurstBayesianPsiStatistics* Analysis of " << text << " statistics" << endl;
16485 }
16486
16487 Int_t fTunits=TMath::Nint(fBurstParameters->GetSignal("Tunits"));
16488 TString tu="days";
16489 if (fTunits==1) tu="hours";
16490 if (fTunits==2) tu="sec";
16491 if (fTunits==3) tu="ns";
16492 if (fTunits==4) tu="ps";
16493
16494 TH1* tot=0;
16495 TH1* bkg=0;
16496 TH1* rat=0;
16497
16498 Double_t psitot=-1, psibkg=-1, psirat=-1;
16499 Float_t psidif=0;
16500 Float_t psimintot=-1, psimaxtot=-1, psifractot=0;
16501 Float_t psiminbkg=-1, psimaxbkg=-1, psifracbkg=0;
16502 Float_t psiminrat=-1, psimaxrat=-1, psifracrat=0;
16503 Double_t nrxtot=-1, nrxbkg=-1, nrxrat=-1;
16504 Double_t pvaluetot=-1, pvaluebkg=-1, pvaluerat=-1;
16505
16506 TH1F* hPsiOn=0;
16507 TH1F* hPsiOff=0;
16508 TH1F* hPsiRat=0;
16509 TH1F* rtot=0;
16510 TH1F* rbkg=0;
16511 TH1F* rrat=0;
16512
16514 // Arrival time histo Bayesian statistics //
16516 if (type=="time")
16517 {
16518 if (!zcor) // Plain observed arrival times
16519 {
16520 tot=(TH1*)fBurstHistos.FindObject("hOnt");
16521 bkg=(TH1*)fBurstHistos.FindObject("hOfft");
16522 }
16523 else // Redshift corrected arrival times
16524 {
16525 tot=(TH1*)fBurstHistos.FindObject("hOnZt");
16526 bkg=(TH1*)fBurstHistos.FindObject("hOffZt");
16527 }
16528
16529 if (!tot) printf(" === No on source data available === \n");
16530 if (!bkg) printf(" === No off source data available === \n");
16531
16532 if (!tot && !bkg) return;
16533
16534 if (tot) psitot=math.PsiValue(tot,0,0,freq);
16535 if (bkg) psibkg=math.PsiValue(bkg,0,0,freq);
16536 psidif=psitot-psibkg;
16537
16538 // Extreme Psi values for a pure background hypothesis of the recorded arrival time entries
16539 if (tot)
16540 {
16541 psimintot=math.PsiExtreme(tot,0,0,-2);
16542 if (psitot<psimintot) psimintot=psitot;
16543 psimaxtot=math.PsiExtreme(tot,0,0,-1);
16544 if (psimaxtot>psimintot) psifractot=(psimaxtot-psitot)/(psimaxtot-psimintot);
16545 }
16546 if (bkg)
16547 {
16548 psiminbkg=math.PsiExtreme(bkg,0,0,-2);
16549 if (psibkg<psiminbkg) psiminbkg=psibkg;
16550 psimaxbkg=math.PsiExtreme(bkg,0,0,-1);
16551 if (psimaxbkg>psiminbkg) psifracbkg=(psimaxbkg-psibkg)/(psimaxbkg-psiminbkg);
16552 }
16553
16554 // P-value determination
16555 if (nr>=0)
16556 {
16557 if (!zcor) // Plain observed arrival times
16558 {
16559 hPsiOn=(TH1F*)fBurstHistos.FindObject("hPsiOnt");
16560 hPsiOff=(TH1F*)fBurstHistos.FindObject("hPsiOfft");
16561 }
16562 else // Redshift corrected arrival times
16563 {
16564 hPsiOn=(TH1F*)fBurstHistos.FindObject("hPsiOnZt");
16565 hPsiOff=(TH1F*)fBurstHistos.FindObject("hPsiOffZt");
16566 }
16567
16568 if (hPsiOn)
16569 {
16570 rtot=(TH1F*)hPsiOn->Clone();
16571 rtot->Reset();
16572 }
16573 else
16574 {
16575 if (tot)
16576 {
16577 if (!zcor) rtot=new TH1F("hPsiOnt","Psi distr. for bkg hypothesis of on-source arrival time data",100,psimintot-1.,psimaxtot+1.);
16578 if (zcor) rtot=new TH1F("hPsiOnZt","Psi distr. for bkg hypothesis of redshift corrected on-source arrival time data",100,psimintot-1.,psimaxtot+1.);
16579 }
16580 }
16581
16582 if (hPsiOff)
16583 {
16584 rbkg=(TH1F*)hPsiOff->Clone();
16585 rbkg->Reset();
16586 }
16587 else
16588 {
16589 if (bkg)
16590 {
16591 if (!zcor) rbkg=new TH1F("hPsiOfft","Psi distr. for bkg hypothesis of off-source arrival time data",100,psiminbkg-1.,psimaxbkg+1.);
16592 if (zcor) rbkg=new TH1F("hPsiOffZt","Psi distr. for bkg hypothesis of redshift corrected off-source arrival time data",100,psiminbkg-1.,psimaxbkg+1.);
16593 }
16594 }
16595
16596 if (tot)
16597 {
16598 pvaluetot=math.PsiPvalue(-1,nr,tot,0,0,freq,0,rtot,ncut,&nrxtot);
16599 fBurstHistos.Add(rtot);
16600 }
16601 if (bkg)
16602 {
16603 pvaluebkg=math.PsiPvalue(-1,nr,bkg,0,0,freq,0,rbkg,ncut,&nrxbkg);
16604 fBurstHistos.Add(rbkg);
16605 }
16606
16607 cout << " The following randomised Psi histograms have been generated :" << endl;
16608 if (rtot) cout << " ... " << rtot->GetName() << " : " << rtot->GetTitle() << endl;
16609 if (rbkg) cout << " ... " << rbkg->GetName() << " : " << rbkg->GetTitle() << endl;
16610 }
16611 }
16612
16614 // Event rate histo Bayesian statistics //
16616 if (type=="BBtime")
16617 {
16618 if (!zcor) // Plain observed arrival times
16619 {
16620 tot=(TH1*)fBurstHistos.FindObject("hOnBBt");
16621 bkg=(TH1*)fBurstHistos.FindObject("hOffBBt");
16622 }
16623 else // Redshift corrected arrival times
16624 {
16625 tot=(TH1*)fBurstHistos.FindObject("hOnBBzt");
16626 bkg=(TH1*)fBurstHistos.FindObject("hOffBBzt");
16627 }
16628
16629 if (!tot) printf(" === No on source data available === \n");
16630 if (!bkg) printf(" === No off source data available === \n");
16631
16632 if (!tot && !bkg) return;
16633
16634 // Temporarily offset the bin contents so that the lowest bin content is 1 for the psi analysis
16635 if (tot)
16636 {
16637 for (Int_t i=1; i<=tot->GetNbinsX(); i++)
16638 {
16639 tot->AddBinContent(i,1);
16640 }
16641 }
16642
16643 if (bkg)
16644 {
16645 for (Int_t i=1; i<=bkg->GetNbinsX(); i++)
16646 {
16647 bkg->AddBinContent(i,1);
16648 }
16649 }
16650
16651 if (tot) psitot=math.PsiValue(tot,0,0,freq);
16652 if (bkg) psibkg=math.PsiValue(bkg,0,0,freq);
16653 psidif=psitot-psibkg;
16654
16655 // Extreme Psi values for a pure background hypothesis of the recorded arrival time entries
16656 if (tot)
16657 {
16658 psimintot=math.PsiExtreme(tot,0,0,-2);
16659 if (psitot<psimintot) psimintot=psitot;
16660 psimaxtot=math.PsiExtreme(tot,0,0,-1);
16661 if (psimaxtot>psimintot) psifractot=(psimaxtot-psitot)/(psimaxtot-psimintot);
16662 }
16663 if (bkg)
16664 {
16665 psiminbkg=math.PsiExtreme(bkg,0,0,-2);
16666 if (psibkg<psiminbkg) psiminbkg=psibkg;
16667 psimaxbkg=math.PsiExtreme(bkg,0,0,-1);
16668 if (psimaxbkg>psiminbkg) psifracbkg=(psimaxbkg-psibkg)/(psimaxbkg-psiminbkg);
16669 }
16670
16671 // P-value determination
16672 if (nr>=0)
16673 {
16674 if (!zcor) // Plain observed arrival times
16675 {
16676 hPsiOn=(TH1F*)fBurstHistos.FindObject("hPsiOnBBt");
16677 hPsiOff=(TH1F*)fBurstHistos.FindObject("hPsiOffBBt");
16678 }
16679 else // Redshift corrected arrival times
16680 {
16681 hPsiOn=(TH1F*)fBurstHistos.FindObject("hPsiOnBBzt");
16682 hPsiOff=(TH1F*)fBurstHistos.FindObject("hPsiOffBBzt");
16683 }
16684
16685 if (hPsiOn)
16686 {
16687 rtot=(TH1F*)hPsiOn->Clone();
16688 rtot->Reset();
16689 }
16690 else
16691 {
16692 if (tot)
16693 {
16694 if (!zcor) rtot=new TH1F("hPsiOnBBt","Psi distr. for bkg hypothesis of on-source event rate Bayesian Block data",100,psimintot-1.,psimaxtot+1.);
16695 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.);
16696 }
16697 }
16698
16699 if (hPsiOff)
16700 {
16701 rbkg=(TH1F*)hPsiOff->Clone();
16702 rbkg->Reset();
16703 }
16704 else
16705 {
16706 if (bkg)
16707 {
16708 if (!zcor) rbkg=new TH1F("hPsiOffBBt","Psi distr. for bkg hypothesis of off-source event rate Bayesian Block data",100,psiminbkg-1.,psimaxbkg+1.);
16709 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.);
16710 }
16711 }
16712
16713 if (tot)
16714 {
16715 pvaluetot=math.PsiPvalue(-1,nr,tot,0,0,freq,0,rtot,ncut,&nrxtot);
16716 fBurstHistos.Add(rtot);
16717 }
16718 if (bkg)
16719 {
16720 pvaluebkg=math.PsiPvalue(-1,nr,bkg,0,0,freq,0,rbkg,ncut,&nrxbkg);
16721 fBurstHistos.Add(rbkg);
16722 }
16723
16724 cout << " The following randomised Psi histograms have been generated :" << endl;
16725 if (rtot) cout << " ... " << rtot->GetName() << " : " << rtot->GetTitle() << endl;
16726 if (rbkg) cout << " ... " << rbkg->GetName() << " : " << rbkg->GetTitle() << endl;
16727 }
16728
16729 // Restore the original histogram data
16730 if (tot)
16731 {
16732 for (Int_t i=1; i<=tot->GetNbinsX(); i++)
16733 {
16734 tot->AddBinContent(i,-1);
16735 }
16736 }
16737 if (bkg)
16738 {
16739 for (Int_t i=1; i<=bkg->GetNbinsX(); i++)
16740 {
16741 bkg->AddBinContent(i,-1);
16742 }
16743 }
16744 }
16745
16747 // On-source/Off-source event rate ratio histo Bayesian statistics //
16749 if (type=="BBrat")
16750 {
16751 if (!zcor) // Plain observed arrival times
16752 {
16753 rat=(TH1*)fBurstHistos.FindObject("hRatUBBt");
16754 }
16755 else // Redshift corrected arrival times
16756 {
16757 rat=(TH1*)fBurstHistos.FindObject("hRatUBBzt");
16758 }
16759
16760 if (!rat)
16761 {
16762 printf(" === No data available === \n");
16763 return;
16764 }
16765
16766 psirat=math.PsiValue(rat,0,0,freq);
16767 psidif=psitot-psibkg;
16768
16769 // Extreme Psi values for a pure background hypothesis of the recorded arrival time entries
16770 psiminrat=math.PsiExtreme(rat,0,0,-2);
16771 if (psirat<psiminrat) psiminrat=psirat;
16772 psimaxrat=math.PsiExtreme(rat,0,0,-1);
16773 if (psimaxrat>psiminrat) psifracrat=(psimaxrat-psirat)/(psimaxrat-psiminrat);
16774
16775 // P-value determination
16776 if (nr>=0)
16777 {
16778 if (!zcor) // Plain observed arrival times
16779 {
16780 hPsiRat=(TH1F*)fBurstHistos.FindObject("hPsiRatUBBt");
16781 }
16782 else // Redshift corrected arrival times
16783 {
16784 hPsiRat=(TH1F*)fBurstHistos.FindObject("hPsiRatUBBzt");
16785 }
16786
16787 if (hPsiRat)
16788 {
16789 rrat=(TH1F*)hPsiRat->Clone();
16790 rrat->Reset();
16791 }
16792 else
16793 {
16794 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.);
16795 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.);
16796 }
16797
16798 pvaluerat=math.PsiPvalue(-1,nr,rat,0,0,freq,0,rrat,ncut,&nrxrat);
16799 fBurstHistos.Add(rrat);
16800
16801 cout << " The following randomised Psi histograms have been generated :" << endl;
16802 if (rrat) cout << " ... " << rrat->GetName() << " : " << rrat->GetTitle() << endl;
16803 }
16804 }
16805
16807 // Opening angle histo Bayesian statistics //
16809 if (type=="angle")
16810 {
16811 tot=(TH1*)fBurstHistos.FindObject("hOna");
16812 bkg=(TH1*)fBurstHistos.FindObject("hOffa");
16813
16814 if (!tot) printf(" === No on source data available === \n");
16815 if (!bkg) printf(" === No off source data available === \n");
16816
16817 if (!tot && !bkg) return;
16818
16819 TF1 pdfa("pdfa","sin(x*acos(-1.)/180.)");
16820 if (tot) psitot=math.PsiValue(tot,0,&pdfa,freq);
16821 if (bkg) psibkg=math.PsiValue(bkg,0,&pdfa,freq);
16822 psidif=psitot-psibkg;
16823
16824 // Extreme Psi values for a pure background hypothesis of the recorded opening angle entries
16825 if (tot)
16826 {
16827 psimintot=math.PsiExtreme(tot,0,&pdfa,-2);
16828 if (psitot<psimintot) psimintot=psitot;
16829 psimaxtot=math.PsiExtreme(tot,0,&pdfa,-1);
16830 if (psimaxtot>psimintot) psifractot=(psimaxtot-psitot)/(psimaxtot-psimintot);
16831 }
16832 if (bkg)
16833 {
16834 psiminbkg=math.PsiExtreme(bkg,0,&pdfa,-2);
16835 if (psibkg<psiminbkg) psiminbkg=psibkg;
16836 psimaxbkg=math.PsiExtreme(bkg,0,&pdfa,-1);
16837 if (psimaxbkg>psiminbkg) psifracbkg=(psimaxbkg-psibkg)/(psimaxbkg-psiminbkg);
16838 }
16839
16840 // P-value determination
16841 if (nr>=0)
16842 {
16843 hPsiOn=(TH1F*)fBurstHistos.FindObject("hPsiOna");
16844 hPsiOff=(TH1F*)fBurstHistos.FindObject("hPsiOffa");
16845
16846 if (hPsiOn)
16847 {
16848 rtot=(TH1F*)hPsiOn->Clone();
16849 rtot->Reset();
16850 }
16851 else
16852 {
16853 if (tot) rtot=new TH1F("hPsiOna","Psi distr. for bkg hypothesis of on-source opening angle data",100,psimintot-1.,psimaxtot+1.);
16854 }
16855
16856 if (hPsiOff)
16857 {
16858 rbkg=(TH1F*)hPsiOff->Clone();
16859 rbkg->Reset();
16860 }
16861 else
16862 {
16863 if (bkg) rbkg=new TH1F("hPsiOffa","Psi distr. for bkg hypothesis of off-source opening angle data",100,psiminbkg-1.,psimaxbkg+1.);
16864 }
16865
16866 if (tot)
16867 {
16868 pvaluetot=math.PsiPvalue(-1,nr,tot,0,&pdfa,freq,0,rtot,ncut,&nrxtot);
16869 fBurstHistos.Add(rtot);
16870 }
16871 if (bkg)
16872 {
16873 pvaluebkg=math.PsiPvalue(-1,nr,bkg,0,&pdfa,freq,0,rbkg,ncut,&nrxbkg);
16874 fBurstHistos.Add(rbkg);
16875 }
16876
16877 cout << " The following randomised Psi histograms have been generated :" << endl;
16878 if (rtot) cout << " ... " << rtot->GetName() << " : " << rtot->GetTitle() << endl;
16879 if (rbkg) cout << " ... " << rbkg->GetName() << " : " << rbkg->GetTitle() << endl;
16880 }
16881 }
16882
16884 // Cosine of opening angle histo Bayesian statistics //
16886 if (type=="cosa")
16887 {
16888 tot=(TH1*)fBurstHistos.FindObject("hOnCosa");
16889 bkg=(TH1*)fBurstHistos.FindObject("hOffCosa");
16890
16891 if (!tot) printf(" === No on source data available === \n");
16892 if (!bkg) printf(" === No off source data available === \n");
16893
16894 if (!tot && !bkg) return;
16895
16896 if (tot) psitot=math.PsiValue(tot,0,0,freq);
16897 if (bkg) psibkg=math.PsiValue(bkg,0,0,freq);
16898 psidif=psitot-psibkg;
16899
16900 // Extreme Psi values for a pure background hypothesis of the recorded cos(opening angle) entries
16901 if (tot)
16902 {
16903 psimintot=math.PsiExtreme(tot,0,0,-2);
16904 if (psitot<psimintot) psimintot=psitot;
16905 psimaxtot=math.PsiExtreme(tot,0,0,-1);
16906 if (psimaxtot>psimintot) psifractot=(psimaxtot-psitot)/(psimaxtot-psimintot);
16907 }
16908 if (bkg)
16909 {
16910 psiminbkg=math.PsiExtreme(bkg,0,0,-2);
16911 if (psibkg<psiminbkg) psiminbkg=psibkg;
16912 psimaxbkg=math.PsiExtreme(bkg,0,0,-1);
16913 if (psimaxbkg>psiminbkg) psifracbkg=(psimaxbkg-psibkg)/(psimaxbkg-psiminbkg);
16914 }
16915
16916 // P-value determination
16917 if (nr>=0)
16918 {
16919 hPsiOn=(TH1F*)fBurstHistos.FindObject("hPsiOnCosa");
16920 hPsiOff=(TH1F*)fBurstHistos.FindObject("hPsiOffCosa");
16921
16922 if (hPsiOn)
16923 {
16924 rtot=(TH1F*)hPsiOn->Clone();
16925 rtot->Reset();
16926 }
16927 else
16928 {
16929 if (tot) rtot=new TH1F("hPsiOnCosa","Psi distr. for bkg hypothesis of on-source cos(opening angle) data",100,psimintot-1.,psimaxtot+1.);
16930 }
16931
16932 if (hPsiOff)
16933 {
16934 rbkg=(TH1F*)hPsiOff->Clone();
16935 rbkg->Reset();
16936 }
16937 else
16938 {
16939 if (bkg) rbkg=new TH1F("hPsiOffCosa","Psi distr. for bkg hypothesis of off-source cos(opening angle) data",100,psiminbkg-1.,psimaxbkg+1.);
16940 }
16941
16942 if (tot)
16943 {
16944 pvaluetot=math.PsiPvalue(-1,nr,tot,0,0,freq,0,rtot,ncut,&nrxtot);
16945 fBurstHistos.Add(rtot);
16946 }
16947 if (bkg)
16948 {
16949 pvaluebkg=math.PsiPvalue(-1,nr,bkg,0,0,freq,0,rbkg,ncut,&nrxbkg);
16950 fBurstHistos.Add(rbkg);
16951 }
16952
16953 cout << " The following randomised Psi histograms have been generated :" << endl;
16954 if (rtot) cout << " ... " << rtot->GetName() << " : " << rtot->GetTitle() << endl;
16955 if (rbkg) cout << " ... " << rbkg->GetName() << " : " << rbkg->GetTitle() << endl;
16956 }
16957 }
16958
16960 // Arrival time interval Bayesian statistics //
16962 if (type=="dt")
16963 {
16964 TH1F hOndt;
16965 TH1F hOffdt;
16966 TF1 pdfdttot;
16967 TF1 pdfdtbkg;
16968
16969 GetBurstDtDistributions(ndt,hOndt,pdfdttot,hOffdt,pdfdtbkg,zcor);
16970
16971 Int_t ntot=hOndt.GetEntries();
16972 Int_t nbkg=hOffdt.GetEntries();
16973
16974 if (!ntot) printf(" === No on source data available === \n");
16975 if (!nbkg) printf(" === No off source data available === \n");
16976
16977 if (!ntot && !nbkg) return;
16978
16979 if (ntot) psitot=math.PsiValue(&hOndt,0,&pdfdttot,freq);
16980 if (nbkg) psibkg=math.PsiValue(&hOffdt,0,&pdfdtbkg,freq);
16981 psidif=psitot-psibkg;
16982
16983 if (ntot)
16984 {
16985 psimintot=math.PsiExtreme(&hOndt,0,&pdfdttot,-2);
16986 if (psitot<psimintot) psimintot=psitot;
16987 psimaxtot=math.PsiExtreme(&hOndt,0,&pdfdttot,-1);
16988 if (psimaxtot>psimintot) psifractot=(psimaxtot-psitot)/(psimaxtot-psimintot);
16989 }
16990 if (nbkg)
16991 {
16992 psiminbkg=math.PsiExtreme(&hOffdt,0,&pdfdtbkg,-2);
16993 if (psibkg<psiminbkg) psiminbkg=psibkg;
16994 psimaxbkg=math.PsiExtreme(&hOffdt,0,&pdfdtbkg,-1);
16995 if (psimaxbkg>psiminbkg) psifracbkg=(psimaxbkg-psibkg)/(psimaxbkg-psiminbkg);
16996 }
16997
16998 // P-value determination
16999 if (nr>=0)
17000 {
17001 TString nametot;
17002 TString namebkg;
17003 if (!zcor)
17004 {
17005 nametot.Form("hPsiOndt%-i",ndt);
17006 namebkg.Form("hPsiOffdt%-i",ndt);
17007 }
17008 else
17009 {
17010 nametot.Form("hPsiOnZdt%-i",ndt);
17011 namebkg.Form("hPsiOffZdt%-i",ndt);
17012 }
17013
17014 TH1F* hPsiOn=(TH1F*)fBurstHistos.FindObject(nametot);
17015 TH1F* hPsiOff=(TH1F*)fBurstHistos.FindObject(namebkg);
17016
17017 TString title;
17018 if (hPsiOn)
17019 {
17020 rtot=(TH1F*)hPsiOn->Clone();
17021 rtot->Reset();
17022 }
17023 else
17024 {
17025 if (!zcor) title.Form("Psi distr. for bkg hypothesis of on-source dt data for n=%-i",ndt);
17026 if (zcor) title.Form("Psi distr. for bkg hypothesis of redshift corrected on-source dt data for n=%-i",ndt);
17027 if (ntot) rtot=new TH1F(nametot,title,100,psimintot-1.,psimaxtot+1.);
17028 }
17029
17030 if (hPsiOff)
17031 {
17032 rbkg=(TH1F*)hPsiOff->Clone();
17033 rbkg->Reset();
17034 }
17035 else
17036 {
17037 if (!zcor) title.Form("Psi distr. for bkg hypothesis of off-source dt data for n=%-i",ndt);
17038 if (zcor) title.Form("Psi distr. for bkg hypothesis of redshift corrected off-source dt data for n=%-i",ndt);
17039 if (nbkg) rbkg=new TH1F(namebkg,title,100,psiminbkg-1.,psimaxbkg+1.);
17040 }
17041
17042 if (ntot)
17043 {
17044 pvaluetot=math.PsiPvalue(-1,nr,&hOndt,0,&pdfdttot,freq,0,rtot,ncut,&nrxtot);
17045 fBurstHistos.Add(rtot);
17046 }
17047 if (nbkg)
17048 {
17049 pvaluebkg=math.PsiPvalue(-1,nr,&hOffdt,0,&pdfdtbkg,freq,0,rbkg,ncut,&nrxbkg);
17050 fBurstHistos.Add(rbkg);
17051 }
17052
17053 cout << " The following randomised Psi histograms have been (re)generated :" << endl;
17054 if (rtot) cout << " ... " << rtot->GetName() << " : " << rtot->GetTitle() << endl;
17055 if (rbkg) cout << " ... " << rbkg->GetName() << " : " << rbkg->GetTitle() << endl;
17056 }
17057 }
17058
17059 // Listing of the statistics results
17060 cout << " *** Observed Psi values (in dB) for the hypothesis of no burst signal ***" << endl;
17061 if (psitot>=0) cout << " For the on-source stacked patches : psi = " << psitot << endl;
17062 if (psibkg>=0) cout << " For the off-source stacked patches : psi = " << psibkg << endl;
17063 if (psitot>=0 && psibkg>=0) cout << " --> Difference between observed on-source and off-source psi values : " << psidif << endl;
17064 if (psirat>=0) cout << " For the on/off source event rate Bayesian Blocks : psi = " << psirat << endl;
17065 cout << " *** Extreme Psi values for the case of pure background ***" << endl;
17066 if (psimintot>=0) cout << " For on-source psimin : " << psimintot << " psimax : " << psimaxtot;
17067 if (psifractot>0) printf(" (psimax-psi)/range : %-g",psifractot);
17068 if (psimintot>=0 || psifractot>0) printf("\n");
17069 if (psiminbkg>=0) cout << " For off-source psimin : " << psiminbkg << " psimax : " << psimaxbkg;
17070 if (psifracbkg>0) printf(" (psimax-psi)/range : %-g",psifracbkg);
17071 if (psiminbkg>=0 || psifracbkg>0) printf("\n");
17072 if (psiminrat>=0) cout << " For on/off source event rate Bayesian Blocks psimin : " << psiminrat << " psimax : " << psimaxrat;
17073 if (psifracrat>0) printf(" (psimax-psi)/range : %-g",psifracrat);
17074 if (psiminrat>=0 || psifracrat>0) printf("\n");
17075
17076 if (nr>=0)
17077 {
17078 cout << " *** P-values of the observed on-source and off-source psi values ***" << endl;
17079 if (nrxtot>0) cout << " For the on-source stacked patches : P-value = " << pvaluetot << " Used number of randomisations : " << nrxtot << endl;
17080 if (nrxbkg>0) cout << " For the off-source stacked patches : P-value = " << pvaluebkg << " Used number of randomisations : " << nrxbkg << endl;
17081 if (nrxrat>0) cout << " For the on/off source event rate Bayesian Blocks : P-value = " << pvaluerat << " Used number of randomisations : " << nrxrat << endl;
17082 }
17083}
17084
17085void NcAstrolab::GetBurstChi2Statistics(TString type,Int_t ndt,Bool_t zcor)
17086{
17121
17122 NcMath math;
17123
17124 TString text="none";
17125 if (type=="time") text="arrival time";
17126 if (type=="BBtime") text="Bayesian Block event rate";
17127 if (type=="BBrat") text="normalized On-source/Off-source Bayesian Block event rate ratio";
17128 if (type=="angle") text="opening angle";
17129 if (type=="cosa") text="cos(opening angle)";
17130 if (type=="dt") text="arrival time interval";
17131
17132 if (zcor)
17133 {
17134 text.ReplaceAll("arrival time","redshift corrected arrival time");
17135 text.ReplaceAll("event rate","redshift corrected event rate");
17136 }
17137
17138 cout << endl;
17139 if (text=="none")
17140 {
17141 cout << " *" << ClassName() << "::GetBurstChi2Statistics* Unknown statistics type : " << type << endl;
17142 return;
17143 }
17144 else
17145 {
17146 cout << " *" << ClassName() << "::GetBurstChi2Statistics* Analysis of " << text << " statistics" << endl;
17147 }
17148
17149 TH1* tot=0;
17150 TH1* bkg=0;
17151 TH1* rat=0;
17152
17153 Int_t ndftot=0;
17154 Int_t ndfbkg=0;
17155 Int_t ndfrat=0;
17156 Float_t chitot=0;
17157 Float_t chibkg=0;
17158 Float_t chirat=0;
17159
17161 // Arrival time histo Chi-squared statistics //
17163 if (type=="time")
17164 {
17165 if (!zcor)
17166 {
17167 tot=(TH1*)fBurstHistos.FindObject("hOnt");
17168 bkg=(TH1*)fBurstHistos.FindObject("hOfft");
17169 }
17170 else
17171 {
17172 tot=(TH1*)fBurstHistos.FindObject("hOnZt");
17173 bkg=(TH1*)fBurstHistos.FindObject("hOffZt");
17174 }
17175
17176 if (!tot) printf(" === No on source data available === \n");
17177 if (!bkg) printf(" === No off source data available === \n");
17178
17179 if (!tot && !bkg) return;
17180
17181 if (tot) chitot=math.Chi2Value(tot,0,0,&ndftot);
17182 if (bkg) chibkg=math.Chi2Value(bkg,0,0,&ndfbkg);
17183 }
17184
17186 // Event rate histo Chi-squared statistics //
17188 if (type=="BBtime")
17189 {
17190 if (!zcor)
17191 {
17192 tot=(TH1*)fBurstHistos.FindObject("hOnBBt");
17193 bkg=(TH1*)fBurstHistos.FindObject("hOffBBt");
17194 }
17195 else
17196 {
17197 tot=(TH1*)fBurstHistos.FindObject("hOnBBzt");
17198 bkg=(TH1*)fBurstHistos.FindObject("hOffBBzt");
17199 }
17200
17201 if (!tot) printf(" === No on source data available === \n");
17202 if (!bkg) printf(" === No off source data available === \n");
17203
17204 if (!tot && !bkg) return;
17205
17206 if (tot) chitot=math.Chi2Value(tot,0,0,&ndftot);
17207 if (bkg) chibkg=math.Chi2Value(bkg,0,0,&ndfbkg);
17208 }
17209
17211 // On-source/Off-source event rate ratio histo Chi-squared statistics //
17213 if (type=="BBrat")
17214 {
17215 if (!zcor)
17216 {
17217 rat=(TH1*)fBurstHistos.FindObject("hRatUBBt");
17218 }
17219 else
17220 {
17221 rat=(TH1*)fBurstHistos.FindObject("hRatUBBzt");
17222 }
17223
17224 if (!rat)
17225 {
17226 printf(" === No data available === \n");
17227 return;
17228 }
17229
17230 chirat=math.Chi2Value(rat,0,0,&ndfrat);
17231 }
17232
17234 // Opening angle histo Chi-squared statistics //
17236 if (type=="angle")
17237 {
17238 tot=(TH1*)fBurstHistos.FindObject("hOna");
17239 bkg=(TH1*)fBurstHistos.FindObject("hOffa");
17240
17241 if (!tot) printf(" === No on source data available === \n");
17242 if (!bkg) printf(" === No off source data available === \n");
17243
17244 if (!tot && !bkg) return;
17245
17246 TF1 pdf("pdf","sin(x*acos(-1.)/180.)");
17247 if (tot) chitot=math.Chi2Value(tot,0,&pdf,&ndftot);
17248 if (bkg) chibkg=math.Chi2Value(bkg,0,&pdf,&ndfbkg);
17249 }
17250
17252 // Cosine of opening angle histo Chi-squared statistics //
17254 if (type=="cosa")
17255 {
17256 tot=(TH1*)fBurstHistos.FindObject("hOnCosa");
17257 bkg=(TH1*)fBurstHistos.FindObject("hOffCosa");
17258
17259 if (!tot) printf(" === No on source data available === \n");
17260 if (!bkg) printf(" === No off source data available === \n");
17261
17262 if (!tot && !bkg) return;
17263
17264 if (tot) chitot=math.Chi2Value(tot,0,0,&ndftot);
17265 if (bkg) chibkg=math.Chi2Value(bkg,0,0,&ndfbkg);
17266 }
17267
17269 // Arrival time interval Chi-squared statistics //
17271 if (type=="dt")
17272 {
17273 TH1F hOndt;
17274 TH1F hOffdt;
17275 TF1 pdfdttot;
17276 TF1 pdfdtbkg;
17277
17278 GetBurstDtDistributions(ndt,hOndt,pdfdttot,hOffdt,pdfdtbkg,zcor);
17279
17280 Int_t ntot=hOndt.GetEntries();
17281 Int_t nbkg=hOffdt.GetEntries();
17282
17283 if (!ntot) printf(" === No on source data available === \n");
17284 if (!nbkg) printf(" === No off source data available === \n");
17285
17286 if (!ntot && !nbkg) return;
17287
17288 if (ntot) chitot=math.Chi2Value(&hOndt,0,&pdfdttot,&ndftot);
17289 if (nbkg) chibkg=math.Chi2Value(&hOffdt,0,&pdfdtbkg,&ndfbkg);
17290 }
17291
17292 // Listing of the statistics results
17293 Float_t chidif=chitot-chibkg;
17294 cout << " *** Observed Chi-squared values for the hypothesis of no burst signal ***" << endl;
17295 if (chitot>0) cout << " For the on-source stacked patches : chi2 = " << chitot << " ndf = " << ndftot << endl;
17296 if (chibkg>0) cout << " For the off-source stacked patches : chi2 = " << chibkg << " ndf = " << ndfbkg << endl;
17297 if (chitot>0 && chibkg>0) cout << " --> Difference between observed on-source and off-source chi2 values : " << chidif << endl;
17298 if (chirat>0) cout << " For the on/off source event rate Bayesian Blocks : chi2 = " << chirat << " ndf = " << ndfrat << endl;
17299
17300 Float_t ptot=-1;
17301 Float_t sigmatot=-1;
17302 Float_t pbkg=-1;
17303 Float_t sigmabkg=-1;
17304 Float_t prat=-1;
17305 Float_t sigmarat=-1;
17306
17307 if (chitot)
17308 {
17309 ptot=math.Chi2Pvalue(chitot,ndftot);
17310 sigmatot=math.Chi2Pvalue(chitot,ndftot,0,1);
17311 }
17312 if (chibkg)
17313 {
17314 pbkg=math.Chi2Pvalue(chibkg,ndfbkg);
17315 sigmabkg=math.Chi2Pvalue(chibkg,ndfbkg,0,1);
17316 }
17317 if (chirat)
17318 {
17319 prat=math.Chi2Pvalue(chirat,ndfrat);
17320 sigmarat=math.Chi2Pvalue(chirat,ndfrat,0,1);
17321 }
17322
17323 cout << " *** P-values of the observed on-source and off-source chi2 values ***" << endl;
17324 if (ptot>=0) cout << " For the on-source stacked patches : P-value = " << ptot << " (" << sigmatot << " sigma)" << endl;
17325 if (pbkg>=0) cout << " For the off-source stacked patches : P-value = " << pbkg << " (" << sigmabkg << " sigma)" << endl;
17326 if (prat>=0) cout << " For the on/off source event rate Bayesian Blocks : P-value = " << prat << " (" << sigmarat << " sigma)" << endl;
17327}
17328
17329void NcAstrolab::GetBurstDtDistributions(Int_t ndt,TH1F& hisdtOn,TF1& pdfdtOn,TH1F& hisdtOff,TF1& pdfdtOff,Bool_t zcor)
17330{
17349
17350
17351 hisdtOn.Reset();
17352 hisdtOff.Reset();
17353
17354 Int_t fTunits=TMath::Nint(fBurstParameters->GetSignal("Tunits"));
17355 TString tu="days";
17356 if (fTunits==1) tu="hours";
17357 if (fTunits==2) tu="sec";
17358 if (fTunits==3) tu="ns";
17359 if (fTunits==4) tu="ps";
17360
17361 Float_t fTfact=fBurstParameters->GetSignal("Tfact");
17362
17363 TString nametot;
17364 TString namebkg;
17365 TString varname;
17366
17367 // Create the automatically binned delta t histograms
17368 if (!zcor)
17369 {
17370 nametot.Form("hOndt%-i",ndt);
17371 namebkg.Form("hOffdt%-i",ndt);
17372 varname="dtime";
17373 }
17374 else
17375 {
17376 nametot.Form("hOnZdt%-i",ndt);
17377 namebkg.Form("hOffZdt%-i",ndt);
17378 varname="dtimez";
17379 }
17380 TH1F* hOndt=(TH1F*)fBurstHistos.FindObject(nametot);
17381 TH1F* hOffdt=(TH1F*)fBurstHistos.FindObject(namebkg);
17382
17383 TString title;
17384 Double_t deltatbin=0;
17385 Int_t nOndt=0;
17386 Int_t nOffdt=0;
17387
17388 if (!hOndt)
17389 {
17390 NcSample sOndt=fBurstOnMatch.GetDtSample(varname,ndt);
17391 nOndt=sOndt.GetN();
17392
17393 if (nOndt)
17394 {
17395 hOndt=new TH1F(nametot,"histo",10000,1,0);
17396
17397 hOndt->SetBuffer(nOndt);
17398
17399 for (Int_t i=1; i<=nOndt; i++)
17400 {
17401 hOndt->Fill(sOndt.GetEntry(i,1));
17402 }
17403
17404 hOndt->BufferEmpty(1);
17405
17406 // Create title and labels for this delta t histograms
17407 deltatbin=hOndt->GetXaxis()->GetBinWidth(1);
17408 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());
17409 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());
17410 hOndt->SetTitle(title);
17411
17412 fBurstHistos.Add(hOndt);
17413 }
17414 }
17415
17416 if (!hOffdt)
17417 {
17418 NcSample sOffdt=fBurstOffMatch.GetDtSample(varname,ndt);
17419 nOffdt=sOffdt.GetN();
17420
17421 if (nOffdt)
17422 {
17423 hOffdt=new TH1F(namebkg,"histo",10000,1,0);
17424
17425 hOffdt->SetBuffer(nOffdt);
17426
17427 for (Int_t i=1; i<=nOffdt; i++)
17428 {
17429 hOffdt->Fill(sOffdt.GetEntry(i,1));
17430 }
17431
17432 hOffdt->BufferEmpty(1);
17433
17434 // Create title and labels for this delta t histograms
17435 deltatbin=hOffdt->GetXaxis()->GetBinWidth(1);
17436 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());
17437 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());
17438 hOffdt->SetTitle(title);
17439
17440 fBurstHistos.Add(hOffdt);
17441 }
17442 }
17443
17444 if (hOndt || hOffdt) cout << " The following arrival time interval (dt) histograms have been generated :" << endl;
17445 if (hOndt) cout << " ... " << hOndt->GetName() << " : " << hOndt->GetTitle() << endl;
17446 if (hOffdt) cout << " ... " << hOffdt->GetName() << " : " << hOffdt->GetTitle() << endl;
17447
17448 if (hOndt) hisdtOn=*hOndt;
17449 if (hOffdt) hisdtOff=*hOffdt;
17450
17451 // Creation of the Poisson based dt PDFs from the observed data for a background only hypothesis
17452
17453 Double_t rateOn=fBurstParameters->GetSignal("rateOn");
17454 Double_t rateOff=fBurstParameters->GetSignal("rateOff");
17455
17456 // Convert the event rates into the correct units
17457 rateOn*=fTfact;
17458 rateOff*=fTfact;
17459
17460 if (zcor) // Redshift corrected arrival times
17461 {
17462 Double_t nevt=fBurstOnMatch.GetN();
17463 Double_t tmin=fBurstOnMatch.GetMinimum(varname);
17464 Double_t tmax=fBurstOnMatch.GetMaximum(varname);
17465 Double_t twin=tmax-tmin;
17466 rateOn=0;
17467 if (twin) rateOn=nevt/twin;
17468 nevt=fBurstOffMatch.GetN();
17469 tmin=fBurstOffMatch.GetMinimum(varname);
17470 tmax=fBurstOffMatch.GetMaximum(varname);
17471 twin=tmax-tmin;
17472 rateOff=0;
17473 if (twin) rateOff=nevt/twin;
17474 }
17475
17476 // Determine the corresponding dt PDFs based on Poisson statistics
17477 // Only the bkg dt PDF is used, since this may be obtained from off-source measurements.
17478 // Using the total dt PDF would artificially lower the sensitivity due to possible signal events.
17479
17480 NcMath math;
17481 pdfdtOn=math.PoissonDtDist(rateOn,ndt); // Poisson dt pdf for the observed on source event rate
17482 pdfdtOff=math.PoissonDtDist(rateOff,ndt); // Poisson dt pdf for the observed off source event rate
17483
17484 if (!zcor)
17485 {
17486 nametot.Form("hpdfOndt%-i",ndt);
17487 namebkg.Form("hpdfOffdt%-i",ndt);
17488 }
17489 else
17490 {
17491 nametot.Form("hpdfOnZdt%-i",ndt);
17492 namebkg.Form("hpdfOffZdt%-i",ndt);
17493 }
17494 TH1* hpdfOndt=(TH1*)fBurstHistos.FindObject(nametot);
17495 TH1* hpdfOffdt=(TH1*)fBurstHistos.FindObject(namebkg);
17496
17497 Double_t xmaxfdt=1;
17498 Double_t deltatmax=0;
17499 if (hOndt)
17500 {
17501 deltatmax=hOndt->GetXaxis()->GetXmax();
17502 xmaxfdt=deltatmax;
17503 }
17504 if (hOffdt)
17505 {
17506 deltatmax=hOffdt->GetXaxis()->GetXmax();
17507 if (deltatmax>xmaxfdt) xmaxfdt=deltatmax;
17508 }
17509 Int_t npx=10000;
17510 pdfdtOn.SetRange(0,xmaxfdt);
17511 pdfdtOn.SetNpx(npx);
17512 pdfdtOff.SetRange(0,xmaxfdt);
17513 pdfdtOff.SetNpx(npx);
17514
17515 // Provide the dt PDFs as histograms in the output file
17516 if (!hpdfOndt && nOndt)
17517 {
17518 hpdfOndt=(TH1*)pdfdtOn.GetHistogram()->Clone();
17519 hpdfOndt->SetName(nametot.Data());
17520 title.Form("dt in %-s",tu.Data());
17521 hpdfOndt->GetXaxis()->SetTitle(title);
17522 fBurstHistos.Add(hpdfOndt);
17523 }
17524
17525 if (!hpdfOffdt && nOffdt)
17526 {
17527 hpdfOffdt=(TH1*)pdfdtOff.GetHistogram()->Clone();
17528 hpdfOffdt->SetName(namebkg.Data());
17529 hpdfOffdt->GetXaxis()->SetTitle(title);
17530 fBurstHistos.Add(hpdfOffdt);
17531 }
17532
17533 if (hpdfOndt || hpdfOffdt) cout << " The following arrival time interval (dt) PDFs have been generated :" << endl;
17534 if (hpdfOndt) cout << " ... " << hpdfOndt->GetName() << " : " << hpdfOndt->GetTitle() << endl;
17535 if (hpdfOffdt) cout << " ... " << hpdfOffdt->GetName() << " : " << hpdfOffdt->GetTitle() << endl;
17536}
17537
17539{
17549
17550 Int_t nh=fBurstHistos.GetEntries();
17551 cout << endl;
17552 cout << " =============== The following " << nh << " histograms have been generated ===============" << endl;
17553 for (Int_t ih=0; ih<nh; ih++)
17554 {
17555 TObject* hx=fBurstHistos.At(ih);
17556 if (!hx) continue;
17557 cout << " " << hx->GetName() << " : " << hx->GetTitle() << endl;
17558 }
17559 cout << " ===============================================================================" << endl;
17560}
17561
17563{
17573
17574 // The output file for the produced histograms
17575 TFile fout(filename.Data(),"RECREATE","NcAstrolab analysis results");
17576
17577 // Write all the histos to the output file
17578 Int_t nh=fBurstHistos.GetEntries();
17579 for (Int_t ih=0; ih<nh; ih++)
17580 {
17581 TObject* hx=fBurstHistos.At(ih);
17582 if (!hx) continue;
17583 hx->Write();
17584 }
17585
17586 fout.Write();
17587
17588 cout << endl;
17589 cout << " *" << ClassName() << "::WriteBurstHistograms* All generated histograms have been written to file " << filename << endl;
17591}
17592
17594{
17603
17604 if (gROOT->IsBatch())
17605 {
17606 printf("\n *%-s::SkyMapPanel* GUI is not available in batch mode. \n",ClassName());
17607 return;
17608 }
17609
17610 // Select the lab timestamp as default
17611 fMapTS.SetMJD(fMJD,fJsec,fJns,fJps,"A");
17612
17613 // Import current Lab settings
17614 Double_t l=0;
17615 Double_t b=0;
17616 GetLabPosition(l,b,"deg");
17617 fMapLabLocL=l;
17618 fMapLabLocB=b;
17621 // Get the lab timestamp data in the text box
17622 UInt_t year=0;
17623 UInt_t month=0;
17624 UInt_t day=0;
17625 GetDate(kTRUE,0,&year,&month,&day);
17626 GetDayTimeString("UTC",3,0,0,&fMapTime);
17627 fMapDate.Form("%02i-%02i-%-i",day,month,year);
17628 fMapTime.ReplaceAll(" UTC","");
17630 fMapDateTime+="/";
17632
17633 // Re-invokation of the SkyMapPanel
17634 if (fSkyMapPanel)
17635 {
17636 // Import the current lab settings
17637 Int_t idx=1;
17638 TString names[9]={"User","IceCube","RNO-G","ARA","Amanda","WSRT","Astron","Greenwich","ARCA"};
17639 for (Int_t i=1; i<=9; i++)
17640 {
17641 if (names[i-1]==fExperiment) idx=i;
17642 }
17643 fMapLabE->Select(idx,kTRUE);
17644
17645 MapLocEnter();
17646
17647 // The Lab UTC time
17648 fMapTStimetype->Select(1,kTRUE);
17649 MapTimeType(10);
17650
17651 // Map all subwindows of main frame
17652 fSkyMapPanel->MapSubwindows();
17653
17654 // Initialize the layout algorithm
17655 fSkyMapPanel->Resize(fSkyMapPanel->GetDefaultSize());
17656
17657 // Map main frame
17658 fSkyMapPanel->MapWindow();
17659
17660 return;
17661 }
17662
17663 // New initialization of the SkyMapPanel
17664 UInt_t border=5;
17665 fSkyMapPanel=new TGMainFrame(gClient->GetRoot());
17666 fSkyMapPanel->SetWindowName("SkyMapPanel");
17667 fSkyMapPanel->Connect("CloseWindow()","NcAstrolab",this,"MapClose()");
17668
17669 // Define the various sub-frames and fill them with the various panels
17670 TGCompositeFrame* frames[4]={0,0,0,0};
17671 TGLayoutHints* layouts[4]={0,0,0,0};
17672
17673 // The Lab specification and timestamp frame
17674 frames[0]=new TGCompositeFrame(fSkyMapPanel,1,1,kHorizontalFrame|kSunkenFrame);
17675 layouts[0]=new TGLayoutHints(kLHintsExpandX,border,border,0,0);
17676 LabLocationPanel(frames[0]);
17677 TimestampPanel(frames[0]);
17678
17679 // The local reference and info frame
17680 frames[1]=new TGCompositeFrame(fSkyMapPanel,1,1,kHorizontalFrame|kSunkenFrame);
17681 layouts[1]=new TGLayoutHints(kLHintsExpandX,border,border,0,0);
17682 LabLocalFramePanel(frames[1]);
17683 InfoPanel(frames[1]);
17684
17685 // The entries frame
17686 frames[2]=new TGCompositeFrame(fSkyMapPanel,1,1,kHorizontalFrame|kSunkenFrame);
17687 layouts[2]=new TGLayoutHints(kLHintsExpandX,border,border,0,0);
17688 EntriesPanel(frames[2]);
17689
17690 // The drawing/listing options and command buttons frame
17691 frames[3]=new TGCompositeFrame(fSkyMapPanel,1,1,kHorizontalFrame|kSunkenFrame);
17692 layouts[3]=new TGLayoutHints(kLHintsExpandX,border,border,0,0);
17693 MapListOptionsPanel(frames[3]);
17694 CommandPanel(frames[3]);
17695
17696 // Add all subframes to the mainframe
17697 for (Int_t i=0; i<4; i++)
17698 {
17699 if (frames[i]) fSkyMapPanel->AddFrame(frames[i],layouts[i]);
17700 }
17701
17702 // Map all subwindows of main frame
17703 fSkyMapPanel->MapSubwindows();
17704
17705 // Initialize the layout algorithm
17706 fSkyMapPanel->Resize(fSkyMapPanel->GetDefaultSize());
17707
17708 // Map main frame
17709 fSkyMapPanel->MapWindow();
17710}
17711
17712void NcAstrolab::LabLocationPanel(TGCompositeFrame* frame)
17713{
17719
17720 if (!frame) return;
17721
17722 TGGroupFrame* panel=new TGGroupFrame(frame,"Lab longitude, latitude, experiment site and detector ID",kHorizontalFrame);
17723 panel->SetTitlePos(TGGroupFrame::kCenter);
17724 frame->AddFrame(panel);
17725
17726 // The lab longitude entry field
17727 fMapLabLBI[0]=new TGNumberEntryField(panel,-1,fMapLabLocL);
17728 fMapLabLBI[0]->SetToolTipText("Longitude");
17729 fMapLabLBI[0]->Connect("TextChanged(const char*)","NcAstrolab",this,"MapLocl(const char*)");
17730 fMapLabLBI[0]->Resize(65,20);
17731 panel->AddFrame(fMapLabLBI[0]);
17732
17733 // The lab latitude entry field
17734 fMapLabLBI[1]=new TGNumberEntryField(panel,-1,fMapLabLocB);
17735 fMapLabLBI[1]->SetToolTipText("Latitude");
17736 fMapLabLBI[1]->Connect("TextChanged(const char*)","NcAstrolab",this,"MapLocb(const char*)");
17737 fMapLabLBI[1]->Resize(65,20);
17738 panel->AddFrame(fMapLabLBI[1]);
17739
17740 // The lab longitude and latitude type selection box
17741 fMapLabU=new TGComboBox(panel);
17742 fMapLabU->Connect("Selected(Int_t)","NcAstrolab",this,"MapUloc(Int_t)");
17743 fMapLabU->AddEntry("deg",1);
17744 fMapLabU->AddEntry("dms",2);
17745 fMapLabU->AddEntry("hms",3);
17746 fMapLabU->AddEntry("rad",4);
17747 fMapLabU->Resize(50,20);
17748 panel->AddFrame(fMapLabU);
17749 fMapLabU->Select(1,kTRUE);
17750
17751 // The experiment name selection box
17752 fMapLabE=new TGComboBox(panel);
17753 fMapLabE->Connect("Selected(Int_t)","NcAstrolab",this,"MapExperiment(Int_t)");
17754 Int_t idx=1;
17755 TString names[9]={"User","IceCube","RNO-G","ARA","Amanda","WSRT","Astron","Greenwich","ARCA"};
17756 for (Int_t i=1; i<=9; i++)
17757 {
17758 fMapLabE->AddEntry(names[i-1],i);
17759 if (names[i-1]==fExperiment) idx=i;
17760 }
17761 fMapLabE->Resize(90,20);
17762 panel->AddFrame(fMapLabE);
17763 fMapLabE->Select(idx,kTRUE);
17764
17765 // The detector element ID field
17766 fMapLabLBI[2]=new TGNumberEntryField(panel,-1,fLabId,TGNumberFormat::kNESInteger);
17767 fMapLabLBI[2]->SetToolTipText("The (optional) detector element ID (0=global)");
17768 fMapLabLBI[2]->Connect("TextChanged(const char*)","NcAstrolab",this,"MapLocId(const char*)");
17769 fMapLabLBI[2]->Resize(40,20);
17770 panel->AddFrame(fMapLabLBI[2]);
17771
17772 // The button to enter the provided data
17773 TGTextButton* enter=new TGTextButton(panel,"Enter");
17774 enter->SetToolTipText("Enter the provided data");
17775 enter->Connect("Clicked()","NcAstrolab",this,"MapLocEnter()");
17776 TGLayoutHints* Lenter=new TGLayoutHints(kLHintsCenterX,10,0,0,0);
17777 panel->AddFrame(enter,Lenter);
17778
17779 MapLocEnter();
17780}
17781
17782void NcAstrolab::MapLocl(const char* text)
17783{
17789
17790 TString s=text;
17791 fMapLabLocL=s.Atof();
17792}
17793
17794void NcAstrolab::MapLocb(const char* text)
17795{
17801
17802 TString s=text;
17803 fMapLabLocB=s.Atof();
17804}
17805
17807{
17813
17814 TString s[4]={"deg","dms","hms","rad"};
17815 if (i<=4) fMapLabLocU=s[i-1];
17816}
17817
17819{
17825
17826 TString s[9]={"User","IceCube","RNO-G","ARA","Amanda","WSRT","Astron","Greenwich","ARCA"};
17827 if (i<=9) fMapLabExpName=s[i-1];
17828}
17829
17830void NcAstrolab::MapLocId(const char* text)
17831{
17837
17838 TString s=text;
17839 fMapLabId=s.Atoi();
17840}
17841
17843{
17849
17850 fSkyMapPanel->RequestFocus();
17851
17853
17854 if (fMapLabExpName=="User")
17855 {
17856 SetNameTitle("User","Virtual Lab for general use");
17857 MapLocId("0");
17858 printf("\n *** Settings adopted for a virtual lab for general use. *** \n");
17859 }
17860 else
17861 {
17864 // Update the longitude, latitude and detector ID selection boxes
17866 TString s;
17867 s.Form("%-.3f",fMapLabLocL);
17868 fMapLabLBI[0]->SetText(s);
17869 s.Form("%-.3f",fMapLabLocB);
17870 fMapLabLBI[1]->SetText(s);
17871 fMapLabU->Select(1,kTRUE);
17872 MapUloc(1);
17873 s.Form("%-i",fMapLabId);
17874 fMapLabLBI[2]->SetText(s);
17875 printf("\n *** Lab settings adopted for the %-s location. *** \n",fMapLabExpName.Data());
17876 }
17877
17878 // Update the local frame data for the selected lab
17879 TString val;
17880 for (Int_t i=0; i<6; i++)
17881 {
17882 val.Form("%-.2f",fAxes[i]);
17883 if (fMapLabLframe[i]) fMapLabLframe[i]->SetText(val);
17884 }
17885}
17886
17887void NcAstrolab::TimestampPanel(TGCompositeFrame* frame)
17888{
17894
17895 if (!frame) return;
17896
17897 TGGroupFrame* panel=new TGGroupFrame(frame,"Timestamp to be used for Entries, List and Map",kHorizontalFrame);
17898 panel->SetTitlePos(TGGroupFrame::kCenter);
17899 frame->AddFrame(panel);
17900
17901 // The Date/Time textbox
17902 fMapTSdatetime=new TGTextEntry(panel,fMapDateTime.Data());
17903 fMapTSdatetime->SetToolTipText("Date/Time as dd-mm-yyyy/hh:mm:ss.sss or MJD");
17904 fMapTSdatetime->Connect("TextChanged(const char*)","NcAstrolab",this,"MapDateTime(const char*)");
17905 fMapTSdatetime->SetAlignment(kTextRight);
17906 fMapTSdatetime->Resize(170,20);
17907 panel->AddFrame(fMapTSdatetime);
17908
17909 // The Time type selection box
17910 fMapTStimetype=new TGComboBox(panel);
17911 fMapTStimetype->Connect("Selected(Int_t)","NcAstrolab",this,"MapTimeType(Int_t)");
17912 fMapTStimetype->AddEntry("UTC",1);
17913 fMapTStimetype->AddEntry("LMT",2);
17914 fMapTStimetype->AddEntry("UT1",3);
17915 fMapTStimetype->AddEntry("MJD",4);
17916 fMapTStimetype->AddEntry("JD",5);
17917 fMapTStimetype->AddEntry("TJD",6);
17918 fMapTStimetype->AddEntry("Unix",7);
17919 fMapTStimetype->AddEntry("GPS",8);
17920 fMapTStimetype->AddEntry("TAI",9);
17921 fMapTStimetype->AddEntry("TT",10);
17922 fMapTStimetype->AddEntry("SysClock",11);
17923 fMapTStimetype->AddEntry("Lab",12);
17924 fMapTStimetype->AddEntry("EntryName",13);
17925 fMapTStimetype->Resize(100,20);
17926 panel->AddFrame(fMapTStimetype);
17927 fMapTStimetype->Select(1,kTRUE);
17928 MapTimeType(1);
17929
17930 // The Lab TS modification button
17931 TGTextButton* labTS=new TGTextButton(panel,"Store as Lab TS");
17932 labTS->SetToolTipText("Store the current selection as Lab timestamp");
17933 labTS->Connect("Clicked()","NcAstrolab",this,"MapLabTS()");
17934 TGLayoutHints* LlabTS=new TGLayoutHints(kLHintsCenterX,10,0,0,0);
17935 panel->AddFrame(labTS,LlabTS);
17936}
17937
17938void NcAstrolab::MapDateTime(const char* text)
17939{
17945
17946 fMapDateTime=text;
17947}
17948
17950{
17956
17957 TString s[13]={"UTC","LMT","UT1","MJD","JD","TJD","Unix","GPS","TAI","TT","SysClock","Lab","EntryName"};
17958
17959 if (i<=13) fMapTimeType=s[i-1];
17960
17961 if (fMapTimeType=="SysClock" || fMapTimeType=="Lab") SetMapTS();
17962 if (fMapTimeType=="MJD" || fMapTimeType=="JD" || fMapTimeType=="TJD" || fMapTimeType=="Unix" || fMapTimeType.Contains("Name")) fMapTSdatetime->SetText("");
17963}
17964
17966{
17972
17973 SetMapTS();
17974
17975 fSkyMapPanel->RequestFocus();
17976
17977 Int_t mjd,sec,ns;
17978 fMapTS.GetMJD(mjd,sec,ns);
17979 Int_t ps=fMapTS.GetPs();
17980 this->SetMJD(mjd,sec,ns,ps,"U");
17981
17982 printf("\n *** Lab timestamp modified *** \n");
17983}
17984
17985void NcAstrolab::LabLocalFramePanel(TGCompositeFrame* frame)
17986{
17992
17993 if (!frame) return;
17994
17995 TGGroupFrame* panel=new TGGroupFrame(frame,"Local frame axes orientations w.r.t. X0=South, Y0=East, Z0=Zenith)",kHorizontalFrame);
17996 panel->SetTitlePos(TGGroupFrame::kCenter);
17997 frame->AddFrame(panel);
17998
17999 // The local X-axis theta (=zenith) angle w.r.t. the MRF
18000 fMapLabLframe[0]=new TGNumberEntryField(panel,-1,fAxes[0]);
18001 fMapLabLframe[0]->SetToolTipText("Local X-axis zenith angle in deg");
18002 fMapLabLframe[0]->Resize(55,20);
18003 panel->AddFrame(fMapLabLframe[0]);
18004
18005 // The local X-axis phi angle w.r.t. the MRF
18006 fMapLabLframe[1]=new TGNumberEntryField(panel,-1,fAxes[1]);
18007 fMapLabLframe[1]->SetToolTipText("Local X-axis phi angle in deg");
18008 fMapLabLframe[1]->Resize(55,20);
18009 panel->AddFrame(fMapLabLframe[1]);
18010
18011 // The local Y-axis theta (=zenith) angle w.r.t. the MRF
18012 fMapLabLframe[2]=new TGNumberEntryField(panel,-1,fAxes[2]);
18013 fMapLabLframe[2]->SetToolTipText("Local Y-axis zenith angle in deg");
18014 fMapLabLframe[2]->Resize(55,20);
18015 panel->AddFrame(fMapLabLframe[2]);
18016
18017 // The local Y-axis phi angle w.r.t. the MRF
18018 fMapLabLframe[3]=new TGNumberEntryField(panel,-1,fAxes[3]);
18019 fMapLabLframe[3]->SetToolTipText("Local Y-axis phi angle in deg");
18020 fMapLabLframe[3]->Resize(55,20);
18021 panel->AddFrame(fMapLabLframe[3]);
18022
18023 // The local Z-axis theta (=zenith) angle w.r.t. the MRF
18024 fMapLabLframe[4]=new TGNumberEntryField(panel,-1,fAxes[4]);
18025 fMapLabLframe[4]->SetToolTipText("Local Z-axis zenith angle in deg");
18026 fMapLabLframe[4]->Resize(55,20);
18027 panel->AddFrame(fMapLabLframe[4]);
18028
18029 // The local Z-axis phi angle w.r.t. the MRF
18030 fMapLabLframe[5]=new TGNumberEntryField(panel,-1,fAxes[5]);
18031 fMapLabLframe[5]->SetToolTipText("Local Z-axis phi angle in deg");
18032 fMapLabLframe[5]->Resize(55,20);
18033 panel->AddFrame(fMapLabLframe[5]);
18034
18036
18037 // The button to enter the provided data
18038 TGTextButton* enter=new TGTextButton(panel,"Enter");
18039 enter->SetToolTipText("Enter the provided data");
18040 enter->Connect("Clicked()","NcAstrolab",this,"MapLabLframeEnter()");
18041 TGLayoutHints* Lenter=new TGLayoutHints(kLHintsLeft,10,0,0,0);
18042 panel->AddFrame(enter,Lenter);
18043}
18044
18046{
18054
18055 fSkyMapPanel->RequestFocus();
18056
18057 if (fMapLabExpName=="IceCube" || fMapLabExpName=="RNO-G" || fMapLabExpName=="Amanda")
18058 {
18059 printf("\n *** Local frame will NOT be changed for experiment site %-s *** \n",fMapLabExpName.Data());
18060
18061 // Update the local frame data for the selected lab
18062 TString val;
18063 for (Int_t i=0; i<6; i++)
18064 {
18065 val.Form("%-.2f",fAxes[i]);
18066 if (fMapLabLframe[i]) fMapLabLframe[i]->SetText(val);
18067 }
18068 return;
18069 }
18070
18071 for (Int_t i=0; i<6; i++)
18072 {
18073 fAxes[i]=fMapLabLframe[i]->GetNumber();
18074 }
18075
18076 SetLocalFrame(fAxes[0],fAxes[1],fAxes[2],fAxes[3],fAxes[4],fAxes[5]);
18077}
18078
18079void NcAstrolab::InfoPanel(TGCompositeFrame* frame)
18080{
18086
18087 if (!frame) return;
18088
18089 TGGroupFrame* panel=new TGGroupFrame(frame,"Informative output",kHorizontalFrame);
18090 panel->SetTitlePos(TGGroupFrame::kCenter);
18091 frame->AddFrame(panel);
18092
18093 // The info category selection box
18094 TGComboBox* cinfo=new TGComboBox(panel);
18095 cinfo->Connect("Selected(Int_t)","NcAstrolab",this,"MapCinfo(Int_t)");
18096 cinfo->AddEntry("Lab",1);
18097 cinfo->AddEntry("TSbox",2);
18098 cinfo->AddEntry("Entry",3);
18099 cinfo->AddEntry("Nstore",4);
18100 cinfo->Resize(60,20);
18101 panel->AddFrame(cinfo);
18102 cinfo->Select(1,kTRUE);
18103 MapCinfo(1);
18104
18105 // The lab info time type selection box
18106 TGComboBox* tinfo=new TGComboBox(panel);
18107 tinfo->Connect("Selected(Int_t)","NcAstrolab",this,"MapTinfo(Int_t)");
18108 tinfo->AddEntry("LAT/LAST",1);
18109 tinfo->AddEntry("LMT/LMST",2);
18110 tinfo->AddEntry("Julian",3);
18111 tinfo->AddEntry("UT1",4);
18112 tinfo->AddEntry("UTC",5);
18113 tinfo->AddEntry("TAI",6);
18114 tinfo->AddEntry("GPS",7);
18115 tinfo->AddEntry("TT",8);
18116 tinfo->AddEntry("Unix",9);
18117 tinfo->Resize(85,20);
18118 panel->AddFrame(tinfo);
18119 tinfo->Select(1,kTRUE);
18120 MapTinfo(1);
18121
18122 // The lab info longitude and latitude type selection box
18123 TGComboBox* uinfo=new TGComboBox(panel);
18124 uinfo->Connect("Selected(Int_t)","NcAstrolab",this,"MapUinfo(Int_t)");
18125 uinfo->AddEntry("deg",1);
18126 uinfo->AddEntry("dms",2);
18127 uinfo->AddEntry("hms",3);
18128 uinfo->AddEntry("rad",4);
18129 uinfo->Resize(50,20);
18130 panel->AddFrame(uinfo);
18131 uinfo->Select(1,kTRUE);
18132 MapUinfo(1);
18133
18134 // The entry name textbox
18135 TGTextEntry* mapiname=new TGTextEntry(panel,"");
18136 mapiname->SetToolTipText("Stored entry name for info");
18137 mapiname->Connect("TextChanged(const char*)","NcAstrolab",this,"MapIname(const char*)");
18138 mapiname->SetAlignment(kTextRight);
18139 mapiname->Resize(100,20);
18140 panel->AddFrame(mapiname);
18141
18142 // The info button
18143 TGTextButton* info=new TGTextButton(panel,"Info");
18144 info->Connect("Clicked()","NcAstrolab",this,"MapInfo()");
18145 info->SetToolTipText("Provide info on the specified item");
18146 TGLayoutHints* Linfo=new TGLayoutHints(kLHintsLeft,10,0,0,0);
18147 panel->AddFrame(info,Linfo);
18148}
18149
18151{
18157
18158 TString s[4]={"Lab","TS box","EntryName","Nstore"};
18159 if (i<=4) fMapCinfo=s[i-1];
18160}
18161
18163{
18169
18170 if (i==1)
18171 {
18172 fMapTinfo=-1;
18173 }
18174 else
18175 {
18176 fMapTinfo=i-1;
18177 }
18178}
18179
18181{
18187
18188 TString s[4]={"deg","dms","hms","rad"};
18189 if (i<=4) fMapUinfo=s[i-1];
18190}
18191
18192void NcAstrolab::MapIname(const char* text)
18193{
18199
18200 fMapIname=text;
18201}
18202
18204{
18210
18211 SetMapTS();
18212
18213 TString modes[9]={"LAT/LAST","LMT/LMST","Julian","UT1","UTC","TAI","GPS","TT","Unix"};
18214 TString datetime;
18215
18216 if (fMapCinfo=="Nstore")
18217 {
18218 Int_t nref=GetNsignals(0);
18219 Int_t nmeas=GetNsignals(1);
18220 Int_t ntot=nref+nmeas;
18221 printf("\n *** Info about the stored entries *** \n");
18222 printf(" Ntotal=%-i Nrefs=%-i Nmeas=%-i \n",ntot,nref,nmeas);
18223 }
18224 else if (fMapCinfo=="Lab")
18225 {
18226 if (fMapTinfo<3)
18227 {
18228 printf("\n *** Info about the current Lab settings *** \n");
18230 }
18231 else
18232 {
18233 printf("\n *** Info for the Lab timestamp *** \n");
18234 if (fMapTinfo==8)
18235 {
18236 printf(" Unix time : %-.12f \n",GetUnixTime());
18237 }
18238 else
18239 {
18240 datetime=GetDayTimeString(modes[fMapTinfo],12);
18241 printf(" %-s \n",datetime.Data());
18242 }
18243 }
18244 }
18245 else if (fMapCinfo.Contains("TS"))
18246 {
18247 printf("\n *** Info for the timestamp in the user selection box *** \n");
18248 if (fMapTinfo<3)
18249 {
18250 printf(" Lab time offset w.r.t. UT : "); PrintTime(fToffset,12); printf("\n");
18252 fMapTS.Date(4);
18253 }
18254 else
18255 {
18256 if (fMapTinfo==8)
18257 {
18258 printf(" Unix time : %-.12f \n",fMapTS.GetUnixTime());
18259 }
18260 else
18261 {
18262 datetime=fMapTS.GetDayTimeString(modes[fMapTinfo],12);
18263 printf(" %-s \n",datetime.Data());
18264 }
18265 }
18266 }
18267 else // Information of the specified entry name
18268 {
18269 NcSignal* sx=0;
18270 NcTimestamp* tx=0;
18271 sx=GetSignal(fMapIname,0);
18272 if(!sx) sx=GetSignal(fMapIname,1);
18273 if (sx)
18274 {
18275 printf("\n *** Info for entry : %-s *** \n",fMapIname.Data());
18276 sx->Data("sph",fMapUinfo);
18277 tx=sx->GetTimestamp();
18278 if (tx)
18279 {
18280 NcTimestamp tx2(*tx);
18282 if (fMapTinfo<3)
18283 {
18284 printf(" Lab time offset w.r.t. UT : "); PrintTime(fToffset,12); printf("\n");
18285 tx2.Date(fMapTinfo,fToffset);
18286 tx2.Date(4);
18287 }
18288 else
18289 {
18290 if (fMapTinfo==8)
18291 {
18292 printf(" Unix time : %-.12f \n",tx2.GetUnixTime());
18293 }
18294 else
18295 {
18296 datetime=tx2.GetDayTimeString(modes[fMapTinfo],12);
18297 printf(" %-s \n",datetime.Data());
18298 }
18299 }
18300 }
18301 }
18302 else
18303 {
18304 printf("\n *** No entry found with name : %-s *** \n",fMapIname.Data());
18305 }
18306 }
18307}
18308
18309void NcAstrolab::EntriesPanel(TGCompositeFrame* frame)
18310{
18316
18317 if (!frame) return;
18318
18319 TGGroupFrame* panel=new TGGroupFrame(frame,"Entries in (a,b) coordinates",kHorizontalFrame);
18320 panel->SetTitlePos(TGGroupFrame::kCenter);
18321 frame->AddFrame(panel);
18322
18323 // The a coordinate entry field
18324 TGNumberEntryField* ea=new TGNumberEntryField(panel,-1,0);
18325 ea->SetToolTipText("Angle a");
18326 ea->Connect("TextChanged(const char*)","NcAstrolab",this,"MapEa(const char*)");
18327 ea->Resize(100,20);
18328 panel->AddFrame(ea);
18329 MapEa("0");
18330
18331 // The a coordinate type selection box
18332 TGComboBox* ua=new TGComboBox(panel);
18333 ua->Connect("Selected(Int_t)","NcAstrolab",this,"MapUa(Int_t)");
18334 ua->AddEntry("deg",1);
18335 ua->AddEntry("dms",2);
18336 ua->AddEntry("hms",3);
18337 ua->AddEntry("rad",4);
18338 ua->AddEntry("hrs",5);
18339 ua->Resize(50,20);
18340 panel->AddFrame(ua);
18341 ua->Select(1,kTRUE);
18342 MapUa(1);
18343
18344 // The b coordinate entry field
18345 TGNumberEntryField* eb=new TGNumberEntryField(panel,-1,0);
18346 eb->SetToolTipText("Angle b");
18347 eb->Connect("TextChanged(const char*)","NcAstrolab",this,"MapEb(const char*)");
18348 eb->Resize(100,20);
18349 panel->AddFrame(eb);
18350 MapEb("0");
18351
18352 // The b coordinate type selection box
18353 TGComboBox* ub=new TGComboBox(panel);
18354 ub->Connect("Selected(Int_t)","NcAstrolab",this,"MapUb(Int_t)");
18355 ub->AddEntry("deg",1);
18356 ub->AddEntry("dms",2);
18357 ub->AddEntry("hms",3);
18358 ub->AddEntry("rad",4);
18359 ub->AddEntry("hrs",5);
18360 ub->Resize(50,20);
18361 panel->AddFrame(ub);
18362 ub->Select(1,kTRUE);
18363 MapUb(1);
18364
18365 TGComboBox* ecoords=new TGComboBox(panel);
18366 ecoords->Connect("Selected(Int_t)","NcAstrolab",this,"MapEcoord(Int_t)");
18367 ecoords->AddEntry("(ra,dec) (J2000)",1);
18368 ecoords->AddEntry("(ra,dec) (Mean)",2);
18369 ecoords->AddEntry("(ra,dec) (True)",3);
18370 ecoords->AddEntry("(ra,dec) (B1950)",4);
18371 ecoords->AddEntry("Galactic (l,b)",5);
18372 ecoords->AddEntry("Ecliptic (l,b)",6);
18373 ecoords->AddEntry("Horizon (azi,zen)",7);
18374 ecoords->AddEntry("ICR (l,b)",8);
18375 ecoords->AddEntry("Local (theta,phi)",9);
18376 ecoords->AddEntry("pdir (theta,phi)",10);
18377 ecoords->Resize(125,20);
18378 panel->AddFrame(ecoords);
18379 ecoords->Select(1,kTRUE);
18380 MapEcoord(1);
18381
18382 // The signal type
18383 TGComboBox* etypes=new TGComboBox(panel);
18384 etypes->Connect("Selected(Int_t)","NcAstrolab",this,"MapEtype(Int_t)");
18385 etypes->AddEntry("Meas",1);
18386 etypes->AddEntry("Ref",2);
18387 etypes->Resize(55,20);
18388 panel->AddFrame(etypes);
18389 etypes->Select(1,kTRUE);
18390 MapEtype(1);
18391
18392 // The (optional) signal name
18393 TGTextEntry* ename=new TGTextEntry(panel,"");
18394 ename->SetToolTipText("The (optional) entry name");
18395 ename->Connect("TextChanged(const char*)","NcAstrolab",this,"MapEname(const char*)");
18396 ename->SetAlignment(kTextRight);
18397 ename->Resize(100,20);
18398 panel->AddFrame(ename);
18399
18400 // The button to Enter the entry
18401 TGTextButton* enter=new TGTextButton(panel,"Enter");
18402 enter->SetToolTipText("Enter the provided entry");
18403 enter->Connect("Clicked()","NcAstrolab",this,"MapEnter()");
18404 TGLayoutHints* Lenter=new TGLayoutHints(kLHintsCenterX,10,0,0,0);
18405 panel->AddFrame(enter,Lenter);
18406
18407 // The button to Remove the entry
18408 TGTextButton* remove=new TGTextButton(panel,"Remove");
18409 remove->SetToolTipText("Remove the entry specified by type and name pattern (name=* means all)");
18410 remove->Connect("Clicked()","NcAstrolab",this,"MapRemove()");
18411 TGLayoutHints* Lremove=new TGLayoutHints(kLHintsCenterX,10,0,0,0);
18412 panel->AddFrame(remove,Lremove);
18413}
18414
18415void NcAstrolab::MapEa(const char* text)
18416{
18422
18423 TString s=text;
18424 fMapEa=s.Atof();
18425}
18426
18428{
18434
18435 TString s[5]={"deg","dms","hms","rad","hrs"};
18436 if (i<=5) fMapEua=s[i-1];
18437}
18438
18439void NcAstrolab::MapEb(const char* text)
18440{
18446
18447 TString s=text;
18448 fMapEb=s.Atof();
18449}
18450
18452{
18458
18459 TString s[5]={"deg","dms","hms","rad","hrs"};
18460 if (i<=5) fMapEub=s[i-1];
18461}
18462
18464{
18470
18471 TString system[10]={"equ","equ","equ","equ","gal","ecl","hor","icr","loc","pdir"};
18472 TString mode[4]={"J","M","T","B"};
18473
18474 if (i<=10) fMapEcoord=system[i-1];
18475
18476 if (i<=4) fMapEmode=mode[i-1];
18477}
18478
18480{
18486
18487 fMapEtype=1;
18488 if (i==2) fMapEtype=0;
18489}
18490
18491void NcAstrolab::MapEname(const char* text)
18492{
18498
18499 fMapEname=text;
18500}
18501
18503{
18509
18510 SetMapTS(); // Set the selected timestamp
18511
18512 fSkyMapPanel->RequestFocus();
18513
18515
18516 printf("\n *** Specified entry stored *** \n");
18517}
18518
18520{
18526
18527 SetMapTS(); // Set the selected timestamp
18528
18529 fSkyMapPanel->RequestFocus();
18530
18531 Int_t nrem=0;
18533
18534 printf("\n *** Number of specified entries have been removed : %-i *** \n",nrem);
18535}
18536
18537void NcAstrolab::MapListOptionsPanel(TGCompositeFrame* frame)
18538{
18544
18545 if (!frame) return;
18546
18547 TGGroupFrame* panel=new TGGroupFrame(frame,"Map/List options for the (a,b) coordinates",kHorizontalFrame);
18548 panel->SetTitlePos(TGGroupFrame::kCenter);
18549 frame->AddFrame(panel);
18550
18551 // A frame with various additional settings
18552 TGVerticalFrame* render=new TGVerticalFrame(panel,1,1);
18553 panel->AddFrame(render);
18554
18555 // The coordinate system selection box
18556 TGGroupFrame* coordsys=new TGGroupFrame(render,"Coordinate system",kHorizontalFrame);
18557 coordsys->SetTitlePos(TGGroupFrame::kCenter);
18558 render->AddFrame(coordsys);
18559 TGComboBox* dcoords=new TGComboBox(coordsys);
18560 dcoords->Connect("Selected(Int_t)","NcAstrolab",this,"MapDcoord(Int_t)");
18561 dcoords->AddEntry("Equatorial (J2000)",1);
18562 dcoords->AddEntry("Equatorial (Mean)",2);
18563 dcoords->AddEntry("Equatorial (True)",3);
18564 dcoords->AddEntry("Equatorial (B1950)",4);
18565 dcoords->AddEntry("Galactic",5);
18566 dcoords->AddEntry("Ecliptic",6);
18567 dcoords->AddEntry("Horizon",7);
18568 dcoords->AddEntry("ICR",8);
18569 dcoords->AddEntry("Local",9);
18570 dcoords->Resize(140,20);
18571 coordsys->AddFrame(dcoords);
18572 dcoords->Select(1,kTRUE);
18573 MapDcoord(1);
18574
18575 // The Map representation selection box
18576 TGGroupFrame* mapview=new TGGroupFrame(render,"Map representation",kHorizontalFrame);
18577 mapview->SetTitlePos(TGGroupFrame::kCenter);
18578 render->AddFrame(mapview);
18579 TGComboBox* projs=new TGComboBox(mapview);
18580 projs->Connect("Selected(Int_t)","NcAstrolab",this,"MapProj(Int_t)");
18581 projs->AddEntry("Hammer projection",1);
18582 projs->AddEntry("Aitoff projection",2);
18583 projs->AddEntry("Mercator projection",3);
18584 projs->AddEntry("sin(b) vs. a",4);
18585 projs->AddEntry("b vs. a",5);
18586 projs->AddEntry("b vs. UT (0-24 hrs)",6);
18587 projs->AddEntry("b vs. LT (0-24 hrs)",7);
18588 projs->AddEntry("b vs. GST (0-24 hrs)",8);
18589 projs->AddEntry("b vs. LST (0-24 hrs)",9);
18590 projs->AddEntry("b vs. Day at UT",10);
18591 projs->AddEntry("b vs. Day at LT",11);
18592 projs->AddEntry("b vs. Day at GST",12);
18593 projs->AddEntry("b vs. Day at LST",13);
18594 projs->Resize(150,20);
18595 mapview->AddFrame(projs);
18596 projs->Select(1,kTRUE);
18597 MapProj(1);
18598
18599 // The meridian representation options
18600 TGGroupFrame* meridian=new TGGroupFrame(render,"Meridian ordering",kHorizontalFrame);
18601 meridian->SetTitlePos(TGGroupFrame::kCenter);
18602 render->AddFrame(meridian);
18603
18604 // The meridian mode selection box
18605 TGComboBox* mermode=new TGComboBox(meridian);
18606 mermode->Connect("Selected(Int_t)","NcAstrolab",this,"MapMerMode(Int_t)");
18607 mermode->AddEntry("Auto",1);
18608 mermode->AddEntry("---->",2);
18609 mermode->AddEntry("<----",3);
18610 mermode->Resize(55,20);
18611 meridian->AddFrame(mermode);
18612 mermode->Select(1,kTRUE);
18613 MapMerMode(1);
18614
18615 // The meridian central value
18616 TGNumberEntryField* merc=new TGNumberEntryField(meridian,-1,0);
18617 merc->SetToolTipText("Central meridian position");
18618 merc->Connect("TextChanged(const char*)","NcAstrolab",this,"MapMerC(const char*)");
18619 merc->Resize(65,20);
18620 meridian->AddFrame(merc);
18621 MapMerC("0");
18622
18623 // The meridian central value type selection box
18624 TGComboBox* meruc=new TGComboBox(meridian);
18625 meruc->Connect("Selected(Int_t)","NcAstrolab",this,"MapMerUc(Int_t)");
18626 meruc->AddEntry("deg",1);
18627 meruc->AddEntry("dms",2);
18628 meruc->AddEntry("hms",3);
18629 meruc->AddEntry("rad",4);
18630 meruc->Resize(50,20);
18631 meridian->AddFrame(meruc);
18632 meruc->Select(1,kTRUE);
18633 MapMerUc(1);
18634
18635 // The options group
18636 TGVButtonGroup* options=new TGVButtonGroup(panel,"Options");
18637 options->SetTitlePos(TGGroupFrame::kCenter);
18638 options->Connect("Clicked(Int_t)","NcAstrolab",this,"MapDoptions(Int_t)");
18639 TGCheckButton* bhist=new TGCheckButton(options,"Hist");
18640 bhist->SetToolTipText("Project data in a histogram");
18641 TGCheckButton* bclr=new TGCheckButton(options,"Clr");
18642 bclr->SetToolTipText("Clear display before drawing");
18643 TGCheckButton* bref=new TGCheckButton(options,"Ref");
18644 bref->SetToolTipText("Display reference signals");
18645 TGCheckButton* bmeas=new TGCheckButton(options,"Meas");
18646 bmeas->SetToolTipText("Display measured signals");
18647 TGCheckButton* brefts=new TGCheckButton(options,"RefTS");
18648 brefts->SetToolTipText("Display/list each reference signal using its actual recorded timestamp");
18649 panel->AddFrame(options);
18650 options->Show();
18651 options->SetButton(1,kFALSE);
18652 options->SetButton(2,kTRUE);
18653 options->SetButton(3,kTRUE);
18654 options->SetButton(4,kTRUE);
18655 options->SetButton(5,kFALSE);
18656 fMapDoptions[0]=kFALSE;
18657 fMapDoptions[1]=kTRUE;
18658 fMapDoptions[2]=kTRUE;
18659 fMapDoptions[3]=kTRUE;
18660 fMapDoptions[4]=kFALSE;
18661
18662 // The Nmax entry field
18663 TGNumberEntryField* nmax=new TGNumberEntryField(options,-1,-1,TGNumberFormat::kNESInteger);
18664 nmax->SetToolTipText("Max. number of Drawn/Listed entries per type (-1=all)");
18665 nmax->Connect("TextChanged(const char*)","NcAstrolab",this,"MapNmax(const char*)");
18666 nmax->Resize(40,20);
18667 options->AddFrame(nmax);
18668 MapNmax("-1");
18669
18670 // The signal name pattern for matching
18671 TGTextEntry* sname=new TGTextEntry(options,"*");
18672 sname->SetToolTipText("The requested entry name pattern (*=all)");
18673 sname->Connect("TextChanged(const char*)","NcAstrolab",this,"MapDname(const char*)");
18674 sname->SetAlignment(kTextRight);
18675 sname->Resize(100,20);
18676 TGLayoutHints* Lsname=new TGLayoutHints(kLHintsLeft,0,0,5,0);
18677 options->AddFrame(sname,Lsname);
18678 MapDname("*");
18679
18680 // The Ndigs entry field
18681 TGNumberEntryField* ndigs=new TGNumberEntryField(options,-1,1,TGNumberFormat::kNESInteger);
18682 ndigs->SetToolTipText("Number of digits for the listed entries");
18683 ndigs->Connect("TextChanged(const char*)","NcAstrolab",this,"MapNdigs(const char*)");
18684 ndigs->Resize(40,20);
18685 options->AddFrame(ndigs);
18686 MapNdigs("1");
18687
18688 // A frame with various additional settings
18689 TGVerticalFrame* others=new TGVerticalFrame(panel,1,1);
18690 panel->AddFrame(others);
18691
18692 // The Marker size frame
18693 TGGroupFrame* markers=new TGGroupFrame(others,"Marker settings",kHorizontalFrame);
18694 markers->SetTitlePos(TGGroupFrame::kCenter);
18695 others->AddFrame(markers);
18696
18697 // The marker size
18698 TGNumberEntryField* marksize=new TGNumberEntryField(markers,-1,1);
18699 marksize->SetToolTipText("Marker size");
18700 marksize->Connect("TextChanged(const char*)","NcAstrolab",this,"MapMarkSize(const char*)");
18701 marksize->Resize(40,20);
18702 markers->AddFrame(marksize);
18703 MapMarkSize("1");
18704
18705 // The marker style
18706 TGComboBox* markstyle=new TGComboBox(markers);
18707 markstyle->Connect("Selected(Int_t)","NcAstrolab",this,"MapMarkStyle(Int_t)");
18708 markstyle->AddEntry("Dot",1);
18709 markstyle->AddEntry("Star",2);
18710 markstyle->AddEntry("Square",3);
18711 markstyle->AddEntry("Utriangle",4);
18712 markstyle->AddEntry("Dtriangle",5);
18713 markstyle->AddEntry("Diamond",6);
18714 markstyle->AddEntry("Cross",7);
18715 markstyle->AddEntry("Ast",8);
18716 markstyle->AddEntry("Plus",9);
18717 markstyle->AddEntry("Times",10);
18718 markstyle->AddEntry("Circle",11);
18719 markstyle->AddEntry("oStar",12);
18720 markstyle->AddEntry("oSquare",13);
18721 markstyle->AddEntry("oUtriangle",14);
18722 markstyle->AddEntry("oDtriangle",15);
18723 markstyle->AddEntry("oDiamond",16);
18724 markstyle->AddEntry("oCross",17);
18725 markstyle->Resize(90,20);
18726 markers->AddFrame(markstyle);
18727 markstyle->Select(1,kTRUE);
18728 MapMarkStyle(1);
18729
18730 // The marker color selection box
18731 TGComboBox* markcolor=new TGComboBox(markers);
18732 markcolor->Connect("Selected(Int_t)","NcAstrolab",this,"MapMarkColor(Int_t)");
18733 markcolor->AddEntry("Black",1);
18734 markcolor->AddEntry("Red",2);
18735 markcolor->AddEntry("Blue",3);
18736 markcolor->AddEntry("Green",4);
18737 markcolor->AddEntry("Yellow",5);
18738 markcolor->AddEntry("Magenta",6);
18739 markcolor->AddEntry("Cyan",7);
18740 markcolor->AddEntry("Orange",8);
18741 markcolor->AddEntry("Violet",9);
18742 markcolor->AddEntry("Pink",10);
18743 markcolor->AddEntry("Azure",11);
18744 markcolor->AddEntry("Spring",12);
18745 markcolor->AddEntry("Teal",13);
18746 markcolor->AddEntry("Gray",14);
18747 markcolor->AddEntry("White",15);
18748 markcolor->Resize(80,20);
18749 markers->AddFrame(markcolor);
18750 markcolor->Select(3,kTRUE);
18751 MapMarkColor(3);
18752
18753 // The marker type selection box
18754 TGComboBox* marktype=new TGComboBox(markers);
18755 marktype->Connect("Selected(Int_t)","NcAstrolab",this,"MapMarkType(Int_t)");
18756 marktype->AddEntry("Ref",1);
18757 marktype->AddEntry("Meas",2);
18758 marktype->AddEntry("GC",3);
18759 marktype->AddEntry("Grid",4);
18760 marktype->Resize(55,20);
18761 markers->AddFrame(marktype);
18762 marktype->Select(2,kTRUE);
18763 MapMarkType(2);
18764
18765 // The Solar system group
18766 TGGroupFrame* solar=new TGGroupFrame(others,"Selection of Solar system reference objects",kHorizontalFrame);
18767 solar->SetTitlePos(TGGroupFrame::kCenter);
18768 others->AddFrame(solar);
18769
18770 TGButtonGroup* Ssolar=new TGButtonGroup(solar,0,3,5);
18771 Ssolar->SetTitlePos(TGGroupFrame::kCenter);
18772 Ssolar->Connect("Clicked(Int_t)","NcAstrolab",this,"MapSolar(Int_t)");
18773 TGCheckButton* bsun=new TGCheckButton(Ssolar,"Sun");
18774 bsun->SetToolTipText("Enter/Remove the Sun as a reference entry");
18775 TGCheckButton* bmoon=new TGCheckButton(Ssolar,"Moon");
18776 bmoon->SetToolTipText("Enter/Remove the Moon as a reference entry");
18777 TGCheckButton* bmercury=new TGCheckButton(Ssolar,"Mercury");
18778 bmercury->SetToolTipText("Enter/Remove Mercury as a reference entry");
18779 TGCheckButton* bvenus=new TGCheckButton(Ssolar,"Venus");
18780 bvenus->SetToolTipText("Enter/Remove Venus as a reference entry");
18781 TGCheckButton* bearth=new TGCheckButton(Ssolar,"Earth");
18782 bearth->SetToolTipText("Enter/Remove the Earth as a reference entry");
18783 TGCheckButton* bmars=new TGCheckButton(Ssolar,"Mars");
18784 bmars->SetToolTipText("Enter/Remove Mars as a reference entry");
18785 TGCheckButton* bjupiter=new TGCheckButton(Ssolar,"Jupiter");
18786 bjupiter->SetToolTipText("Enter/Remove Jupiter as a reference entry");
18787 TGCheckButton* bsaturn=new TGCheckButton(Ssolar,"Saturn");
18788 bsaturn->SetToolTipText("Enter/Remove Saturn as a reference entry");
18789 TGCheckButton* buranus=new TGCheckButton(Ssolar,"Uranus");
18790 buranus->SetToolTipText("Enter/Remove Uranus as a reference entry");
18791 TGCheckButton* bneptune=new TGCheckButton(Ssolar,"Neptune");
18792 bneptune->SetToolTipText("Enter/Remove Neptune as a reference entry");
18793 solar->AddFrame(Ssolar);
18794 Ssolar->Show();
18795 Ssolar->SetButton(1,kFALSE);
18796 Ssolar->SetButton(2,kFALSE);
18797 Ssolar->SetButton(3,kFALSE);
18798 Ssolar->SetButton(4,kFALSE);
18799 Ssolar->SetButton(5,kFALSE);
18800 Ssolar->SetButton(6,kFALSE);
18801 Ssolar->SetButton(7,kFALSE);
18802 Ssolar->SetButton(8,kFALSE);
18803 Ssolar->SetButton(9,kFALSE);
18804 Ssolar->SetButton(10,kFALSE);
18805 for (Int_t i=0; i<10; i++)
18806 {
18807 fMapSolar[i]=kFALSE;
18808 }
18809
18810 // The Solar system Enter and Remove command buttons
18811 TGVerticalFrame* comms=new TGVerticalFrame(solar,1,1);
18812 TGLayoutHints* Lcomms=new TGLayoutHints(kLHintsLeft,10,0,15,0);
18813 solar->AddFrame(comms,Lcomms); // Command buttons
18814
18815 // The button to Enter the solar system entries
18816 TGTextButton* enter=new TGTextButton(comms,"Enter");
18817 enter->SetToolTipText("Enter the selected Solar system objects as reference signals");
18818 enter->Connect("Clicked()","NcAstrolab",this,"MapEnterSolar()");
18819 TGLayoutHints* Lenter=new TGLayoutHints(kLHintsCenterX,0,0,10,15);
18820 comms->AddFrame(enter,Lenter);
18821
18822 // The button to Remove the solar system entries
18823 TGTextButton* remove=new TGTextButton(comms,"Remove");
18824 remove->SetToolTipText("Remove the selected Solar system objects from the reference signals");
18825 remove->Connect("Clicked()","NcAstrolab",this,"MapRemoveSolar()");
18826 TGLayoutHints* Lremove=new TGLayoutHints(kLHintsCenterX,0,0,0,0);
18827 comms->AddFrame(remove,Lremove);
18828}
18829
18831{
18837
18838 TString system[9]={"equ","equ","equ","equ","gal","ecl","hor","icr","loc"};
18839 TString mode[4]={"J","M","T","B"};
18840
18841 if (i<=9) fMapDcoord=system[i-1];
18842
18843 if (i<=4) fMapDmode=mode[i-1];
18844}
18845
18847{
18853
18854 TString s[13]={"ham","ait","mer","ang","cyl","UTh","LTh","GSTh","LSTh","UYh","LYh","GSYh","LSYh"};
18855 TString sh[13]={"hamh","aith","merh","angh","cylh","UTh","LTh","GSTh","LSTh","UYh","LYh","GSYh","LSYh"};
18856 if (!fMapDoptions[0] && i<13) fMapProj=s[i-1];
18857 if (fMapDoptions[0] && i<13) fMapProj=sh[i-1];
18858 for (Int_t k=0; k<13; k++)
18859 {
18860 if (fMapDoptions[0] && fMapProj==s[k]) fMapProj=sh[k];
18861 if (!fMapDoptions[0] && fMapProj==sh[k]) fMapProj=s[k];
18862 }
18863}
18864
18866{
18872
18873 Int_t modes[3]={0,1,-1};
18874 if (i<=3) fMapMerMode=modes[i-1];
18875}
18876
18877void NcAstrolab::MapMerC(const char* text)
18878{
18884
18885 TString s=text;
18886 fMapMerC=s.Atof();
18887}
18888
18890{
18896
18897 TString s[4]={"deg","dms","hms","rad"};
18898 if (i<=4) fMapMerUc=s[i-1];
18899}
18900
18902{
18908
18909 if (i>5) return;
18910
18911 if (!fMapDoptions[i-1])
18912 {
18913 fMapDoptions[i-1]=1;
18914 }
18915 else
18916 {
18917 fMapDoptions[i-1]=0;
18918 }
18919 if (i==1) MapProj(14); // Set histogram selection
18920}
18921
18922void NcAstrolab::MapNmax(const char* text)
18923{
18929
18930 TString s=text;
18931 fMapNmax=s.Atoi();
18932}
18933
18934void NcAstrolab::MapNdigs(const char* text)
18935{
18941
18942 TString s=text;
18943 fMapNdigs=s.Atoi();
18944}
18945
18946void NcAstrolab::MapDname(const char* text)
18947{
18953
18954 fMapDname=text;
18955}
18956
18957void NcAstrolab::MapMarkSize(const char* text)
18958{
18964
18965 TString s=text;
18966 fMapMarkSize=s.Atof();
18967}
18968
18970{
18976
18977 Int_t styles[17]={8,29,21,22,23,33,34,31,2,5,24,30,25,26,32,27,28};
18978
18979 if (i>17) return;
18980
18981 fMapMarkStyle=styles[i-1];
18982}
18983
18985{
18991
18992 Int_t colors[15]={kBlack,kRed,kBlue,kGreen,kYellow,kMagenta,kCyan,kOrange,kViolet,kPink,kAzure,kSpring,kTeal,kGray,kWhite};
18993
18994 if (i>15) return;
18995
18996 fMapMarkColor=colors[i-1];
18997}
18998
19000{
19006
19007 if (i<=4) fMapMarkType=i-1;
19008}
19009
19011{
19017
19018 if (i>10) return;
19019
19020 if (!fMapSolar[i-1])
19021 {
19022 fMapSolar[i-1]=1;
19023 }
19024 else
19025 {
19026 fMapSolar[i-1]=0;
19027 }
19028}
19029
19031{
19037
19038 TString names[10]={"Sun","Moon","Mercury","Venus","Earth","Mars","Jupiter","Saturn","Uranus","Neptune"};
19039
19040 SetMapTS(); // Get the selected timestamp
19041
19042 fSkyMapPanel->RequestFocus();
19043
19044 for (Int_t i=0; i<10; i++)
19045 {
19046 if (fMapSolar[i]) GetSignal(names[i],0,&fMapTS);
19047 }
19048 printf("\n *** Selected Solar system object(s) entered *** \n");
19049}
19050
19052{
19058
19059 TString names[10]={"Sun","Moon","Mercury","Venus","Earth","Mars","Jupiter","Saturn","Uranus","Neptune"};
19060
19061 SetMapTS(); // Get the selected timestamp
19062
19063 fSkyMapPanel->RequestFocus();
19064
19065 Int_t nrem=0;
19066 Int_t nremx=0;
19067 for (Int_t i=0; i<10; i++)
19068 {
19069 if (fMapSolar[i])
19070 {
19071 nremx=RemoveSignal(names[i],0,1);
19072 if (nremx) nrem++;
19073 }
19074 }
19075
19076 printf("\n *** Number of Solar system object that have been removed : %-i *** \n",nrem);
19077}
19078
19079void NcAstrolab::CommandPanel(TGCompositeFrame* frame)
19080{
19086
19087 if (!frame) return;
19088
19089 TGGroupFrame* panel=new TGGroupFrame(frame,"Commands",kVerticalFrame);
19090 panel->SetTitlePos(TGGroupFrame::kCenter);
19091 frame->AddFrame(panel);
19092
19093 TGTextButton* list=new TGTextButton(panel,"List");
19094 list->Connect("Clicked()","NcAstrolab",this,"MapList()");
19095 list->SetToolTipText("List the selected entries");
19096 TGLayoutHints* Llist=new TGLayoutHints(kLHintsCenterX,0,0,10,10);
19097 panel->AddFrame(list,Llist);
19098
19099 TGTextButton* map=new TGTextButton(panel,"Map");
19100 map->Connect("Clicked()","NcAstrolab",this,"MapDraw()");
19101 map->SetToolTipText("Display the selected entries");
19102 TGLayoutHints* Lmap=new TGLayoutHints(kLHintsCenterX,0,0,10,10);
19103 panel->AddFrame(map,Lmap);
19104
19105 TGTextButton* close=new TGTextButton(panel,"Close");
19106 close->Connect("Clicked()","NcAstrolab",this,"MapClose()");
19107 close->SetToolTipText("Close this panel window");
19108 TGLayoutHints* Lclose=new TGLayoutHints(kLHintsCenterX,0,0,10,10);
19109 panel->AddFrame(close,Lclose);
19110
19111 TGTextButton* exit=new TGTextButton(panel,"Exit");
19112 exit->Connect("Clicked()","NcAstrolab",this,"MapExit()");
19113 exit->SetToolTipText("Exit this ROOT session");
19114 TGLayoutHints* Lexit=new TGLayoutHints(kLHintsCenterX,0,0,10,10);
19115 panel->AddFrame(exit,Lexit);
19116}
19117
19119{
19125
19126 SetMapTS(); // Set the skymap timestamp
19127
19128 fSkyMapPanel->RequestFocus();
19129
19130 Int_t type=0;
19131 if (fMapDoptions[3]) type=1;
19132 if (fMapDoptions[2] && fMapDoptions[3]) type=-1;
19133
19134 NcTimestamp* ts=&fMapTS; // User selected timestamp
19135 if (fMapLabTS) ts=0; // To get Lab timestamp notification in listings
19136
19137 Int_t j=0;
19138 if (fMapDoptions[4]) j=-1; // Individual reference timestamps
19139
19140 printf("\n");
19142}
19143
19145{
19151
19152 SetMapTS(); // Set the skymap timestamp
19153
19154 fSkyMapPanel->RequestFocus();
19155
19156 Int_t type=0;
19157 if (fMapDoptions[3]) type=1;
19158 if (fMapDoptions[2] && fMapDoptions[3]) type=-1;
19159
19160 NcTimestamp* ts=&fMapTS; // User selected timestamp
19161 if (fMapLabTS) ts=0; // To get Lab timestamp notification in listings
19162
19163 Int_t j=0;
19164 if (fMapDoptions[4]) j=-1; // Individual reference timestamps
19165
19170
19172}
19173
19175{
19181
19182 // De-activate all automatic CloseWindow() actions of the system window manager
19183 // in order to fully control it in this function
19184 fSkyMapPanel->DontCallClose();
19185
19186 // To prevent crash when the cursor is still left active in a TextEntry
19187 fSkyMapPanel->RequestFocus();
19188
19189 // Unmap the display window
19190 fSkyMapPanel->UnmapWindow();
19191}
19192
19194{
19200
19201 fSkyMapPanel->RequestFocus();
19202 fSkyMapPanel->Cleanup();
19203 gApplication->Terminate(0);
19204}
19205
19207{
19213
19214 fMapLabTS=kFALSE;
19215 Int_t imjd=0;
19216 Int_t isec=0;
19217 Int_t ins=0;
19218 Int_t ips=0;
19219
19220 if (fMapTimeType=="SysClock") // Use the system clock time
19221 {
19222 fMapTS.SetSystemTime();
19223 }
19224 else if (fMapTimeType=="Lab") // Use the Lab timestamp
19225 {
19226 fMapTS.SetMJD(fMJD,fJsec,fJns,fJps);
19227 fMapLabTS=kTRUE;
19228 }
19229 else if (fMapTimeType=="MJD") // Modified Julian Date entry
19230 {
19231 Double_t mjd=fMapDateTime.Atof();
19232 fMapTS.SetMJD(mjd);
19233 }
19234 else if (fMapTimeType=="JD") // Julian Date entry
19235 {
19236 Double_t jd=fMapDateTime.Atof();
19237 fMapTS.SetJD(jd);
19238 }
19239 else if (fMapTimeType=="TJD") // Truncated Julian Date entry
19240 {
19241 Double_t tjd=fMapDateTime.Atof();
19242 fMapTS.SetTJD(tjd);
19243 }
19244 else if (fMapTimeType=="Unix") // Unix time
19245 {
19246 Double_t val=fMapDateTime.Atof();
19247 fMapTS.SetUnixTime(val);
19248 }
19249 else
19250 {
19251 if (fMapTimeType.Contains("Name")) // Get timestamp of the specified named entry
19252 {
19253 NcSignal* sx=0;
19254 NcTimestamp* tx=0;
19255 TString name=fMapDateTime;
19256 sx=GetSignal(name,1);
19257 if (!sx) sx=GetSignal(name,0);
19258 if (sx) tx=sx->GetTimestamp();
19259 if (tx) // Stored entry was found
19260 {
19261 tx->GetMJD(imjd,isec,ins);
19262 ips=tx->GetPs();
19263 fMapTS.SetMJD(imjd,isec,ins,ips);
19264 }
19265 else
19266 {
19267 printf("\n *** No stored entry with name %-s found --> Lab TS will be used *** \n",name.Data());
19268 GetMJD(imjd,isec,ins);
19269 ips=GetPs();
19270 fMapTS.SetMJD(imjd,isec,ins,ips);
19271 fMapLabTS=kTRUE;
19272 }
19273 fMapTS.GetDayTimeString("UTC",12,0,&fMapDate,&fMapTime,kFALSE);
19274 }
19275 else // Date/Time entry
19276 {
19278 fMapDate.Remove(fMapDateTime.Index("/"),fMapDateTime.Length());
19280 fMapTime.Remove(0,fMapDateTime.Index("/")+1);
19281 }
19282
19283 // Set the timestamp according to the date/time strings
19284 fMapTS.SetUT(fMapDate,fMapTime,0);
19285 if (fMapTimeType=="UT1") fMapTS.SetUT(fMapDate,fMapTime,0,"U");
19286 if (fMapTimeType=="LMT") fMapTS.SetLT(fToffset,fMapDate,fMapTime,0);
19287 if (fMapTimeType=="GPS" || fMapTimeType=="TAI" || fMapTimeType=="TT")
19288 {
19289 fMapTS.SetTAI(fMapTimeType,fMapDate,fMapTime,0,"A",0);
19290 }
19291 }
19292
19293 // Show the new timestamp in the textbox
19294 fMapTS.GetDayTimeString("UTC",3,0,&fMapDate,&fMapTime,kFALSE);
19296 fMapDateTime+="/";
19298 fMapTSdatetime->SetText(fMapDateTime);
19299
19300 // Adapt the timestamp type for the updated text window contents
19301 if (fMapTStimetype) fMapTStimetype->Select(1,kTRUE);
19302 MapTimeType(1);
19303}
19304
19305TObject* NcAstrolab::Clone(const char* name) const
19306{
19315
19316 NcAstrolab* lab=new NcAstrolab(*this);
19317 if (name)
19318 {
19319 if (strlen(name)) lab->SetName(name);
19320 }
19321 return lab;
19322}
19323
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:371
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:355
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:301
Double_t GetTargetThickness(Double_t prob, Double_t lambda) const
Double_t fMp
Definition NcAstrolab.h:369
TRotMatrix fL
Definition NcAstrolab.h:265
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:372
Double_t fSpeedC
Definition NcAstrolab.h:363
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:404
ULong64_t fNen[2]
Definition NcAstrolab.h:256
Double_t fMapMarkSize
! The GUI entered marker size for the Map
Definition NcAstrolab.h:357
TF1 * fPhiscfunc
Definition NcAstrolab.h:280
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:259
Double_t fHbarc2
Definition NcAstrolab.h:393
Double_t fTscmin
Definition NcAstrolab.h:268
void MapCinfo(Int_t)
void MapEb(const char *text)
Double_t fAlphaEM
Definition NcAstrolab.h:375
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)
TString fMapEcoord
! The GUI entered coordinate system of the entry
Definition NcAstrolab.h:343
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:321
Double_t fToffset
Definition NcAstrolab.h:252
TString fMapEua
! The GUI entered angular units of a
Definition NcAstrolab.h:339
Double_t fOmegaR
Definition NcAstrolab.h:385
Double_t fThetascmin
Definition NcAstrolab.h:275
Double_t fAmu
Definition NcAstrolab.h:368
Int_t fSolUpdate
Definition NcAstrolab.h:296
void SetBurstParameter(TString name, Double_t value)
void MapProj(Int_t i)
TObjArray * fSigs
Definition NcAstrolab.h:255
Double_t fDscmin
Definition NcAstrolab.h:272
NcObjMatrix fDataNames
Definition NcAstrolab.h:406
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:261
Float_t fMarkerSize[4]
Definition NcAstrolab.h:306
TString fMapTime
! The GUI entered time
Definition NcAstrolab.h:328
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:250
TRotMatrix fB
! The frame bias matrix for conversion of ICRS to J2000 coordinates
Definition NcAstrolab.h:257
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:410
void SetNmatrix(NcTimestamp *ts)
Double_t fGn
Definition NcAstrolab.h:380
Double_t fOmegaC
Definition NcAstrolab.h:388
Double_t fHbar
Definition NcAstrolab.h:391
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:249
TString fProj
! Projection which is currently in use
Definition NcAstrolab.h:302
Double_t GetLuminosityDistance(Double_t z, TString u="Mpc") const
NcDevice * fBurstParameters
Definition NcAstrolab.h:409
TRotMatrix fH
! Matrix for conversion of equatorial to horizontal coordinates
Definition NcAstrolab.h:264
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:329
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:379
TH2 * fHist[2]
! Temp. histograms for the sky display
Definition NcAstrolab.h:304
TGComboBox * fMapTStimetype
! The GUI TS time type selection box
Definition NcAstrolab.h:326
TString fMapCinfo
! The GUI selected info category
Definition NcAstrolab.h:334
Double_t fTscmax
Definition NcAstrolab.h:269
void MapMerMode(Int_t i)
TArrayI * fIndices
! Storage indices of the matching reference signals
Definition NcAstrolab.h:266
TH1 * GetBurstSigmaPosdist(TString name, TString type)
TString fMapProj
! The GUI selected projection for the Map
Definition NcAstrolab.h:347
Bool_t fMapLabTS
! The GUI selection to use the Lab timestamp for the List/Map
Definition NcAstrolab.h:332
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:413
Double_t fGammaZ
Definition NcAstrolab.h:374
NcSample fBurstOnReco
Definition NcAstrolab.h:411
void InitBurstHistograms(Int_t mode)
TF1 * fThetascfunc
Definition NcAstrolab.h:277
TString fMapLabLocU
! The GUI entered Lab location angular units
Definition NcAstrolab.h:322
TCanvas * fCanvas
! The canvas for the skymap
Definition NcAstrolab.h:303
Double_t fOmegaM
Definition NcAstrolab.h:384
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:325
void MapLocb(const char *text)
TRotMatrix fN
! Matrix for nutation correction
Definition NcAstrolab.h:260
void ListBurstParameters() const
TGNumberEntryField * fMapLabLBI[3]
! The GUI number entries for the Lab location specification
Definition NcAstrolab.h:317
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)
Int_t fMapMarkStyle
! The GUI selected marker style for the Map
Definition NcAstrolab.h:358
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:346
void MapUinfo(Int_t)
void MapDcoord(Int_t i)
Double_t fPhiscmin
Definition NcAstrolab.h:278
Double_t fPhiscmax
Definition NcAstrolab.h:279
void SetPmatrix(NcTimestamp *ts)
Double_t GetLAST()
Double_t fMapEb
! The GUI entered b coordinate of an entry
Definition NcAstrolab.h:340
TString fMapDate
! The GUI entered date
Definition NcAstrolab.h:327
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:273
Double_t fMapLabLocL
! The GUI entered Lab longitude
Definition NcAstrolab.h:320
Int_t fMapMarkType
! The GUI selected entry type to apply the marker attributes on
Definition NcAstrolab.h:360
void MapMarkStyle(Int_t i)
Double_t fPc
Definition NcAstrolab.h:382
Double_t fMn
Definition NcAstrolab.h:370
void Project(Double_t l, Double_t b, TString proj, Double_t &x, Double_t &y)
Double_t fQe
Definition NcAstrolab.h:364
void MapUloc(Int_t i)
void SetBmatrix()
NcRandom * fRan
Definition NcAstrolab.h:281
void MapDateTime(const char *text)
Double_t fThetascmax
Definition NcAstrolab.h:276
TString fMapDmode
! The GUI selected coordinate system mode for the Map/List
Definition NcAstrolab.h:348
Double_t GetShieldingThickness(Double_t prob, Double_t lambda) const
TString fMapEub
! The GUI entered angular units of b
Definition NcAstrolab.h:341
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:342
TGComboBox * fMapLabU
! The GUI Lab location angular unit selection box
Definition NcAstrolab.h:318
Double_t fAu
Definition NcAstrolab.h:381
NcSample fBurstOffMatch
Definition NcAstrolab.h:416
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:352
TGNumberEntryField * fMapLabLframe[6]
! The GUI number entries for the local frame specification
Definition NcAstrolab.h:333
Double_t fOmegaL
Definition NcAstrolab.h:386
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:365
NcDevice * GetBurstParameters()
void ListBurstHistograms() const
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:251
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:262
NcSample fBurstSignal
Definition NcAstrolab.h:414
Int_t fMapLabId
! The GUI entered Lab detector Id
Definition NcAstrolab.h:324
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:359
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:305
TString fMapDateTime
! The GUI entered datetime
Definition NcAstrolab.h:330
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:351
TRotMatrix fE
! Matrix for conversion of equatorial to ecliptic coordinates
Definition NcAstrolab.h:263
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:337
Double_t fMapEa
! The GUI entered a coordinate of an entry
Definition NcAstrolab.h:338
Double_t fFermi
Definition NcAstrolab.h:376
Double_t fAxes[6]
Definition NcAstrolab.h:253
Bool_t fMapSolar[10]
! The GUI selection of solar system objects
Definition NcAstrolab.h:353
TF1 * fTscfunc
Definition NcAstrolab.h:270
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:349
Int_t fRscmode
Definition NcAstrolab.h:271
Int_t RemoveSignals(TString name, Int_t type, Int_t compress)
void SetPhysicalParameter(TString name, Double_t value)
Double_t fHubble
Definition NcAstrolab.h:383
Double_t fMmu
Definition NcAstrolab.h:366
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:405
TArrayI * MatchRefSignal(Double_t da, TString au, Double_t dt, TString tu, Int_t mode=1)
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:267
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:274
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:356
NcSample fBurstOffReco
Definition NcAstrolab.h:415
TF1 * fNuAngle
Definition NcAstrolab.h:396
Int_t fMarkerStyle[4]
Definition NcAstrolab.h:307
Int_t fUsMeridian
Definition NcAstrolab.h:300
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:336
Double_t fMaxDt
Definition NcAstrolab.h:282
TString fMapEname
! The GUI entered name of the entry
Definition NcAstrolab.h:345
Int_t GetLabDetectorId() const
Double_t fMtau
Definition NcAstrolab.h:367
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:387
TGMainFrame * fSkyMapPanel
! The main frame for the SkyMapPanel GUI
Definition NcAstrolab.h:316
Int_t GetNsignals(Int_t type, Int_t mode=0) const
Double_t fPlanck
Definition NcAstrolab.h:377
Double_t fBoltz
Definition NcAstrolab.h:378
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:403
Double_t GetLMST()
Int_t fMapMerMode
! The GUI selected meridian orientation for the Map
Definition NcAstrolab.h:354
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:308
void MapMerC(const char *text)
Int_t fMapTinfo
! The GUI selected mode for the timestamp info
Definition NcAstrolab.h:335
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:331
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:319
virtual void CommandPanel(TGCompositeFrame *frame)
Double_t GetSurvivalProbability(Double_t x, Double_t lambda) const
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
void MakeBurstEnergydist(Int_t mode, TString file, TString tree, TString name1, TString name2, TString u, Double_t Emin, Double_t Emax, Int_t nb=1000)
Int_t fMapNmax
! The GUI selected max. number of signals of each type to Map/List
Definition NcAstrolab.h:350
Int_t fBias
! Initialisation flag for fB values (0=uninitialised 1=initialised)
Definition NcAstrolab.h:258
void RandomPosition(Nc3Vector &v, Double_t thetamin, Double_t thetamax, Double_t phimin, Double_t phimax)
TObjArray * fRefs
Definition NcAstrolab.h:254
TString fMapLabExpName
! The GUI entered Lab experimental site
Definition NcAstrolab.h:323
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:344
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:373
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:412
Double_t fHbarc
Definition NcAstrolab.h:392
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)