Index: trunk/FACT++/src/gcn.cc
===================================================================
--- trunk/FACT++/src/gcn.cc	(revision 19516)
+++ trunk/FACT++/src/gcn.cc	(revision 19528)
@@ -82,9 +82,9 @@
 
         const string role = root.attribute("role", "").toStdString();
-        const string name = root.tagName().toStdString();
+        const string trn  = root.tagName().toStdString();
 
         // A full description can be found at http://voevent.dc3.com/schema/default.html
 
-        if (name=="trn:Transport")
+        if (trn=="trn:Transport")
         {
             if (role=="iamalive")
@@ -99,5 +99,5 @@
                 if (fIsVerbose)
                 {
-                    Out() << Time().GetAsStr() << " ----- " << name << " [" << role << "] -----" << endl;
+                    Out() << Time().GetAsStr() << " ----- " << trn << " [" << role << "] -----" << endl;
                     Out() << " " << time.tagName().toStdString() << " = " << fLastKeepAlive.GetAsStr() << '\n';
                     Out() << " " << orig.tagName().toStdString() << " = " << orig.text().toStdString() << '\n';
@@ -114,5 +114,5 @@
         fout << "------------------------------------------------------------------------------\n" << fRxData.data() << endl;
 
-        if (name=="voe:VOEvent")
+        if (trn=="voe:VOEvent")
         {
             // WHAT: http://gcn.gsfc.nasa.gov/tech_describe.html
@@ -150,6 +150,8 @@
             const auto &id = ptype->first;
 
+            // Gravitational wave event
             const bool is_gw = id==150 || id==151 || id==152 || id==153 || id==164;
 
+            // Required keywords
             vector<string> missing;
             if (date.isNull())
@@ -238,20 +240,145 @@
              */
 
+            // ----------------------------- Create Name ----------------------
+
             const auto &paket = ptype->second;
 
+            string name;
+            bool prefix = true;
+
+            switch (id)
+            {
+            case 60:
+            case 61:
+            case 62:
+
+            case 110:
+            case 111:
+            case 112:
+            case 115:
+                name = GetParamValue(what, "TRIGGER_NUM").toStdString();
+                break;
+
+            case 123:
+                name = GetParamValue(what, "REF_NUM").toStdString();
+                break;
+
+            case 125:
+                name = GetParamValue(what, "SourceName").toStdString();
+                prefix = false;
+                break;
+
+            case 157:
+            case 158:
+                {
+                    const string event_id = GetParamValue(what, "event_id").toStdString();
+                    const string run_id   = GetParamValue(what, "run_id").toStdString();
+                    name = event_id+"_"+run_id;
+                    break;
+                }
+
+                // Missing ID
+                // case 51:
+                // case 83:
+                // case 119:
+                // case 129:
+            default:
+                name = GetParamValue(what, "TrigID").toStdString();
+            }
+
+            if (name.empty() || name=="0")
+            {
+                Warn("Missing ID... cannot create default source name... using date instead.");
+                name = Time().GetAsStr("%Y%m%d_%H%M%S");
+                prefix = true;
+            }
+
+            if (prefix)
+                name.insert(0, paket.instrument+"#");
+
+            // ----------------------------------------------------------------
+
             const string unit = pos2d.attribute("unit").toStdString();
 
-            const uint32_t trig  = GetParamValue(what, "TrigID").toUInt();
-            const double   ra    = c1.text().toDouble();
-            const double   dec   = c2.text().toDouble();
-            const double   err   = errad.text().toDouble();
+            const double ra  = c1.text().toDouble();
+            const double dec = c2.text().toDouble();
+            const double err = errad.text().toDouble();
 
             const string n1 = name1.text().toStdString();
             const string n2 = name2.text().toStdString();
+
+            const bool has_coordinates = n1=="RA" && n2=="Dec" && unit=="deg";
+
+            const std::set<int16_t> typelist =
+            {
+                51,  // INTEGRAL_POINTDIR
+
+                53,  // INTEGRAL_WAKEUP
+                54,  // INTEGRAL_REFINED
+                55,  // INTEGRAL_OFFLINE
+
+                // 56, // INTEGRAL_WEAK
+                // 59, // KONUS_LC
+
+                60,  // SWIFT_BAT_GRB_ALERT
+                61,  // SWIFT_BAT_GRB_POS_ACK
+                62,  // SWIFT_BAT_GRB_POS_NACK
+
+                83,  // SWIFT_POINTDIR
+
+                97,  // SWIFT_BAT_QL_POS
+
+                100, // AGILE_GRB_WAKEUP
+                101, // AGILE_GRB_GROUND
+                102, // AGILE_GRB_REFINED
+
+                110, // FERMI_GBM_FLT_POS
+                111, // FERMI_GBM_GND_POS
+                112, // FERMI_GBM_LC
+                115, // FERMI_GBM_TRANS
+
+                123, // FERMI_LAT_TRANS
+                125, // FERMI_LAT_MONITOR
+
+                // 134, // MAXI_UNKNOWN
+                // 135, // MAXI_KNOWN
+                // 136, // MAXI_TEST
+
+                157, // AMON_ICECUBE_COINC
+                158, // AMON_ICECUBE_HESE
+
+                169, // AMON_ICECUBE_EHE
+                171, // HAWC_BURST_MONITOR
+                173, // ICECUBE_GOLD
+                174, // ICECUBE_BRONZE
+            };
+
+            const bool integral_test = role=="test" && id>=53 && id<=56;
+
+            const bool valid_id = typelist.find(id)!=typelist.end();
+
+            if (valid_id && has_coordinates && !integral_test)
+            {
+                const ToO::DataGRB data =
+                {
+                    .type   = id,
+                    .ra     = ra,
+                    .dec    = dec,
+                    .err    = err,
+                };
+
+                vector<char> dim(sizeof(ToO::DataGRB) + name.size() + 1);
+
+                memcpy(dim.data(),                      &data,        sizeof(ToO::DataGRB));
+                memcpy(dim.data()+sizeof(ToO::DataGRB), name.c_str(), name.size());
+
+                Dim::SendCommandNB("SCHEDULER/GCN", dim);
+                Info("Sent ToO '"+name+"' ["+role+"]");
+            }
 
             Out() << Time(date.text().toStdString()).GetAsStr() << " ----- " << sname.text().toStdString() << " [" << role << "]\n";
             if (!desc.isNull())
                 Out() << "[" << desc.text().toStdString()  << "]\n";
-            Out() << paket.name << "[" << id << "]: " << paket.description << endl;
+            Out() << name << ": " << paket.name << "[" << id << "]: " << paket.description << endl;
             Out() << left;
             Out() << "  " << setw(5) << "TIME" << "= " << Time(time.text().toStdString()).GetAsStr() << '\n';
@@ -259,101 +386,4 @@
             Out() << "  " << setw(5) << n2     << "= " << dec << unit << '\n';
             Out() << "  " << setw(5) << "ERR"  << "= " << err << unit << '\n';
-
-            const bool has_coordinates = n1=="RA" && n2=="Dec" && unit=="deg";
-
-            const std::set<int16_t> typelist =
-            {
-                51,  // INTEGRAL_POINTDIR
-
-                53,  // INTEGRAL_WAKEUP
-                54,  // INTEGRAL_REFINED
-                55,  // INTEGRAL_OFFLINE
-
-                // 56, // INTEGRAL_WEAK
-                // 59, // KONUS_LC
-
-                60,  // SWIFT_BAT_GRB_ALERT
-                61,  // SWIFT_BAT_GRB_POS_ACK
-                62,  // SWIFT_BAT_GRB_POS_NACK
-
-                83,  // SWIFT_POINTDIR
-
-                97,  // SWIFT_BAT_QL_POS
-
-                100, // AGILE_GRB_WAKEUP
-                101, // AGILE_GRB_GROUND
-                102, // AGILE_GRB_REFINED
-
-                110, // FERMI_GBM_FLT_POS
-                111, // FERMI_GBM_GND_POS
-                112, // FERMI_GBM_LC
-                115, // FERMI_GBM_TRANS
-
-                123, // FERMI_LAT_TRANS
-                125, // FERMI_LAT_MONITOR
-
-                // 134, // MAXI_UNKNOWN
-                // 135, // MAXI_KNOWN
-                // 136, // MAXI_TEST
-
-                157, // AMON_ICECUBE_COINC
-                158, // AMON_ICECUBE_HESE
-
-                169, // AMON_ICECUBE_EHE
-                171, // HAWC_BURST_MONITOR
-                173, // ICECUBE_GOLD
-                174, // ICECUBE_BRONZE
-            };
-
-            const bool valid = typelist.find(id)!=typelist.end();
-
-            if (valid && has_coordinates)
-            {
-                const ToO::DataGRB data =
-                {
-                    .type   = id,
-                    .trigid = trig,
-                    .ra     = ra,
-                    .dec    = dec,
-                    .err    = err,
-                };
-
-                Info("Sending ToO #"+to_string(trig)+" ["+role+"]");
-                Dim::SendCommandNB("SCHEDULER/GCN", data);
-
-/*
-                const double jd = Time().JD();
-
-                Nova::EquPosn equ;
-                equ.ra  = ra;
-                equ.dec = dec; 
-
-                const Nova::ZdAzPosn pos = Nova::GetHrzFromEqu(equ, jd);
-                const Nova::EquPosn moon = Nova::GetLunarEquCoords(jd);
-                const Nova::ZdAzPosn sun = Nova::GetHrzFromEqu(Nova::GetSolarEquCoords(jd), jd);
-
-                const double disk = Nova::GetLunarDisk(jd);
-                const double dist = Nova::GetAngularSeparation(equ, moon);
-
-                Out() << "  " << setw(5) << "ZD"   << "= " << pos.zd << "deg\n";
-                Out() << "  " << setw(5) << "Az"   << "= " << pos.az << "deg\n";
-
-                Out() << "  " << setw(5) << "MOON" << "= " << int(disk*100) << "%\n";
-                Out() << "  " << setw(5) << "DIST" << "= " << dist << "deg\n";
-
-                if (dist>10 && dist<170 && pos.zd<80 && sun.zd>108)
-                {
-                    Out() << "  visible ";
-                    if (pos.zd<70)
-                        Out() << '+';
-                    if (pos.zd<60)
-                        Out() << '+';
-                    if (pos.zd<45)
-                        Out() << '+';
-                    Out() << '\n';
-                }
-*/
-            }
-
             Out() << endl;
 
@@ -381,5 +411,5 @@
         }
 
-        Out() << Time().GetAsStr() << " ----- " << name << " [" << role << "] -----" << endl;
+        Out() << Time().GetAsStr() << " ----- " << trn << " [" << role << "] -----" << endl;
 
         return false;
