| 50 | int offDate = 20060928; | int offDate = 20060928; | 
| 51 | //  int offDate = 20060614; | //  int offDate = 20060614; | 
| 52 | int offTime = 210000; | int offTime = 210000; | 
| 53 |  | bool field = false; | 
| 54 |  |  | 
| 55 | if (argc < 2){ | if (argc < 2){ | 
| 56 | printf("You have to insert at least the file to analyze and the mapFile \n"); | printf("You have to insert at least the file to analyze and the mapFile \n"); | 
| 67 | printf( "\t -outDir[path]          Path where to put the output.\n"); | printf( "\t -outDir[path]          Path where to put the output.\n"); | 
| 68 | printf( "\t -offDate               Date of resetting of the Resource counter [format YYMMDD (UTC date) default 20060928] \n"); | printf( "\t -offDate               Date of resetting of the Resource counter [format YYMMDD (UTC date) default 20060928] \n"); | 
| 69 | printf( "\t -offTime               Time of resetting of the Resource counter [format HHMMSS (UTC date) default 210000] \n"); | printf( "\t -offTime               Time of resetting of the Resource counter [format HHMMSS (UTC date) default 210000] \n"); | 
| 70 |  | printf( "\t -field               Produce maps of the magnetic field \n"); | 
| 71 | exit(1); | exit(1); | 
| 72 | } | } | 
| 73 |  |  | 
| 81 | } | } | 
| 82 |  |  | 
| 83 | for (int i = 2; i < argc; i++){ | for (int i = 2; i < argc; i++){ | 
| 84 |  | if (!strcmp(argv[i], "-field")){ | 
| 85 |  | field = true; | 
| 86 |  | i++; | 
| 87 |  | continue; | 
| 88 |  | } | 
| 89 |  |  | 
| 90 | if (!strcmp(argv[i], "-outDir")){ | if (!strcmp(argv[i], "-outDir")){ | 
| 91 | if (++i >= argc){ | if (++i >= argc){ | 
| 92 | printf( "-outDir needs arguments. \n"); | printf( "-outDir needs arguments. \n"); | 
| 146 | } | } | 
| 147 |  |  | 
| 148 | if (mapFile != ""){ | if (mapFile != ""){ | 
| 149 | Rate(rootFile, outDir, mapFile, tleFile, offDate, offTime); | Rate(rootFile, outDir, mapFile, tleFile, offDate, offTime, field); | 
| 150 | } else { | } else { | 
| 151 | printf("You have to insert at least the file to analyze and the mapFile \n"); | printf("You have to insert at least the file to analyze and the mapFile \n"); | 
| 152 | printf("Try '--help' for more information. \n"); | printf("Try '--help' for more information. \n"); | 
| 215 | } | } | 
| 216 |  |  | 
| 217 |  |  | 
| 218 | void Rate(TString *filename, TString outDirectory = "", TString mapFile = "", TString tleFile = "", int offDate = 20060614, int offTime = 210000) | void Rate(TString *filename, TString outDirectory = "", TString mapFile = "", TString tleFile = "", int offDate = 20060614, int offTime = 210000, bool field = false) | 
| 219 | { | { | 
| 220 | // **** Offset to temporarily correct the TDatime bug ****/ | // **** Offset to temporarily correct the TDatime bug ****/ | 
| 221 | //  offTime += 10000; | //  offTime += 10000; | 
| 280 | // Magnetic field histograms.  I use always the suffix _counter | // Magnetic field histograms.  I use always the suffix _counter | 
| 281 | // because they are not normalized.  Imagine that an instrument | // because they are not normalized.  Imagine that an instrument | 
| 282 | // give us the value of the magnetic field for each event. | // give us the value of the magnetic field for each event. | 
| 283 | TH2F *hbabs_counter = new TH2F("hbabs_counter", "B module", 360, -180, 180, 180, -90, 90); | TH2F *hbabs_counter; | 
| 284 | TH2F *hbnorth_counter = new TH2F("hbnorth_counter", "B north", 360, -180, 180, 180, -90, 90); | TH2F *hbnorth_counter; | 
| 285 | TH2F *hbdown_counter = new TH2F("hbdown_counter", "B down", 360, -180, 180, 180, -90, 90); | TH2F *hbdown_counter; | 
| 286 | TH2F *hbeast_counter = new TH2F("hbeast_counter", "B east", 360, -180, 180, 180, -90, 90); | TH2F *hbeast_counter; | 
| 287 | TH2F *hb0_counter = new TH2F("hb0_counter", "B_0", 360, -180, 180, 180, -90, 90); | TH2F *hb0_counter; | 
| 288 | TH2F *hl_counter = new TH2F("hl_counter", "l", 360, -180, 180, 180, -90, 90); | TH2F *hl_counter; | 
| 289 |  |  | 
| 290 |  | if(field) { | 
| 291 |  | hbabs_counter = new TH2F("hbabs_counter", "B module", 360, -180, 180, 180, -90, 90); | 
| 292 |  | hbnorth_counter = new TH2F("hbnorth_counter", "B north", 360, -180, 180, 180, -90, 90); | 
| 293 |  | hbdown_counter = new TH2F("hbdown_counter", "B down", 360, -180, 180, 180, -90, 90); | 
| 294 |  | hbeast_counter = new TH2F("hbeast_counter", "B east", 360, -180, 180, 180, -90, 90); | 
| 295 |  | hb0_counter = new TH2F("hb0_counter", "B_0", 360, -180, 180, 180, -90, 90); | 
| 296 |  | hl_counter = new TH2F("hl_counter", "l", 360, -180, 180, 180, -90, 90); | 
| 297 |  | } | 
| 298 |  |  | 
| 299 | // Get a char* to "file" from "/dir1/dir2/.../file.root" | // Get a char* to "file" from "/dir1/dir2/.../file.root" | 
| 300 | TString basename; | TString basename; | 
| 324 | exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | 
| 325 | } | } | 
| 326 |  |  | 
| 327 | //Get the Julian date of the Resours offset | // Here I do: resurs offset + timesync | 
| 328 | TDatime offRes = TDatime(offDate, offTime); | TDatime offRes = TDatime(offDate, offTime); | 
| 329 | // Add to the Resours Offset the timesync.  This is now the date at | TTimeStamp offResTS = TTimeStamp(offRes.GetYear(), offRes.GetMonth(), offRes.GetDay(), offRes.GetHour(), offRes.GetMinute(), offRes.GetSecond(), 0, kTRUE, timesync); | 
|  | // the moment of the timesync. |  | 
|  | offRes.Set(offRes.Convert() + (UInt_t) timesync); |  | 
| 330 |  |  | 
| 331 | // Now I need a pointer to a cTle object.  The class misses a | // Now I need a pointer to a cTle object.  The class misses a | 
| 332 | // constructor without arguments, so we have to give it a dummy TLE. | // constructor without arguments, so we have to give it a dummy TLE. | 
| 337 |  |  | 
| 338 | // If we have to use a TLE file, call getTle(). | // If we have to use a TLE file, call getTle(). | 
| 339 | if (tleFile != "") | if (tleFile != "") | 
| 340 | tle1 = getTle(tleFile, offRes); | tle1 = getTle(tleFile, offResTS); // modify getTle() to use offResTS! | 
| 341 |  | else | 
| 342 |  | cout<<"OrbitalRate: Warning!!! No tle file supplied.\n"; | 
| 343 |  |  | 
| 344 |  | // Here I do: resurs offset + timesync - obt of the timesync | 
| 345 |  | offResTS.Set(offResTS.GetSec() - obt_timesync, kTRUE, 0, kFALSE); | 
| 346 |  |  | 
| 347 | cOrbit       orbit(*tle1); | cOrbit       orbit(*tle1); | 
| 348 | cEci         eci; | cEci         eci; | 
| 349 | cCoordGeo    coo; | cCoordGeo    coo; | 
| 350 |  |  | 
| 351 | // offRes is now "offset date" + timesync.  Now I subtract the obt | // Here I do: resurs offset + timesync - obt of the timesync - tle time | 
| 352 | // of the timesync.  Remember that the time of the event from the | TTimeStamp tledate = getTleDatetime(tle1); | 
|  | // tle date is: |  | 
|  | // tle date - (offset date + timesync - obt timesync + obt event). |  | 
|  | offRes.Set(offRes.Convert() - (UInt_t) obt_timesync); |  | 
|  |  |  | 
|  | // Get the Julian date of the TLE epoch |  | 
|  | string datetime = getTleDatetime(tle1); |  | 
|  | TDatime tledate = TDatime(datetime.c_str()); |  | 
|  |  |  | 
| 353 | cJulian jdatetime = cJulian((int) (tle1->getField(cTle::FLD_EPOCHYEAR)+2e3), tle1->getField(cTle::FLD_EPOCHDAY)); | cJulian jdatetime = cJulian((int) (tle1->getField(cTle::FLD_EPOCHYEAR)+2e3), tle1->getField(cTle::FLD_EPOCHDAY)); | 
| 354 | int pYear, pMon; double pDOM; | int pYear, pMon; double pDOM; | 
| 355 | jdatetime.getComponent(&pYear, &pMon, &pDOM); | jdatetime.getComponent(&pYear, &pMon, &pDOM); | 
| 356 |  | offsetTime = ((Long64_t) offResTS.GetSec() - (Long64_t) tledate.GetSec()); | 
|  | offsetTime = ((Long64_t) offRes.Convert() - (Long64_t) tledate.Convert()); |  | 
| 357 |  |  | 
| 358 | /********** Magnetic Field **************/ | /********** Magnetic Field **************/ | 
| 359 | // Check that all this is correct! | // Check that all this is correct! | 
| 362 | // I can now compute the magnetic dipole moment at the actual date, | // I can now compute the magnetic dipole moment at the actual date, | 
| 363 | // using the cJulian date.  I don't to recompute it for every event | // using the cJulian date.  I don't to recompute it for every event | 
| 364 | // beacause changes are not relevant at all. | // beacause changes are not relevant at all. | 
| 365 | Int_t y = tledate.GetYear(); | //   Int_t y = tledate.GetYear(); | 
| 366 | Int_t m = tledate.GetMonth(); | //   Int_t m = tledate.GetMonth(); | 
| 367 | Int_t d = tledate.GetDay(); | //   Int_t d = tledate.GetDay(); | 
| 368 |  | UInt_t y, m, d; | 
| 369 |  | tledate.GetDate(kTRUE, 0, &y, &m, &d); | 
| 370 | float year = (float) y + (m*31+d)/365; | float year = (float) y + (m*31+d)/365; | 
| 371 |  |  | 
| 372 | // Initialize common data for geopack | // Initialize common data for geopack | 
| 373 | recalc_(y, m*31+d, 0, 0, 0); | if(field) | 
| 374 |  | recalc_(y, m*31+d, 0, 0, 0); | 
| 375 | /********** Magnetic Field **************/ | /********** Magnetic Field **************/ | 
| 376 |  |  | 
| 377 | tr = (TTree*)rootFile->Get("Physics"); | tr = (TTree*)rootFile->Get("Physics"); | 
| 418 | ph = eh->GetPscuHeader(); | ph = eh->GetPscuHeader(); | 
| 419 |  |  | 
| 420 | // obt in ms | // obt in ms | 
| 421 | ULong64_t obt = ph->GetOrbitalTime(); | UInt_t obt = (UInt_t) ph->GetOrbitalTime(); | 
| 422 |  |  | 
| 423 | // timeElapsedFromTLE is the difference, in seconds, between the | // timeElapsedFromTLE is the difference, in seconds, between the | 
| 424 | // event and the tle date.  I use seconds and not milliseconds | // event and the tle date.  I use seconds and not milliseconds | 
| 471 | alt = coo.m_Alt; | alt = coo.m_Alt; | 
| 472 |  |  | 
| 473 | /********** Magnetic Field **************/ | /********** Magnetic Field **************/ | 
| 474 | igrf_geo__((coo.m_Alt+6371.2)/6371.2, M_PI/2.-coo.m_Lat, coo.m_Lon, br, btheta, bphi); | if(field) | 
| 475 |  | igrf_geo__((coo.m_Alt+6371.2)/6371.2, M_PI/2.-coo.m_Lat, coo.m_Lon, br, btheta, bphi); | 
| 476 | //      cout<<"("<<(coo.m_Alt+6371.2)/6371.2<<", "<<M_PI/2.-coo.m_Lat<<", "<<coo.m_Lon<<")"<<endl; | //      cout<<"("<<(coo.m_Alt+6371.2)/6371.2<<", "<<M_PI/2.-coo.m_Lat<<", "<<coo.m_Lon<<")"<<endl; | 
| 477 | /********** Magnetic Field **************/ | /********** Magnetic Field **************/ | 
| 478 |  |  | 
| 500 | // this values but I need to count how many times I fill | // this values but I need to count how many times I fill | 
| 501 | // each bin.  This is done by the histogram event_counter. | // each bin.  This is done by the histogram event_counter. | 
| 502 | // I will normalize later. | // I will normalize later. | 
| 503 | hbabs_counter->Fill(lon, lat, sqrt(br*br+btheta*btheta+bphi*bphi)*1e-5); | if(field) { | 
| 504 | hbnorth_counter->Fill(lon, lat, -btheta*1e-5); | hbabs_counter->Fill(lon, lat, sqrt(br*br+btheta*btheta+bphi*bphi)*1e-5); | 
| 505 | hbdown_counter->Fill(lon, lat, -br*1e-5); | hbnorth_counter->Fill(lon, lat, -btheta*1e-5); | 
| 506 | hbeast_counter->Fill(lon, lat, bphi*1e-5); | hbdown_counter->Fill(lon, lat, -br*1e-5); | 
| 507 |  | hbeast_counter->Fill(lon, lat, bphi*1e-5); | 
| 508 |  | } | 
| 509 | // This histograms is now filled with the number of entries. | // This histograms is now filled with the number of entries. | 
| 510 | // Below we will divide with the time (in seconds) to get | // Below we will divide with the time (in seconds) to get | 
| 511 | // event rate per bin. | // event rate per bin. | 
| 571 | TH2F *trigAndOr_rate = (TH2F*) trigAndOr_counter->Clone("trigAndOr_rate"); | TH2F *trigAndOr_rate = (TH2F*) trigAndOr_counter->Clone("trigAndOr_rate"); | 
| 572 | TH2F *trigAndAnd_rate = (TH2F*) trigAndAnd_counter->Clone("trigAndAnd_rate"); | TH2F *trigAndAnd_rate = (TH2F*) trigAndAnd_counter->Clone("trigAndAnd_rate"); | 
| 573 | TH2F *nd_rate = (TH2F*) nd_counter->Clone("nd_rate"); | TH2F *nd_rate = (TH2F*) nd_counter->Clone("nd_rate"); | 
| 574 | TH2F *hbabs_norm = (TH2F*) hbabs_counter->Clone("hbabs_norm"); |  | 
| 575 | TH2F *hbnorth_norm = (TH2F*) hbnorth_counter->Clone("hbnorth_norm"); | TH2F *hbabs_norm; | 
| 576 | TH2F *hbdown_norm = (TH2F*) hbabs_counter->Clone("hbdown_norm"); | TH2F *hbnorth_norm; | 
| 577 | TH2F *hbeast_norm = (TH2F*) hbabs_counter->Clone("hbeast_norm"); | TH2F *hbdown_norm; | 
| 578 |  | TH2F *hbeast_norm; | 
| 579 |  |  | 
| 580 |  | if(field) { | 
| 581 |  | hbabs_norm = (TH2F*) hbabs_counter->Clone("hbabs_norm"); | 
| 582 |  | hbnorth_norm = (TH2F*) hbnorth_counter->Clone("hbnorth_norm"); | 
| 583 |  | hbdown_norm = (TH2F*) hbabs_counter->Clone("hbdown_norm"); | 
| 584 |  | hbeast_norm = (TH2F*) hbabs_counter->Clone("hbeast_norm"); | 
| 585 |  | } | 
| 586 |  |  | 
| 587 | // Now we divide each histogram _counter with the time histogram | // Now we divide each histogram _counter with the time histogram | 
| 588 | // obtBinTime to have an histogram _rate.  Note that, when a second | // obtBinTime to have an histogram _rate.  Note that, when a second | 
| 649 | // fill the bins with the values of the magnetic field for each | // fill the bins with the values of the magnetic field for each | 
| 650 | // event, we need to divide with the number of fills done, that is | // event, we need to divide with the number of fills done, that is | 
| 651 | // event_counter. | // event_counter. | 
| 652 | hbabs_norm->Divide(hbabs_counter, event_counter, 1, 1, ""); | if(field) { | 
| 653 | oss.str(""); | hbabs_norm->Divide(hbabs_counter, event_counter, 1, 1, ""); | 
| 654 | oss << basename.Data() << "_orbit_Babs.png"; | oss.str(""); | 
| 655 | printHist(hbabs_norm, mapFile, outDirectory, oss.str().c_str(), "B abs (G)", -width, height, 0, 0); | oss << basename.Data() << "_orbit_Babs.png"; | 
| 656 |  | printHist(hbabs_norm, mapFile, outDirectory, oss.str().c_str(), "B abs (G)", -width, height, 0, 0); | 
| 657 | hbnorth_norm->Divide(hbnorth_counter, event_counter, 1, 1, ""); |  | 
| 658 | oss.str(""); | hbnorth_norm->Divide(hbnorth_counter, event_counter, 1, 1, ""); | 
| 659 | oss << basename.Data() << "_orbit_Bnorth.png"; | oss.str(""); | 
| 660 | printHist(hbnorth_norm, mapFile, outDirectory, oss.str().c_str(), "B north (G)", -width, height, 0, 1); | oss << basename.Data() << "_orbit_Bnorth.png"; | 
| 661 |  | printHist(hbnorth_norm, mapFile, outDirectory, oss.str().c_str(), "B north (G)", -width, height, 0, 1); | 
| 662 | hbdown_norm->Divide(hbdown_counter, event_counter, 1, 1, ""); |  | 
| 663 | oss.str(""); | hbdown_norm->Divide(hbdown_counter, event_counter, 1, 1, ""); | 
| 664 | oss << basename.Data() << "_orbit_Bdown.png"; | oss.str(""); | 
| 665 | printHist(hbdown_norm, mapFile, outDirectory, oss.str().c_str(), "B down (G)", -width, height, 0, 1); | oss << basename.Data() << "_orbit_Bdown.png"; | 
| 666 |  | printHist(hbdown_norm, mapFile, outDirectory, oss.str().c_str(), "B down (G)", -width, height, 0, 1); | 
| 667 | hbeast_norm->Divide(hbeast_counter, event_counter, 1, 1, ""); |  | 
| 668 | oss.str(""); | hbeast_norm->Divide(hbeast_counter, event_counter, 1, 1, ""); | 
| 669 | oss << basename.Data() << "_orbit_Beast.png"; | oss.str(""); | 
| 670 | printHist(hbeast_norm, mapFile, outDirectory, oss.str().c_str(), "B east (G)", -width, height, 0, 1); | oss << basename.Data() << "_orbit_Beast.png"; | 
| 671 |  | printHist(hbeast_norm, mapFile, outDirectory, oss.str().c_str(), "B east (G)", -width, height, 0, 1); | 
| 672 |  | } | 
| 673 |  |  | 
| 674 | delete obtBinTime; | delete obtBinTime; | 
| 675 | delete event_counter; | delete event_counter; | 
| 693 | delete trigS111A_rate; | delete trigS111A_rate; | 
| 694 | delete trigS12andS21andS22_rate; | delete trigS12andS21andS22_rate; | 
| 695 |  |  | 
| 696 | delete hbabs_counter; | if(field) { | 
| 697 | delete hbnorth_counter; | delete hbabs_counter; | 
| 698 | delete hbdown_counter; | delete hbnorth_counter; | 
| 699 | delete hbeast_counter; | delete hbdown_counter; | 
| 700 | delete hbabs_norm; | delete hbeast_counter; | 
| 701 | delete hbnorth_norm; | delete hbabs_norm; | 
| 702 | delete hbdown_norm; | delete hbnorth_norm; | 
| 703 | delete hbeast_norm; | delete hbdown_norm; | 
| 704 |  | delete hbeast_norm; | 
| 705 |  | } | 
| 706 |  |  | 
| 707 | rootFile->Close(); | rootFile->Close(); | 
| 708 | } | } | 
| 726 | // Scale() and Merge()). | // Scale() and Merge()). | 
| 727 | // | // | 
| 728 | // This function depends on InitStyle(); | // This function depends on InitStyle(); | 
| 729 | int printHist(TH2F *h, TString mapFile, TString outDirectory, TString outputFilename, char *title, int width, int height, bool use_log, bool bool_shift) | int printHist(TH2F *h, TString mapFile, TString outDirectory, TString outputFilename, const char *title, int width, int height, bool use_log, bool bool_shift) | 
| 730 | { | { | 
| 731 | InitStyle(); | InitStyle(); | 
| 732 |  |  | 
| 824 | // querying the database with the RESURS DK-1 id number 29228, | // querying the database with the RESURS DK-1 id number 29228, | 
| 825 | // selecting the widest timespan, including the satellite name in the | // selecting the widest timespan, including the satellite name in the | 
| 826 | // results. | // results. | 
| 827 | cTle *getTle(TString tleFile, TDatime offRes) | cTle *getTle(TString tleFile, TTimeStamp offResTS) | 
| 828 | { | { | 
| 829 | Float_t tledatefromfile, tledatefromroot; | Float_t tledatefromfile, tledatefromroot; | 
| 830 | fstream tlefile(tleFile.Data(), ios::in); | fstream tlefile(tleFile.Data(), ios::in); | 
| 854 | // Sort by date | // Sort by date | 
| 855 | sort(ctles.begin(), ctles.end(), compTLE); | sort(ctles.begin(), ctles.end(), compTLE); | 
| 856 |  |  | 
| 857 | tledatefromroot = (offRes.GetYear()-2000)*1e3 + (offRes.Convert() - (TDatime(offRes.GetYear(), 1, 1, 0, 0, 0)).Convert())/ (24.*3600.); | UInt_t year, month, day; | 
| 858 |  | offResTS.GetDate(kTRUE, 0, &year, &month, &day); | 
| 859 |  | TTimeStamp firstofjan = TTimeStamp(year, 1, 1, 0, 0, 0); | 
| 860 |  | tledatefromroot = (year-2000)*1e3 + (offResTS.GetSec() - firstofjan.GetSec())/(24.*3600.); | 
| 861 |  |  | 
| 862 | for(iter = ctles.begin(); iter != ctles.end(); iter++) { | for(iter = ctles.begin(); iter != ctles.end(); iter++) { | 
| 863 | cTle *tle = *iter; | cTle *tle = *iter; | 
| 901 |  |  | 
| 902 | // Look for a timesync in the TFile rootFile.  Set timesync and | // Look for a timesync in the TFile rootFile.  Set timesync and | 
| 903 | // obt_timesync.  Returns 1 if timesync is found, 0 otherwise. | // obt_timesync.  Returns 1 if timesync is found, 0 otherwise. | 
| 904 | int lookforTimesync(TFile *rootFile, Float_t *timesync, Float_t *obt_timesync) { | UInt_t lookforTimesync(TFile *rootFile, Float_t *timesync, Float_t *obt_timesync) { | 
| 905 | *timesync = -1;  // will be != -1 if found | *timesync = -1;  // will be != -1 if found | 
| 906 |  |  | 
| 907 | ULong64_t             nevents    = 0; | ULong64_t             nevents    = 0; | 
| 972 | } | } | 
| 973 |  |  | 
| 974 |  |  | 
| 975 | // Return a string like YYYY-MM-DD hh:mm:ss, a datetime format. | // | 
| 976 | string getTleDatetime(cTle *tle) | // Returns the tle date as a TTimeStamp object. | 
| 977 |  | // | 
| 978 |  | TTimeStamp getTleDatetime(cTle *tle) | 
| 979 | { | { | 
| 980 | int year, mon, day, hh, mm, ss; | int year, mon, day, hh, mm, ss; | 
| 981 | double dom; // day of month (is double!) | double dom; // day of month (is double!) | 
| 995 | ss = (int) floor( ((((dom - day) * 24 - hh) * 60 - mm) * 60)); | ss = (int) floor( ((((dom - day) * 24 - hh) * 60 - mm) * 60)); | 
| 996 | //  ms = (int) floor( (((((dom - day) * 24 - hh) * 60 - mm) * 60) - ss) * 1000); | //  ms = (int) floor( (((((dom - day) * 24 - hh) * 60 - mm) * 60) - ss) * 1000); | 
| 997 |  |  | 
| 998 | date << year << "-" << mon << "-" << day << " " << hh << ":" << mm << ":" << ss; | TTimeStamp t = TTimeStamp(year, mon, day, hh, mm, ss, 0, true); | 
| 999 |  |  | 
| 1000 | return date.str(); | return t; | 
| 1001 | } | } | 
| 1002 |  |  | 
| 1003 | // | // |